import edu.neu.ccs.demeterf.*; import edu.neu.ccs.demeter.Ident; public class TypeChecker extends IDba{ static Type ftype(String s){ return FuncT.parse(s); } static Type NumOpT = ftype("(int int -> int)"); static Type BoolOpT = ftype("(int int -> bool)"); static Type AndOrT = ftype("(bool bool -> bool)"); TEnv update(Lambda l, TEnv te){ return te.extend(l.formal); } Type combine(Arg a, Type t){ return t; } Type combine(Sym s, Ident id, TEnv te){ return te.lookup(s); } Type combine(Num n){ return new NumT(); } Type combine(Bool b){ return new BoolT(); } Type combine(Type t){ return t; } Type combine(If i, Type cond, Type ift, Type iff){ if(!cond.isBoolT()) throw new TE("If: Condition was not Boolean ("+cond+")"); if(!ift.equals(iff)) throw new TE("If: then and else were not the same Type"+ " ("+ift+" != "+iff+")"); return iff; } Type combine(Lambda proc, Type arg, Type body){ return new FuncT(new TypeEmpty().push(arg), body); } Type combine(Call call, Type proc, TypeList args){ if(!proc.isFuncT()) throw new TE("Call: arguments applied to non-function ("+proc+")"); FuncT f = (FuncT)proc; if(f.args.equals(args))return f.ret; throw new TE("Call: argument types are incorrect: got ("+ args+") expected ("+f.args+")"); } Type combine(Op op){ return NumOpT; } Type combine(Less lt){ return BoolOpT; } Type combine(Greater gt){ return BoolOpT; } Type combine(Eq eq){ return BoolOpT; } Type combine(Or or){ return AndOrT; } Type combine(And an){ return AndOrT; } Type combine(Print p, Type t){ return ftype("("+t+" -> "+t+")"); } TypeList combine(ConsList cl, Type f, TypeList r){ return r.push(f); } TypeList combine(EmptyList el){ return new TypeEmpty(); } }