(* * An interpreter. *) structure Interpreter : Interpreter = struct open Env open Parser exception UndefVar exception NonVarLHSofAssign exception NonVarAfterFor (* * evalExp evaluates the parse tree of an expression * and returns the integer obtained by evaluating the expression. * env is an environment in which (variable,integer)-pairs are stored. *) fun evalExp (NumNode n) _ = n | evalExp (VarNode v) env = (case lookup(v,env) of NONE => raise UndefVar | SOME x => x) | evalExp (UminusNode e) env = ~1 * (evalExp e env) | evalExp (MulNode (e1,e2)) env = (evalExp e1 env) * (evalExp e2 env) | evalExp (DivNode (e1,e2)) env = (evalExp e1 env) div (evalExp e2 env) | evalExp (PlusNode (e1,e2)) env = (evalExp e1 env) + (evalExp e2 env) | evalExp (MinusNode (e1,e2)) env = (evalExp e1 env) - (evalExp e2 env) | evalExp (LtNode (e1,e2)) env = (case (evalExp e1 env) < (evalExp e2 env) of true => 1 | false => 0) | evalExp (GtNode (e1,e2)) env = (case (evalExp e1 env) > (evalExp e2 env) of true => 1 | false => 0) | evalExp (EqNode (e1,e2)) env = (case (evalExp e1 env) = (evalExp e2 env) of true => 1 | false => 0) | evalExp (NeqNode (e1,e2)) env = (case (evalExp e1 env) = (evalExp e2 env) of true => 0 | false => 1) | evalExp (AndNode (e1,e2)) env = (case (evalExp e1 env) <> 0 andalso (evalExp e2 env) <> 0 of true => 1 | false => 0) | evalExp (OrNode (e1,e2)) env = (case (evalExp e1 env) <> 0 orelse (evalExp e2 env) <> 0 of true => 1 | false => 0) (* * eval evaluates a parse tree. * evalAssign, evalIf, evalWhile and evalFor are auxiliary for eval. * env is an environment in which (variable,integer)-pairs are stored. *) fun eval [] env = env | eval (sn::sl) env = case sn of AssignNode (e1,e2) => (case e1 of (VarNode v) => eval sl (evalAssign v e2 env) | _ => raise NonVarLHSofAssign) | IfNode (e,sl1,sl2) => eval sl (evalIf e sl1 sl2 env) | WhileNode (e,sl1) => eval sl (evalWhile e sl1 env) | ForNode (e1,e2,e3,sl1) => (case e1 of (VarNode v) => eval sl (evalFor v (evalExp e2 env) e3 sl1 env) | _ => raise NonVarAfterFor) and evalAssign v e env = update (v,(evalExp e env),env) and evalIf e sl1 sl2 env = case (evalExp e env) <> 0 of true => eval sl1 env | false => eval sl2 env and evalWhile e sl env = case (evalExp e env) <> 0 of true => let val env1 = eval sl env in evalWhile e sl env1 end | false => env (* * evalFor is not implemented as intended. * The current implementation just ignores For statements. *) and evalFor v n e sl env = env fun interpreter sl = toList (eval sl empty) end