import edu.neu.ccs.demeterf.ID; import edu.neu.ccs.demeterf.Traversal; import edu.neu.ccs.demeterf.control.EdgeControl; import edu.neu.ccs.demeterf.control.Edge; import edu.neu.ccs.demeter.Ident; public class Eval extends ID{ static Env empty = Env.empty(); Traversal trav; static Value doEval(Exp e, ClassList c){ Eval eval = new ConstrEval(c); EdgeControl ctrl = EdgeControl.create(new Edge(IfExp.class, "thn"), new Edge(IfExp.class, "els"), /*[*/new Edge(Assign.class, "sym"), /*]*/new Edge(RevDef.class, "rest")); ctrl.addBuiltIns(Ident.class,UserT.class,SymExp.class,SymMethExp.class); eval.trav = new Traversal(eval, ctrl); return eval.eval(e, empty); } Value eval(Object e, Env env){ return trav.traverse(e, env); } ValueList eval(AssignList a, Env env){ return trav.traverse(a, env); }/*[*/ ValueList combine(EmptyList e){ return new ValueEmpty(); } ValueList combine(ConsList c, Value f, ValueList r){ return r.push(f); }/*]*/ } class LitEval extends Eval{ Value combine(IntLit lit, int i){ return new IntV(i); } Value combine(BoolLit lit, boolean b){ return new BoolV(b); } } class ExpEval extends LitEval{ Value combine(AddExp e, IntV l, IntV r){ return l.add(r); } Value combine(MultExp e, IntV l, IntV r){ return l.mult(r); } Value combine(NegExp e, IntV l){ return new IntV(-l.val); } Value combine(LessExp e, IntV l, IntV r){ return l.less(r); } Value combine(AndExp e, BoolV l, BoolV r){ return l.and(r); } Value combine(IfExp f, BoolV c, Exp t, Exp e, Env env){ return eval((c.val?t:e), env); } } class ConstrEval extends MethodEval{ ConDescList constr; ConstrEval(ClassList c){ super(c); constr = Methods.conEnv(c); } Value combine(NewExp n, UserT t, ValueList args, Env env){ ConDesc c = constr.find(t); ValueList vl = eval(c.body, empty.push(c.flds.env()) .push(args.env())), obj = vl.pop(args.length()); if(obj.hasNull())throw new RunErr("Uninitialized Fields!"); return new ObjV(t, obj); } ValueList combine(Assign a, AddrExp f, Value v, Env env){ return ValueList.from(env.replace(v, f.addr)); } ValueList combine(AssignCons c, ValueList f, ValueEmpty r){ return f; } ValueList combine(AssignCons c, ValueList f, ValueCons r){ return f.merge(r); } } class MethodEval extends ExpEval{ ClassMethList mthds; MethodEval(ClassList c){ mthds = Methods.methEnv(c); } Value combine(CallExp c, ObjV v, SymMethExp m, ValueList args, Env env){ MethDesc meth = mthds.findMethod(v.type, m.id); Env nenv = empty.push(v.fields.env()) .push(v).push(args.env()); return eval(meth.body, nenv); } Value combine(AddrExp a, int addr, Env env){ return env.get(addr); } Value combine(RevDef rd, Value v, RevDefRest rst, Env env) { return eval(rst.rest, env.push(v)); } Value combine(Return r, Value v){ return v; } }