using System; using compile; using type; using Type = type.Type; using edu.neu.ccs.demeterf; using edu.neu.ccs.demeterf.demfgen.lib; // TypeChecking public class TypeCheck : ID{ public class TE:Exception{ public TE(String s):base(s){}} static Type intT = new Int(); static Type boolT = new Bool(); Type combine(S s){ return intT; } Op combine(Op o){ return o; } Type combine(C c, ArithOp op, Int l, Int r){ return intT; } Type combine(C c, CompOp op, Int l, Int r){ return boolT; } Type combine(C c, BoolOp op, Bool l, Bool r){ return boolT; } Type combine(C c, Op op, Type l, Type r){ throw new TE("Op ("+op.Print()+") doesn\'t match Args: "+ l.Print()+" and "+r.Print()); } Type combine(I ife, Bool c, Int t, Int e){ return t; } Type combine(I ife, Bool c, Bool t, Bool e){ return t; } Type combine(I ife, Bool c, Type t, Type e){ throw new TE("If Branches Don\'t Match: "+t.Print()+" != "+e.Print()); } Type combine(L l, ident id, Type e, E body, List te){ return check(body, te.push(new Pair(id,e))); } class find : List.Pred{ ident id; public find(ident i){ id = i; } public override bool huh(Pair p){ return p.id.Equals(id); } } Type combine(V v, ident id, List te){ return te.find(new find(id)).t; } // Cache the Traversal... and a few static methods for recursion // Ok... the Naming/Lookup of classes is a little difficult. // It goes: "full.name.space.Class,Assembly.Field" static Traversal trav = new Traversal(new TypeCheck(),Control.bypass("L.body")); public static Type check(E e){ return check(e, List.create()); } static Type check(E e, List te){ return trav.traverse(e, te); } }