Main { static void p(String s){{ System.out.print(s); }} public static void main(String args[]) throws Exception {{ try{ Main m = parse(System.in); p("\n"); m = Translate.fixExps(m); //p("Read: ");m.print();p("\n"); TypeCheck.methods(m.cl); //p("\nMeth Types Correct!!\n"); Type t = TypeCheck.doCheck(m.e,m.cl); p(" Type: ");t.print();p("\n"); m = Rewrite.rewrite(m); //p("\nRewrite: ");m.print();p("\n"); Value v = Eval.doEval(m.e,m.cl); p(" Eval: ");v.print();p("\n\n"); }catch(ParseException pe){ System.err.println(" !! ParseError:\n"+pe.getMessage()); //pe.printStackTrace(System.err); } catch(RunErr re){ System.err.println(" !! Error:\n ** "+re.getMessage()); //re.printStackTrace(System.err); } catch(TypeErr te){ System.err.println(" !! Type Error:\n ** "+te.getMessage()); //te.printStackTrace(System.err); } }} void print() to * (PrintVisitor); } Value{ void print() to * (PrintVisitor); } AssignList{ void print() to * (PrintVisitor); } RunErr{ {{ RunErr(String s){ super(s); } }} } TypeErr{ {{ TypeErr(String s){ super(s); } }} } TransErr{ {{ TransErr(String s){ super(s); } }} } ClassDecl{ void print() to * (PrintVisitor); } FFormalList{ void print() to * (PrintVisitor); } MethodI{ FFormalList getArgs(); } Method{ public FFormalList getArgs(){{ return args; }} } Constr{ public FFormalList getArgs(){{ return args; }} } ValueList{ {{ static NullV nuller = new NullV(); boolean isEmpty(){ return true; } ValueList push(Value v){ return new ValueCons(v, this); } ValueList push(ValueList vl){ return vl.append(this); } ValueList append(ValueList vl){ return vl; } ValueList replace(int i, Value v){ throw new RunErr("replace: Bad Address"); } Value lookup(int i){ throw new RunErr("lookup: Bad Address"); } static ValueList nulls(int l){ return (l == 0)?new ValueEmpty():nulls(l-1).push(nuller); } static ValueList from(Env e){ if(e.isEmpty())return new ValueEmpty(); return from(e.pop(1)).push(e.get(0)); } ValueList merge(ValueList l){ if(l.isEmpty())return this; return l; } ValueList pop(int i){ if(i == 0)return this; throw new RunErr("pop: No More Values!"); } int length(){ return 0; } boolean hasNull(){ return false; } Env env(){ return Env.empty(); } public String toString(){ return "]"; } }} void print() to * (PrintVisitor); } ValueCons{ {{ boolean isEmpty(){ return false; } ValueList append(ValueList vl){ return rest.append(vl).push(first); } ValueList replace(int i, Value v){ return (i == 0)?rest.push(v):rest.replace(i-1,v).push(first); } Value lookup(int i){ return (i == 0)?first:rest.lookup(i-1); } ValueList merge(ValueList l){ if(l.isEmpty())return this; ValueCons c = (ValueCons)l; if(first.isNull()) return rest.merge(c.rest).push(c.first); return rest.merge(c.rest).push(first); } ValueList pop(int i){ if(i == 0)return this; return rest.pop(i-1); } int length(){ return 1+rest.length(); } boolean hasNull(){ return first.isNull() || rest.hasNull(); } Env env(){ return rest.env().push(first); } public String toString(){ return "["+first+":"+rest; } }} } Type{ void print() to * (PrintVisitor); {{ public boolean equals(Object o){ return getClass().equals(o.getClass()); } }} } UserT{ {{ UserT(String s){ this(new Ident(s)); } }} void print() to * (PrintVisitor); {{ public boolean equals(Object o){ return ((o instanceof UserT) && name.equals(((UserT)o).name)); } public String toString(){ return ""+name; } }} } IntT{ public String toString(){{ return "int"; }} } BoolT{ public String toString(){{ return "bool"; }} } TypeList{ {{ TypeList push(Type t){ return new TypeCons(t, this); } TypeList push(TypeList tl){ return tl.append(this); } TypeList append(TypeList tl){ return tl; } Type lookup(int i){ throw new RunErr("Bad Address"); } boolean applicable(TypeList l){ return (l instanceof TypeEmpty); } }} void print() to * (PrintVisitor); } TypeCons{ {{ TypeList append(TypeList tl){ return rest.append(tl).push(first); } Type lookup(int i){ return (i == 0)?first:rest.lookup(i-1); } boolean applicable(TypeList l){ if(!(l instanceof TypeCons))return false; TypeCons c = (TypeCons)l; return (c.first.equals(first) && rest.applicable(c.rest)); } }} } ClassList{ {{ ClassDecl find(Ident n){ return find(""+n); } ClassDecl find(String n){ throw new RunErr("Bad Class Name: "+n); } }} } ClassCons{ {{ ClassDecl find(String n){ return n.equals(""+first.id)?first:rest.find(n); } }} } MethDescList{ {{ MethDescList push(MethDesc v){ return new MethDescCons(v, this); } MethDescList push(MethDescList vl){ return vl.append(this); } MethDescList append(MethDescList vl){ return vl; } MethDesc lookup(int i){ throw new RunErr("Bad Address"); } MethDesc find(Ident n){ return find(""+n); } MethDesc find(String name){ throw new RunErr("Method Not Found: "+name); } }} void print() to * (PrintVisitor); } MethDescCons{ {{ MethDescList append(MethDescList vl){ return rest.append(vl).push(first); } MethDesc lookup(int i){ return (i == 0)?first:rest.lookup(i-1); } MethDesc find(String name){ return first.name.equals(name)?first:rest.find(name); } }} } FFormalList{ {{ int length(){ return 0; } TypeList types(){ return new TypeEmpty(); } Env env(){ return Env.empty(); } }} } FFormalCons{ {{ int length(){ return 1+rest.length(); } TypeList types(){ return new TypeCons(first.type,rest.types()); } Env env(){ return rest.env().push(new VarT(""+first.id, first.type)); } }} } FormalList{ {{ int length(){ return 0; } TypeList types(){ return new TypeEmpty(); } Env env(){ return Env.empty(); } }} } FormalCons{ {{ int length(){ return 1+rest.length(); } Env env(){ return rest.env().push(new VarT(""+first.id, first.type)); } }} } FieldList{ {{ int length(){ return 0; } TypeList types(){ return new TypeEmpty(); } Env env(){ return Env.empty(); } }} } FieldCons{ {{ int length(){ return 1+rest.length(); } Env env(){ return rest.env().push(new VarT(""+first.id, first.type)); } }} } Value{ {{ boolean isNull(){ return false; } }} } NullV{ {{ boolean isNull(){ return true; } public String toString(){ return ""; } }} } IntV{ {{ IntV add(IntV i){ return new IntV(val+i.val); } IntV mult(IntV i){ return new IntV(val*i.val); } BoolV less(IntV i){ return new BoolV(val