diff options
-rw-r--r-- | Typecheck.java | 11 | ||||
-rw-r--r-- | minijava/SymTableVis.java | 20 | ||||
-rw-r--r-- | minijava/TypeCheckSimp.java | 942 | ||||
-rw-r--r-- | minijava/TypeInstance.java | 40 |
4 files changed, 669 insertions, 344 deletions
diff --git a/Typecheck.java b/Typecheck.java index be979f5..8e970be 100644 --- a/Typecheck.java +++ b/Typecheck.java @@ -16,13 +16,14 @@ public class Typecheck { // GJDepthFirst<R,A>. R=Void, A=String. PPrinter<Void,String> pp = new PPrinter<Void,String>(); root.accept(pp, ""); + System.out.println("==================================================="); // // Build the symbol table. Top-down visitor, inherits from // // GJDepthFirst<R,A>. R=Void, A=Integer. - // SymTableVis<Void, Integer> pv = - // new SymTableVis<Void,Integer>(); - // root.accept(pv, 0); - // HashMap<String, String> symt = pv.symt; + SymTableVis<Void,Integer> pv = + new SymTableVis<Void,Integer>(); + root.accept(pv, 0); + HashMap<String, TypeEnum> symt = pv.symt; // Do type checking. Bottom-up visitor, also inherits from // GJDepthFirst. Visit functions return MyTpe (=R), and @@ -30,7 +31,7 @@ public class Typecheck { // argument (=A). You may implement things differently of // course! TypeCheckSimp ts = new TypeCheckSimp(); - TypeInstance res = root.accept(ts, null); + TypeInstance res = root.accept(ts, symt); // Ugly code not to be inspired from: "my" way of storing // type info / typecheck property: if some of my internal diff --git a/minijava/SymTableVis.java b/minijava/SymTableVis.java index 3d8003b..e0854f0 100644 --- a/minijava/SymTableVis.java +++ b/minijava/SymTableVis.java @@ -8,9 +8,9 @@ import java.util.*; * Provides default methods which visit each node in the tree in depth-first * order. Your visitors may extend this class. */ -public class SymTableVis<R,A> implements GJVisitor<R,A> { +public class SymTableVis<R,A> extends GJDepthFirst<R,A> { - public HashMap<String,String> symt = new HashMap<>(); + public HashMap<String,TypeEnum> symt = new HashMap<>(); private void print_filter(String message) { boolean debug = true; @@ -18,26 +18,30 @@ public class SymTableVis<R,A> implements GJVisitor<R,A> { System.out.println(message); } - public R visit(VarDeclaraction n, A argu) { - R _ret=null; + /** + * f0 -> Type() + * f1 -> Identifier() + * f2 -> ";" + */ + public R visit(VarDeclaration n, A argu) { this.print_filter("Processing declaration"); - String type = ""; + TypeEnum type = TypeEnum.ERROR; switch (n.f0.f0.which) { case 2: - type = "Int"; break; + type = TypeEnum.integer; break; default: this.print_filter("Unsupported case"); } String id = n.f1.f0.tokenImage; - this.printfilter("Inserting " + id + " => " + type); + this.print_filter("Inserting " + id + " => " + type); // Safe? symt.put(id, type); - return _ret; + return null; } } diff --git a/minijava/TypeCheckSimp.java b/minijava/TypeCheckSimp.java index 01f8b27..ab5d8c9 100644 --- a/minijava/TypeCheckSimp.java +++ b/minijava/TypeCheckSimp.java @@ -8,58 +8,114 @@ import java.util.*; * Provides default methods which visit each node in the tree in depth-first * order. Your visitors may extend this class. */ -public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,String>> { - - private void print_filter(String message) { - boolean debug = true; - if (debug) - System.out.println(message); +public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,TypeEnum>> { + + private int offset; + + private void printNode(Node n, HashMap<String,TypeEnum> argu, boolean enter, TypeEnum consensus) { + for (int i=0; i < this.offset; ++i) + System.out.print("."); + if (enter) + System.out.print("Visiting "); + else + System.out.print("Leaving "); + System.out.print(n.getClass().getSimpleName()); + if (!enter) { + if (consensus == TypeEnum.ERROR) + System.out.print(" did not type check."); + else + System.out.print(" found type " + consensus); + } + System.out.println(); } + // // Auto class visitors--probably don't need to be overridden. // - public TypeInstance visit(NodeList n, HashMap<String,String> argu) { - TypeInstance _ret=null; - int _count=0; - for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) { - e.nextElement().accept(this,argu); - _count++; - } - return _ret; - } - - public TypeInstance visit(NodeListOptional n, HashMap<String,String> argu) { - if ( n.present() ) { - TypeInstance _ret=null; - int _count=0; - for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) { - e.nextElement().accept(this,argu); - _count++; - } - return _ret; - } - else - return null; + public TypeInstance visit(NodeList n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = new TypeInstance(TypeEnum.CHECK); + int _count=0; + for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) { + TypeInstance node = e.nextElement().accept(this,argu); + e.nextElement().accept(this,argu); + if (node.get_type() == TypeEnum.ERROR) + ret = node; + _count++; + } + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; + } + + public TypeInstance visit(NodeListOptional n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret; + if ( n.present() ) { // FIXME "present" seems to check if any nodes exist at all! + ret = new TypeInstance(TypeEnum.CHECK); + int _count=0; + for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) { + TypeInstance node = e.nextElement().accept(this,argu); + if (node.get_type() == TypeEnum.ERROR) + ret = node; + _count++; + } + } + else + ret = new TypeInstance(TypeEnum.CHECK); // FIXME used to read 'null' + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } - public TypeInstance visit(NodeOptional n, HashMap<String,String> argu) { - if ( n.present() ) - return n.node.accept(this,argu); - else - return null; + // FIXME + public TypeInstance visit(NodeOptional n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret; + + if ( n.present() ) + ret = n.node.accept(this,argu); + else + ret = new TypeInstance(TypeEnum.CHECK); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } - public TypeInstance visit(NodeSequence n, HashMap<String,String> argu) { - TypeInstance _ret=null; - int _count=0; - for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) { - e.nextElement().accept(this,argu); - _count++; - } - return _ret; + public TypeInstance visit(NodeSequence n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = new TypeInstance(TypeEnum.CHECK); + int _count=0; + for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) { + TypeInstance node = e.nextElement().accept(this,argu); + if (node.get_type() == TypeEnum.ERROR) + ret = node; + _count++; + } + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } - public TypeInstance visit(NodeToken n, HashMap<String,String> argu) { return null; } + public TypeInstance visit(NodeToken n, HashMap<String,TypeEnum> argu) { + // A fixed string token. '⌣' + ++this.offset; + // this.printNode(n, argu, false, null); + --this.offset; + return null; + } // // User-generated visitor methods below @@ -70,11 +126,17 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> ( TypeDeclaration() )* * f2 -> <EOF> */ - public TypeInstance visit(Goal n, HashMap<String,String> argu) { - TypeInstance ret = n.f0.accept(this, argu); - n.f1.accept(this, argu); - n.f2.accept(this, argu); - return ret; + public TypeInstance visit(Goal n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = n.f0.accept(this, argu); + n.f1.accept(this, argu); + n.f2.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -97,34 +159,47 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f16 -> "}" * f17 -> "}" */ - public TypeInstance visit(MainClass n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - TypeInstance name = n.f1.accept(this, argu); - n.f2.accept(this, argu); - n.f3.accept(this, argu); - n.f4.accept(this, argu); - n.f5.accept(this, argu); - n.f6.accept(this, argu); - n.f7.accept(this, argu); - n.f8.accept(this, argu); - n.f9.accept(this, argu); - n.f10.accept(this, argu); - TypeInstance args = n.f11.accept(this, argu); - n.f12.accept(this, argu); - n.f13.accept(this, argu); - TypeInstance var_dec = n.f14.accept(this, argu); - TypeInstance stmt = n.f15.accept(this, argu); - n.f16.accept(this, argu); - n.f17.accept(this, argu); - return stmt; + public TypeInstance visit(MainClass n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + TypeInstance name = n.f1.accept(this, argu); + n.f2.accept(this, argu); + n.f3.accept(this, argu); + n.f4.accept(this, argu); + n.f5.accept(this, argu); + n.f6.accept(this, argu); + n.f7.accept(this, argu); + n.f8.accept(this, argu); + n.f9.accept(this, argu); + n.f10.accept(this, argu); + TypeInstance args = n.f11.accept(this, argu); + n.f12.accept(this, argu); + n.f13.accept(this, argu); + TypeInstance var_dec = n.f14.accept(this, argu); + TypeInstance stmt = n.f15.accept(this, argu); + n.f16.accept(this, argu); + n.f17.accept(this, argu); + + this.printNode(n, argu, false, stmt.get_type()); + --this.offset; + return stmt; } /** * f0 -> ClassDeclaration() * | ClassExtendsDeclaration() */ - public TypeInstance visit(TypeDeclaration n, HashMap<String,String> argu) { - return n.f0.accept(this, argu); + public TypeInstance visit(TypeDeclaration n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = n.f0.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -135,15 +210,19 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f4 -> ( MethodDeclaration() )* * f5 -> "}" */ - public TypeInstance visit(ClassDeclaration n, HashMap<String,String> argu) { - TypeInstance _ret=null; - n.f0.accept(this, argu); - n.f1.accept(this, argu); - n.f2.accept(this, argu); - n.f3.accept(this, argu); - n.f4.accept(this, argu); - n.f5.accept(this, argu); - return _ret; + public TypeInstance visit(ClassDeclaration n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance _ret=null; + n.f0.accept(this, argu); + n.f1.accept(this, argu); + n.f2.accept(this, argu); + n.f3.accept(this, argu); + n.f4.accept(this, argu); + n.f5.accept(this, argu); + --this.offset; + return _ret; } /** @@ -156,17 +235,21 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f6 -> ( MethodDeclaration() )* * f7 -> "}" */ - public TypeInstance visit(ClassExtendsDeclaration n, HashMap<String,String> argu) { - TypeInstance _ret=null; - n.f0.accept(this, argu); - n.f1.accept(this, argu); - n.f2.accept(this, argu); - n.f3.accept(this, argu); - n.f4.accept(this, argu); - n.f5.accept(this, argu); - n.f6.accept(this, argu); - n.f7.accept(this, argu); - return _ret; + public TypeInstance visit(ClassExtendsDeclaration n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance _ret=null; + n.f0.accept(this, argu); + n.f1.accept(this, argu); + n.f2.accept(this, argu); + n.f3.accept(this, argu); + n.f4.accept(this, argu); + n.f5.accept(this, argu); + n.f6.accept(this, argu); + n.f7.accept(this, argu); + --this.offset; + return _ret; } // FIXME @@ -175,13 +258,20 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> Identifier() * f2 -> ";" */ - public TypeInstance visit(VarDeclaration n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - n.f1.accept(this, argu); - n.f2.accept(this, argu); - return new TypeInstance(TypeEnum.CHECK); + public TypeInstance visit(VarDeclaration n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = n.f0.accept(this, argu); + n.f1.accept(this, argu); + n.f2.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } + // FIXME /** * f0 -> "public" * f1 -> Type() @@ -197,55 +287,84 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f11 -> ";" * f12 -> "}" */ - public TypeInstance visit(MethodDeclaration n, HashMap<String,String> argu) { - TypeInstance _ret=null; - n.f0.accept(this, argu); - n.f1.accept(this, argu); - n.f2.accept(this, argu); - n.f3.accept(this, argu); - n.f4.accept(this, argu); - n.f5.accept(this, argu); - n.f6.accept(this, argu); - n.f7.accept(this, argu); - n.f8.accept(this, argu); - n.f9.accept(this, argu); - n.f10.accept(this, argu); - n.f11.accept(this, argu); - n.f12.accept(this, argu); - return _ret; + public TypeInstance visit(MethodDeclaration n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + TypeInstance ret_type = n.f1.accept(this, argu); + n.f2.accept(this, argu); + n.f3.accept(this, argu); + n.f4.accept(this, argu); + n.f5.accept(this, argu); + n.f6.accept(this, argu); + n.f7.accept(this, argu); + TypeInstance stmt = n.f8.accept(this, argu); + n.f9.accept(this, argu); + TypeInstance retur = n.f10.accept(this, argu); + n.f11.accept(this, argu); + n.f12.accept(this, argu); + TypeInstance ret = (stmt.equal_type(ret_type) && + stmt.get_type() == TypeEnum.CHECK) ? + new TypeInstance(TypeEnum.CHECK) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** * f0 -> FormalParameter() * f1 -> ( FormalParameterRest() )* */ - public TypeInstance visit(FormalParameterList n, HashMap<String,String> argu) { - TypeInstance _ret=null; - n.f0.accept(this, argu); - n.f1.accept(this, argu); - return _ret; + public TypeInstance visit(FormalParameterList n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance _ret=null; + TypeInstance para1 = n.f0.accept(this, argu); + TypeInstance parar = n.f1.accept(this, argu); + TypeInstance ret = (para1.get_type() == TypeEnum.CHECK && + parar.get_type() == TypeEnum.CHECK) ? + new TypeInstance(TypeEnum.CHECK) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** * f0 -> Type() * f1 -> Identifier() */ - public TypeInstance visit(FormalParameter n, HashMap<String,String> argu) { - TypeInstance _ret=null; - n.f0.accept(this, argu); - n.f1.accept(this, argu); - return _ret; + public TypeInstance visit(FormalParameter n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = n.f0.accept(this, argu); + n.f1.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** * f0 -> "," * f1 -> FormalParameter() */ - public TypeInstance visit(FormalParameterRest n, HashMap<String,String> argu) { - TypeInstance _ret=null; - n.f0.accept(this, argu); - n.f1.accept(this, argu); - return _ret; + public TypeInstance visit(FormalParameterRest n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + TypeInstance ret = n.f1.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -254,8 +373,15 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * | IntegerType() * | Identifier() */ - public TypeInstance visit(Type n, HashMap<String,String> argu) { - return n.f0.accept(this, argu); + public TypeInstance visit(Type n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = n.f0.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -263,26 +389,45 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> "[" * f2 -> "]" */ - public TypeInstance visit(ArrayType n, HashMap<String,String> argu) { - TypeInstance _ret=null; - n.f0.accept(this, argu); - n.f1.accept(this, argu); - n.f2.accept(this, argu); - return new TypeInstance(TypeEnum.int_array); + public TypeInstance visit(ArrayType n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + n.f1.accept(this, argu); + n.f2.accept(this, argu); + TypeInstance ret = new TypeInstance(TypeEnum.int_array); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** * f0 -> "boolean" */ - public TypeInstance visit(BooleanType n, HashMap<String,String> argu) { - return n.f0.accept(this, argu); + public TypeInstance visit(BooleanType n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = new TypeInstance(TypeEnum.bool); + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** * f0 -> "int" */ - public TypeInstance visit(IntegerType n, HashMap<String,String> argu) { - return n.f0.accept(this, argu); + public TypeInstance visit(IntegerType n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = new TypeInstance(TypeEnum.integer); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -293,8 +438,15 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * | WhileStatement() * | PrintStatement() */ - public TypeInstance visit(Statement n, HashMap<String,String> argu) { - return n.f0.accept(this, argu); + public TypeInstance visit(Statement n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = n.f0.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -302,11 +454,17 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> ( Statement() )* * f2 -> "}" */ - public TypeInstance visit(Block n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - TypeInstance ret = n.f1.accept(this, argu); - n.f2.accept(this, argu); - return ret; + public TypeInstance visit(Block n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + TypeInstance ret = n.f1.accept(this, argu); + n.f2.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -315,14 +473,21 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f2 -> Expression() * f3 -> ";" */ - public TypeInstance visit(AssignmentStatement n, HashMap<String,String> argu) { - TypeInstance lhs = n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance rhs = n.f2.accept(this, argu); - n.f3.accept(this, argu); - return (lhs.equal_type(rhs)) ? - new TypeInstance(TypeEnum.CHECK) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(AssignmentStatement n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance lhs = n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance rhs = n.f2.accept(this, argu); + n.f3.accept(this, argu); + TypeInstance ret = (lhs.equal_type(rhs)) ? + new TypeInstance(TypeEnum.CHECK) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -334,18 +499,25 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f5 -> Expression() //int * f6 -> ";" */ - public TypeInstance visit(ArrayAssignmentStatement n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance index = n.f2.accept(this, argu); - n.f3.accept(this, argu); - n.f4.accept(this, argu); - TypeInstance value = n.f5.accept(this, argu); - n.f6.accept(this, argu); - return (index.get_type() == TypeEnum.integer && - value.get_type() == TypeEnum.integer) ? - new TypeInstance(TypeEnum.CHECK) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(ArrayAssignmentStatement n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance index = n.f2.accept(this, argu); + n.f3.accept(this, argu); + n.f4.accept(this, argu); + TypeInstance value = n.f5.accept(this, argu); + n.f6.accept(this, argu); + TypeInstance ret = (index.get_type() == TypeEnum.integer && + value.get_type() == TypeEnum.integer) ? + new TypeInstance(TypeEnum.CHECK) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -357,18 +529,27 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f5 -> "else" * f6 -> Statement() */ - public TypeInstance visit(IfStatement n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance expr = n.f2.accept(this, argu); - n.f3.accept(this, argu); - TypeInstance stmt1 = n.f4.accept(this, argu); - n.f5.accept(this, argu); - TypeInstance stmt2 = n.f6.accept(this, argu); - return (expr.get_type() == TypeEnum.bool && - stmt1.get_type() == stmt2.get_type() == TypeEnum.CHECK) ? - new TypeInstance(TypeEnum.CHECK) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(IfStatement n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance expr = n.f2.accept(this, argu); + n.f3.accept(this, argu); + TypeInstance stmt1 = n.f4.accept(this, argu); + n.f5.accept(this, argu); + TypeInstance stmt2 = n.f6.accept(this, argu); + TypeInstance ret = (expr.get_type() == TypeEnum.bool && + stmt1.get_type() == stmt2.get_type() && + stmt1.get_type() == TypeEnum.CHECK) ? + new TypeInstance(TypeEnum.CHECK) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; + } /** @@ -378,16 +559,23 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f3 -> ")" * f4 -> Statement() */ - public TypeInstance visit(WhileStatement n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance expr = n.f2.accept(this, argu); - n.f3.accept(this, argu); - TypeInstance stmt = n.f4.accept(this, argu); - return (expr.get_type() == TypeEnum.bool && - stmt.get_type() == TypeEnum.CHECK) ? - new TypeInstance(TypeEnum.CHECK) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(WhileStatement n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance expr = n.f2.accept(this, argu); + n.f3.accept(this, argu); + TypeInstance stmt = n.f4.accept(this, argu); + TypeInstance ret = (expr.get_type() == TypeEnum.bool && + stmt.get_type() == TypeEnum.CHECK) ? + new TypeInstance(TypeEnum.CHECK) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -397,15 +585,22 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f3 -> ")" * f4 -> ";" */ - public TypeInstance visit(PrintStatement n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance ret = n.f2.accept(this, argu); - n.f3.accept(this, argu); - n.f4.accept(this, argu); - return (ret.get_type() == TypeEnum.integer) ? - new TypeInstance(TypeEnum.CHECK) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(PrintStatement n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance ret = n.f2.accept(this, argu); + n.f3.accept(this, argu); + n.f4.accept(this, argu); + ret = (ret.get_type() == TypeEnum.integer) ? + new TypeInstance(TypeEnum.CHECK) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -419,8 +614,15 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * | MessageSend() * | PrimaryExpression() */ - public TypeInstance visit(Expression n, HashMap<String,String> argu) { - return n.f0.accept(this, argu); + public TypeInstance visit(Expression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = n.f0.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -428,14 +630,21 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> "&&" * f2 -> PrimaryExpression() */ - public TypeInstance visit(AndExpression n, HashMap<String,String> argu) { - TypeInstance oper1 = n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance oper2 = n.f2.accept(this, argu); - return (oper1.get_type() == TypeEnum.bool && - oper2.get_type() == TypeEnum.bool) ? - new TypeInstance(TypeEnum.bool) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(AndExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance oper1 = n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance oper2 = n.f2.accept(this, argu); + TypeInstance ret = (oper1.get_type() == TypeEnum.bool && + oper2.get_type() == TypeEnum.bool) ? + new TypeInstance(TypeEnum.bool) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -443,15 +652,21 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> "<" * f2 -> PrimaryExpression() */ - public TypeInstance visit(CompareExpression n, HashMap<String,String> argu) { - TypeInstance _ret=null; - TypeInstance oper1 = n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance oper2 = n.f2.accept(this, argu); - return (oper1.get_type() == TypeEnum.integer && - oper2.get_type() == TypeEnum.integer) ? - new TypeInstance(TypeEnum.bool) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(CompareExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance oper1 = n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance oper2 = n.f2.accept(this, argu); + TypeInstance ret = (oper1.get_type() == TypeEnum.integer && + oper2.get_type() == TypeEnum.integer) ? + new TypeInstance(TypeEnum.bool) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -459,14 +674,21 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> "+" * f2 -> PrimaryExpression() */ - public TypeInstance visit(PlusExpression n, HashMap<String,String> argu) { - TypeInstance oper1 = n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance oper2 = n.f2.accept(this, argu); - return (oper1.get_type() == TypeEnum.integer && - oper2.get_type() == TypeEnum.integer) ? - new TypeInstance(TypeEnum.integer) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(PlusExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance oper1 = n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance oper2 = n.f2.accept(this, argu); + TypeInstance ret = (oper1.get_type() == TypeEnum.integer && + oper2.get_type() == TypeEnum.integer) ? + new TypeInstance(TypeEnum.integer) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -474,14 +696,21 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> "-" * f2 -> PrimaryExpression() */ - public TypeInstance visit(MinusExpression n, HashMap<String,String> argu) { - TypeInstance oper1 = n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance oper2 = n.f2.accept(this, argu); - return (oper1.get_type() == TypeEnum.integer && - oper2.get_type() == TypeEnum.integer) ? - new TypeInstance(TypeEnum.integer) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(MinusExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance oper1 = n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance oper2 = n.f2.accept(this, argu); + TypeInstance ret = (oper1.get_type() == TypeEnum.integer && + oper2.get_type() == TypeEnum.integer) ? + new TypeInstance(TypeEnum.integer) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -489,14 +718,21 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> "*" * f2 -> PrimaryExpression() */ - public TypeInstance visit(TimesExpression n, HashMap<String,String> argu) { - TypeInstance oper1 = n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance oper2 = n.f2.accept(this, argu); - return (oper1.get_type() == TypeEnum.integer && - oper2.get_type() == TypeEnum.integer) ? - new TypeInstance(TypeEnum.integer) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(TimesExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance oper1 = n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance oper2 = n.f2.accept(this, argu); + TypeInstance ret = (oper1.get_type() == TypeEnum.integer && + oper2.get_type() == TypeEnum.integer) ? + new TypeInstance(TypeEnum.integer) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -505,16 +741,22 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f2 -> PrimaryExpression() * f3 -> "]" */ - public TypeInstance visit(ArrayLookup n, HashMap<String,String> argu) { - TypeInstance _ret=null; - TypeInstance array = n.f0.accept(this, argu); - n.f1.accept(this, argu); - TypeInstance index = n.f2.accept(this, argu); - n.f3.accept(this, argu); - return (array.get_type() == TypeEnum.int_array && - index.get_type() == TypeEnum.integer) ? - new TypeInstance(TypeEnum.integer) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(ArrayLookup n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance array = n.f0.accept(this, argu); + n.f1.accept(this, argu); + TypeInstance index = n.f2.accept(this, argu); + n.f3.accept(this, argu); + TypeInstance ret = (array.get_type() == TypeEnum.int_array && + index.get_type() == TypeEnum.integer) ? + new TypeInstance(TypeEnum.integer) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -522,14 +764,19 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> "." * f2 -> "length" */ - public TypeInstance visit(ArrayLength n, HashMap<String,String> argu) { - // can only act on an array - TypeInstance _ret=null; - TypeInstance ret = n.f0.accept(this, argu); - n.f1.accept(this, argu); - n.f2.accept(this, argu); - return (ret.get_type() == TypeEnum.int_array) ? new TypeInstance(TypeEnum.integer) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(ArrayLength n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = n.f0.accept(this, argu); + n.f1.accept(this, argu); + n.f2.accept(this, argu); + ret = (ret.get_type() == TypeEnum.int_array) ? new TypeInstance(TypeEnum.integer) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -540,15 +787,19 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f4 -> ( ExpressionList() )? * f5 -> ")" */ - public TypeInstance visit(MessageSend n, HashMap<String,String> argu) { - TypeInstance _ret=null; - n.f0.accept(this, argu); - n.f1.accept(this, argu); - n.f2.accept(this, argu); - n.f3.accept(this, argu); - n.f4.accept(this, argu); - n.f5.accept(this, argu); - return _ret; + public TypeInstance visit(MessageSend n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance _ret=null; + n.f0.accept(this, argu); + n.f1.accept(this, argu); + n.f2.accept(this, argu); + n.f3.accept(this, argu); + n.f4.accept(this, argu); + n.f5.accept(this, argu); + --this.offset; + return _ret; } // FIXME @@ -556,21 +807,31 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f0 -> Expression() * f1 -> ( ExpressionRest() )* */ - public TypeInstance visit(ExpressionList n, HashMap<String,String> argu) { + public TypeInstance visit(ExpressionList n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + TypeInstance _ret=null; - n.f0.accept(this, argu); - n.f1.accept(this, argu); - return _ret; + TypeInstance expr1 = n.f0.accept(this, argu); + TypeInstance exprr = n.f1.accept(this, argu); + --this.offset; + return _ret; } /** * f0 -> "," * f1 -> Expression() */ - public TypeInstance visit(ExpressionRest n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - TypeInstance ret = n.f1.accept(this, argu); - return ret; + public TypeInstance visit(ExpressionRest n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + TypeInstance ret = n.f1.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -584,46 +845,81 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * | NotExpression() * | BracketExpression() */ - public TypeInstance visit(PrimaryExpression n, HashMap<String,String> argu) { - return n.f0.accept(this, argu); + public TypeInstance visit(PrimaryExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = n.f0.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** * f0 -> <INTEGER_LITERAL> */ - public TypeInstance visit(IntegerLiteral n, HashMap<String,String> argu) { - return new TypeInstance(TypeEnum.integer); + public TypeInstance visit(IntegerLiteral n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + this.printNode(n, argu, false, TypeEnum.integer); + --this.offset; + return new TypeInstance(TypeEnum.integer); } /** * f0 -> "true" */ - public TypeInstance visit(TrueLiteral n, HashMap<String,String> argu) { - return new TypeInstance(TypeEnum.bool); + public TypeInstance visit(TrueLiteral n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + this.printNode(n, argu, false, TypeEnum.bool); + --this.offset; + return new TypeInstance(TypeEnum.bool); } /** * f0 -> "false" */ - public TypeInstance visit(FalseLiteral n, HashMap<String,String> argu) { - return new TypeInstance(TypeEnum.bool); + public TypeInstance visit(FalseLiteral n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + this.printNode(n, argu, false, TypeEnum.bool); + --this.offset; + return new TypeInstance(TypeEnum.bool); } /** * f0 -> <IDENTIFIER> */ - public TypeInstance visit(Identifier n, HashMap<String,String> argu) { - return new TypeInstance(TypeEnum.CHECK); + public TypeInstance visit(Identifier n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + TypeInstance ret = new TypeInstance(argu.get(n.f0.tokenImage)); + + this.printNode(n, argu, false, TypeEnum.CHECK); + --this.offset; + return new TypeInstance(TypeEnum.CHECK); } //FIXME /** * f0 -> "this" */ - public TypeInstance visit(ThisExpression n, HashMap<String,String> argu) { - TypeInstance _ret=null; - n.f0.accept(this, argu); - return _ret; + public TypeInstance visit(ThisExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + TypeInstance ret = new TypeInstance(TypeEnum.CHECK); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -633,15 +929,21 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f3 -> Expression() * f4 -> "]" */ - public TypeInstance visit(ArrayAllocationExpression n, HashMap<String,String> argu) { - TypeInstance _ret=null; - n.f0.accept(this, argu); - TypeInstance ret = n.f1.accept(this, argu); - n.f2.accept(this, argu); - n.f3.accept(this, argu); - n.f4.accept(this, argu); - return (ret.get_type() == TypeEnum.integer) ? new TypeInstance(TypeEnum.int_array) : - new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(ArrayAllocationExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + TypeInstance ret = n.f1.accept(this, argu); + n.f2.accept(this, argu); + n.f3.accept(this, argu); + n.f4.accept(this, argu); + ret = (ret.get_type() == TypeEnum.integer) ? new TypeInstance(TypeEnum.int_array) : + new TypeInstance(TypeEnum.ERROR); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** @@ -650,22 +952,34 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f2 -> "(" * f3 -> ")" */ - public TypeInstance visit(AllocationExpression n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - TypeInstance ret = n.f1.accept(this, argu); - n.f2.accept(this, argu); - n.f3.accept(this, argu); - return ret; + public TypeInstance visit(AllocationExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + TypeInstance ret = n.f1.accept(this, argu); + n.f2.accept(this, argu); + n.f3.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } /** * f0 -> "!" * f1 -> Expression() */ - public TypeInstance visit(NotExpression n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - TypeInstance ret = n.f1.accept(this, argu); - return (ret.get_type() == TypeEnum.bool) ? ret : new TypeInstance(TypeEnum.ERROR); + public TypeInstance visit(NotExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + TypeInstance ret = n.f1.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return (ret.get_type() == TypeEnum.bool) ? ret : new TypeInstance(TypeEnum.ERROR); } /** @@ -673,11 +987,17 @@ public class TypeCheckSimp implements GJVisitor<TypeInstance,HashMap<String,Stri * f1 -> Expression() * f2 -> ")" */ - public TypeInstance visit(BracketExpression n, HashMap<String,String> argu) { - n.f0.accept(this, argu); - TypeInstance ret = n.f1.accept(this, argu); - n.f2.accept(this, argu); - return ret; + public TypeInstance visit(BracketExpression n, HashMap<String,TypeEnum> argu) { + ++this.offset; + this.printNode(n, argu, true, null); + + n.f0.accept(this, argu); + TypeInstance ret = n.f1.accept(this, argu); + n.f2.accept(this, argu); + + this.printNode(n, argu, false, ret.get_type()); + --this.offset; + return ret; } } diff --git a/minijava/TypeInstance.java b/minijava/TypeInstance.java index 13920e4..483a093 100644 --- a/minijava/TypeInstance.java +++ b/minijava/TypeInstance.java @@ -1,29 +1,29 @@ package minijava; public class TypeInstance { - TypeEnum type; + TypeEnum type; - public TypeInstance(TypeEnum type) { - this.type = type; - } + public TypeInstance(TypeEnum type) { + this.type = type; + } - public boolean equal_type(TypeInstance other) { - /** - * Given a TypeInstance object other, - * returns true if other object - * is the same type as this one. - * - * We can say two types are equal, as - * long as they are not equal on a - * type error! - */ + public boolean equal_type(TypeInstance other) { + /** + * Given a TypeInstance object other, + * returns true if other object + * is the same type as this one. + * + * We can say two types are equal, as + * long as they are not equal on a + * type error! + */ - return this.type != TypeEnum.ERROR - this.type == other.type; - } + return this.type != TypeEnum.ERROR && + this.type == other.type; + } - public TypeEnum get_type() { - return this.type; - } + public TypeEnum get_type() { + return this.type; + } } |