sExpression *eval(sExpression *exp, sEnvironment *env){ /* ------------------atom-----------------------*/ /* 1, 10, false, null, "abc" */ if(isSelfEval(exp)) { return exp; } /* a symbol */ else if(isVariable(exp, env)) { return lookupVariable(toSymb(exp), env); } /* ------------------list-----------------------*/ /* (quote blur blur) */ else if(isQuoted(exp)) { return textOfQuoted(exp); } /* (set! name value) */ else if(isAssignment(exp)) { return evalAssignment(exp, env); } /* (define name value) */ else if(isDefinition(exp)) { return evalDefine(exp, env); } /* (define-syntax name ...) */ else if(isDefinitionSyntax(exp)) { return evalDefineSyntax(exp, env); } /* (if blur blur blur) */ else if(isIf(exp)) { return evalIf(toList(exp), env); } /* (lambda (args) (body)) */ else if(isLambdaConst(exp)) { sList *body; sList *param = toList( cadr(toList(exp))); sExpression *temp = cdr(toList( cdr(toList(exp)))); if(isList(temp)){ body = toList(temp); }else{ body = toList(cons(temp, &sNull)); } return newLambda(param, body, env); } /* (syntax blur blur) syntax rule */ else if(isSymbol(car(toList(exp))) && isSyntaxRule(eval(car(toList(exp)), env))) { sExpression *exp2 = evalSyntaxRule(toSyntax(eval(car(toList(exp)), env)), exp); return eval(exp2, env); } /* the other list (x . y) */ else if(isApplication(exp)) { if(LAZY_EVAL){ sExpression *proexp = actualValue(operator(toList(exp)), env); if(isLambdaType(proexp) || isPrimitiveProc(proexp)){ sExpression *operand = operands(toList(exp)); return applyLazly(proexp, operand, env); } }else{ sExpression *proexp = eval(operator(toList(exp)), env); if(isLambdaType(proexp) || isPrimitiveProc(proexp)){ sExpression *operand = operands(toList(exp)); sExpression *arguments = listOfValues(operand, env); return apply(proexp, arguments, env); } } } return &sError; }
bool isCompoundStatement() const { return isForKeyword() || isIf(); }
static Statement *statement(void) { if (isId()) { Statement *p = NEW(Statement); p->kind = sAssignment; p->assignName = getId(); consume(); if (!isEq()) error(); consume(); p->assignValue = expression(); if (isSemi()) { consume(); } return p; } else if (isReturn()) { Statement *p = NEW(Statement); p->kind = sReturn; consume(); p->returnValue = expression(); if (isSemi()) { consume(); } return p; } else if (isLeftBlock()) { Statement *p = NEW(Statement); p->kind = sBlock; consume(); p->block = block(); if (!isRightBlock()) error(); consume(); return p; } else if (isPrint()) { Statement *p = NEW(Statement); p->kind = sPrint; consume(); p->printValue = expression(); if (isSemi()) { consume(); } return p; } else if (isIf()) { Statement *p = NEW(Statement); p->kind = sIf; consume(); p->ifCondition = expression(); p->ifThen = statement(); if (isElse()) { consume(); p->ifElse = statement(); } else { p->ifElse = 0; } return p; } else if (isWhile()) { Statement *p = NEW(Statement); p->kind = sWhile; consume(); /* while */ p->whileCondition = expression(); p->whileBody = statement(); return p; } else if (isSemi()) { Statement *p = NEW(Statement); p->kind = sBlock; p->block = 0; consume(); return p; } else { return 0; } }