[uim-commit] r1053 - in branches/r5rs/sigscheme: . test
kzk at freedesktop.org
kzk at freedesktop.org
Thu Jul 28 16:25:39 EST 2005
Author: kzk
Date: 2005-07-27 23:25:36 -0700 (Wed, 27 Jul 2005)
New Revision: 1053
Modified:
branches/r5rs/sigscheme/eval.c
branches/r5rs/sigscheme/sigscheme.c
branches/r5rs/sigscheme/test/test-exp.scm
Log:
* implement "cond" correctly
* sigscheme/sigscheme.c
- (SigScm_Initialize): intern "=>" symbol
* sigscheme/eval.c
- (lookup_frame): handle "((lambda (x . z) z) 1)" correctly
- (ScmOp_apply): fixed typo
- (ScmExp_cond): behave as defined in R5RS
- (ScmExp_case): fixed typo
- (ScmExp_or): handle "true" value correctly
Modified: branches/r5rs/sigscheme/eval.c
===================================================================
--- branches/r5rs/sigscheme/eval.c 2005-07-28 06:06:05 UTC (rev 1052)
+++ branches/r5rs/sigscheme/eval.c 2005-07-28 06:25:36 UTC (rev 1053)
@@ -178,7 +178,7 @@
vars = SCM_CAR(frame);
vals = SCM_CDR(frame);
- for (; !SCM_NULLP(vars) && !SCM_NULLP(vals); vars = SCM_CDR(vars), vals = SCM_CDR(vals)) {
+ for (; !SCM_NULLP(vars); vars = SCM_CDR(vars), vals = SCM_CDR(vals)) {
/* handle dot list */
if (SCM_CONSP(vars)) {
if (SCM_EQ(SCM_CAR(vars), var))
@@ -534,7 +534,7 @@
SCM_CAR(SCM_CDR(SCM_CDR(SCM_CDR(SCM_CDR(SCM_CDR(args)))))));
}
default:
- SigScm_ErrorObj("apply : invalid applycation ", args);
+ SigScm_ErrorObj("apply : invalid application ", args);
}
break;
case ScmClosure:
@@ -584,7 +584,7 @@
return ScmOp_eval(obj, env);
}
default:
- SigScm_ErrorObj("apply : invalid applycation ", args);
+ SigScm_ErrorObj("apply : invalid application ", args);
}
/* never reaches here */
@@ -749,7 +749,7 @@
pred = ScmOp_eval(SCM_CAR(exp), env);
/* if pred is SCM_TRUE */
- if (EQ(pred, SCM_TRUE)) {
+ if (!EQ(pred, SCM_FALSE)) {
/* doesn't evaluate now for tail-recursion. */
return SCM_CAR(SCM_CDR(exp));
}
@@ -805,25 +805,63 @@
===========================================================================*/
ScmObj ScmExp_cond(ScmObj arg, ScmObj *envp)
{
+ /*
+ * (cond <clause1> <clause2> ...)
+ *
+ * <clause> should be the form:
+ * (<test> <expression1> <expression2> ...)
+ *
+ * <clause> may be of the form
+ * (<test> => <expression)
+ */
ScmObj env = *envp;
ScmObj clause = SCM_NIL;
ScmObj test = SCM_NIL;
ScmObj exps = SCM_NIL;
+ ScmObj proc = SCM_NIL;
+
/* looping in each clause */
for (; !SCM_NULLP(arg); arg = SCM_CDR(arg)) {
clause = SCM_CAR(arg);
test = SCM_CAR(clause);
exps = SCM_CDR(clause);
- if (SCM_NULLP(clause) || SCM_NULLP(test) || SCM_NULLP(exps))
+
+ if (SCM_NULLP(clause) || SCM_NULLP(test))
SigScm_Error("cond : syntax error\n");
- /* evaluate test and check the result */
- if (SCM_EQ(ScmOp_eval(test, env), SCM_TRUE)) {
+ /* evaluate test */
+ test = ScmOp_eval(test, env);
+
+ /* check the result */
+ if (!SCM_EQ(test, SCM_FALSE)) {
+ /*
+ * if the selected <clause> contains only the <test> and no <expression>s,
+ * then the value of the <test> is returned as the result.
+ */
+ if (SCM_NULLP(exps))
+ return test;
+
+ /*
+ * If the selected <clause> uses the => alternate form, then the <expression>
+ * is evaluated. Its value must be a procedure that accepts one argument;
+ * this procedure is then called on the value of the <test> and the value
+ * returned by this procedure is returned by the cond expression.
+ */
+ if (SCM_EQ(Scm_Intern("=>"), SCM_CAR(exps))) {
+ proc = ScmOp_eval(SCM_CAR(SCM_CDR(exps)), env);
+ if (EQ(ScmOp_procedurep(proc), SCM_FALSE))
+ SigScm_Error("cond : the value of exp after => must be the procedure but got ", proc);
+
+ return ScmOp_apply(Scm_NewCons(proc,
+ Scm_NewCons(test,
+ SCM_NIL)),
+ env);
+ }
+
return ScmExp_begin(exps, &env);
}
}
- SigScm_Error("cond : invalid expression\n");
return SCM_NIL;
}
@@ -841,7 +879,7 @@
datums = SCM_CAR(clause);
exps = SCM_CDR(clause);
if (SCM_NULLP(clause) || SCM_NULLP(datums) || SCM_NULLP(exps))
- SigScm_Error("cond : syntax error\n");
+ SigScm_Error("case : syntax error\n");
/* check "else" symbol */
if (SCM_NULLP(SCM_CDR(arg)) && !SCM_CONSP(datums) && EQ(SCM_SYMBOL_VCELL(datums), SCM_TRUE))
@@ -902,8 +940,8 @@
for (; !SCM_NULLP(arg); arg = SCM_CDR(arg)) {
obj = SCM_CAR(arg);
ret = ScmOp_eval(obj, env);
- if (EQ(ret, SCM_TRUE))
- return SCM_TRUE;
+ if (!EQ(ret, SCM_FALSE))
+ return ret;
/* return last item */
if (SCM_NULLP(SCM_CDR(arg))) {
Modified: branches/r5rs/sigscheme/sigscheme.c
===================================================================
--- branches/r5rs/sigscheme/sigscheme.c 2005-07-28 06:06:05 UTC (rev 1052)
+++ branches/r5rs/sigscheme/sigscheme.c 2005-07-28 06:25:36 UTC (rev 1053)
@@ -96,6 +96,7 @@
SCM_SYMBOL_VCELL(Scm_Intern("#t")) = SCM_TRUE;
SCM_SYMBOL_VCELL(Scm_Intern("#f")) = SCM_FALSE;
SCM_SYMBOL_VCELL(Scm_Intern("else")) = SCM_TRUE;
+ SCM_SYMBOL_VCELL(Scm_Intern("=>")) = SCM_TRUE;
/*=======================================================================
Export Scheme Functions
Modified: branches/r5rs/sigscheme/test/test-exp.scm
===================================================================
--- branches/r5rs/sigscheme/test/test-exp.scm 2005-07-28 06:06:05 UTC (rev 1052)
+++ branches/r5rs/sigscheme/test/test-exp.scm 2005-07-28 06:25:36 UTC (rev 1053)
@@ -27,8 +27,8 @@
(assert-equal? "basic cond test3" #t (cond ((> 3 2))
((< 3 4) 'less)
(else 'equal)))
-;(assert-equal? "basic cond test4" 2 (cond ((assv 'b '((a 1) (b 2))) => cadr)
-; (else #f)))
+(assert-equal? "basic cond test4" 2 (cond ((assv 'b '((a 1) (b 2))) => cadr)
+ (else #f)))
;; case
(assert-eq? "basic case check1" 'case1 (case 1
More information about the uim-commit
mailing list