public static JymlAST.Cons Eval(JymlAST.Cons exp, JymlEnvironment env) { if (exp != null) { if (Parser.IsSelfEvaluating(exp)) { return(new JymlAST.Cons(exp.car, Eval(exp.cdr as JymlAST.Cons, env))); } else if (Parser.IsAssignment(exp)) { return(EvalAssignment(exp, env)); } else if (Parser.IsDefinition(exp)) { return(EvalDefinition(exp, env)); } else if (Parser.IsIf(exp)) { return(EvalIf(exp, env)); } else if (Parser.IsLambda(exp)) { return(MakeLambda(Parser.GetLambdaParameters(exp), Parser.GetLambdaBody(exp), env)); } else if (Parser.IsBegin(exp)) { return(EvalSequence(exp.cdr as JymlAST.Cons, env)); } else if (exp.car is JymlAST.Cons subexp) { return(new JymlAST.Cons(Eval(subexp, env), Eval(exp.cdr as JymlAST.Cons, env))); } else { if (exp.car is string proc) { JymlEnvironment.Restraint restraint = env[proc]; if (restraint != null) { if (restraint.Value is Procedures || restraint.Value is PrimitiveProcedure) { return(Apply(proc, ListOfValues(exp.cdr as JymlAST.Cons, env), env)); } else { return(new JymlAST.Cons(restraint.Value, Eval(exp.cdr as JymlAST.Cons, env))); } } else { if (Parser.IsVariable(exp)) { throw new Exception($"变量 {exp.car} 未定义。"); } else { throw new Exception($"无效的语法:{exp}"); } } } else if (exp.car is JymlAST.Cons cons) { return(Apply(cons, ListOfValues(exp.cdr as JymlAST.Cons, env), env)); } else { throw new Exception($"无效的过程调用:{exp}"); } } } else { return(null); } }
/* * (define (eval-definition exp env) * (define-variable! (definition-variable exp) * (eval (definition-value exp) env) * env)) */ private static JymlAST.Cons EvalDefinition(JymlAST.Cons exp, JymlEnvironment env) { /* * (define (definition-variable exp) * (if [symbol? [mcar [mcdr exp]]] * [mcar [mcdr exp]] * [mcar [mcar [mcdr exp]]])) */ string defineVariable(JymlAST.Cons c) => Parser.IsVariable(c.cdr as JymlAST.Cons) ? (c.cdr as JymlAST.Cons).car as string // 普通变量或 lambda 变量 : ((c.cdr as JymlAST.Cons).car as JymlAST.Cons).car as string; // 过程定义 /* * (define (definition-value exp) * (if [symbol? [mcar [mcdr exp]]] * [mcar [mcdr [mcdr exp]]] * (make-lambda [mcdr [mcar [mcdr exp]]] ; formal parameters * [mcdr [mcdr exp]]))) ; body */ JymlType defineValue(JymlAST.Cons c) { if (Parser.IsVariable(c.cdr as JymlAST.Cons)) { if (((c.cdr as JymlAST.Cons).cdr as JymlAST.Cons).car is string atom) { return(JymlType.CreateType(atom)); // 普通变量或 lambda 变量 } else if (((c.cdr as JymlAST.Cons).cdr as JymlAST.Cons).car is JymlAST.Cons cons) { return(JymlType.CreateType(Eval(cons, env).car)); // 返回一个 value 的子表达式(过程调用) } else { throw new Exception($"define 表达式 {exp} 的 value 部分只能是一个原子值或一个返回原子值的过程调用。"); } } else { return(new Procedures(Parser.GetProcedureName(exp), (JymlAST.Cons)Parser.GetLambdaParameters(exp), Parser.GetLambdaBody(exp), env)); // 过程定义 } } env.DefineVariable(defineVariable(exp), defineValue(exp)); return(null); }