diff --git a/README.md b/README.md
index 99535e3..f26ce65 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,19 @@
MiniJava Compiler
=================
-[Version 1.0.0 - 04/15/2014]
+[Version 1.0.0 - 04/26/2014]
-The following is a LL(1) compiler for a subset of Java, denoted MiniJava. As of now, it appears to work for the most
-part, passing the regression tests performed after each segment.
+The following is a complete MiniJava Compiler implementation, according to the specifications in the docs folder.
-Noted bugs:
-* Changing a field of an object in an array causes crashes
- This is not really a surprise, considering the Contextual Analysis aspect of the project
- is in fairly rough shape.
-
-As of now, I do not plan on implementing more things to this, unless there is some potential for extra credit.
+Other Features to include in future releases
+--------------------------------------------
+* Static Field Initialization
+* Keyword 'null'
+* Support class constructors
+* 'for' loop
+* String type and string literals
+* Code generation for conditional operations && and ||
+* Overloaded methods
+* Inheritance of fields and methods
+* Dynamic Method Invocation
+* Support for instanceof/super
diff --git a/docs/PA1.pdf b/docs/PA1.pdf
deleted file mode 100644
index b934180..0000000
Binary files a/docs/PA1.pdf and /dev/null differ
diff --git a/docs/pa-final.pdf b/docs/pa-final.pdf
new file mode 100644
index 0000000..baaf0d5
Binary files /dev/null and b/docs/pa-final.pdf differ
diff --git a/docs/pa1-updated.pdf b/docs/pa1-updated.pdf
new file mode 100644
index 0000000..827a832
Binary files /dev/null and b/docs/pa1-updated.pdf differ
diff --git a/docs/PA2.pdf b/docs/pa2.pdf
similarity index 100%
rename from docs/PA2.pdf
rename to docs/pa2.pdf
diff --git a/docs/PA3.pdf b/docs/pa3.pdf
similarity index 100%
rename from docs/PA3.pdf
rename to docs/pa3.pdf
diff --git a/docs/PA4.pdf b/docs/pa4.pdf
similarity index 100%
rename from docs/PA4.pdf
rename to docs/pa4.pdf
diff --git a/src/mJAM/Test.java b/src/mJAM/Test.java
index b886ca9..c3b0d66 100644
--- a/src/mJAM/Test.java
+++ b/src/mJAM/Test.java
@@ -151,7 +151,6 @@ public class Test
/* run code */
System.out.println("Running code ... ");
Interpreter.debug(objectCodeFileName, asmCodeFileName);
- // Interpreter.interpret(objectCodeFileName);
System.out.println("*** mJAM execution completed");
}
diff --git a/src/miniJava/AbstractSyntaxTrees/AST.java b/src/miniJava/AbstractSyntaxTrees/AST.java
index 9303c82..5982b3f 100644
--- a/src/miniJava/AbstractSyntaxTrees/AST.java
+++ b/src/miniJava/AbstractSyntaxTrees/AST.java
@@ -1,27 +1,27 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public abstract class AST {
-
- public AST(SourcePosition posn) {
- this.posn = posn;
- }
-
- public String toString() {
- String fullClassName = this.getClass().getName();
- String cn = fullClassName.substring(1 + fullClassName.lastIndexOf('.'));
- if (ASTDisplay.showPosition)
- cn = cn + " " + posn.toString();
- return cn;
- }
-
- public abstract R visit(Visitor v, A o);
-
- public SourcePosition posn;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public abstract class AST {
+
+ public AST(SourcePosition posn) {
+ this.posn = posn;
+ }
+
+ public String toString() {
+ String fullClassName = this.getClass().getName();
+ String cn = fullClassName.substring(1 + fullClassName.lastIndexOf('.'));
+ if (ASTDisplay.showPosition)
+ cn = cn + " " + posn.toString();
+ return cn;
+ }
+
+ public abstract R visit(Visitor v, A o);
+
+ public SourcePosition posn;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/ASTDisplay.java b/src/miniJava/AbstractSyntaxTrees/ASTDisplay.java
index e0daf6b..08d18db 100644
--- a/src/miniJava/AbstractSyntaxTrees/ASTDisplay.java
+++ b/src/miniJava/AbstractSyntaxTrees/ASTDisplay.java
@@ -1,358 +1,358 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-/*
- * Display AST in text form
- * In-order traversal of AST, visiting each node with a method of the form
- *
- * public Object visitXXX( XXX astnode, String arg)
- *
- * where arg is a prefix string (indentation) to precede display of ast node
- * and a null Object is returned as the result.
- *
- * implements Visitor
- */
-public class ASTDisplay implements Visitor {
-
- public static boolean showPosition = false;
-
- /**
- * print text representation of AST to stdout
- *
- * @param ast
- * root node of AST
- */
- public void showTree(AST ast) {
- System.out.println("======= AST Display =========================");
- ast.visit(this, "");
- System.out.println("=============================================");
- }
-
- // methods to format output
-
- /**
- * display arbitrary text for a node
- *
- * @param prefix
- * spacing to indicate depth in AST
- * @param text
- * preformatted node display
- */
- private void show(String prefix, String text) {
- System.out.println(prefix + text);
- }
-
- /**
- * display AST node by name
- *
- * @param prefix
- * spacing to indicate depth in AST
- * @param node
- * AST node, will be shown by name
- */
- private void show(String prefix, AST node) {
- System.out.println(prefix + node.toString());
- }
-
- /**
- * quote a string
- *
- * @param text
- * string to quote
- */
- private String quote(String text) {
- return ("\"" + text + "\"");
- }
-
- /**
- * increase depth in AST
- *
- * @param prefix
- * current spacing to indicate depth in AST
- * @return new spacing
- */
- private String indent(String prefix) {
- return prefix + " ";
- }
-
- // /////////////////////////////////////////////////////////////////////////////
- //
- // PACKAGE
- //
- // /////////////////////////////////////////////////////////////////////////////
-
- public Object visitPackage(Package prog, String arg) {
- show(arg, prog);
- ClassDeclList cl = prog.classDeclList;
- show(arg, " ClassDeclList [" + cl.size() + "]");
- String pfx = arg + " . ";
- for (ClassDecl c : prog.classDeclList) {
- c.visit(this, pfx);
- }
- return null;
- }
-
- // /////////////////////////////////////////////////////////////////////////////
- //
- // DECLARATIONS
- //
- // /////////////////////////////////////////////////////////////////////////////
-
- public Object visitClassDecl(ClassDecl clas, String arg) {
- show(arg, clas);
- show(indent(arg), quote(clas.name) + " classname");
- show(arg, " FieldDeclList [" + clas.fieldDeclList.size() + "]");
- String pfx = arg + " . ";
- for (FieldDecl f : clas.fieldDeclList)
- f.visit(this, pfx);
- show(arg, " MethodDeclList [" + clas.methodDeclList.size() + "]");
- for (MethodDecl m : clas.methodDeclList)
- m.visit(this, pfx);
- return null;
- }
-
- public Object visitFieldDecl(FieldDecl f, String arg) {
- show(arg, "(" + (f.isPrivate ? "private" : "public")
- + (f.isStatic ? " static) " : ") ") + f.toString());
- f.type.visit(this, indent(arg));
- show(indent(arg), quote(f.name) + " fieldname");
- return null;
- }
-
- public Object visitMethodDecl(MethodDecl m, String arg) {
- show(arg, "(" + (m.isPrivate ? "private" : "public")
- + (m.isStatic ? " static) " : ") ") + m.toString());
- m.type.visit(this, indent(arg));
- show(indent(arg), quote(m.name) + " methodname");
- ParameterDeclList pdl = m.parameterDeclList;
- show(arg, " ParameterDeclList [" + pdl.size() + "]");
- String pfx = ((String) arg) + " . ";
- for (ParameterDecl pd : pdl) {
- pd.visit(this, pfx);
- }
- StatementList sl = m.statementList;
- show(arg, " StmtList [" + sl.size() + "]");
- for (Statement s : sl) {
- s.visit(this, pfx);
- }
- if (m.returnExp != null) {
- m.returnExp.visit(this, indent(arg));
- }
- return null;
- }
-
- public Object visitParameterDecl(ParameterDecl pd, String arg) {
- show(arg, pd);
- pd.type.visit(this, indent(arg));
- show(indent(arg), quote(pd.name) + "parametername ");
- return null;
- }
-
- public Object visitVarDecl(VarDecl vd, String arg) {
- show(arg, vd);
- vd.type.visit(this, indent(arg));
- show(indent(arg), quote(vd.name) + " varname");
- return null;
- }
-
- // /////////////////////////////////////////////////////////////////////////////
- //
- // TYPES
- //
- // /////////////////////////////////////////////////////////////////////////////
-
- public Object visitBaseType(BaseType type, String arg) {
- show(arg, type.typeKind + " " + type.toString());
- return null;
- }
-
- public Object visitClassType(ClassType type, String arg) {
- show(arg, type);
- show(indent(arg), quote(type.className.spelling) + " classname");
- return null;
- }
-
- public Object visitArrayType(ArrayType type, String arg) {
- show(arg, type);
- type.eltType.visit(this, indent(arg));
- return null;
- }
-
- // /////////////////////////////////////////////////////////////////////////////
- //
- // STATEMENTS
- //
- // /////////////////////////////////////////////////////////////////////////////
-
- public Object visitBlockStmt(BlockStmt stmt, String arg) {
- show(arg, stmt);
- StatementList sl = stmt.sl;
- show(arg, " StatementList [" + sl.size() + "]");
- String pfx = arg + " . ";
- for (Statement s : sl) {
- s.visit(this, pfx);
- }
- return null;
- }
-
- public Object visitVardeclStmt(VarDeclStmt stmt, String arg) {
- show(arg, stmt);
- stmt.varDecl.visit(this, indent(arg));
- stmt.initExp.visit(this, indent(arg));
- return null;
- }
-
- public Object visitAssignStmt(AssignStmt stmt, String arg) {
- show(arg, stmt);
- stmt.ref.visit(this, indent(arg));
- stmt.val.visit(this, indent(arg));
- return null;
- }
-
- public Object visitCallStmt(CallStmt stmt, String arg) {
- show(arg, stmt);
- stmt.methodRef.visit(this, indent(arg));
- ExprList al = stmt.argList;
- show(arg, " ExprList [" + al.size() + "]");
- String pfx = arg + " . ";
- for (Expression e : al) {
- e.visit(this, pfx);
- }
- return null;
- }
-
- public Object visitIfStmt(IfStmt stmt, String arg) {
- show(arg, stmt);
- stmt.cond.visit(this, indent(arg));
- stmt.thenStmt.visit(this, indent(arg));
- if (stmt.elseStmt != null)
- stmt.elseStmt.visit(this, indent(arg));
- return null;
- }
-
- public Object visitWhileStmt(WhileStmt stmt, String arg) {
- show(arg, stmt);
- stmt.cond.visit(this, indent(arg));
- stmt.body.visit(this, indent(arg));
- return null;
- }
-
- // /////////////////////////////////////////////////////////////////////////////
- //
- // EXPRESSIONS
- //
- // /////////////////////////////////////////////////////////////////////////////
-
- public Object visitUnaryExpr(UnaryExpr expr, String arg) {
- show(arg, expr);
- expr.operator.visit(this, indent(arg));
- expr.expr.visit(this, indent(indent(arg)));
- return null;
- }
-
- public Object visitBinaryExpr(BinaryExpr expr, String arg) {
- show(arg, expr);
- expr.operator.visit(this, indent(arg));
- expr.left.visit(this, indent(indent(arg)));
- expr.right.visit(this, indent(indent(arg)));
- return null;
- }
-
- public Object visitRefExpr(RefExpr expr, String arg) {
- show(arg, expr);
- expr.ref.visit(this, indent(arg));
- return null;
- }
-
- public Object visitCallExpr(CallExpr expr, String arg) {
- show(arg, expr);
- expr.functionRef.visit(this, indent(arg));
- ExprList al = expr.argList;
- show(arg, " ExprList + [" + al.size() + "]");
- String pfx = arg + " . ";
- for (Expression e : al) {
- e.visit(this, pfx);
- }
- return null;
- }
-
- public Object visitLiteralExpr(LiteralExpr expr, String arg) {
- show(arg, expr);
- expr.literal.visit(this, indent(arg));
- return null;
- }
-
- public Object visitNewArrayExpr(NewArrayExpr expr, String arg) {
- show(arg, expr);
- expr.eltType.visit(this, indent(arg));
- expr.sizeExpr.visit(this, indent(arg));
- return null;
- }
-
- public Object visitNewObjectExpr(NewObjectExpr expr, String arg) {
- show(arg, expr);
- expr.classtype.visit(this, indent(arg));
- return null;
- }
-
- // /////////////////////////////////////////////////////////////////////////////
- //
- // REFERENCES
- //
- // /////////////////////////////////////////////////////////////////////////////
-
- public Object visitQualifiedRef(QualifiedRef qr, String arg) {
- show(arg, qr);
- qr.id.visit(this, indent(arg));
- qr.ref.visit(this, indent(arg));
- return null;
- }
-
- public Object visitIndexedRef(IndexedRef ir, String arg) {
- show(arg, ir);
- ir.indexExpr.visit(this, indent(arg));
- ir.ref.visit(this, indent(arg));
- return null;
- }
-
- public Object visitIdRef(IdRef ref, String arg) {
- show(arg, ref);
- ref.id.visit(this, indent(arg));
- return null;
- }
-
- public Object visitThisRef(ThisRef ref, String arg) {
- show(arg, ref);
- return null;
- }
-
- // /////////////////////////////////////////////////////////////////////////////
- //
- // TERMINALS
- //
- // /////////////////////////////////////////////////////////////////////////////
-
- public Object visitIdentifier(Identifier id, String arg) {
- show(arg, quote(id.spelling) + " " + id.toString());
- return null;
- }
-
- public Object visitOperator(Operator op, String arg) {
- show(arg, quote(op.spelling) + " " + op.toString());
- return null;
- }
-
- public Object visitIntLiteral(IntLiteral num, String arg) {
- show(arg, quote(num.spelling) + " " + num.toString());
- return null;
- }
-
- public Object visitBooleanLiteral(BooleanLiteral bool, String arg) {
- show(arg, quote(bool.spelling) + " " + bool.toString());
- return null;
- }
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+/*
+ * Display AST in text form
+ * In-order traversal of AST, visiting each node with a method of the form
+ *
+ * public Object visitXXX( XXX astnode, String arg)
+ *
+ * where arg is a prefix string (indentation) to precede display of ast node
+ * and a null Object is returned as the result.
+ *
+ * implements Visitor
+ */
+public class ASTDisplay implements Visitor {
+
+ public static boolean showPosition = false;
+
+ /**
+ * print text representation of AST to stdout
+ *
+ * @param ast
+ * root node of AST
+ */
+ public void showTree(AST ast) {
+ System.out.println("======= AST Display =========================");
+ ast.visit(this, "");
+ System.out.println("=============================================");
+ }
+
+ // methods to format output
+
+ /**
+ * display arbitrary text for a node
+ *
+ * @param prefix
+ * spacing to indicate depth in AST
+ * @param text
+ * preformatted node display
+ */
+ private void show(String prefix, String text) {
+ System.out.println(prefix + text);
+ }
+
+ /**
+ * display AST node by name
+ *
+ * @param prefix
+ * spacing to indicate depth in AST
+ * @param node
+ * AST node, will be shown by name
+ */
+ private void show(String prefix, AST node) {
+ System.out.println(prefix + node.toString());
+ }
+
+ /**
+ * quote a string
+ *
+ * @param text
+ * string to quote
+ */
+ private String quote(String text) {
+ return ("\"" + text + "\"");
+ }
+
+ /**
+ * increase depth in AST
+ *
+ * @param prefix
+ * current spacing to indicate depth in AST
+ * @return new spacing
+ */
+ private String indent(String prefix) {
+ return prefix + " ";
+ }
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // PACKAGE
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ public Object visitPackage(Package prog, String arg) {
+ show(arg, prog);
+ ClassDeclList cl = prog.classDeclList;
+ show(arg, " ClassDeclList [" + cl.size() + "]");
+ String pfx = arg + " . ";
+ for (ClassDecl c : prog.classDeclList) {
+ c.visit(this, pfx);
+ }
+ return null;
+ }
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // DECLARATIONS
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ public Object visitClassDecl(ClassDecl clas, String arg) {
+ show(arg, clas);
+ show(indent(arg), quote(clas.name) + " classname");
+ show(arg, " FieldDeclList [" + clas.fieldDeclList.size() + "]");
+ String pfx = arg + " . ";
+ for (FieldDecl f : clas.fieldDeclList)
+ f.visit(this, pfx);
+ show(arg, " MethodDeclList [" + clas.methodDeclList.size() + "]");
+ for (MethodDecl m : clas.methodDeclList)
+ m.visit(this, pfx);
+ return null;
+ }
+
+ public Object visitFieldDecl(FieldDecl f, String arg) {
+ show(arg, "(" + (f.isPrivate ? "private" : "public")
+ + (f.isStatic ? " static) " : ") ") + f.toString());
+ f.type.visit(this, indent(arg));
+ show(indent(arg), quote(f.name) + " fieldname");
+ return null;
+ }
+
+ public Object visitMethodDecl(MethodDecl m, String arg) {
+ show(arg, "(" + (m.isPrivate ? "private" : "public")
+ + (m.isStatic ? " static) " : ") ") + m.toString());
+ m.type.visit(this, indent(arg));
+ show(indent(arg), quote(m.name) + " methodname");
+ ParameterDeclList pdl = m.parameterDeclList;
+ show(arg, " ParameterDeclList [" + pdl.size() + "]");
+ String pfx = ((String) arg) + " . ";
+ for (ParameterDecl pd : pdl) {
+ pd.visit(this, pfx);
+ }
+ StatementList sl = m.statementList;
+ show(arg, " StmtList [" + sl.size() + "]");
+ for (Statement s : sl) {
+ s.visit(this, pfx);
+ }
+ if (m.returnExp != null) {
+ m.returnExp.visit(this, indent(arg));
+ }
+ return null;
+ }
+
+ public Object visitParameterDecl(ParameterDecl pd, String arg) {
+ show(arg, pd);
+ pd.type.visit(this, indent(arg));
+ show(indent(arg), quote(pd.name) + "parametername ");
+ return null;
+ }
+
+ public Object visitVarDecl(VarDecl vd, String arg) {
+ show(arg, vd);
+ vd.type.visit(this, indent(arg));
+ show(indent(arg), quote(vd.name) + " varname");
+ return null;
+ }
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // TYPES
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ public Object visitBaseType(BaseType type, String arg) {
+ show(arg, type.typeKind + " " + type.toString());
+ return null;
+ }
+
+ public Object visitClassType(ClassType type, String arg) {
+ show(arg, type);
+ show(indent(arg), quote(type.className.spelling) + " classname");
+ return null;
+ }
+
+ public Object visitArrayType(ArrayType type, String arg) {
+ show(arg, type);
+ type.eltType.visit(this, indent(arg));
+ return null;
+ }
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // STATEMENTS
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ public Object visitBlockStmt(BlockStmt stmt, String arg) {
+ show(arg, stmt);
+ StatementList sl = stmt.sl;
+ show(arg, " StatementList [" + sl.size() + "]");
+ String pfx = arg + " . ";
+ for (Statement s : sl) {
+ s.visit(this, pfx);
+ }
+ return null;
+ }
+
+ public Object visitVardeclStmt(VarDeclStmt stmt, String arg) {
+ show(arg, stmt);
+ stmt.varDecl.visit(this, indent(arg));
+ stmt.initExp.visit(this, indent(arg));
+ return null;
+ }
+
+ public Object visitAssignStmt(AssignStmt stmt, String arg) {
+ show(arg, stmt);
+ stmt.ref.visit(this, indent(arg));
+ stmt.val.visit(this, indent(arg));
+ return null;
+ }
+
+ public Object visitCallStmt(CallStmt stmt, String arg) {
+ show(arg, stmt);
+ stmt.methodRef.visit(this, indent(arg));
+ ExprList al = stmt.argList;
+ show(arg, " ExprList [" + al.size() + "]");
+ String pfx = arg + " . ";
+ for (Expression e : al) {
+ e.visit(this, pfx);
+ }
+ return null;
+ }
+
+ public Object visitIfStmt(IfStmt stmt, String arg) {
+ show(arg, stmt);
+ stmt.cond.visit(this, indent(arg));
+ stmt.thenStmt.visit(this, indent(arg));
+ if (stmt.elseStmt != null)
+ stmt.elseStmt.visit(this, indent(arg));
+ return null;
+ }
+
+ public Object visitWhileStmt(WhileStmt stmt, String arg) {
+ show(arg, stmt);
+ stmt.cond.visit(this, indent(arg));
+ stmt.body.visit(this, indent(arg));
+ return null;
+ }
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // EXPRESSIONS
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ public Object visitUnaryExpr(UnaryExpr expr, String arg) {
+ show(arg, expr);
+ expr.operator.visit(this, indent(arg));
+ expr.expr.visit(this, indent(indent(arg)));
+ return null;
+ }
+
+ public Object visitBinaryExpr(BinaryExpr expr, String arg) {
+ show(arg, expr);
+ expr.operator.visit(this, indent(arg));
+ expr.left.visit(this, indent(indent(arg)));
+ expr.right.visit(this, indent(indent(arg)));
+ return null;
+ }
+
+ public Object visitRefExpr(RefExpr expr, String arg) {
+ show(arg, expr);
+ expr.ref.visit(this, indent(arg));
+ return null;
+ }
+
+ public Object visitCallExpr(CallExpr expr, String arg) {
+ show(arg, expr);
+ expr.functionRef.visit(this, indent(arg));
+ ExprList al = expr.argList;
+ show(arg, " ExprList + [" + al.size() + "]");
+ String pfx = arg + " . ";
+ for (Expression e : al) {
+ e.visit(this, pfx);
+ }
+ return null;
+ }
+
+ public Object visitLiteralExpr(LiteralExpr expr, String arg) {
+ show(arg, expr);
+ expr.literal.visit(this, indent(arg));
+ return null;
+ }
+
+ public Object visitNewArrayExpr(NewArrayExpr expr, String arg) {
+ show(arg, expr);
+ expr.eltType.visit(this, indent(arg));
+ expr.sizeExpr.visit(this, indent(arg));
+ return null;
+ }
+
+ public Object visitNewObjectExpr(NewObjectExpr expr, String arg) {
+ show(arg, expr);
+ expr.classtype.visit(this, indent(arg));
+ return null;
+ }
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // REFERENCES
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ public Object visitQualifiedRef(QualifiedRef qr, String arg) {
+ show(arg, qr);
+ qr.id.visit(this, indent(arg));
+ qr.ref.visit(this, indent(arg));
+ return null;
+ }
+
+ public Object visitIndexedRef(IndexedRef ir, String arg) {
+ show(arg, ir);
+ ir.indexExpr.visit(this, indent(arg));
+ ir.ref.visit(this, indent(arg));
+ return null;
+ }
+
+ public Object visitIdRef(IdRef ref, String arg) {
+ show(arg, ref);
+ ref.id.visit(this, indent(arg));
+ return null;
+ }
+
+ public Object visitThisRef(ThisRef ref, String arg) {
+ show(arg, ref);
+ return null;
+ }
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // TERMINALS
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ public Object visitIdentifier(Identifier id, String arg) {
+ show(arg, quote(id.spelling) + " " + id.toString());
+ return null;
+ }
+
+ public Object visitOperator(Operator op, String arg) {
+ show(arg, quote(op.spelling) + " " + op.toString());
+ return null;
+ }
+
+ public Object visitIntLiteral(IntLiteral num, String arg) {
+ show(arg, quote(num.spelling) + " " + num.toString());
+ return null;
+ }
+
+ public Object visitBooleanLiteral(BooleanLiteral bool, String arg) {
+ show(arg, quote(bool.spelling) + " " + bool.toString());
+ return null;
+ }
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/ArrayType.java b/src/miniJava/AbstractSyntaxTrees/ArrayType.java
index bee4008..3275a14 100644
--- a/src/miniJava/AbstractSyntaxTrees/ArrayType.java
+++ b/src/miniJava/AbstractSyntaxTrees/ArrayType.java
@@ -1,23 +1,27 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class ArrayType extends Type {
-
- public ArrayType(Type eltType, SourcePosition posn) {
- super(TypeKind.ARRAY, posn);
- this.eltType = eltType;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitArrayType(this, o);
- }
-
- public Type eltType;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class ArrayType extends Type {
+
+ public ArrayType(Type eltType, SourcePosition posn) {
+ super(TypeKind.ARRAY, posn);
+ this.eltType = eltType;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitArrayType(this, o);
+ }
+
+ public String toString() {
+ return eltType + " Array";
+ }
+
+ public Type eltType;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/AssignStmt.java b/src/miniJava/AbstractSyntaxTrees/AssignStmt.java
index cc78e3f..d7c3d44 100644
--- a/src/miniJava/AbstractSyntaxTrees/AssignStmt.java
+++ b/src/miniJava/AbstractSyntaxTrees/AssignStmt.java
@@ -1,23 +1,23 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class AssignStmt extends Statement {
- public AssignStmt(Reference r, Expression e, SourcePosition posn) {
- super(posn);
- ref = r;
- val = e;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitAssignStmt(this, o);
- }
-
- public Reference ref;
- public Expression val;
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class AssignStmt extends Statement {
+ public AssignStmt(Reference r, Expression e, SourcePosition posn) {
+ super(posn);
+ ref = r;
+ val = e;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitAssignStmt(this, o);
+ }
+
+ public Reference ref;
+ public Expression val;
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/BaseType.java b/src/miniJava/AbstractSyntaxTrees/BaseType.java
index d39fe5b..69bc9af 100644
--- a/src/miniJava/AbstractSyntaxTrees/BaseType.java
+++ b/src/miniJava/AbstractSyntaxTrees/BaseType.java
@@ -1,18 +1,22 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class BaseType extends Type {
- public BaseType(TypeKind t, SourcePosition posn) {
- super(t, posn);
- }
-
- public R visit(Visitor v, A o) {
- return v.visitBaseType(this, o);
- }
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class BaseType extends Type {
+ public BaseType(TypeKind t, SourcePosition posn) {
+ super(t, posn);
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitBaseType(this, o);
+ }
+
+ public String toString() {
+ return typeKind.toString();
+ }
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/BinaryExpr.java b/src/miniJava/AbstractSyntaxTrees/BinaryExpr.java
index 4488c19..cb925a5 100644
--- a/src/miniJava/AbstractSyntaxTrees/BinaryExpr.java
+++ b/src/miniJava/AbstractSyntaxTrees/BinaryExpr.java
@@ -1,26 +1,26 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class BinaryExpr extends Expression {
- public BinaryExpr(Operator o, Expression e1, Expression e2,
- SourcePosition posn) {
- super(posn);
- operator = o;
- left = e1;
- right = e2;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitBinaryExpr(this, o);
- }
-
- public Operator operator;
- public Expression left;
- public Expression right;
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class BinaryExpr extends Expression {
+ public BinaryExpr(Operator o, Expression e1, Expression e2,
+ SourcePosition posn) {
+ super(posn);
+ operator = o;
+ left = e1;
+ right = e2;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitBinaryExpr(this, o);
+ }
+
+ public Operator operator;
+ public Expression left;
+ public Expression right;
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/BlockStmt.java b/src/miniJava/AbstractSyntaxTrees/BlockStmt.java
index 1a4e2d9..a2c7459 100644
--- a/src/miniJava/AbstractSyntaxTrees/BlockStmt.java
+++ b/src/miniJava/AbstractSyntaxTrees/BlockStmt.java
@@ -1,21 +1,21 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class BlockStmt extends Statement {
- public BlockStmt(StatementList sl, SourcePosition posn) {
- super(posn);
- this.sl = sl;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitBlockStmt(this, o);
- }
-
- public StatementList sl;
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class BlockStmt extends Statement {
+ public BlockStmt(StatementList sl, SourcePosition posn) {
+ super(posn);
+ this.sl = sl;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitBlockStmt(this, o);
+ }
+
+ public StatementList sl;
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/BooleanLiteral.java b/src/miniJava/AbstractSyntaxTrees/BooleanLiteral.java
index d0b4302..669c205 100644
--- a/src/miniJava/AbstractSyntaxTrees/BooleanLiteral.java
+++ b/src/miniJava/AbstractSyntaxTrees/BooleanLiteral.java
@@ -1,19 +1,19 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class BooleanLiteral extends Literal {
-
- public BooleanLiteral(String spelling, SourcePosition posn) {
- super(spelling, posn);
- }
-
- public R visit(Visitor v, A o) {
- return v.visitBooleanLiteral(this, o);
- }
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class BooleanLiteral extends Literal {
+
+ public BooleanLiteral(String spelling, SourcePosition posn) {
+ super(spelling, posn);
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitBooleanLiteral(this, o);
+ }
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/CallExpr.java b/src/miniJava/AbstractSyntaxTrees/CallExpr.java
index 5aaa41f..d17ba9f 100644
--- a/src/miniJava/AbstractSyntaxTrees/CallExpr.java
+++ b/src/miniJava/AbstractSyntaxTrees/CallExpr.java
@@ -1,23 +1,23 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class CallExpr extends Expression {
- public CallExpr(Reference f, ExprList el, SourcePosition posn) {
- super(posn);
- functionRef = f;
- argList = el;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitCallExpr(this, o);
- }
-
- public Reference functionRef;
- public ExprList argList;
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class CallExpr extends Expression {
+ public CallExpr(Reference f, ExprList el, SourcePosition posn) {
+ super(posn);
+ functionRef = f;
+ argList = el;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitCallExpr(this, o);
+ }
+
+ public Reference functionRef;
+ public ExprList argList;
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/CallStmt.java b/src/miniJava/AbstractSyntaxTrees/CallStmt.java
index 966f984..2353a82 100644
--- a/src/miniJava/AbstractSyntaxTrees/CallStmt.java
+++ b/src/miniJava/AbstractSyntaxTrees/CallStmt.java
@@ -1,23 +1,23 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class CallStmt extends Statement {
- public CallStmt(Reference m, ExprList el, SourcePosition posn) {
- super(posn);
- methodRef = m;
- argList = el;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitCallStmt(this, o);
- }
-
- public Reference methodRef;
- public ExprList argList;
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class CallStmt extends Statement {
+ public CallStmt(Reference m, ExprList el, SourcePosition posn) {
+ super(posn);
+ methodRef = m;
+ argList = el;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitCallStmt(this, o);
+ }
+
+ public Reference methodRef;
+ public ExprList argList;
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/ClassDecl.java b/src/miniJava/AbstractSyntaxTrees/ClassDecl.java
index 39a96be..d99706c 100644
--- a/src/miniJava/AbstractSyntaxTrees/ClassDecl.java
+++ b/src/miniJava/AbstractSyntaxTrees/ClassDecl.java
@@ -1,27 +1,25 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class ClassDecl extends Declaration {
-
- public ClassDecl(String cn, FieldDeclList fdl, MethodDeclList mdl, SourcePosition posn) {
- super(cn, null, posn);
- fieldDeclList = fdl;
- methodDeclList = mdl;
-
- Identifier ident = new Identifier(cn, posn);
- type = new ClassType(ident, posn);
- }
-
- public R visit(Visitor v, A o) {
- return v.visitClassDecl(this, o);
- }
-
- public FieldDeclList fieldDeclList;
- public MethodDeclList methodDeclList;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class ClassDecl extends Declaration {
+
+ public ClassDecl(String cn, FieldDeclList fdl, MethodDeclList mdl,
+ SourcePosition posn) {
+ super(cn, null, posn);
+ fieldDeclList = fdl;
+ methodDeclList = mdl;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitClassDecl(this, o);
+ }
+
+ public FieldDeclList fieldDeclList;
+ public MethodDeclList methodDeclList;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/ClassDeclList.java b/src/miniJava/AbstractSyntaxTrees/ClassDeclList.java
index 64dd757..495908d 100644
--- a/src/miniJava/AbstractSyntaxTrees/ClassDeclList.java
+++ b/src/miniJava/AbstractSyntaxTrees/ClassDeclList.java
@@ -1,32 +1,32 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import java.util.*;
-
-public class ClassDeclList implements Iterable {
- public ClassDeclList() {
- classDeclList = new ArrayList();
- }
-
- public void add(ClassDecl cd) {
- classDeclList.add(cd);
- }
-
- public ClassDecl get(int i) {
- return classDeclList.get(i);
- }
-
- public int size() {
- return classDeclList.size();
- }
-
- public Iterator iterator() {
- return classDeclList.iterator();
- }
-
- private List classDeclList;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import java.util.*;
+
+public class ClassDeclList implements Iterable {
+ public ClassDeclList() {
+ classDeclList = new ArrayList();
+ }
+
+ public void add(ClassDecl cd) {
+ classDeclList.add(cd);
+ }
+
+ public ClassDecl get(int i) {
+ return classDeclList.get(i);
+ }
+
+ public int size() {
+ return classDeclList.size();
+ }
+
+ public Iterator iterator() {
+ return classDeclList.iterator();
+ }
+
+ private List classDeclList;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/ClassType.java b/src/miniJava/AbstractSyntaxTrees/ClassType.java
index 0c2c312..b1e8df9 100644
--- a/src/miniJava/AbstractSyntaxTrees/ClassType.java
+++ b/src/miniJava/AbstractSyntaxTrees/ClassType.java
@@ -1,21 +1,25 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class ClassType extends Type {
- public ClassType(Identifier cn, SourcePosition posn) {
- super(TypeKind.CLASS, posn);
- className = cn;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitClassType(this, o);
- }
-
- public Identifier className;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class ClassType extends Type {
+ public ClassType(Identifier cn, SourcePosition posn) {
+ super(TypeKind.CLASS, posn);
+ className = cn;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitClassType(this, o);
+ }
+
+ public String toString() {
+ return "Class " + className.spelling;
+ }
+
+ public Identifier className;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/Declaration.java b/src/miniJava/AbstractSyntaxTrees/Declaration.java
index a412631..05f6021 100644
--- a/src/miniJava/AbstractSyntaxTrees/Declaration.java
+++ b/src/miniJava/AbstractSyntaxTrees/Declaration.java
@@ -1,32 +1,24 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.CodeGenerator.RuntimeEntity;
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public abstract class Declaration extends AST {
-
- public Declaration(String name, Type type, SourcePosition posn) {
- super(posn);
- this.name = name;
- this.type = type;
- }
-
- @Override
- public String toString() {
- if (posn != null) {
- return this.name + "(Line: " + posn.line + ", Column: " + posn.col
- + ")";
- } else {
- return super.toString();
- }
- }
-
- public RuntimeEntity entity;
- public String name;
- public Type type;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.CodeGenerator.RuntimeEntity;
+import miniJava.ContextualAnalyzer.IdTable;
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public abstract class Declaration extends AST {
+
+ public Declaration(String name, Type type, SourcePosition posn) {
+ super(posn);
+ this.name = name;
+ this.type = type;
+ }
+
+ public RuntimeEntity entity;
+ public IdTable table;
+ public String name;
+ public Type type;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/Declarators.java b/src/miniJava/AbstractSyntaxTrees/Declarators.java
index 3f10afb..e6c3a0e 100644
--- a/src/miniJava/AbstractSyntaxTrees/Declarators.java
+++ b/src/miniJava/AbstractSyntaxTrees/Declarators.java
@@ -2,6 +2,10 @@ package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
+/**
+ * The following is a custom class, included for use with method and field
+ * declarations.
+ */
public class Declarators {
public Declarators(boolean isPrivate, boolean isStatic, Type mt,
@@ -16,4 +20,4 @@ public class Declarators {
public boolean isStatic;
public Type mt;
public SourcePosition posn;
-}
+}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/ExprList.java b/src/miniJava/AbstractSyntaxTrees/ExprList.java
index 3aa9cf8..a30054f 100644
--- a/src/miniJava/AbstractSyntaxTrees/ExprList.java
+++ b/src/miniJava/AbstractSyntaxTrees/ExprList.java
@@ -1,32 +1,32 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import java.util.*;
-
-public class ExprList implements Iterable {
- public ExprList() {
- elist = new ArrayList();
- }
-
- public void add(Expression e) {
- elist.add(e);
- }
-
- public Expression get(int i) {
- return elist.get(i);
- }
-
- public int size() {
- return elist.size();
- }
-
- public Iterator iterator() {
- return elist.iterator();
- }
-
- private List elist;
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import java.util.*;
+
+public class ExprList implements Iterable {
+ public ExprList() {
+ elist = new ArrayList();
+ }
+
+ public void add(Expression e) {
+ elist.add(e);
+ }
+
+ public Expression get(int i) {
+ return elist.get(i);
+ }
+
+ public int size() {
+ return elist.size();
+ }
+
+ public Iterator iterator() {
+ return elist.iterator();
+ }
+
+ private List elist;
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/Expression.java b/src/miniJava/AbstractSyntaxTrees/Expression.java
index 7086815..34912ee 100644
--- a/src/miniJava/AbstractSyntaxTrees/Expression.java
+++ b/src/miniJava/AbstractSyntaxTrees/Expression.java
@@ -1,16 +1,16 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public abstract class Expression extends AST {
-
- public Expression(SourcePosition posn) {
- super(posn);
- }
-
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public abstract class Expression extends AST {
+
+ public Expression(SourcePosition posn) {
+ super(posn);
+ }
+
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/FieldDecl.java b/src/miniJava/AbstractSyntaxTrees/FieldDecl.java
index 12a11f7..ee7e71e 100644
--- a/src/miniJava/AbstractSyntaxTrees/FieldDecl.java
+++ b/src/miniJava/AbstractSyntaxTrees/FieldDecl.java
@@ -1,24 +1,28 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class FieldDecl extends MemberDecl {
-
- public FieldDecl(boolean isPrivate, boolean isStatic, Type t, String name,
- SourcePosition posn) {
- super(isPrivate, isStatic, t, name, posn);
- }
-
- public FieldDecl(MemberDecl md, SourcePosition posn) {
- super(md, posn);
- }
-
- public R visit(Visitor v, A o) {
- return v.visitFieldDecl(this, o);
- }
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class FieldDecl extends MemberDecl {
+
+ public FieldDecl(boolean isPrivate, boolean isStatic, Type t, String name,
+ SourcePosition posn) {
+ super(isPrivate, isStatic, t, name, posn);
+ }
+
+ public FieldDecl(MemberDecl md, SourcePosition posn) {
+ super(md, posn);
+ }
+
+ public FieldDecl(Declarators d, String name) {
+ super(d.isPrivate, d.isStatic, d.mt, name, d.posn);
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitFieldDecl(this, o);
+ }
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/FieldDeclList.java b/src/miniJava/AbstractSyntaxTrees/FieldDeclList.java
index a2a476b..03e8226 100644
--- a/src/miniJava/AbstractSyntaxTrees/FieldDeclList.java
+++ b/src/miniJava/AbstractSyntaxTrees/FieldDeclList.java
@@ -1,37 +1,32 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import java.util.*;
-
-public class FieldDeclList implements Iterable {
- public FieldDeclList() {
- fieldDeclList = new ArrayList();
- }
-
- public FieldDeclList(FieldDecl f) {
- fieldDeclList = new ArrayList();
- fieldDeclList.add(f);
- }
-
- public void add(FieldDecl cd) {
- fieldDeclList.add(cd);
- }
-
- public FieldDecl get(int i) {
- return fieldDeclList.get(i);
- }
-
- public int size() {
- return fieldDeclList.size();
- }
-
- public Iterator iterator() {
- return fieldDeclList.iterator();
- }
-
- private List fieldDeclList;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import java.util.*;
+
+public class FieldDeclList implements Iterable {
+ public FieldDeclList() {
+ fieldDeclList = new ArrayList();
+ }
+
+ public void add(FieldDecl cd) {
+ fieldDeclList.add(cd);
+ }
+
+ public FieldDecl get(int i) {
+ return fieldDeclList.get(i);
+ }
+
+ public int size() {
+ return fieldDeclList.size();
+ }
+
+ public Iterator iterator() {
+ return fieldDeclList.iterator();
+ }
+
+ private List fieldDeclList;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/IdRef.java b/src/miniJava/AbstractSyntaxTrees/IdRef.java
index cc3e555..696ec40 100644
--- a/src/miniJava/AbstractSyntaxTrees/IdRef.java
+++ b/src/miniJava/AbstractSyntaxTrees/IdRef.java
@@ -1,22 +1,22 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class IdRef extends Reference {
-
- public IdRef(Identifier id, SourcePosition posn) {
- super(posn);
- this.id = id;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitIdRef(this, o);
- }
-
- public Identifier id;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class IdRef extends Reference {
+
+ public IdRef(Identifier id, SourcePosition posn) {
+ super(posn);
+ this.id = id;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitIdRef(this, o);
+ }
+
+ public Identifier id;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/Identifier.java b/src/miniJava/AbstractSyntaxTrees/Identifier.java
index 1d0c0a5..dde46f7 100644
--- a/src/miniJava/AbstractSyntaxTrees/Identifier.java
+++ b/src/miniJava/AbstractSyntaxTrees/Identifier.java
@@ -1,21 +1,23 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class Identifier extends Terminal {
-
- public Identifier(String s, SourcePosition posn) {
- super(s, posn);
- }
-
- public R visit(Visitor v, A o) {
- return v.visitIdentifier(this, o);
- }
-
- public Declaration decl = null;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.CodeGenerator.RuntimeEntity;
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class Identifier extends Terminal {
+
+ public Identifier(String s, SourcePosition posn) {
+ super(s, posn);
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitIdentifier(this, o);
+ }
+
+ public Declaration decl;
+ public RuntimeEntity entity;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/IfStmt.java b/src/miniJava/AbstractSyntaxTrees/IfStmt.java
index 7ceb5aa..f546cb2 100644
--- a/src/miniJava/AbstractSyntaxTrees/IfStmt.java
+++ b/src/miniJava/AbstractSyntaxTrees/IfStmt.java
@@ -1,32 +1,32 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class IfStmt extends Statement {
- public IfStmt(Expression b, Statement t, Statement e, SourcePosition posn) {
- super(posn);
- cond = b;
- thenStmt = t;
- elseStmt = e;
- }
-
- public IfStmt(Expression b, Statement t, SourcePosition posn) {
- super(posn);
- cond = b;
- thenStmt = t;
- elseStmt = null;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitIfStmt(this, o);
- }
-
- public Expression cond;
- public Statement thenStmt;
- public Statement elseStmt;
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class IfStmt extends Statement {
+ public IfStmt(Expression b, Statement t, Statement e, SourcePosition posn) {
+ super(posn);
+ cond = b;
+ thenStmt = t;
+ elseStmt = e;
+ }
+
+ public IfStmt(Expression b, Statement t, SourcePosition posn) {
+ super(posn);
+ cond = b;
+ thenStmt = t;
+ elseStmt = null;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitIfStmt(this, o);
+ }
+
+ public Expression cond;
+ public Statement thenStmt;
+ public Statement elseStmt;
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/IndexedRef.java b/src/miniJava/AbstractSyntaxTrees/IndexedRef.java
index a52a014..d009e2c 100644
--- a/src/miniJava/AbstractSyntaxTrees/IndexedRef.java
+++ b/src/miniJava/AbstractSyntaxTrees/IndexedRef.java
@@ -1,24 +1,24 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class IndexedRef extends Reference {
-
- public IndexedRef(Reference ref, Expression expr, SourcePosition posn) {
- super(posn);
- this.ref = ref;
- this.indexExpr = expr;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitIndexedRef(this, o);
- }
-
- public Reference ref;
- public Expression indexExpr;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class IndexedRef extends Reference {
+
+ public IndexedRef(Reference ref, Expression expr, SourcePosition posn) {
+ super(posn);
+ this.ref = ref;
+ this.indexExpr = expr;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitIndexedRef(this, o);
+ }
+
+ public Reference ref;
+ public Expression indexExpr;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/IntLiteral.java b/src/miniJava/AbstractSyntaxTrees/IntLiteral.java
index 2e0e0d1..8b97e8e 100644
--- a/src/miniJava/AbstractSyntaxTrees/IntLiteral.java
+++ b/src/miniJava/AbstractSyntaxTrees/IntLiteral.java
@@ -1,19 +1,19 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class IntLiteral extends Literal {
-
- public IntLiteral(String s, SourcePosition posn) {
- super(s, posn);
- }
-
- public R visit(Visitor v, A o) {
- return v.visitIntLiteral(this, o);
- }
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class IntLiteral extends Literal {
+
+ public IntLiteral(String s, SourcePosition posn) {
+ super(s, posn);
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitIntLiteral(this, o);
+ }
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/Literal.java b/src/miniJava/AbstractSyntaxTrees/Literal.java
index 5c0f5cc..ae727fc 100644
--- a/src/miniJava/AbstractSyntaxTrees/Literal.java
+++ b/src/miniJava/AbstractSyntaxTrees/Literal.java
@@ -1,15 +1,15 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public abstract class Literal extends Terminal {
-
- public Literal(String spelling, SourcePosition posn) {
- super(spelling, posn);
- }
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public abstract class Literal extends Terminal {
+
+ public Literal(String spelling, SourcePosition posn) {
+ super(spelling, posn);
+ }
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/LiteralExpr.java b/src/miniJava/AbstractSyntaxTrees/LiteralExpr.java
index 83c26d1..70aad01 100644
--- a/src/miniJava/AbstractSyntaxTrees/LiteralExpr.java
+++ b/src/miniJava/AbstractSyntaxTrees/LiteralExpr.java
@@ -1,21 +1,21 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class LiteralExpr extends Expression {
- public LiteralExpr(Literal c, SourcePosition posn) {
- super(posn);
- literal = c;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitLiteralExpr(this, o);
- }
-
- public Literal literal;
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class LiteralExpr extends Expression {
+ public LiteralExpr(Literal c, SourcePosition posn) {
+ super(posn);
+ literal = c;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitLiteralExpr(this, o);
+ }
+
+ public Literal literal;
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/LocalDecl.java b/src/miniJava/AbstractSyntaxTrees/LocalDecl.java
index d03b6c2..8968ac0 100644
--- a/src/miniJava/AbstractSyntaxTrees/LocalDecl.java
+++ b/src/miniJava/AbstractSyntaxTrees/LocalDecl.java
@@ -1,16 +1,16 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public abstract class LocalDecl extends Declaration {
-
- public LocalDecl(String name, Type t, SourcePosition posn) {
- super(name, t, posn);
- }
-
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public abstract class LocalDecl extends Declaration {
+
+ public LocalDecl(String name, Type t, SourcePosition posn) {
+ super(name, t, posn);
+ }
+
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/MemberDecl.java b/src/miniJava/AbstractSyntaxTrees/MemberDecl.java
index a199a86..5a2df13 100644
--- a/src/miniJava/AbstractSyntaxTrees/MemberDecl.java
+++ b/src/miniJava/AbstractSyntaxTrees/MemberDecl.java
@@ -1,27 +1,27 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-abstract public class MemberDecl extends Declaration {
-
- public MemberDecl(boolean isPrivate, boolean isStatic, Type mt,
- String name, SourcePosition posn) {
- super(name, mt, posn);
- this.isPrivate = isPrivate;
- this.isStatic = isStatic;
- }
-
- public MemberDecl(MemberDecl md, SourcePosition posn) {
- super(md.name, md.type, posn);
- this.isPrivate = md.isPrivate;
- this.isStatic = md.isStatic;
- }
-
- public boolean isPrivate;
- public boolean isStatic;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+abstract public class MemberDecl extends Declaration {
+
+ public MemberDecl(boolean isPrivate, boolean isStatic, Type mt,
+ String name, SourcePosition posn) {
+ super(name, mt, posn);
+ this.isPrivate = isPrivate;
+ this.isStatic = isStatic;
+ }
+
+ public MemberDecl(MemberDecl md, SourcePosition posn) {
+ super(md.name, md.type, posn);
+ this.isPrivate = md.isPrivate;
+ this.isStatic = md.isStatic;
+ }
+
+ public boolean isPrivate;
+ public boolean isStatic;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/MethodDecl.java b/src/miniJava/AbstractSyntaxTrees/MethodDecl.java
index 54ab4e5..71c58a2 100644
--- a/src/miniJava/AbstractSyntaxTrees/MethodDecl.java
+++ b/src/miniJava/AbstractSyntaxTrees/MethodDecl.java
@@ -1,27 +1,27 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class MethodDecl extends MemberDecl {
-
- public MethodDecl(MemberDecl md, ParameterDeclList pl, StatementList sl,
- Expression e, SourcePosition posn) {
- super(md, posn);
- parameterDeclList = pl;
- statementList = sl;
- returnExp = e;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitMethodDecl(this, o);
- }
-
- public ParameterDeclList parameterDeclList;
- public StatementList statementList;
- public Expression returnExp;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class MethodDecl extends MemberDecl {
+
+ public MethodDecl(MemberDecl md, ParameterDeclList pl, StatementList sl,
+ Expression e, SourcePosition posn) {
+ super(md, posn);
+ parameterDeclList = pl;
+ statementList = sl;
+ returnExp = e;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitMethodDecl(this, o);
+ }
+
+ public ParameterDeclList parameterDeclList;
+ public StatementList statementList;
+ public Expression returnExp;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/MethodDeclList.java b/src/miniJava/AbstractSyntaxTrees/MethodDeclList.java
index 41bb12f..bf79e72 100644
--- a/src/miniJava/AbstractSyntaxTrees/MethodDeclList.java
+++ b/src/miniJava/AbstractSyntaxTrees/MethodDeclList.java
@@ -1,37 +1,32 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import java.util.*;
-
-public class MethodDeclList implements Iterable {
- public MethodDeclList() {
- methodDeclList = new ArrayList();
- }
-
- public MethodDeclList(MethodDecl m) {
- methodDeclList = new ArrayList();
- methodDeclList.add(m);
- }
-
- public void add(MethodDecl cd) {
- methodDeclList.add(cd);
- }
-
- public MethodDecl get(int i) {
- return methodDeclList.get(i);
- }
-
- public int size() {
- return methodDeclList.size();
- }
-
- public Iterator iterator() {
- return methodDeclList.iterator();
- }
-
- private List methodDeclList;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import java.util.*;
+
+public class MethodDeclList implements Iterable {
+ public MethodDeclList() {
+ methodDeclList = new ArrayList();
+ }
+
+ public void add(MethodDecl cd) {
+ methodDeclList.add(cd);
+ }
+
+ public MethodDecl get(int i) {
+ return methodDeclList.get(i);
+ }
+
+ public int size() {
+ return methodDeclList.size();
+ }
+
+ public Iterator iterator() {
+ return methodDeclList.iterator();
+ }
+
+ private List methodDeclList;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/NewArrayExpr.java b/src/miniJava/AbstractSyntaxTrees/NewArrayExpr.java
index 398c18e..52a8934 100644
--- a/src/miniJava/AbstractSyntaxTrees/NewArrayExpr.java
+++ b/src/miniJava/AbstractSyntaxTrees/NewArrayExpr.java
@@ -1,23 +1,23 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class NewArrayExpr extends NewExpr {
- public NewArrayExpr(Type et, Expression e, SourcePosition posn) {
- super(posn);
- eltType = et;
- sizeExpr = e;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitNewArrayExpr(this, o);
- }
-
- public Type eltType;
- public Expression sizeExpr;
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class NewArrayExpr extends NewExpr {
+ public NewArrayExpr(Type et, Expression e, SourcePosition posn) {
+ super(posn);
+ eltType = et;
+ sizeExpr = e;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitNewArrayExpr(this, o);
+ }
+
+ public Type eltType;
+ public Expression sizeExpr;
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/NewExpr.java b/src/miniJava/AbstractSyntaxTrees/NewExpr.java
index 62c271d..9842110 100644
--- a/src/miniJava/AbstractSyntaxTrees/NewExpr.java
+++ b/src/miniJava/AbstractSyntaxTrees/NewExpr.java
@@ -1,15 +1,15 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public abstract class NewExpr extends Expression {
-
- public NewExpr(SourcePosition posn) {
- super(posn);
- }
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public abstract class NewExpr extends Expression {
+
+ public NewExpr(SourcePosition posn) {
+ super(posn);
+ }
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/NewObjectExpr.java b/src/miniJava/AbstractSyntaxTrees/NewObjectExpr.java
index 9217ebf..82ea4ea 100644
--- a/src/miniJava/AbstractSyntaxTrees/NewObjectExpr.java
+++ b/src/miniJava/AbstractSyntaxTrees/NewObjectExpr.java
@@ -1,21 +1,21 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class NewObjectExpr extends NewExpr {
- public NewObjectExpr(ClassType ct, SourcePosition posn) {
- super(posn);
- classtype = ct;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitNewObjectExpr(this, o);
- }
-
- public ClassType classtype;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class NewObjectExpr extends NewExpr {
+ public NewObjectExpr(ClassType ct, SourcePosition posn) {
+ super(posn);
+ classtype = ct;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitNewObjectExpr(this, o);
+ }
+
+ public ClassType classtype;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/Operator.java b/src/miniJava/AbstractSyntaxTrees/Operator.java
index 00016ab..f570d02 100644
--- a/src/miniJava/AbstractSyntaxTrees/Operator.java
+++ b/src/miniJava/AbstractSyntaxTrees/Operator.java
@@ -1,23 +1,22 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-import miniJava.SyntacticAnalyzer.Token;
-
-public class Operator extends Terminal {
-
- public Operator(Token t, SourcePosition posn) {
- super(t.spelling, posn);
- token = t;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitOperator(this, o);
- }
-
- public Token token;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+import miniJava.SyntacticAnalyzer.Token;
+
+public class Operator extends Terminal {
+
+ public Operator(Token t, SourcePosition posn) {
+ super(t.spelling, posn);
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitOperator(this, o);
+ }
+
+ public Token token;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/Package.java b/src/miniJava/AbstractSyntaxTrees/Package.java
index 974564c..638d322 100644
--- a/src/miniJava/AbstractSyntaxTrees/Package.java
+++ b/src/miniJava/AbstractSyntaxTrees/Package.java
@@ -1,22 +1,22 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class Package extends AST {
-
- public Package(ClassDeclList cdl, SourcePosition posn) {
- super(posn);
- classDeclList = cdl;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitPackage(this, o);
- }
-
- public ClassDeclList classDeclList;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class Package extends AST {
+
+ public Package(ClassDeclList cdl, SourcePosition posn) {
+ super(posn);
+ classDeclList = cdl;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitPackage(this, o);
+ }
+
+ public ClassDeclList classDeclList;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/ParameterDecl.java b/src/miniJava/AbstractSyntaxTrees/ParameterDecl.java
index 56655e4..ba454e2 100644
--- a/src/miniJava/AbstractSyntaxTrees/ParameterDecl.java
+++ b/src/miniJava/AbstractSyntaxTrees/ParameterDecl.java
@@ -1,19 +1,19 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class ParameterDecl extends LocalDecl {
-
- public ParameterDecl(Type t, String name, SourcePosition posn) {
- super(name, t, posn);
- }
-
- public R visit(Visitor v, A o) {
- return v.visitParameterDecl(this, o);
- }
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class ParameterDecl extends LocalDecl {
+
+ public ParameterDecl(Type t, String name, SourcePosition posn) {
+ super(name, t, posn);
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitParameterDecl(this, o);
+ }
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/ParameterDeclList.java b/src/miniJava/AbstractSyntaxTrees/ParameterDeclList.java
index 9612836..2b80ada 100644
--- a/src/miniJava/AbstractSyntaxTrees/ParameterDeclList.java
+++ b/src/miniJava/AbstractSyntaxTrees/ParameterDeclList.java
@@ -1,37 +1,32 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import java.util.*;
-
-public class ParameterDeclList implements Iterable {
- public ParameterDeclList() {
- parameterDeclList = new ArrayList();
- }
-
- public ParameterDeclList(ParameterDecl p) {
- parameterDeclList = new ArrayList();
- parameterDeclList.add(p);
- }
-
- public void add(ParameterDecl s) {
- parameterDeclList.add(s);
- }
-
- public ParameterDecl get(int i) {
- return parameterDeclList.get(i);
- }
-
- public int size() {
- return parameterDeclList.size();
- }
-
- public Iterator iterator() {
- return parameterDeclList.iterator();
- }
-
- private List parameterDeclList;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import java.util.*;
+
+public class ParameterDeclList implements Iterable {
+ public ParameterDeclList() {
+ parameterDeclList = new ArrayList();
+ }
+
+ public void add(ParameterDecl s) {
+ parameterDeclList.add(s);
+ }
+
+ public ParameterDecl get(int i) {
+ return parameterDeclList.get(i);
+ }
+
+ public int size() {
+ return parameterDeclList.size();
+ }
+
+ public Iterator iterator() {
+ return parameterDeclList.iterator();
+ }
+
+ private List parameterDeclList;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/QualifiedRef.java b/src/miniJava/AbstractSyntaxTrees/QualifiedRef.java
index c147f79..74192a7 100644
--- a/src/miniJava/AbstractSyntaxTrees/QualifiedRef.java
+++ b/src/miniJava/AbstractSyntaxTrees/QualifiedRef.java
@@ -1,25 +1,25 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class QualifiedRef extends Reference {
-
- public QualifiedRef(Reference ref, Identifier id, SourcePosition posn) {
- super(posn);
- this.ref = ref;
- this.id = id;
- }
-
- @Override
- public R visit(Visitor v, A o) {
- return v.visitQualifiedRef(this, o);
- }
-
- public Reference ref;
- public Identifier id;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class QualifiedRef extends Reference {
+
+ public QualifiedRef(Reference ref, Identifier id, SourcePosition posn) {
+ super(posn);
+ this.ref = ref;
+ this.id = id;
+ }
+
+ @Override
+ public R visit(Visitor v, A o) {
+ return v.visitQualifiedRef(this, o);
+ }
+
+ public Reference ref;
+ public Identifier id;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/RefExpr.java b/src/miniJava/AbstractSyntaxTrees/RefExpr.java
index 4f289b2..2d570e2 100644
--- a/src/miniJava/AbstractSyntaxTrees/RefExpr.java
+++ b/src/miniJava/AbstractSyntaxTrees/RefExpr.java
@@ -1,21 +1,21 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class RefExpr extends Expression {
- public RefExpr(Reference r, SourcePosition posn) {
- super(posn);
- ref = r;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitRefExpr(this, o);
- }
-
- public Reference ref;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class RefExpr extends Expression {
+ public RefExpr(Reference r, SourcePosition posn) {
+ super(posn);
+ ref = r;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitRefExpr(this, o);
+ }
+
+ public Reference ref;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/Reference.java b/src/miniJava/AbstractSyntaxTrees/Reference.java
index 7998896..c373659 100644
--- a/src/miniJava/AbstractSyntaxTrees/Reference.java
+++ b/src/miniJava/AbstractSyntaxTrees/Reference.java
@@ -1,18 +1,19 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.CodeGenerator.RuntimeEntity;
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public abstract class Reference extends AST {
- public Reference(SourcePosition posn) {
- super(posn);
- }
-
- public Declaration decl;
- public RuntimeEntity entity;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.CodeGenerator.RuntimeEntity;
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public abstract class Reference extends AST {
+ public Reference(SourcePosition posn) {
+ super(posn);
+ }
+
+ public String spelling;
+ public Declaration decl;
+ public RuntimeEntity entity;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/Statement.java b/src/miniJava/AbstractSyntaxTrees/Statement.java
index e8db4cb..6d332b0 100644
--- a/src/miniJava/AbstractSyntaxTrees/Statement.java
+++ b/src/miniJava/AbstractSyntaxTrees/Statement.java
@@ -1,16 +1,16 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public abstract class Statement extends AST {
-
- public Statement(SourcePosition posn) {
- super(posn);
- }
-
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public abstract class Statement extends AST {
+
+ public Statement(SourcePosition posn) {
+ super(posn);
+ }
+
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/StatementList.java b/src/miniJava/AbstractSyntaxTrees/StatementList.java
index b6bd1d9..d2fbfb8 100644
--- a/src/miniJava/AbstractSyntaxTrees/StatementList.java
+++ b/src/miniJava/AbstractSyntaxTrees/StatementList.java
@@ -1,32 +1,32 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import java.util.*;
-
-public class StatementList implements Iterable {
- public StatementList() {
- slist = new ArrayList();
- }
-
- public void add(Statement s) {
- slist.add(s);
- }
-
- public Statement get(int i) {
- return slist.get(i);
- }
-
- public int size() {
- return slist.size();
- }
-
- public Iterator iterator() {
- return slist.iterator();
- }
-
- private List slist;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import java.util.*;
+
+public class StatementList implements Iterable {
+ public StatementList() {
+ slist = new ArrayList();
+ }
+
+ public void add(Statement s) {
+ slist.add(s);
+ }
+
+ public Statement get(int i) {
+ return slist.get(i);
+ }
+
+ public int size() {
+ return slist.size();
+ }
+
+ public Iterator iterator() {
+ return slist.iterator();
+ }
+
+ private List slist;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/Terminal.java b/src/miniJava/AbstractSyntaxTrees/Terminal.java
index fb28172..4ee4f21 100644
--- a/src/miniJava/AbstractSyntaxTrees/Terminal.java
+++ b/src/miniJava/AbstractSyntaxTrees/Terminal.java
@@ -1,18 +1,18 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-abstract public class Terminal extends AST {
-
- public Terminal(String s, SourcePosition posn) {
- super(posn);
- spelling = s;
- }
-
- public String spelling;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+abstract public class Terminal extends AST {
+
+ public Terminal(String s, SourcePosition posn) {
+ super(posn);
+ spelling = s;
+ }
+
+ public String spelling;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/ThisRef.java b/src/miniJava/AbstractSyntaxTrees/ThisRef.java
index 082340c..874a590 100644
--- a/src/miniJava/AbstractSyntaxTrees/ThisRef.java
+++ b/src/miniJava/AbstractSyntaxTrees/ThisRef.java
@@ -1,21 +1,21 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class ThisRef extends Reference {
-
- public ThisRef(SourcePosition posn) {
- super(posn);
- }
-
- @Override
- public R visit(Visitor v, A o) {
- return v.visitThisRef(this, o);
- }
-
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class ThisRef extends Reference {
+
+ public ThisRef(SourcePosition posn) {
+ super(posn);
+ }
+
+ @Override
+ public R visit(Visitor v, A o) {
+ return v.visitThisRef(this, o);
+ }
+
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/Type.java b/src/miniJava/AbstractSyntaxTrees/Type.java
index ef45865..463bfb6 100644
--- a/src/miniJava/AbstractSyntaxTrees/Type.java
+++ b/src/miniJava/AbstractSyntaxTrees/Type.java
@@ -1,19 +1,19 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-abstract public class Type extends AST {
-
- public Type(TypeKind typ, SourcePosition posn) {
- super(posn);
- typeKind = typ;
- }
-
- public TypeKind typeKind;
-
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+abstract public class Type extends AST {
+
+ public Type(TypeKind typ, SourcePosition posn) {
+ super(posn);
+ typeKind = typ;
+ }
+
+ public TypeKind typeKind;
+
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/TypeKind.java b/src/miniJava/AbstractSyntaxTrees/TypeKind.java
index 824ddbb..b9421bb 100644
--- a/src/miniJava/AbstractSyntaxTrees/TypeKind.java
+++ b/src/miniJava/AbstractSyntaxTrees/TypeKind.java
@@ -1,10 +1,10 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-public enum TypeKind {
- VOID, INT, BOOLEAN, CLASS, ARRAY, UNSUPPORTED, ERROR, EQUALS, RELATIONAL;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+public enum TypeKind {
+ VOID, INT, BOOLEAN, CLASS, ARRAY, UNSUPPORTED, ERROR;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/UnaryExpr.java b/src/miniJava/AbstractSyntaxTrees/UnaryExpr.java
index eeb8e56..ecf8504 100644
--- a/src/miniJava/AbstractSyntaxTrees/UnaryExpr.java
+++ b/src/miniJava/AbstractSyntaxTrees/UnaryExpr.java
@@ -1,23 +1,23 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class UnaryExpr extends Expression {
- public UnaryExpr(Operator o, Expression e, SourcePosition posn) {
- super(posn);
- operator = o;
- expr = e;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitUnaryExpr(this, o);
- }
-
- public Operator operator;
- public Expression expr;
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class UnaryExpr extends Expression {
+ public UnaryExpr(Operator o, Expression e, SourcePosition posn) {
+ super(posn);
+ operator = o;
+ expr = e;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitUnaryExpr(this, o);
+ }
+
+ public Operator operator;
+ public Expression expr;
}
\ No newline at end of file
diff --git a/src/miniJava/AbstractSyntaxTrees/VarDecl.java b/src/miniJava/AbstractSyntaxTrees/VarDecl.java
index 2be65c3..8231714 100644
--- a/src/miniJava/AbstractSyntaxTrees/VarDecl.java
+++ b/src/miniJava/AbstractSyntaxTrees/VarDecl.java
@@ -1,19 +1,19 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class VarDecl extends LocalDecl {
-
- public VarDecl(Type t, String name, SourcePosition posn) {
- super(name, t, posn);
- }
-
- public R visit(Visitor v, A o) {
- return v.visitVarDecl(this, o);
- }
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class VarDecl extends LocalDecl {
+
+ public VarDecl(Type t, String name, SourcePosition posn) {
+ super(name, t, posn);
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitVarDecl(this, o);
+ }
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/VarDeclStmt.java b/src/miniJava/AbstractSyntaxTrees/VarDeclStmt.java
index 3e74d70..56db252 100644
--- a/src/miniJava/AbstractSyntaxTrees/VarDeclStmt.java
+++ b/src/miniJava/AbstractSyntaxTrees/VarDeclStmt.java
@@ -1,23 +1,23 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class VarDeclStmt extends Statement {
- public VarDeclStmt(VarDecl vd, Expression e, SourcePosition posn) {
- super(posn);
- varDecl = vd;
- initExp = e;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitVardeclStmt(this, o);
- }
-
- public VarDecl varDecl;
- public Expression initExp;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class VarDeclStmt extends Statement {
+ public VarDeclStmt(VarDecl vd, Expression e, SourcePosition posn) {
+ super(posn);
+ varDecl = vd;
+ initExp = e;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitVardeclStmt(this, o);
+ }
+
+ public VarDecl varDecl;
+ public Expression initExp;
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/Visitor.java b/src/miniJava/AbstractSyntaxTrees/Visitor.java
index 2045d36..08c2541 100644
--- a/src/miniJava/AbstractSyntaxTrees/Visitor.java
+++ b/src/miniJava/AbstractSyntaxTrees/Visitor.java
@@ -1,80 +1,80 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-/**
- * An implementation of the Visitor interface provides a method visitX for each
- * non-abstract AST class X.
- */
-public interface Visitor {
-
- // Package
- public ResultType visitPackage(Package prog, ArgType arg);
-
- // Declarations
- public ResultType visitClassDecl(ClassDecl cd, ArgType arg);
-
- public ResultType visitFieldDecl(FieldDecl fd, ArgType arg);
-
- public ResultType visitMethodDecl(MethodDecl md, ArgType arg);
-
- public ResultType visitParameterDecl(ParameterDecl pd, ArgType arg);
-
- public ResultType visitVarDecl(VarDecl decl, ArgType arg);
-
- // Types
- public ResultType visitBaseType(BaseType type, ArgType arg);
-
- public ResultType visitClassType(ClassType type, ArgType arg);
-
- public ResultType visitArrayType(ArrayType type, ArgType arg);
-
- // Statements
- public ResultType visitBlockStmt(BlockStmt stmt, ArgType arg);
-
- public ResultType visitVardeclStmt(VarDeclStmt stmt, ArgType arg);
-
- public ResultType visitAssignStmt(AssignStmt stmt, ArgType arg);
-
- public ResultType visitCallStmt(CallStmt stmt, ArgType arg);
-
- public ResultType visitIfStmt(IfStmt stmt, ArgType arg);
-
- public ResultType visitWhileStmt(WhileStmt stmt, ArgType arg);
-
- // Expressions
- public ResultType visitUnaryExpr(UnaryExpr expr, ArgType arg);
-
- public ResultType visitBinaryExpr(BinaryExpr expr, ArgType arg);
-
- public ResultType visitRefExpr(RefExpr expr, ArgType arg);
-
- public ResultType visitCallExpr(CallExpr expr, ArgType arg);
-
- public ResultType visitLiteralExpr(LiteralExpr expr, ArgType arg);
-
- public ResultType visitNewObjectExpr(NewObjectExpr expr, ArgType arg);
-
- public ResultType visitNewArrayExpr(NewArrayExpr expr, ArgType arg);
-
- // References
- public ResultType visitQualifiedRef(QualifiedRef ref, ArgType arg);
-
- public ResultType visitIndexedRef(IndexedRef ref, ArgType arg);
-
- public ResultType visitIdRef(IdRef ref, ArgType arg);
-
- public ResultType visitThisRef(ThisRef ref, ArgType arg);
-
- // Terminals
- public ResultType visitIdentifier(Identifier id, ArgType arg);
-
- public ResultType visitOperator(Operator op, ArgType arg);
-
- public ResultType visitIntLiteral(IntLiteral num, ArgType arg);
-
- public ResultType visitBooleanLiteral(BooleanLiteral bool, ArgType arg);
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+/**
+ * An implementation of the Visitor interface provides a method visitX for each
+ * non-abstract AST class X.
+ */
+public interface Visitor {
+
+ // Package
+ public ResultType visitPackage(Package prog, ArgType arg);
+
+ // Declarations
+ public ResultType visitClassDecl(ClassDecl cd, ArgType arg);
+
+ public ResultType visitFieldDecl(FieldDecl fd, ArgType arg);
+
+ public ResultType visitMethodDecl(MethodDecl md, ArgType arg);
+
+ public ResultType visitParameterDecl(ParameterDecl pd, ArgType arg);
+
+ public ResultType visitVarDecl(VarDecl decl, ArgType arg);
+
+ // Types
+ public ResultType visitBaseType(BaseType type, ArgType arg);
+
+ public ResultType visitClassType(ClassType type, ArgType arg);
+
+ public ResultType visitArrayType(ArrayType type, ArgType arg);
+
+ // Statements
+ public ResultType visitBlockStmt(BlockStmt stmt, ArgType arg);
+
+ public ResultType visitVardeclStmt(VarDeclStmt stmt, ArgType arg);
+
+ public ResultType visitAssignStmt(AssignStmt stmt, ArgType arg);
+
+ public ResultType visitCallStmt(CallStmt stmt, ArgType arg);
+
+ public ResultType visitIfStmt(IfStmt stmt, ArgType arg);
+
+ public ResultType visitWhileStmt(WhileStmt stmt, ArgType arg);
+
+ // Expressions
+ public ResultType visitUnaryExpr(UnaryExpr expr, ArgType arg);
+
+ public ResultType visitBinaryExpr(BinaryExpr expr, ArgType arg);
+
+ public ResultType visitRefExpr(RefExpr expr, ArgType arg);
+
+ public ResultType visitCallExpr(CallExpr expr, ArgType arg);
+
+ public ResultType visitLiteralExpr(LiteralExpr expr, ArgType arg);
+
+ public ResultType visitNewObjectExpr(NewObjectExpr expr, ArgType arg);
+
+ public ResultType visitNewArrayExpr(NewArrayExpr expr, ArgType arg);
+
+ // References
+ public ResultType visitQualifiedRef(QualifiedRef ref, ArgType arg);
+
+ public ResultType visitIndexedRef(IndexedRef ref, ArgType arg);
+
+ public ResultType visitIdRef(IdRef ref, ArgType arg);
+
+ public ResultType visitThisRef(ThisRef ref, ArgType arg);
+
+ // Terminals
+ public ResultType visitIdentifier(Identifier id, ArgType arg);
+
+ public ResultType visitOperator(Operator op, ArgType arg);
+
+ public ResultType visitIntLiteral(IntLiteral num, ArgType arg);
+
+ public ResultType visitBooleanLiteral(BooleanLiteral bool, ArgType arg);
+}
diff --git a/src/miniJava/AbstractSyntaxTrees/WhileStmt.java b/src/miniJava/AbstractSyntaxTrees/WhileStmt.java
index 3695b45..88d3a22 100644
--- a/src/miniJava/AbstractSyntaxTrees/WhileStmt.java
+++ b/src/miniJava/AbstractSyntaxTrees/WhileStmt.java
@@ -1,23 +1,23 @@
-/**
- * miniJava Abstract Syntax Tree classes
- * @author prins
- * @version COMP 520 (v2.2)
- */
-package miniJava.AbstractSyntaxTrees;
-
-import miniJava.SyntacticAnalyzer.SourcePosition;
-
-public class WhileStmt extends Statement {
- public WhileStmt(Expression b, Statement s, SourcePosition posn) {
- super(posn);
- cond = b;
- body = s;
- }
-
- public R visit(Visitor v, A o) {
- return v.visitWhileStmt(this, o);
- }
-
- public Expression cond;
- public Statement body;
-}
+/**
+ * miniJava Abstract Syntax Tree classes
+ * @author prins
+ * @version COMP 520 (v2.2)
+ */
+package miniJava.AbstractSyntaxTrees;
+
+import miniJava.SyntacticAnalyzer.SourcePosition;
+
+public class WhileStmt extends Statement {
+ public WhileStmt(Expression b, Statement s, SourcePosition posn) {
+ super(posn);
+ cond = b;
+ body = s;
+ }
+
+ public R visit(Visitor v, A o) {
+ return v.visitWhileStmt(this, o);
+ }
+
+ public Expression cond;
+ public Statement body;
+}
diff --git a/src/miniJava/CodeGenerator/Code.java b/src/miniJava/CodeGenerator/Code.java
new file mode 100644
index 0000000..fa32703
--- /dev/null
+++ b/src/miniJava/CodeGenerator/Code.java
@@ -0,0 +1,55 @@
+package miniJava.CodeGenerator;
+
+import mJAM.Machine;
+import miniJava.AbstractSyntaxTrees.*;
+
+public class Code {
+
+ public boolean addr;
+ public Declaration decl;
+
+ /**
+ * If addr true, returns the address of the declaration.
+ * Otherwise, uses the size of the declaration in its place.
+ * @param op
+ * @param decl
+ * @param addr
+ */
+ public Code(Declaration decl, boolean addr) {
+ this.decl = decl;
+ this.addr = addr;
+ }
+
+ /**
+ *
+ * @param index
+ */
+ public void modify(int instr) {
+
+ // Setup size
+ switch(decl.type.typeKind) {
+ case ARRAY:
+ case CLASS:
+ Machine.code[instr].n = Machine.addressSize;
+ case INT:
+ Machine.code[instr].n = Machine.integerSize;
+ case BOOLEAN:
+ Machine.code[instr].n = Machine.booleanSize;
+ case VOID:
+ Machine.code[instr].n = 0;
+ default:
+ Machine.code[instr].n = -1;
+ }
+
+ // Setup displacement
+ if(addr) {
+ Machine.code[instr].d += decl.entity.addr;
+ } else {
+ Machine.code[instr].d += decl.entity.size;
+ }
+
+ // Setup register
+ Machine.code[instr].r = decl.entity.reg.ordinal();
+ }
+
+}
diff --git a/src/miniJava/CodeGenerator/Encoder.java b/src/miniJava/CodeGenerator/Encoder.java
index 5773186..6ee76b6 100644
--- a/src/miniJava/CodeGenerator/Encoder.java
+++ b/src/miniJava/CodeGenerator/Encoder.java
@@ -1,94 +1,79 @@
package miniJava.CodeGenerator;
+import java.util.HashMap;
+
import mJAM.Machine;
import mJAM.Machine.*;
import miniJava.AbstractSyntaxTrees.*;
import miniJava.AbstractSyntaxTrees.Package;
import miniJava.ContextualAnalyzer.Analyzer;
-public class Encoder implements Visitor {
+public class Encoder implements Visitor {
- private int mdLBOffset = 0;
-
- // /////////////////////////////////////////////////////////////////////////////
- //
- // Convenience Functions
- //
- // /////////////////////////////////////////////////////////////////////////////
+ // Keeps track of variables placed on the stack
+ private int methodDataOffset = 0;
+
+ // Maintains data to correct once completed traversal
+ private HashMap patches = new HashMap<>();
- /**
- * Get size of type for declaration purposes.
- * @param t
- * @return
- */
- private int getSize(Type t) {
- switch(t.typeKind) {
- case ARRAY:
- case CLASS:
- return Machine.addressSize;
- case INT:
- return Machine.integerSize;
- case BOOLEAN:
- return Machine.booleanSize;
- case VOID:
- return 0;
- default:
- return -1;
- }
- }
-
// /////////////////////////////////////////////////////////////////////////////
//
// PACKAGE
//
// /////////////////////////////////////////////////////////////////////////////
-
+
@Override
- public Integer visitPackage(Package prog, Integer arg) {
+ public Object visitPackage(Package prog, Integer arg) {
- // Initialize static fields
+ Machine.initCodeGen();
+
+ // Initialize all static fields
+ int staticFieldsSize = 0;
for(ClassDecl cd : prog.classDeclList) {
for(int i = 0; i < cd.fieldDeclList.size(); i++) {
- if(cd.fieldDeclList.get(i).isStatic) {
- cd.fieldDeclList.get(i).visit(this, i);
+ FieldDecl fd = cd.fieldDeclList.get(i);
+ if(fd.isStatic) {
+ int size = getSize(fd.type);
+ fd.entity = new RuntimeEntity(size, staticFieldsSize, Reg.SB);
+ staticFieldsSize += size;
}
}
}
- int patch = Machine.nextInstrAddr();
- Machine.emit(Op.JUMP, Reg.CB, 0);
-
- // Initialize all classes and methods
- for(ClassDecl cd : prog.classDeclList) {
- cd.visit(this, 1);
+ if(staticFieldsSize > 0) {
+ Machine.emit(Op.PUSH, staticFieldsSize);
}
- // Link classes & build stack
- Machine.patch(patch, Machine.nextInstrAddr());
+ // Build Classes
for(ClassDecl cd : prog.classDeclList) {
int cdPatch = Machine.nextInstrAddr();
Machine.emit(Op.JUMP, Reg.CB, 0);
- Machine.patch(cdPatch, cd.visit(this, 0));
+ cd.visit(this, cdPatch);
}
// Build main function
- mdLBOffset = Machine.linkDataSize;
+ methodDataOffset = Machine.linkDataSize;
int mainPatch = Machine.nextInstrAddr();
Machine.emit(Op.JUMP, Reg.CB, 0);
- Analyzer.mainMethod.visit(this, 0);
-
-
+ Analyzer.main.visit(this, null);
+
// Run main function
int mainLabel = Machine.nextInstrAddr();
- RuntimeEntity main = Analyzer.mainMethod.entity;
-
+ RuntimeEntity main = Analyzer.main.entity;
+
Machine.emit(Op.LOADL, Machine.nullRep);
Machine.emit(Op.CALL, Reg.CB, main.addr);
Machine.emit(Machine.Op.HALT, 0 ,0, 0);
Machine.patch(mainPatch, mainLabel);
- return 0;
+ // Patch up
+ for(Integer instr : patches.keySet()) {
+ Code c = patches.get(instr);
+ c.modify(instr);
+ }
+
+ return null;
}
@@ -99,163 +84,128 @@ public class Encoder implements Visitor {
// /////////////////////////////////////////////////////////////////////////////
@Override
- public Integer visitClassDecl(ClassDecl cd, Integer init) {
+ public Object visitClassDecl(ClassDecl cd, Integer patch) {
- /* Give an address to each method and class, so it can be referred
- * to directly by jumping.
- */
- if(init != 0) {
-
- // Get size of class
- int size = 0;
- for(FieldDecl fd : cd.fieldDeclList) {
- if(!fd.isStatic) {
- fd.visit(this, size);
- size += getSize(fd.type);
- }
+ // Get size of class
+ int size = 0;
+ for(FieldDecl fd : cd.fieldDeclList) {
+ if(!fd.isStatic) {
+ fd.visit(this, size);
+ size += fd.entity.size;
}
-
- // Build Methods
- for(MethodDecl md : cd.methodDeclList) {
- md.visit(this, init);
- }
-
- // Runtime Entity
- int addr = Machine.nextInstrAddr();
- cd.entity = new RuntimeEntity(size, addr, Reg.CB, addr);
- Machine.emit(Op.JUMP, Reg.CB, 0);
-
- return addr;
- }
+ }
// Build Instance Methods
for(MethodDecl md : cd.methodDeclList) {
- if(!md.isStatic) {
- md.visit(this, 0);
+ if(md != Analyzer.main) {
+ md.visit(this, null);
}
}
- // Build class descriptor
- int label = Machine.nextInstrAddr();
- Machine.patch(cd.entity.instr, label);
+ // Build Class Descriptor
+ int addr = Machine.nextInstrAddr();
+ Machine.patch(patch, addr);
- Machine.emit(Op.LOADL, -1); // No superclasses allowed
- Machine.emit(Op.LOADL, cd.entity.size); // Size of class
- Machine.emit(Op.LOADA, Reg.CB, cd.entity.addr); // Address of class
+ Machine.emit(Op.LOADL, -1); // No superclasses allowed
+ Machine.emit(Op.LOADL, size); // Size of class
+ Machine.emit(Op.LOADA, Reg.CB, addr); // Address of class
- return label;
+ // Save entity
+ cd.entity = new RuntimeEntity(size, addr, Reg.CB);
+
+ return null;
}
@Override
- public Integer visitFieldDecl(FieldDecl fd, Integer addr) {
-
+ public Object visitFieldDecl(FieldDecl fd, Integer offset) {
+
+ // Only non-static fields should ever reach this method
int size = getSize(fd.type);
-
- // Static fields are placed onto the stack
- if(fd.isStatic) {
- fd.entity = new RuntimeEntity(size, addr, Reg.SB);
- Machine.emit(Op.PUSH, size);
- } else {
- fd.entity = new RuntimeEntity(size, addr, Reg.OB);
- }
-
- return 0;
+ fd.entity = new RuntimeEntity(size, offset, Reg.OB);
+
+ return null;
}
-
@Override
- public Integer visitMethodDecl(MethodDecl md, Integer init) {
+ public Object visitMethodDecl(MethodDecl md, Integer arg) {
- mdLBOffset = Machine.linkDataSize;
+ // Reset for next local LB
+ methodDataOffset = Machine.linkDataSize;
- if(init != 0) {
- int size = getSize(md.type);
- int addr = Machine.nextInstrAddr();
- md.entity = new RuntimeEntity(size, addr, Reg.CB, addr);
- Machine.emit(Op.JUMP, Reg.CB, 0);
- }
+ // Save Entity
+ int size = getSize(md.type);
+ int addr = Machine.nextInstrAddr();
+ md.entity = new RuntimeEntity(size, addr, Reg.CB);
- else {
- // Setup parameters
- int paramS = 0;
- for(ParameterDecl pd : md.parameterDeclList) {
- paramS += getSize(md.type);
- pd.visit(this, -paramS);
- }
-
- // Setup body
- int addr = Machine.nextInstrAddr();
- Machine.patch(md.entity.instr, addr);
- for(Statement s : md.statementList) {
- s.visit(this, 0);
- }
-
- // Setup return statement
- if(md.returnExp != null) {
- md.returnExp.visit(this, 0);
- }
-
- // Return from function
- // Machine.emit(Op.HALT, 4, 0, 0); (See snapshot)
- Machine.emit(Op.RETURN, md.entity.size, 0, paramS);
+ // Setup parameters
+ int parameterSize = 0;
+ for(ParameterDecl pd : md.parameterDeclList) {
+ parameterSize += getSize(pd.type);
+ pd.visit(this, -parameterSize);
}
- return 0;
+ // Build Body
+ for(Statement s : md.statementList) {
+ s.visit(this, null);
+ }
+
+ // Setup Return
+ if(md.returnExp != null) {
+ md.returnExp.visit(this, null);
+ }
+
+ Machine.emit(Op.RETURN, size, 0, parameterSize);
+
+ return null;
}
- /**
- * Note parameter addresses are negative to LB since they are
- * placed onto the stack before emitting a CALL.
- */
@Override
- public Integer visitParameterDecl(ParameterDecl pd, Integer addr) {
+ public Object visitParameterDecl(ParameterDecl pd, Integer offset) {
- // Builds runtime entity, offset at LB
+ // Builds runtime entity (should be negative of LB)
int size = getSize(pd.type);
- pd.entity = new RuntimeEntity(size, addr, Reg.LB);
-
- return 0;
+ pd.entity = new RuntimeEntity(size, offset, Reg.LB);
+
+ return null;
}
- /**
- * Variable declarations are never disposed (even in static closures).
- */
@Override
- public Integer visitVarDecl(VarDecl decl, Integer addr) {
-
+ public Object visitVarDecl(VarDecl decl, Integer arg) {
+
// Builds runtime entity, offset at LB
int size = getSize(decl.type);
- decl.entity = new RuntimeEntity(size, addr, Reg.LB);
+ decl.entity = new RuntimeEntity(size, methodDataOffset, Reg.LB);
// Allocates space on stack
Machine.emit(Op.PUSH, size);
-
- return 0;
+ methodDataOffset += size;
+
+ return null;
}
// /////////////////////////////////////////////////////////////////////////////
//
// TYPES
- //
+ //
// /////////////////////////////////////////////////////////////////////////////
@Override
- public Integer visitBaseType(BaseType type, Integer arg) {
+ public Object visitBaseType(BaseType type, Integer arg) {
- return 0;
+ return null;
}
@Override
- public Integer visitClassType(ClassType type, Integer arg) {
+ public Object visitClassType(ClassType type, Integer arg) {
- return 0;
+ return null;
}
@Override
- public Integer visitArrayType(ArrayType type, Integer arg) {
+ public Object visitArrayType(ArrayType type, Integer arg) {
- return 0;
+ return null;
}
@@ -265,171 +215,187 @@ public class Encoder implements Visitor {
//
// /////////////////////////////////////////////////////////////////////////////
- /**
- * We note a block statement may contain a variable declaration,
- * that should go out of scope at the end of the statement.
- * If the passed argument is 1, we indicate we want this to
- * happen.
- */
@Override
- public Integer visitBlockStmt(BlockStmt stmt, Integer arg) {
+ public Object visitBlockStmt(BlockStmt stmt, Integer arg) {
// Execute statements
int size = 0;
for(Statement s : stmt.sl) {
- s.visit(this, 0);
-
- // Push variable declarations if necessary
- if(arg == 1 && s instanceof VarDeclStmt) {
- VarDeclStmt decl = (VarDeclStmt) s;
- size += getSize(decl.varDecl.type);
+ s.visit(this, null);
+ if(s instanceof VarDeclStmt) {
+ VarDeclStmt vds = (VarDeclStmt) s;
+ size += vds.varDecl.entity.size;
}
}
// Pop off variable declarations
- Machine.emit(Op.POP, size);
-
- return 0;
+ if(size > 0) {
+ Machine.emit(Op.POP, size);
+ methodDataOffset -= size;
+ }
+
+ return null;
}
- /**
- * We declare the variable, place the RHS onto the stack, and
- * replace the value of the variable with the top of the stack.
- */
@Override
- public Integer visitVardeclStmt(VarDeclStmt stmt, Integer arg) {
- stmt.varDecl.visit(this, mdLBOffset);
- stmt.initExp.visit(this, 0);
+ public Object visitVardeclStmt(VarDeclStmt stmt, Integer arg) {
+
+ stmt.varDecl.visit(this, null);
+ stmt.initExp.visit(this, null);
- // Assign value
RuntimeEntity e = stmt.varDecl.entity;
- Machine.emit(Op.STORE, e.size, e.register, e.addr);
+ Machine.emit(Op.STORE, e.size, e.reg, e.addr);
- // Update position
- mdLBOffset += getSize(stmt.varDecl.type);
-
- return 0;
+ return null;
}
@Override
- public Integer visitAssignStmt(AssignStmt stmt, Integer arg) {
+ public Object visitAssignStmt(AssignStmt stmt, Integer arg) {
- stmt.ref.visit(this, 0);
+ // Can potentially reach declaration directly
+ if(stmt.ref instanceof QualifiedRef) {
+
+ QualifiedRef ref = (QualifiedRef) stmt.ref;
+ MemberDecl md = (MemberDecl) ref.id.decl;
+
+ // Just access directly
+ if(md.isStatic) {
+ stmt.val.visit(this, null);
+ patches.put(Machine.nextInstrAddr(), new Code(md, true));
+ Machine.emit(Op.STORE, getSize(md.type), Reg.SB, 0);
+
+ return null;
+ }
+
+ // Access member directly
+ else if(ref.ref instanceof ThisRef) {
+ stmt.val.visit(this, null);
+
+ int addr = Machine.nextInstrAddr();
+ int size = getSize(ref.id.decl.type);
+ patches.put(addr, new Code(ref.id.decl, true));
+ Machine.emit(Op.STORE, size, Reg.OB, 0);
+
+ return null;
+ }
+ }
+
+ // Must access member iteratively
+ stmt.ref.visit(this, 1);
+ stmt.val.visit(this, null);
- // Setup
- RuntimeEntity e = stmt.ref.entity;
-
- // Build code accordingly
- if(stmt.ref instanceof QualifiedRef) {
- e.parent.load();
- Machine.emit(Op.LOADL, e.addr);
- stmt.val.visit(this, 0);
+ if(stmt.ref instanceof QualifiedRef) {
Machine.emit(Prim.fieldupd);
}
else if(stmt.ref instanceof IndexedRef) {
- IndexedRef ref = (IndexedRef) stmt.ref;
- e.load();
- ref.indexExpr.visit(this, 0);
- stmt.val.visit(this, 0);
Machine.emit(Prim.arrayupd);
}
else if(stmt.ref instanceof IdRef) {
- stmt.val.visit(this, 0);
- Machine.emit(Op.STORE, e.size, e.register, e.addr);
+ int addr = Machine.nextInstrAddr();
+ int size = getSize(stmt.ref.decl.type);
+ patches.put(addr, new Code(stmt.ref.decl, true));
+ Machine.emit(Op.STORE, size, Reg.ZR, 0);
}
- return 0;
+ return null;
}
- /**
- * The method in question can either be an instance or static
- * function (it must be a MethodDecl).
- */
@Override
- public Integer visitCallStmt(CallStmt stmt, Integer arg) {
+ public Object visitCallStmt(CallStmt stmt, Integer arg) {
MethodDecl md = (MethodDecl) stmt.methodRef.decl;
// Request to print out
if(md == Analyzer.println) {
- stmt.argList.get(0).visit(this, 0);
+ stmt.argList.get(0).visit(this, null);
Machine.emit(Prim.putintnl);
- return 0;
+ return null;
}
// Push parameters on (must iterate in reverse order)
for(int i = stmt.argList.size() - 1; i >= 0; i--) {
- stmt.argList.get(i).visit(this, 0);
+ stmt.argList.get(i).visit(this, null);
}
- // Call Method
- stmt.methodRef.visit(this, 0);
+ // Call method directly
if(md.isStatic) {
- Machine.emit(Op.CALL, Reg.CB, md.entity.addr);
- } else {
- stmt.methodRef.entity.call();
- Machine.emit(Op.CALLI, Reg.CB, md.entity.addr);
+ patches.put(Machine.nextInstrAddr(), new Code(md, true));
+ Machine.emit(Op.CALL, Reg.CB, 0);
+ }
+
+ // Get address of qualified object
+ else {
+ if(stmt.methodRef instanceof QualifiedRef) {
+ QualifiedRef ref = (QualifiedRef) stmt.methodRef;
+ ref.ref.visit(this, null);
+ } else {
+ Machine.emit(Op.LOADA, Machine.addressSize, Reg.OB, 0);
+ }
+
+ patches.put(Machine.nextInstrAddr(), new Code(md, true));
+ Machine.emit(Op.CALLI, Reg.CB, 0);
}
- return 0;
+ // Clear off stack if necessary
+ int returnSize = getSize(md.type);
+ if(returnSize > 0) {
+ Machine.emit(Op.POP, returnSize);
+ }
+
+ return null;
}
@Override
- public Integer visitIfStmt(IfStmt stmt, Integer arg) {
+ public Object visitIfStmt(IfStmt stmt, Integer arg) {
- stmt.cond.visit(this, 0);
+ stmt.cond.visit(this, null);
- // Build Then Statement
+ // Do not have to build as many jump instructions in this case
+ if(stmt.elseStmt == null) {
+ int ifPatch = Machine.nextInstrAddr();
+ Machine.emit(Op.JUMPIF, Machine.falseRep, Reg.CB, 0);
+
+ stmt.thenStmt.visit(this, null);
+ Machine.patch(ifPatch, Machine.nextInstrAddr());
+
+ return null;
+ }
+
+ // Must jump out at end of 'if' clause
int ifPatch = Machine.nextInstrAddr();
- Machine.emit(Op.JUMPIF, Machine.trueRep, Reg.CB, 0);
-
- int elsePatch = Machine.nextInstrAddr();
- Machine.emit(Op.JUMP, Reg.CB, 0);
-
- int thenLabel = Machine.nextInstrAddr();
- stmt.thenStmt.visit(this, 0);
+ Machine.emit(Op.JUMPIF, Machine.falseRep, Reg.CB, 0);
+ stmt.thenStmt.visit(this, null);
int thenPatch = Machine.nextInstrAddr();
Machine.emit(Op.JUMP, Reg.CB, 0);
- // Connect labels/patches
- int endLabel = Machine.nextInstrAddr();
- Machine.patch(elsePatch, endLabel);
+ // Build 'else' clause
+ Machine.patch(ifPatch, Machine.nextInstrAddr());
+ stmt.elseStmt.visit(this, null);
+ Machine.patch(thenPatch, Machine.nextInstrAddr());
- if(stmt.elseStmt != null) {
- stmt.elseStmt.visit(this, 0);
- endLabel = Machine.nextInstrAddr();
- }
-
- Machine.patch(ifPatch, thenLabel);
- Machine.patch(thenPatch, endLabel);
-
- return 0;
+ return null;
}
- /**
- * We note since the same declaration can be reached multiple times, we
- * are forced to pop each declaration initialized.
- */
@Override
- public Integer visitWhileStmt(WhileStmt stmt, Integer arg) {
+ public Object visitWhileStmt(WhileStmt stmt, Integer arg) {
// Must check the condition each loop
int whileLabel = Machine.nextInstrAddr();
- stmt.cond.visit(this, 0);
+ stmt.cond.visit(this, null);
// Jump out once condition fails
int whileEndPatch = Machine.nextInstrAddr();
Machine.emit(Op.JUMPIF, Machine.falseRep, Reg.CB, 0);
// Execute
- stmt.body.visit(this, 1);
+ stmt.body.visit(this, null);
Machine.emit(Op.JUMP, Reg.CB, whileLabel);
Machine.patch(whileEndPatch, Machine.nextInstrAddr());
-
- return 0;
+
+ return null;
}
@@ -440,9 +406,9 @@ public class Encoder implements Visitor {
// /////////////////////////////////////////////////////////////////////////////
@Override
- public Integer visitUnaryExpr(UnaryExpr expr, Integer arg) {
+ public Object visitUnaryExpr(UnaryExpr expr, Integer arg) {
- expr.expr.visit(this, 0);
+ expr.expr.visit(this, null);
switch(expr.operator.spelling) {
case "!":
Machine.emit(Prim.not);
@@ -452,115 +418,105 @@ public class Encoder implements Visitor {
break;
}
- return 0;
+ return null;
}
@Override
- public Integer visitBinaryExpr(BinaryExpr expr, Integer arg) {
- expr.left.visit(this, 0);
- expr.right.visit(this, 0);
- expr.operator.visit(this, 0);
+ public Object visitBinaryExpr(BinaryExpr expr, Integer arg) {
- return 0;
- }
-
- @Override
- public Integer visitRefExpr(RefExpr expr, Integer arg) {
-
- expr.ref.visit(this, 0);
+ String op = expr.operator.spelling;
- // Build code accordingly
- if(expr.ref instanceof QualifiedRef) {
+ if(op.equals("&&") || op.equals("||")) {
+ int rep = (op.equals("&&")) ? Machine.falseRep : Machine.trueRep;
- // Must be requesting length of array
- if(expr.ref.decl.type.typeKind == TypeKind.ARRAY) {
- int size = Machine.integerSize;
- int addr = expr.ref.entity.addr + size;
- Machine.emit(Op.LOAD, size, Reg.LB, addr);
- } else {
- expr.ref.entity.load();
- }
- }
-
- else if(expr.ref instanceof IndexedRef) {
- IndexedRef ref = (IndexedRef) expr.ref;
- ref.entity.load();
- ref.indexExpr.visit(this, 0);
- Machine.emit(Prim.arrayref);
- }
-
- else if(expr.ref instanceof ThisRef) {
- RuntimeEntity e = expr.ref.entity;
- Machine.emit(Op.LOADA, e.size, e.register, e.addr);
+ expr.left.visit(this, null);
+ int leftJump = Machine.nextInstrAddr();
+ Machine.emit(Op.JUMPIF, rep, Reg.CB, 0);
+
+ expr.right.visit(this, null);
+ expr.operator.visit(this, null);
+
+ Machine.patch(leftJump, Machine.nextInstrAddr());
}
else {
- expr.ref.entity.load();
+ expr.left.visit(this, null);
+ expr.right.visit(this, null);
+ expr.operator.visit(this, null);
}
- return 0;
+ return null;
}
@Override
- public Integer visitCallExpr(CallExpr expr, Integer arg) {
+ public Object visitRefExpr(RefExpr expr, Integer arg) {
+
+ expr.ref.visit(this, null);
+
+ return null;
+ }
+
+ @Override
+ public Object visitCallExpr(CallExpr expr, Integer arg) {
+
+ MethodDecl md = (MethodDecl) expr.functionRef.decl;
// Push parameters on (must iterate in reverse order)
for(int i = expr.argList.size() - 1; i >= 0; i--) {
- expr.argList.get(i).visit(this, 0);
+ expr.argList.get(i).visit(this, null);
}
-
- // Call method
- MethodDecl md = (MethodDecl) expr.functionRef.decl;
- expr.functionRef.visit(this, 0);
+
+ // Call Method
if(md.isStatic) {
- Machine.emit(Op.CALL, Reg.CB, md.entity.addr);
+ patches.put(Machine.nextInstrAddr(), new Code(md, true));
+ Machine.emit(Op.CALL, Reg.CB, 0);
} else {
- expr.functionRef.entity.call();
- Machine.emit(Op.CALLI, Reg.CB, md.entity.addr);
+
+ if(expr.functionRef instanceof QualifiedRef) {
+ QualifiedRef ref = (QualifiedRef) expr.functionRef;
+ ref.ref.visit(this, null);
+ } else {
+ Machine.emit(Op.LOADA, Machine.addressSize, Reg.OB, 0);
+ }
+
+ patches.put(Machine.nextInstrAddr(), new Code(md, true));
+ Machine.emit(Op.CALLI, Reg.CB, 0);
}
- return 0;
+ return null;
}
@Override
- public Integer visitLiteralExpr(LiteralExpr expr, Integer arg) {
+ public Object visitLiteralExpr(LiteralExpr expr, Integer arg) {
- expr.literal.visit(this, 0);
+ expr.literal.visit(this, null);
- return 0;
+ return null;
}
@Override
- public Integer visitNewObjectExpr(NewObjectExpr expr, Integer arg) {
-
- RuntimeEntity e = expr.classtype.className.decl.entity;
- Machine.emit(Op.LOADA, e.register, e.addr);
- Machine.emit(Op.LOADL, e.size);
+ public Object visitNewObjectExpr(NewObjectExpr expr, Integer arg) {
+
+ Declaration decl = expr.classtype.className.decl;
+
+ patches.put(Machine.nextInstrAddr(), new Code(decl, true));
+ Machine.emit(Op.LOADA, Reg.CB, 0);
+
+ patches.put(Machine.nextInstrAddr(), new Code(decl, false));
+ Machine.emit(Op.LOADL, 0);
+
Machine.emit(Prim.newobj);
- return 0;
+ return null;
}
- /**
- * Returns the address where the new array's size is being
- * stored (as it cannot be easily accessed otherwise).
- */
@Override
- public Integer visitNewArrayExpr(NewArrayExpr expr, Integer arg) {
-
- // Setup
- int addr = mdLBOffset;
- int size = Machine.integerSize;
- mdLBOffset += Machine.integerSize;
-
- // Add to stack
- expr.sizeExpr.visit(this, 0);
-
- // Create new array
- Machine.emit(Op.LOAD, size, Reg.LB, addr);
+ public Object visitNewArrayExpr(NewArrayExpr expr, Integer arg) {
+
+ expr.sizeExpr.visit(this, null);
Machine.emit(Prim.newarr);
- return addr;
+ return null;
}
@@ -571,49 +527,91 @@ public class Encoder implements Visitor {
// /////////////////////////////////////////////////////////////////////////////
@Override
- public Integer visitQualifiedRef(QualifiedRef ref, Integer arg) {
+ public Object visitQualifiedRef(QualifiedRef ref, Integer arg) {
- ref.ref.visit(this, 0);
-
- // Must be accessing length of an array
+ // Array type always returns value
if(ref.ref.decl.type.typeKind == TypeKind.ARRAY) {
- ref.decl = ref.ref.decl;
- ref.entity = ref.ref.entity;
- }
-
- // Access class member
- else {
- ref.entity = ref.id.decl.entity;
- ref.entity.parent = ref.ref.entity;
+
+ // Get address of object
+ if(ref.ref instanceof QualifiedRef) {
+ ref.ref.visit(this, null);
+ } else if(ref.ref instanceof ThisRef) {
+ patches.put(Machine.nextInstrAddr(), new Code(ref.id.decl, true));
+ Machine.emit(Op.STORE, getSize(ref.id.decl.type), Reg.OB, 0);
+ } else {
+ patches.put(Machine.nextInstrAddr(), new Code(ref.ref.decl, true));
+ Machine.emit(Op.LOAD, Machine.addressSize, Reg.LB, 0);
+ }
+
+ Machine.emit(Op.LOADL, 1);
+ Machine.emit(Prim.sub);
+ Machine.emit(Op.LOADI, Machine.integerSize);
+
+ return null;
}
- return 0;
+ MemberDecl md = (MemberDecl) ref.id.decl;
+
+ // Assigning
+ if(arg != null) {
+ ref.ref.visit(this, null);
+ patches.put(Machine.nextInstrAddr(), new Code(ref.id.decl, true));
+ Machine.emit(Op.LOADL, 0);
+ }
+
+ // Retrieving
+ else if(md.isStatic) {
+ patches.put(Machine.nextInstrAddr(), new Code(md, true));
+ Machine.emit(Op.LOAD, getSize(md.type), Reg.SB, 0);
+ } else {
+ ref.ref.visit(this, null);
+ int addr = Machine.nextInstrAddr();
+ patches.put(addr, new Code(ref.decl, true));
+
+ Machine.emit(Op.LOADL, 0);
+ Machine.emit(Prim.fieldref);
+ }
+
+ return null;
}
@Override
- public Integer visitIndexedRef(IndexedRef ref, Integer arg) {
+ public Object visitIndexedRef(IndexedRef ref, Integer arg) {
+
+ ref.ref.visit(this, null);
+ ref.indexExpr.visit(this, null);
+
+ // Retrieving
+ if(arg == null) {
+ Machine.emit(Prim.arrayref);
+ }
+
+ return null;
+ }
+
+ @Override
+ public Object visitIdRef(IdRef ref, Integer arg) {
ref.entity = ref.decl.entity;
- return 0;
+ // Retrieving
+ if(arg == null) {
+ int size = getSize(ref.decl.type);
+ int addr = Machine.nextInstrAddr();
+ patches.put(addr, new Code(ref.decl, true));
+
+ Machine.emit(Op.LOAD, size, Reg.ZR, 0);
+ }
+
+ return null;
}
@Override
- public Integer visitIdRef(IdRef ref, Integer arg) {
-
- ref.entity = ref.decl.entity;
+ public Object visitThisRef(ThisRef ref, Integer arg) {
- return 0;
- }
-
- @Override
- public Integer visitThisRef(ThisRef ref, Integer arg) {
+ Machine.emit(Op.LOADA, Machine.addressSize, Reg.OB, 0);
- RuntimeEntity e = ref.decl.entity;
- ref.entity = new RuntimeEntity(e.size, 0, Reg.OB);
- ref.entity.indirect = true;
-
- return 0;
+ return null;
}
@@ -624,15 +622,15 @@ public class Encoder implements Visitor {
// /////////////////////////////////////////////////////////////////////////////
@Override
- public Integer visitIdentifier(Identifier id, Integer arg) {
+ public Object visitIdentifier(Identifier id, Integer arg) {
- return 0;
+ return null;
}
@Override
- public Integer visitOperator(Operator op, Integer arg) {
+ public Object visitOperator(Operator op, Integer arg) {
- switch(op.token.spelling) {
+ switch(op.spelling) {
case "+":
Machine.emit(Prim.add);
break;
@@ -671,20 +669,20 @@ public class Encoder implements Visitor {
break;
}
- return 0;
+ return null;
}
@Override
- public Integer visitIntLiteral(IntLiteral num, Integer arg) {
+ public Object visitIntLiteral(IntLiteral num, Integer arg) {
Integer lit = Integer.parseInt(num.spelling);
Machine.emit(Op.LOADL, lit.intValue());
- return 0;
+ return null;
}
@Override
- public Integer visitBooleanLiteral(BooleanLiteral bool, Integer arg) {
+ public Object visitBooleanLiteral(BooleanLiteral bool, Integer arg) {
if(bool.spelling.equals("true")) {
Machine.emit(Op.LOADL, Machine.trueRep);
@@ -692,7 +690,35 @@ public class Encoder implements Visitor {
Machine.emit(Op.LOADL, Machine.falseRep);
}
- return 0;
+ return null;
+ }
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // Convenience Methods
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Get size of type for declaration purposes.
+ * @param t
+ * @return
+ */
+ private int getSize(Type t) {
+ switch(t.typeKind) {
+ case ARRAY:
+ case CLASS:
+ return Machine.addressSize;
+ case INT:
+ return Machine.integerSize;
+ case BOOLEAN:
+ return Machine.booleanSize;
+ case VOID:
+ return 0;
+ default:
+ return -1;
+ }
}
}
diff --git a/src/miniJava/CodeGenerator/RuntimeEntity.java b/src/miniJava/CodeGenerator/RuntimeEntity.java
index a05ebce..8571a10 100644
--- a/src/miniJava/CodeGenerator/RuntimeEntity.java
+++ b/src/miniJava/CodeGenerator/RuntimeEntity.java
@@ -1,52 +1,19 @@
package miniJava.CodeGenerator;
-import mJAM.Machine;
-import mJAM.Machine.Op;
-import mJAM.Machine.Prim;
import mJAM.Machine.Reg;
public class RuntimeEntity {
+
+ public Reg reg;
+ public int size;
+ public int addr;
- public int size = -1; // Size of type
- public int addr = -1; // Position relative to register
- public int instr = -1; // Instruction relative to CB
- public Reg register = Reg.ZR; // Register to offset by
+ RuntimeEntity parent = null;
- // For use with nested elements
- public boolean indirect = false;
- public RuntimeEntity parent = null;
-
- public RuntimeEntity(int size, int addr, Reg register) {
- this(size, addr, register, -1);
- }
-
- public RuntimeEntity(int size, int addr, Reg register, int instr) {
+ public RuntimeEntity(int size, int addr, Reg reg) {
+ this.reg = reg;
this.size = size;
this.addr = addr;
- this.register = register;
- this.instr = instr;
}
- // Load entity into memory (if this, should call LOADA)
- public void load() {
- if(parent != null) {
- parent.load();
- Machine.emit(Op.LOADL, addr);
- Machine.emit(Prim.fieldref);
- } else {
- if(indirect) {
- Machine.emit(Op.LOADA, size, register, addr);
- } else {
- Machine.emit(Op.LOAD, size, register, addr);
- }
- }
- }
-
- public void call() {
- if(parent != null) {
- parent.load();
- } else {
- Machine.emit(Op.LOADA, size, Reg.OB, 0);
- }
- }
}
diff --git a/src/miniJava/Compiler.java b/src/miniJava/Compiler.java
index f137eb9..2059ca1 100644
--- a/src/miniJava/Compiler.java
+++ b/src/miniJava/Compiler.java
@@ -1,13 +1,21 @@
package miniJava;
-import java.io.*;
+import java.io.FileReader;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.FileNotFoundException;
-import mJAM.*;
-import miniJava.SyntacticAnalyzer.*;
+import mJAM.Disassembler;
+import mJAM.Interpreter;
+import mJAM.ObjectFile;
+import miniJava.SyntacticAnalyzer.Scanner;
+import miniJava.SyntacticAnalyzer.Parser;
import miniJava.AbstractSyntaxTrees.Package;
-import miniJava.ContextualAnalyzer.Analyzer;
+import miniJava.AbstractSyntaxTrees.ASTDisplay;
import miniJava.CodeGenerator.Encoder;
-import miniJava.Exceptions.*;
+import miniJava.ContextualAnalyzer.IdTable;
+import miniJava.ContextualAnalyzer.Analyzer;
+import miniJava.ContextualAnalyzer.Reporter;
public class Compiler {
@@ -26,15 +34,22 @@ public class Compiler {
Scanner scanner = new Scanner(new BufferedReader(input));
Parser parser = new Parser(scanner);
Package p = parser.parse();
-
- // Identification/Type Checking
- Analyzer analyzer = new Analyzer();
- analyzer.visitPackage(p, null);
- int analyzed = analyzer.validate();
- // Begin Compilation to mJAM
- if(analyzed == 0) {
+ // Display
+ ASTDisplay display = new ASTDisplay();
+ display.showTree(p);
+
+ // Contextual Analyzer
+ IdTable table = new IdTable();
+ Analyzer analyzer = new Analyzer();
+ analyzer.visitPackage(p, table);
+
+ // Compilation
+ if(Reporter.error) {
+ System.exit(rc);
+ } else {
+ // Build mJAM assembly
Encoder encoder = new Encoder();
encoder.visitPackage(p, null);
@@ -43,23 +58,36 @@ public class Compiler {
String objectFileName = args[0].substring(0, pos) + ".mJAM";
ObjectFile objF = new ObjectFile(objectFileName);
if(objF.write()) {
- System.out.println("***Object File Failed.");
+ Reporter.emit("Object File Failed.");
}
+
+ // create asm file using disassembler
+ String asmCodeFileName = "test.asm";
+ System.out.print("Writing assembly file ... ");
+ Disassembler d = new Disassembler(objectFileName);
+ if (d.disassemble()) {
+ System.out.println("FAILED!");
+ return;
+ }
+ else
+ System.out.println("SUCCEEDED");
+
+ // run
+ System.out.println("Running code ... ");
+ Interpreter.debug(objectFileName, asmCodeFileName);
+
+ System.out.println("*** mJAM execution completed");
}
- System.exit(analyzed);
+ System.exit(0);
} catch (FileNotFoundException e) {
- System.out.println("***" + e.getMessage());
+ Reporter.emit(e.getMessage());
} catch (IOException e) {
- System.out.println("***" + e.getMessage());
- } catch (ScanningException e) {
- System.out.println("***" + e.getMessage());
- } catch (ParsingException e) {
- System.out.println("***" + e.getMessage());
+ Reporter.emit(e.getMessage());
}
System.exit(rc);
}
-}
+}
\ No newline at end of file
diff --git a/src/miniJava/ContextualAnalyzer/Analyzer.java b/src/miniJava/ContextualAnalyzer/Analyzer.java
index 9a23e8a..65f4bff 100644
--- a/src/miniJava/ContextualAnalyzer/Analyzer.java
+++ b/src/miniJava/ContextualAnalyzer/Analyzer.java
@@ -1,68 +1,38 @@
package miniJava.ContextualAnalyzer;
-import java.util.*;
+import java.io.IOException;
+import java.util.ArrayList;
import miniJava.Compiler;
-import miniJava.Exceptions.*;
-import miniJava.SyntacticAnalyzer.*;
-import miniJava.SyntacticAnalyzer.Scanner;
import miniJava.AbstractSyntaxTrees.*;
import miniJava.AbstractSyntaxTrees.Package;
+import miniJava.SyntacticAnalyzer.Parser;
+import miniJava.SyntacticAnalyzer.Scanner;
-public class Analyzer implements Visitor {
-
- public static MethodDecl mainMethod = null;
- public static MethodDecl println = null;
+public class Analyzer implements Visitor {
- // Notifies if handling predefined as opposed to user defined code
- private boolean predefinedGen = true;
+ public Reporter reporter = new Reporter();
- // Keeps track of declarations
- private VarDecl currentVarDecl = null;
- private ClassDecl currentClassDecl = null;
- private MethodDecl currentMethodDecl = null;
+ // Required Methods
+ public static MethodDecl main;
+ public static MethodDecl println;
- // Keeps track of identifcatoin
- private IdentificationTable table = new IdentificationTable();
-
- // Keep track of all predefined names to handle
+ // Predefined
private static ArrayList predefined;
static
{
predefined = new ArrayList();
- predefined.add("class _PrintStream { public void println(int n){} }");
- predefined.add("class System { public static _PrintStream out; }");
predefined.add("class String { }");
+ predefined.add("class _PrintStream { public void println(int n){} }");
+ predefined.add("class System { public static _PrintStream out; }");
}
-
- /**
- * Adds predefined names to topmost table. These names should not be allowed
- * redefinition and must be ordered such that no class refers to one
- * undeclared yet.
- */
- public Analyzer() throws ParsingException, ScanningException {
- for (String s : predefined) {
- Scanner scanner = new Scanner(s);
- Parser parser = new Parser(scanner);
- parser.parse().visit(this, table);
- }
- predefinedGen = false;
- }
-
- /**
- * Checks that contextual analysis was successful or not, returning the
- * proper error code in either case.
- *
- * @return
- */
- public int validate() {
- // Exactly one public static void main(String[] args) function must be declared
- if (mainMethod == null)
- Reporter.report(ErrorType.MAIN_UNDECLARED, null, null);
-
- return (Reporter.error) ? Compiler.rc : 0;
- }
-
+
+ // Keep Track Of Declarations
+ private IdTable top = null;
+ private VarDecl currentVarDecl = null;
+ private ClassDecl currentClassDecl = null;
+ private MethodDecl currentMethodDecl = null;
+
// /////////////////////////////////////////////////////////////////////////////
//
@@ -70,40 +40,44 @@ public class Analyzer implements Visitor {
//
// /////////////////////////////////////////////////////////////////////////////
- public Type visitPackage(Package prog, IdentificationTable arg) {
-
- /*
- * Since classes and static methods/fields can be referenced before the
- * classes themselves are declared, we preprocess all classes and
- * methods first.
- */
- for (ClassDecl cd : prog.classDeclList) {
-
- IdentificationTable cdTable = table.openScope(cd);
-
- if (cdTable != null) {
-
- // Simply add fields to current scope
- for (FieldDecl fd : cd.fieldDeclList) {
- cdTable.setDeclarationAtScope(fd);
- }
-
- // Just Add Declaration (also creates another identification table)
- for (MethodDecl md : cd.methodDeclList) {
- cdTable.openScope(md);
- }
+ @Override
+ public Type visitPackage(Package prog, IdTable table) {
+
+ top = table;
+
+ // Begin predefinitions
+ try {
+ for(String pd : predefined) {
+ Scanner scanner = new Scanner(pd, true);
+ Parser parser = new Parser(scanner);
+ ClassDecl cd = parser.parseClassDeclaration();
+
+ addDeclarations(cd, table);
+ cd.visit(this, table);
}
+ } catch(IOException e) {
+ Reporter.emit("System Predefinitions Error!");
+ System.exit(Compiler.rc);
}
-
- // Begin Traversal
- for (ClassDecl cd : prog.classDeclList) {
- currentClassDecl = cd;
+
+ // Add all second level declarations
+ for(ClassDecl cd : prog.classDeclList) {
+ addDeclarations(cd, table);
+ }
+
+ // Begin traversal
+ for(ClassDecl cd : prog.classDeclList) {
cd.visit(this, table);
}
+
+ // Check a main exists
+ if(main == null) {
+ Reporter.emit("Main method undeclared.");
+ }
return null;
}
-
+
// /////////////////////////////////////////////////////////////////////////////
//
@@ -111,228 +85,283 @@ public class Analyzer implements Visitor {
//
// /////////////////////////////////////////////////////////////////////////////
- public Type visitClassDecl(ClassDecl cd, IdentificationTable arg) {
-
- IdentificationTable cdTable = arg.getScope(cd);
-
- if (cdTable != null) {
-
- for (FieldDecl fd : cd.fieldDeclList) {
- fd.visit(this, cdTable);
- }
-
- for (MethodDecl md : cd.methodDeclList) {
- currentMethodDecl = md;
- md.visit(this, cdTable);
- }
- }
-
- return cd.type;
- }
-
- public Type visitFieldDecl(FieldDecl fd, IdentificationTable arg) {
-
- // Must check that the type of the field can be identified
- if (!table.classExists(fd.type)) {
- Reporter.report(ErrorType.UNDECLARED_TYPE, fd.type, null);
- } else if(fd.type.typeKind == TypeKind.VOID) {
- Reporter.report(ErrorType.VOID_TYPE, fd.type, null);
- }
-
- return fd.type;
- }
-
- public Type visitMethodDecl(MethodDecl md, IdentificationTable arg) {
+ @Override
+ public Type visitClassDecl(ClassDecl cd, IdTable table) {
- if(predefinedGen && md.name.equals("println")) {
+ currentClassDecl = cd;
+
+ for(FieldDecl fd : cd.fieldDeclList) {
+ fd.visit(this, cd.table);
+ }
+
+ for(MethodDecl md : cd.methodDeclList) {
+ md.visit(this, cd.table);
+ }
+
+ return null;
+ }
+
+ @Override
+ public Type visitFieldDecl(FieldDecl fd, IdTable table) {
+
+ fd.type.visit(this, table);
+ if(fd.type.typeKind == TypeKind.VOID) {
+ Reporter.emit("Field " + fd.name + " at " + fd.posn + " cannot have type 'void'");
+ }
+
+ return null;
+ }
+
+ @Override
+ public Type visitMethodDecl(MethodDecl md, IdTable table) {
+
+ currentMethodDecl = md;
+
+ // Save println method
+ if(println == null && md.name.equals("println")) {
println = md;
}
-
- // Check if a valid entry point to program
- if (IdentificationTable.isMainMethod(md)) {
- if (mainMethod != null)
- Reporter.report(ErrorType.MULTIPLE_MAIN, md, mainMethod);
- else
- mainMethod = md;
+
+ // Save main method
+ if(isMain(md)) {
+ if(main != null) {
+ Reporter.emit("Main at " + md.posn + " previously defined at " + main.posn);
+ } else {
+ main = md;
+ }
}
-
- // Must check that the type of the method can be identified
- if (!table.classExists(md.type)) {
- Reporter.report(ErrorType.UNDECLARED_TYPE, md.type, null);
- }
-
+
// Continue Traversal
- IdentificationTable mdTable = arg.getScope(md);
- if (mdTable != null) {
- for (ParameterDecl pd : md.parameterDeclList)
- pd.visit(this, mdTable);
- for (Statement s : md.statementList)
- s.visit(this, mdTable);
-
- // Check that return type matches expected type
- if (md.returnExp == null && md.type.typeKind != TypeKind.VOID) {
- Reporter.report(ErrorType.NO_RETURN, md, null);
- } else if (md.returnExp != null) {
- Type returnType = md.returnExp.visit(this, mdTable);
- IdentificationTable.match(md.type, returnType, true);
+ md.type.visit(this, table);
+
+ for(ParameterDecl pd : md.parameterDeclList) {
+ pd.visit(this, md.table);
+ }
+
+ for(Statement s : md.statementList) {
+ s.visit(this, md.table);
+ }
+
+ // Check return status
+ if(md.type.typeKind != TypeKind.VOID && md.returnExp == null) {
+ Reporter.emit("Method " + md.name + " at " + md.posn + " must have a return expression");
+ } else if(md.type.typeKind == TypeKind.VOID && md.returnExp != null) {
+ Reporter.emit("Method " + md.name + " at " + md.posn + " cannot have a return expression");
+ }
+
+ if(md.returnExp != null) {
+ Type returnType = md.returnExp.visit(this, md.table);
+ if(!match(returnType, md.type)) {
+ Reporter.emit("Expected " + md.type + " but got " + returnType + " at " + md.returnExp.posn);
}
}
- return md.type;
+ return null;
}
- public Type visitParameterDecl(ParameterDecl pd, IdentificationTable arg) {
- arg.setDeclarationAtScope(pd);
- if (!table.classExists(pd.type)) {
- Reporter.report(ErrorType.UNDECLARED_TYPE, pd.type, null);
- } else if(pd.type.typeKind == TypeKind.VOID) {
- Reporter.report(ErrorType.VOID_TYPE, pd.type, null);
- }
-
- return pd.type;
- }
-
- public Type visitVarDecl(VarDecl decl, IdentificationTable arg) {
- arg.setDeclarationAtScope(decl);
- if (!table.classExists(decl.type)) {
- Reporter.report(ErrorType.UNDECLARED_TYPE, decl.type, null);
- } else if(decl.type.typeKind == TypeKind.VOID) {
- Reporter.report(ErrorType.VOID_TYPE, decl.type, null);
+ @Override
+ public Type visitParameterDecl(ParameterDecl pd, IdTable table) {
+
+ table.add(pd);
+ pd.type.visit(this, table);
+ if(pd.type.typeKind == TypeKind.VOID) {
+ Reporter.emit("Parameter " + pd.name + " at " + pd.posn + " cannot have type 'void'");
}
- return decl.type;
+ return null;
}
-
+ @Override
+ public Type visitVarDecl(VarDecl decl, IdTable table) {
+
+ table.add(decl);
+ decl.type.visit(this, table);
+ if(decl.type.typeKind == TypeKind.VOID) {
+ Reporter.emit("Variable " + decl.name + " at " + decl.posn + " cannot have type 'void'");
+ }
+
+ return null;
+ }
+
+
// /////////////////////////////////////////////////////////////////////////////
//
// TYPES
//
// /////////////////////////////////////////////////////////////////////////////
-
- public Type visitBaseType(BaseType type, IdentificationTable arg) {
-
+
+ @Override
+ public Type visitBaseType(BaseType type, IdTable table) {
+
return type;
}
- public Type visitClassType(ClassType type, IdentificationTable arg) {
- type.className.visit(this, arg);
+ @Override
+ public Type visitClassType(ClassType type, IdTable table) {
+
+ type.className.visit(this, table);
+
+ // Must check that the type is valid
+ String cn = type.className.spelling;
+ if(top.getDeclarationAtScope(cn) == null) {
+ Reporter.emit("Class '" + cn + "' undeclared at " + type.posn);
+ }
+
return type;
}
- public Type visitArrayType(ArrayType type, IdentificationTable arg) {
- type.eltType.visit(this, arg);
+ @Override
+ public Type visitArrayType(ArrayType type, IdTable table) {
+
+ type.eltType.visit(this, table);
+
return type;
}
-
+
// /////////////////////////////////////////////////////////////////////////////
//
// STATEMENTS
//
// /////////////////////////////////////////////////////////////////////////////
- public Type visitBlockStmt(BlockStmt stmt, IdentificationTable arg) {
- arg.pushLevel();
- for (Statement s : stmt.sl)
- s.visit(this, arg);
- arg.popLevel();
-
+ @Override
+ public Type visitBlockStmt(BlockStmt stmt, IdTable table) {
+
+ table.push();
+
+ for(Statement s : stmt.sl) {
+ s.visit(this, table);
+ }
+
+ table.pop();
+
return null;
}
- // The stmt of the vardecl may not refer to the variable itself
- public Type visitVardeclStmt(VarDeclStmt stmt, IdentificationTable arg) {
- Type varDeclType = stmt.varDecl.visit(this, arg);
+ @Override
+ public Type visitVardeclStmt(VarDeclStmt stmt, IdTable table) {
+
+ stmt.varDecl.visit(this, table);
currentVarDecl = stmt.varDecl;
- Type initExpType = stmt.initExp.visit(this, arg);
- IdentificationTable.match(varDeclType, initExpType, true);
+ Type exprType = stmt.initExp.visit(this, table);
currentVarDecl = null;
- // Can't have a class reference as the sole rhs
- if(stmt.initExp instanceof RefExpr && initExpType.typeKind == TypeKind.CLASS) {
- RefExpr re = (RefExpr)stmt.initExp;
- Declaration decl = table.getDeclarationAtScope(re.ref.decl.name);
- if(decl != null) Reporter.report(ErrorType.CLASS_IDENTIFER, stmt, null);
+ // Types must match
+ if(!match(stmt.varDecl.type, exprType)) {
+ Reporter.emit("Expected " + stmt.varDecl.type + " but got " + exprType + " at " + stmt.initExp.posn);
}
-
- return varDeclType;
+
+ return null;
}
- public Type visitAssignStmt(AssignStmt stmt, IdentificationTable arg) {
- Type refType = stmt.ref.visit(this, arg);
- Type valType = stmt.val.visit(this, arg);
- IdentificationTable.match(valType, refType, true);
+ @Override
+ public Type visitAssignStmt(AssignStmt stmt, IdTable table) {
- if(stmt.ref.decl instanceof MethodDecl)
- Reporter.report(ErrorType.FUNCTION_ASSIGNMENT, stmt.ref.decl, null);
-
- return refType;
- }
-
- public Type visitCallStmt(CallStmt stmt, IdentificationTable arg) {
-
- Type methodType = stmt.methodRef.visit(this, arg);
+ Type refType = stmt.ref.visit(this, table);
+ Type valType = stmt.val.visit(this, table);
- if(methodType.typeKind != TypeKind.ERROR) {
-
- // Check that parameter count is correct and each type is correct
- MethodDecl decl = (MethodDecl) stmt.methodRef.decl;
- if (decl.parameterDeclList.size() != stmt.argList.size()) {
- Reporter.report(ErrorType.INVALID_PARAM_COUNT, stmt, decl);
- } else {
- for (int i = 0; i < stmt.argList.size(); i++) {
- Type exprType = stmt.argList.get(i).visit(this, arg);
- Type pdType = decl.parameterDeclList.get(i).type;
- IdentificationTable.match(pdType, exprType, true);
- }
+ if(!match(refType, valType)) {
+ Reporter.emit("Expected " + refType + " but got " + valType + " at " + stmt.posn);
+ }
+
+ // Should never assign 'this' to anything
+ if(stmt.ref instanceof ThisRef) {
+ Reporter.emit("Cannot assign 'this' to a value at " + stmt.posn);
+ }
+
+ // Should never assign a method a value
+ if(stmt.ref.decl instanceof MethodDecl) {
+ Reporter.emit("Cannot assign a method a value at " + stmt.posn);
+ }
+
+ // Cannot assign array length field
+ if(stmt.ref instanceof QualifiedRef) {
+ QualifiedRef ref = (QualifiedRef) stmt.ref;
+ if(ref.ref.decl.type.typeKind == TypeKind.ARRAY && ref.id.spelling.equals("length")) {
+ Reporter.emit("'length' field cannot be changed at " + stmt.posn);
}
}
-
- return methodType;
+
+ return null;
}
- public Type visitIfStmt(IfStmt stmt, IdentificationTable arg) {
+ @Override
+ public Type visitCallStmt(CallStmt stmt, IdTable table) {
+
+ stmt.methodRef.visit(this, table);
+
+ // Check valid parameter count
+ MethodDecl md = (MethodDecl) stmt.methodRef.decl;
+ if(md.parameterDeclList.size() != stmt.argList.size()) {
+ Reporter.emit("Expected " + md.parameterDeclList.size() + " parameters at " + stmt.posn);
+ return null;
+ }
+
+ // Check parameter types match
+ for (int i = 0; i < stmt.argList.size(); i++) {
+ Expression e = stmt.argList.get(i);
+ Type exprType = e.visit(this, table);
+ ParameterDecl pd = md.parameterDeclList.get(i);
- // The conditional statment must be a boolean
- Type condType = stmt.cond.visit(this, arg);
- IdentificationTable.match(new BaseType(TypeKind.BOOLEAN, null), condType, true);
-
- // A single vardecl cannot exist after a conditional statement
- if (stmt.thenStmt instanceof VarDeclStmt) {
- Reporter.report(ErrorType.SINGLE_VARCOND, stmt.thenStmt, null);
- } else {
- stmt.thenStmt.visit(this, arg);
- if (stmt.elseStmt != null) {
- if (stmt.elseStmt instanceof VarDeclStmt) {
- Reporter.report(ErrorType.SINGLE_VARCOND, stmt.elseStmt,
- null);
- } else {
- stmt.elseStmt.visit(this, arg);
- }
+ if(!match(pd.type, exprType)) {
+ Reporter.emit("Parameter " + pd.name + " is of type " + pd.type + " but got " + exprType + " at " + e.posn);
}
}
return null;
}
- public Type visitWhileStmt(WhileStmt stmt, IdentificationTable arg) {
-
- // The conditional statment must be a boolean
- Type condType = stmt.cond.visit(this, arg);
- IdentificationTable.match(new BaseType(TypeKind.BOOLEAN, null), condType, true);
-
- // A single vardecl cannot exist after a conditional statement
- if (stmt.body instanceof VarDeclStmt) {
- Reporter.report(ErrorType.SINGLE_VARCOND, stmt.body, null);
- } else {
- stmt.body.visit(this, arg);
+ @Override
+ public Type visitIfStmt(IfStmt stmt, IdTable table) {
+
+ // Conditional statement must have type boolean
+ Type condType = stmt.cond.visit(this, table);
+ if(condType.typeKind != TypeKind.BOOLEAN) {
+ Reporter.emit("Expected boolean but got " + condType + " at " + condType.posn);
+ }
+
+ // A single variable declaration not allowed after conditional statement
+ if(stmt.thenStmt instanceof VarDeclStmt) {
+ Reporter.emit("Variable declaration not allowed solely in 'then' clause at " + stmt.thenStmt.posn);
+ return null;
+ }
+
+ stmt.thenStmt.visit(this, table);
+
+ // Check else statement
+ if (stmt.elseStmt != null) {
+ if (stmt.elseStmt instanceof VarDeclStmt) {
+ Reporter.emit("Variable declaration not allowed solely in 'else' clause at " + stmt.elseStmt.posn);
+ return null;
+ }
+
+ stmt.elseStmt.visit(this, table);
}
return null;
}
+ @Override
+ public Type visitWhileStmt(WhileStmt stmt, IdTable table) {
+
+ // Conditional statement must have type boolean
+ Type condType = stmt.cond.visit(this, table);
+ if(condType.typeKind != TypeKind.BOOLEAN) {
+ Reporter.emit("Expected boolean but got " + condType + " at " + condType.posn);
+ }
+
+ if(stmt.body instanceof VarDeclStmt) {
+ Reporter.emit("Variable declaration not allowed solely in 'while' clause at " + stmt.body.posn);
+ return null;
+ }
+
+ stmt.body.visit(this, table);
+
+ return null;
+ }
+
// /////////////////////////////////////////////////////////////////////////////
//
@@ -340,85 +369,153 @@ public class Analyzer implements Visitor {
//
// /////////////////////////////////////////////////////////////////////////////
- public Type visitUnaryExpr(UnaryExpr expr, IdentificationTable arg) {
- Type opType = expr.operator.visit(this, arg);
- Type exprType = expr.expr.visit(this, arg);
- IdentificationTable.match(opType, exprType, true);
-
+ @Override
+ public Type visitUnaryExpr(UnaryExpr expr, IdTable table) {
+
+ Type exprType = expr.expr.visit(this, table);
+ Type opType = expr.operator.visit(this, table);
+ if(!match(exprType, opType)) {
+ String op = expr.operator.spelling;
+ Reporter.emit("Operator " + op + " applies to " + opType + " but got " + exprType + " at " + expr.posn);
+ }
+
return opType;
}
- public Type visitBinaryExpr(BinaryExpr expr, IdentificationTable arg) {
- Type opType = expr.operator.visit(this, arg);
- Type leftType = expr.left.visit(this, arg);
- Type rightType = expr.right.visit(this, arg);
+ @Override
+ public Type visitBinaryExpr(BinaryExpr expr, IdTable table) {
- // Both sides must be the same
- if(opType.typeKind == TypeKind.EQUALS) {
- IdentificationTable.match(leftType, rightType, true);
- return new BaseType(TypeKind.BOOLEAN, opType.posn);
- }
+ Type lType = expr.left.visit(this, table);
+ Type rType = expr.right.visit(this, table);
- // Both sides must be integers
- else if(opType.typeKind == TypeKind.RELATIONAL) {
- BaseType bt = new BaseType(TypeKind.INT, opType.posn);
- IdentificationTable.match(bt, leftType, true);
- IdentificationTable.match(bt, rightType, true);
- return new BaseType(TypeKind.BOOLEAN, opType.posn);
- }
-
- // Both sides must match operator type
- IdentificationTable.match(leftType, opType, true);
- IdentificationTable.match(rightType, opType, true);
- return opType;
- }
-
- public Type visitRefExpr(RefExpr expr, IdentificationTable arg) {
- Type exprType = expr.ref.visit(this, arg);
- return exprType;
- }
-
- public Type visitCallExpr(CallExpr expr, IdentificationTable arg) {
- Type functionRefType = expr.functionRef.visit(this, arg);
-
- if(expr.functionRef.decl instanceof MethodDecl) {
+ BaseType type = null;
+ String op = expr.operator.spelling;
+ switch(op) {
- MethodDecl decl = (MethodDecl) expr.functionRef.decl;
-
- // Check that parameter count is correct and each type is correct
- if (decl.parameterDeclList.size() != expr.argList.size()) {
- Reporter.report(ErrorType.INVALID_PARAM_COUNT, expr, decl);
- } else {
- for (int i = 0; i < expr.argList.size(); i++) {
- Type exprType = expr.argList.get(i).visit(this, arg);
- Type pdType = decl.parameterDeclList.get(i).type;
- IdentificationTable.match(pdType, exprType, true);
+ // Equality Operators
+ case "==":
+ case "!=":
+ if(!match(lType, rType)) {
+ Reporter.emit("Left hand side must be of right hand side's type " + rType + " at " + expr.posn);
}
+ return new BaseType(TypeKind.BOOLEAN, expr.posn);
+
+ // Boolean Operators
+ case "&&":
+ case "||":
+ type = new BaseType(TypeKind.BOOLEAN, expr.posn);
+ break;
+
+ // Integer operators
+ case ">":
+ case "<":
+ case "+":
+ case "-":
+ case "*":
+ case "/":
+ case "<=":
+ case ">=":
+ type = new BaseType(TypeKind.INT, expr.posn);
+ break;
+
+ default:
+ return new BaseType(TypeKind.ERROR, expr.posn);
+ }
+
+ // Make sure types match
+ if(!match(lType, type)) {
+ Reporter.emit("Expected " + type + " but got " + lType + " at " + expr.posn);
+ }
+
+ if(!match(rType, type)) {
+ Reporter.emit("Expected " + type + " but got " + lType + " at " + expr.posn);
+ }
+
+ // Resulting type
+ return expr.operator.visit(this, table);
+ }
+
+ @Override
+ public Type visitRefExpr(RefExpr expr, IdTable table) {
+
+ Type refType = expr.ref.visit(this, table);
+ Declaration decl = table.getDeclaration(expr.ref.spelling);
+
+ // Should never reference a class name
+ if(decl instanceof ClassDecl) {
+ Reporter.emit("Class declaration referenced at " + expr.posn);
+ }
+
+ // Should never reference a method name
+ else if(decl instanceof MethodDecl) {
+ Reporter.emit("Method declaration referenced at " + expr.posn);
+ }
+
+ // Cannot access instance members in static context
+ if(!(expr.ref instanceof QualifiedRef) && decl instanceof FieldDecl) {
+ FieldDecl fd = (FieldDecl) decl;
+ if(currentMethodDecl.isStatic && !fd.isStatic) {
+ Reporter.emit("Cannot access instance member in static context at " + expr.posn);
}
- } else {
- Reporter.report(ErrorType.NONFUNCTION_CALL, expr, null);
}
- return functionRefType;
+ return refType;
}
- public Type visitLiteralExpr(LiteralExpr expr, IdentificationTable arg) {
- Type literalType = expr.literal.visit(this, arg);
- return literalType;
+ @Override
+ public Type visitCallExpr(CallExpr expr, IdTable table) {
+
+ Type refType = expr.functionRef.visit(this, table);
+
+ // Check parameter count matches
+ MethodDecl md = (MethodDecl) expr.functionRef.decl;
+ if(md.parameterDeclList.size() != expr.argList.size()) {
+ Reporter.emit("Expected " + md.parameterDeclList.size() + " parameters at " + expr.posn);
+ return refType;
+ }
+
+ // Check parameter types match
+ for (int i = 0; i < expr.argList.size(); i++) {
+ Expression e = expr.argList.get(i);
+ Type exprType = e.visit(this, table);
+ ParameterDecl pd = md.parameterDeclList.get(i);
+
+ if(!match(pd.type, exprType)) {
+ Reporter.emit("Parameter " + pd.name + " is of type " + pd.type + " but got " + exprType + " at " + e.posn);
+ }
+ }
+
+ return refType;
}
- public Type visitNewObjectExpr(NewObjectExpr expr, IdentificationTable arg) {
- Type objectType = expr.classtype.visit(this, arg);
- return objectType;
+ @Override
+ public Type visitLiteralExpr(LiteralExpr expr, IdTable table) {
+
+ return expr.literal.visit(this, table);
}
- public Type visitNewArrayExpr(NewArrayExpr expr, IdentificationTable arg) {
- Type sizeExprType = expr.sizeExpr.visit(this, arg);
- if (sizeExprType.typeKind != TypeKind.INT) {
- Reporter.report(ErrorType.INVALID_INDEX, expr.sizeExpr, null);
+ @Override
+ public Type visitNewObjectExpr(NewObjectExpr expr, IdTable table) {
+
+ return expr.classtype.visit(this, table);
+ }
+
+ @Override
+ public Type visitNewArrayExpr(NewArrayExpr expr, IdTable table) {
+
+ // Arrays only of classes and integers
+ Type eltType = expr.eltType.visit(this, table);
+ if(eltType.typeKind != TypeKind.INT && eltType.typeKind != TypeKind.CLASS) {
+ Reporter.emit("Cannot create array of type " + eltType + " at " + expr.posn);
+ }
+
+ // Size must be an integer value
+ Type sizeType = expr.sizeExpr.visit(this, table);
+ if (sizeType.typeKind != TypeKind.INT) {
+ BaseType type = new BaseType(TypeKind.INT, expr.sizeExpr.posn);
+ Reporter.emit("Expected " + type + " but got " + sizeType + " at " + type.posn);
}
- Type eltType = expr.eltType.visit(this, arg);
return new ArrayType(eltType, expr.posn);
}
@@ -428,171 +525,166 @@ public class Analyzer implements Visitor {
// REFERENCES
//
// /////////////////////////////////////////////////////////////////////////////
-
- public Type visitQualifiedRef(QualifiedRef ref, IdentificationTable arg) {
- Type refType = ref.ref.visit(this, arg);
+ @Override
+ public Type visitQualifiedRef(QualifiedRef ref, IdTable table) {
- // Array types only have the single 'length' field
+ Type refType = ref.ref.visit(this, table);
+
+ // Should not try and access a method in qualified manner
+ if(ref.ref.decl instanceof MethodDecl) {
+ Reporter.emit("Cannot use method " + ref.ref.decl.name + " in qualified manner at " + ref.ref.posn);
+ return new BaseType(TypeKind.ERROR, ref.ref.posn);
+ }
+
+ // Array types can have a length field
if(refType.typeKind == TypeKind.ARRAY) {
if(!ref.id.spelling.equals("length")) {
- Reporter.report(ErrorType.LENGTH, ref.id, null);
- return refType;
+ Reporter.emit(ref.id.spelling + " attribute not available with arrays at " + ref.id.posn);
+ return new BaseType(TypeKind.ERROR, ref.id.posn);
}
return new BaseType(TypeKind.INT, ref.id.posn);
- }
-
- // Note qualified ref's only make sense in the context of classes
- else if(refType.typeKind != TypeKind.CLASS) {
- if(refType.typeKind != TypeKind.ERROR) // Don't need to report multiple times
- Reporter.report(ErrorType.TYPE_MISMATCH, new BaseType(TypeKind.CLASS, null), refType);
-
- return refType;
- }
-
- // Try to find qualified member
- Declaration qualified = ref.ref.decl;
- ClassType qualType = (ClassType) qualified.type;
- Declaration qualClassDecl = table.getDeclaration(qualType.className.spelling);
- if(qualClassDecl == null) {
- Reporter.report(ErrorType.UNDECLARED_TYPE, qualified.type, null);
- return new BaseType(TypeKind.ERROR, qualified.posn);
}
- // Get member
- IdentificationTable cdTable = table.getScope(qualClassDecl);
- MemberDecl md = (MemberDecl) cdTable.getDeclarationAtScope(ref.id.spelling);
-
- // Check the member exists at all
+ // Otherwise, should have a class type
+ if(refType.typeKind != TypeKind.CLASS) {
+ Reporter.emit("Qualified reference not of type class or array at " + ref.posn);
+ return new BaseType(TypeKind.ERROR, ref.posn);
+ }
+
+ // Get member in question
+ ClassType ct = (ClassType) refType;
+ ClassDecl cd = (ClassDecl) top.getDeclarationAtScope(ct.className.spelling);
+ if(cd == null) {
+ Reporter.emit("Accessing non-existant class at " + ct.posn);
+ return new BaseType(TypeKind.ERROR, ref.posn);
+ }
+
+ MemberDecl md = (MemberDecl) cd.table.getDeclarationAtScope(ref.id.spelling);
if(md == null) {
- Reporter.report(ErrorType.UNDEFINED, ref.id, null);
- return new BaseType(TypeKind.ERROR, ref.id.posn);
- }
-
- // If the qualifed ref is a class declaration, members must be static (must check for 'this')
- else if(qualified instanceof ClassDecl && !(ref.ref instanceof ThisRef)) {
- if(!md.isStatic) {
- Reporter.report(ErrorType.STATIC, md, ref.id);
- return new BaseType(TypeKind.ERROR, ref.id.posn);
- } else if(md.isPrivate) {
- Reporter.report(ErrorType.VISIBILITY, md, ref.id);
- return new BaseType(TypeKind.ERROR, ref.id.posn);
- }
+ Reporter.emit("Accessing non-existant field at " + ref.id.posn);
+ return new BaseType(TypeKind.ERROR, ref.posn);
}
- // The member should not be a method, as this is unsupported
- else if(qualified instanceof MethodDecl) {
- Reporter.report(ErrorType.UNDEFINED, ref.id, null);
+ // Check if static member
+ Declaration decl = table.getDeclaration(ref.ref.spelling);
+ if(decl instanceof ClassDecl && !md.isStatic) {
+ Reporter.emit("Cannot access non-static member at " + ref.id.posn);
}
-
- // Otherwise, we can assume the object is a variable and attempt to access members
- else if(md.isPrivate && currentClassDecl != qualClassDecl) {
- Reporter.report(ErrorType.VISIBILITY, md, ref.id);
- return new BaseType(TypeKind.ERROR, ref.id.posn);
+
+ // Check Visibility Status
+ if(md.isPrivate && cd != currentClassDecl) {
+ Reporter.emit("Cannot access private member at " + ref.id.posn);
}
-
- ref.id.decl = md;
+
ref.decl = md;
+ ref.id.decl = md;
+ ref.spelling = ref.id.spelling;
+
return md.type;
}
- public Type visitIndexedRef(IndexedRef ref, IdentificationTable arg) {
-
- ArrayType refType = (ArrayType) ref.ref.visit(this, arg);
-
- // Make sure index is an integer
- Type indexExprType = ref.indexExpr.visit(this, arg);
- if (indexExprType.typeKind != TypeKind.INT) {
- Reporter.report(ErrorType.INVALID_INDEX, ref.indexExpr, null);
+ @Override
+ public Type visitIndexedRef(IndexedRef ref, IdTable table) {
+
+ Type refType = ref.ref.visit(this, table);
+ ref.spelling = ref.ref.spelling;
+
+ // Must be an array type
+ if(refType.typeKind != TypeKind.ARRAY) {
+ Reporter.emit("Trying to index " + refType + " at " + ref.ref.posn);
+ return refType;
+ }
+
+ // Index must be an integer value
+ Type indexType = ref.indexExpr.visit(this, table);
+ if(indexType.typeKind != TypeKind.INT) {
+ BaseType type = new BaseType(TypeKind.INT, ref.indexExpr.posn);
+ Reporter.emit("Expected " + type + " but got " + indexType + " at " + type.posn);
+ }
+
+ // Array types can be of either classes or ints
+ ArrayType at = (ArrayType) refType;
+ if(at.eltType.typeKind == TypeKind.CLASS) {
+ ClassType ct = (ClassType) at.eltType;
+ ref.decl = table.getDeclaration(ct.className.spelling);
+ return ref.decl.type;
+ } else {
+ ref.decl = null;
+ return new BaseType(TypeKind.INT, ref.posn);
}
-
- ref.decl = ref.ref.decl;
- return refType.eltType;
}
- public Type visitIdRef(IdRef ref, IdentificationTable arg) {
- Type idType = ref.id.visit(this, arg);
+ @Override
+ public Type visitIdRef(IdRef ref, IdTable table) {
+
+ ref.id.visit(this, table);
ref.decl = ref.id.decl;
-
- return idType;
+ ref.spelling = ref.id.spelling;
+
+ return ref.decl.type;
}
- public Type visitThisRef(ThisRef ref, IdentificationTable arg) {
+ @Override
+ public Type visitThisRef(ThisRef ref, IdTable table) {
+
+ ref.spelling = "this";
ref.decl = currentClassDecl;
if(currentMethodDecl.isStatic) {
- Reporter.report(ErrorType.THIS, ref, currentMethodDecl);
+ Reporter.emit("'this' cannot be referenced in a static context at " + ref.posn);
}
return ref.decl.type;
}
-
+
// /////////////////////////////////////////////////////////////////////////////
//
// TERMINALS
//
// /////////////////////////////////////////////////////////////////////////////
-
- public Type visitIdentifier(Identifier id, IdentificationTable arg) {
- // Must check identifier is not of the same type being declared
+ @Override
+ public Type visitIdentifier(Identifier id, IdTable table) {
+
+ // An variable cannot be used in its declaration
if(currentVarDecl != null && currentVarDecl.name.equals(id.spelling)) {
- Reporter.report(ErrorType.VARDECL_USED, id, currentVarDecl);
- return new BaseType(TypeKind.ERROR, id.posn);
+ Reporter.emit("Cannot use variable in declaration at " + id.posn);
}
-
- // Check if identifier can be found in current scope
- Declaration decl = arg.getDeclarationAtScope(id.spelling);
- if (decl != null) { id.decl = decl; return decl.type; }
- // Access member and check visibility properties
- Declaration d = arg.getDeclaration(id.spelling);
- if(d == null) {
- Reporter.report(ErrorType.UNDEFINED, id, null);
- return new BaseType(TypeKind.ERROR, id.posn);
- } else {
-
- // Can only be a member at this point
- if(d.type.typeKind != TypeKind.CLASS) {
- MemberDecl md = (MemberDecl) d;
-
- // A static method cannot access instance members
- if(currentMethodDecl.isStatic && !md.isStatic) {
- Reporter.report(ErrorType.STATIC, md, id);
- return new BaseType(TypeKind.ERROR, id.posn);
- }
-
- // If a member declaration is private, it must be a member of the current class
- else if(md.isPrivate) {
-
- // Check if member is part of the current class
- IdentificationTable cdTable = table.getScope(currentClassDecl);
- if(cdTable.getDeclarationAtScope(md.name) == null) {
- Reporter.report(ErrorType.VISIBILITY, md, id);
- return new BaseType(TypeKind.ERROR, id.posn);
- }
- }
- }
-
- id.decl = d;
- return d.type;
+ // Try to find declaration (and abort if not found)
+ id.decl = table.getDeclaration(id.spelling);
+ if(id.decl == null) {
+ Reporter.emit(id.spelling + " undefined at " + id.posn);
+ System.exit(Compiler.rc);
}
+
+ // Cannot access instance method from static context
+ if(id.decl instanceof MemberDecl) {
+ MemberDecl md = (MemberDecl) id.decl;
+ if(currentMethodDecl.isStatic && !md.isStatic) {
+ Reporter.emit("Cannot access instance member " + md.name + " in a static context at " + id.posn);
+ }
+ }
+
+ return id.decl.type;
+
}
- public Type visitOperator(Operator op, IdentificationTable arg) {
-
- switch (op.token.spelling) {
+ @Override
+ public Type visitOperator(Operator op, IdTable table) {
+ switch(op.spelling) {
case "!":
case "&&":
case "||":
- return new BaseType(TypeKind.BOOLEAN, op.posn);
-
case ">":
case "<":
case "<=":
case ">=":
- return new BaseType(TypeKind.RELATIONAL, op.posn);
+ case "==":
+ case "!=":
+ return new BaseType(TypeKind.BOOLEAN, op.posn);
case "+":
case "-":
@@ -600,22 +692,107 @@ public class Analyzer implements Visitor {
case "/":
return new BaseType(TypeKind.INT, op.posn);
- case "==":
- case "!=":
- return new BaseType(TypeKind.EQUALS, op.posn);
+ default:
+ return new BaseType(TypeKind.ERROR, op.posn);
}
-
- return null;
}
- public Type visitIntLiteral(IntLiteral num, IdentificationTable arg) {
-
+ @Override
+ public Type visitIntLiteral(IntLiteral num, IdTable table) {
+
return new BaseType(TypeKind.INT, num.posn);
}
- public Type visitBooleanLiteral(BooleanLiteral bool, IdentificationTable arg) {
-
+ @Override
+ public Type visitBooleanLiteral(BooleanLiteral bool, IdTable table) {
+
return new BaseType(TypeKind.BOOLEAN, bool.posn);
}
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // Convenience Functions
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ *
+ * @param cd
+ * @param table
+ */
+ private void addDeclarations(ClassDecl cd, IdTable table) {
+
+ table.add(cd);
+ cd.table = new IdTable(table);
+
+ for(FieldDecl fd : cd.fieldDeclList) {
+ cd.table.add(fd);
+ }
+
+ for(MethodDecl md : cd.methodDeclList) {
+ cd.table.add(md);
+ md.table = new IdTable(cd.table);
+ }
+ }
+
+ /**
+ *
+ * @param md
+ * @return
+ */
+ private boolean isMain(MethodDecl md) {
+
+ // Correct Signature
+ if(!md.isPrivate && md.isStatic) {
+ if(md.type.typeKind == TypeKind.VOID) {
+ if(md.name.equals("main") && md.parameterDeclList.size() == 1) {
+
+ // Check parameter declaration
+ ParameterDecl pd = md.parameterDeclList.get(0);
+ if(pd.type.typeKind == TypeKind.ARRAY) {
+ ArrayType at = (ArrayType) pd.type;
+ if(at.eltType.typeKind == TypeKind.CLASS) {
+ ClassType ct = (ClassType) at.eltType;
+
+ return ct.className.spelling.equals("String");
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ *
+ * @param t1
+ * @param t2
+ * @return
+ */
+ private boolean match(Type t1, Type t2) {
+
+ if(t1.typeKind != t2.typeKind) {
+ return false;
+ }
+
+ // Check Class Types match
+ else if(t1.typeKind == TypeKind.CLASS) {
+ ClassType c1 = (ClassType) t1;
+ ClassType c2 = (ClassType) t2;
+
+ return c1.className.spelling.equals(c2.className.spelling);
+ }
+
+ // Check Array Types match
+ else if(t1.typeKind == TypeKind.ARRAY) {
+ ArrayType a1 = (ArrayType) t1;
+ ArrayType a2 = (ArrayType) t2;
+
+ return match(a1.eltType, a2.eltType);
+ }
+
+ return true;
+ }
}
diff --git a/src/miniJava/ContextualAnalyzer/IdTable.java b/src/miniJava/ContextualAnalyzer/IdTable.java
new file mode 100644
index 0000000..50da518
--- /dev/null
+++ b/src/miniJava/ContextualAnalyzer/IdTable.java
@@ -0,0 +1,127 @@
+package miniJava.ContextualAnalyzer;
+
+import java.util.HashMap;
+import java.util.ArrayList;
+import miniJava.Compiler;
+
+import miniJava.AbstractSyntaxTrees.*;
+
+/**
+ *
+ */
+public class IdTable {
+
+ private IdTable parent;
+ private ArrayList> scope;
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // CONSTRUCTORS
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public IdTable() {
+ this(null);
+ }
+
+ /**
+ *
+ * @param parent
+ */
+ public IdTable(IdTable parent) {
+ this.parent = parent;
+ this.scope = new ArrayList<>();
+ push();
+ }
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // ACTIVE SCOPE
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ *
+ */
+ public void pop() {
+ int last = scope.size() - 1;
+ scope.remove(last);
+ }
+
+ /**
+ *
+ */
+ public void push() {
+ HashMap nested = new HashMap<>();
+ scope.add(nested);
+ }
+
+ /**
+ *
+ */
+ public void add(Declaration decl) {
+ for(int i = 0; i < scope.size(); i++) {
+ HashMap nest = scope.get(i);
+ if(nest.containsKey(decl.name)) {
+
+ Declaration prev = nest.get(decl.name);
+
+ if(decl instanceof ClassDecl) {
+ Reporter.report(decl, prev, "Class");
+ } else if(decl instanceof FieldDecl) {
+ Reporter.report(decl, prev, "Field");
+ } else if(decl instanceof MethodDecl) {
+ Reporter.report(decl, prev, "Method");
+ } else if(decl instanceof ParameterDecl) {
+ Reporter.report(decl, prev, "Parameter");
+ } else if(decl instanceof VarDecl) {
+ Reporter.report(decl, prev, "Variable");
+ }
+
+ System.exit(Compiler.rc);
+ }
+ }
+
+ scope.get(scope.size()-1).put(decl.name, decl);
+ }
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // GETTERS
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
+ /**
+ *
+ * @param name
+ */
+ public Declaration getDeclaration(String name) {
+ IdTable current = this;
+ while (current != null) {
+ Declaration decl = current.getDeclarationAtScope(name);
+ if (decl == null) current = current.parent;
+ else return decl;
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * @param name
+ */
+ public Declaration getDeclarationAtScope(String name) {
+ for (int i = scope.size() - 1; i >= 0; i--) {
+ HashMap nest = scope.get(i);
+ if (nest.containsKey(name)) return nest.get(name);
+ }
+
+ return null;
+ }
+}
diff --git a/src/miniJava/ContextualAnalyzer/IdentificationTable.java b/src/miniJava/ContextualAnalyzer/IdentificationTable.java
deleted file mode 100644
index 6faa248..0000000
--- a/src/miniJava/ContextualAnalyzer/IdentificationTable.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package miniJava.ContextualAnalyzer;
-
-import java.util.*;
-
-import miniJava.AbstractSyntaxTrees.*;
-
-public class IdentificationTable {
-
- private IdentificationTable parent;
- private HashMap scope;
- private ArrayList> table;
-
- /**
- *
- */
- public IdentificationTable() {
- this(null);
- }
-
- /**
- *
- * @param parent
- */
- public IdentificationTable(IdentificationTable parent) {
- this.parent = parent;
- this.scope = new HashMap();
- this.table = new ArrayList>();
- this.table.add(new HashMap());
- }
-
- /**
- * Adds another level for variables to be stored at
- */
- public void popLevel() {
- table.remove(table.size() - 1);
- }
-
- /**
- * Removes all variables declared at the current level
- */
- public void pushLevel() {
- table.add(new HashMap());
- }
-
- /**
- * This method will only ever be called with class/method declarations.
- *
- * @param decl
- * @return
- */
- public IdentificationTable openScope(Declaration decl) {
- Declaration current = getDeclarationAtScope(decl.name);
- if (scope.containsKey(decl.name) || current != null) {
- Reporter.report(ErrorType.REDEFINITION, decl, current);
- return null;
- } else {
- table.get(table.size() - 1).put(decl.name, decl);
- scope.put(decl.name, new IdentificationTable(this));
- return scope.get(decl.name);
- }
- }
-
- /**
- * Return nested scope corresponding to declaration (or null if
- * non-existant).
- *
- * @param decl
- * @return
- */
- public IdentificationTable getScope(Declaration decl) {
- if (scope.containsKey(decl.name)) {
- return scope.get(decl.name);
- }
-
- return null;
- }
-
- /**
- * Iterates through all parents and tries to find the specified declaration
- * by name.
- *
- * @param name
- * @return
- */
- public Declaration getDeclaration(String name) {
- IdentificationTable current = this;
- while (current != null) {
- Declaration decl = current.getDeclarationAtScope(name);
- if (decl == null) current = current.parent;
- else return decl;
- }
-
- return null;
- }
-
- /**
- * Iterates through levels (from higher to lower) for declaration, returning
- * none if it does not exist.
- *
- * @param name
- * @return
- */
- public Declaration getDeclarationAtScope(String name) {
- for (int i = table.size() - 1; i >= 0; i--) {
- HashMap level = table.get(i);
- if (level.containsKey(name)) return level.get(name);
- }
-
- return null;
- }
-
- /**
- * Add declaration to current table's table member.
- *
- * @param name
- */
- public void setDeclarationAtScope(Declaration decl) {
- for (int i = 0; i < table.size(); i++) {
- HashMap level = table.get(i);
- if (level.containsKey(decl.name)) {
- Declaration defined = level.get(decl.name);
- Reporter.report(ErrorType.REDEFINITION, decl, defined);
- return;
- }
- }
-
- table.get(table.size() - 1).put(decl.name, decl);
- }
-
- /**
- * Checks whether the specified class has been declared.
- *
- * @param t
- * @return
- */
- public boolean classExists(Type t) {
- if (t.typeKind == TypeKind.CLASS) {
- ClassType ct = (ClassType) t;
- return getDeclaration(ct.className.spelling) != null;
- }
-
- return true;
- }
-
- /**
- * Determines whether two types match.
- *
- * @param t1
- * @param t2
- * @return
- */
- public static boolean match(Type t1, Type t2) {
- return IdentificationTable.match(t1, t2, false);
- }
-
- /**
- * Determines whether two type match, reporting an error if they do not.
- *
- * @param t1
- * @param t2
- * @param report
- * @return
- */
- public static boolean match(Type t1, Type t2, boolean report) {
-
- if (t1.typeKind != t2.typeKind) {
- if (report) Reporter.report(ErrorType.TYPE_MISMATCH, t1, t2);
- return false;
- }
-
- // Check Class Types match
- else if (t1.typeKind == TypeKind.CLASS) {
- ClassType c1 = (ClassType) t1;
- ClassType c2 = (ClassType) t2;
- if (!c1.className.spelling.equals(c2.className.spelling)) {
- if (report) Reporter.report(ErrorType.TYPE_MISMATCH, t1, t2);
- return false;
- }
- }
-
- // Check array types match
- else if (t1.typeKind == TypeKind.ARRAY) {
- ArrayType a1 = (ArrayType) t1;
- ArrayType a2 = (ArrayType) t2;
- if (!IdentificationTable.match(a1.eltType, a2.eltType)) {
- if (report) Reporter.report(ErrorType.TYPE_MISMATCH, t1, t2);
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Determines if the passed method is a valid entry point for the
- * compilation phase.
- *
- * @param md
- * @return
- */
- public static boolean isMainMethod(MethodDecl md) {
-
- // Check Declaration
- if (!md.isPrivate && md.isStatic && md.type.typeKind == TypeKind.VOID
- && md.name.equals("main") && md.parameterDeclList.size() == 1) {
-
- // Check Parameter Declaration
- ParameterDecl pd = md.parameterDeclList.get(0);
-
- if (pd.type.typeKind != TypeKind.ARRAY) return false;
- ArrayType at = (ArrayType) pd.type;
-
- if (at.eltType.typeKind != TypeKind.CLASS) return false;
- ClassType ct = (ClassType) at.eltType;
-
- return ct.className.spelling.equals("String");
- }
-
- return false;
- }
-}
diff --git a/src/miniJava/ContextualAnalyzer/Reporter.java b/src/miniJava/ContextualAnalyzer/Reporter.java
index 66fd900..0b65f4b 100644
--- a/src/miniJava/ContextualAnalyzer/Reporter.java
+++ b/src/miniJava/ContextualAnalyzer/Reporter.java
@@ -1,205 +1,27 @@
package miniJava.ContextualAnalyzer;
-import miniJava.AbstractSyntaxTrees.*;
-
-enum ErrorType {
- THIS,
- LENGTH,
- VOID_TYPE,
- CLASS_IDENTIFER,
- VARDECL_USED,
- NONFUNCTION_CALL,
- FUNCTION_ASSIGNMENT,
- UNDEFINED,
- STATIC,
- VISIBILITY,
- NO_RETURN,
- TYPE_MISMATCH,
- REDEFINITION,
- MAIN_UNDECLARED,
- INVALID_PARAM_COUNT,
- MULTIPLE_MAIN,
- UNDECLARED_TYPE,
- SINGLE_VARCOND,
- INVALID_INDEX
-}
+import miniJava.AbstractSyntaxTrees.Declaration;
public class Reporter {
-
+
public static boolean error = false;
-
+
/**
- * Convenience function for getting type names.
- *
- * @param t
- * @return
- */
- private static String getTypeName(Type t) {
- if (t instanceof ClassType) {
- ClassType ct = (ClassType) t;
- return ct.className.spelling;
- } else if (t instanceof ArrayType) {
- ArrayType at = (ArrayType) t;
- return getTypeName(at.eltType);
- }
-
- return t.typeKind.toString();
- }
-
- /**
- * Convenience method for formatting error message.
*
* @param message
*/
- private static void emit(String message) {
+ public static void emit(String message) {
+ error = true;
System.out.println("***" + message);
}
-
+
/**
- * Convenience function for managing all error types.
- *
- * @param type
- * @param a1
- * @param a2
+ * Redefinitions
+ * @param d1
+ * @param d2
*/
- public static void report(ErrorType type, AST a1, AST a2) {
-
- switch (type) {
-
- // Cannot access 'this' in a static method
- case THIS: {
- MethodDecl md = (MethodDecl) a2;
- emit("Cannot reference 'this' " + a1.posn + " in static method '" + md.name + "' " + md.posn);
- break;
- }
-
- // Array types have the single field 'length'
- case LENGTH: {
- emit("Array types have only a single field 'length' (at " + a1.posn + ").");
- break;
- }
-
- // Can't use a class as an identifier solely
- case CLASS_IDENTIFER: {
- emit("Cannot use class identifier outside of a qualified reference at " + a1.posn);
- break;
- }
-
- // Cannot have a parameter of type void
- case VOID_TYPE: {
- emit("Cannot have a parameter of type void at " + a1.posn);
- break;
- }
-
- // Attempting to call a non function as a function
- case NONFUNCTION_CALL: {
- emit("Not a valid function call at " + a1.posn);
- break;
- }
-
- // Cannot assign a value to a function
- case FUNCTION_ASSIGNMENT: {
- emit("Cannot assign a value to a function at " + a1.posn);
- break;
- }
-
- // Tried accessing a non-static member from a static method
- case STATIC: {
- MemberDecl md = (MemberDecl) a1;
- Identifier ident = (Identifier) a2;
- emit("'" + md.name + "' " + md.posn + " is an instance member and cannot be accessed at " + ident.posn);
- break;
- }
-
- // Tried accessing a private member of a different class
- case VISIBILITY: {
- MemberDecl md = (MemberDecl) a1;
- Identifier ident = (Identifier) a2;
- emit("'" + md.name + "' " + md.posn + " is a private member and cannot be accessed at " + ident.posn);
- break;
- }
-
- // Non-void function does not have a return statement
- case NO_RETURN: {
- MethodDecl md = (MethodDecl) a1;
- emit("'" + md.name + "' " + md.posn + " must have a return statement");
- break;
- }
-
- // The passed types are not the same
- case TYPE_MISMATCH: {
- String name1 = getTypeName((Type) a1);
- String name2 = getTypeName((Type) a2);
- if(a1 instanceof ArrayType) name1 += " Array";
- if(a2 instanceof ArrayType) name2 += " Array";
- emit("Expected type '" + name1 + "' but got '" + name2 + "' " + a2.posn);
- break;
- }
-
- // Attempting to redeclare a variable
- case REDEFINITION: {
- emit("Variable at " + a1.posn + " already declared earlier at " + a2.posn);
- break;
- }
-
- // Identifier could not be found
- case UNDEFINED: {
- Identifier ident = (Identifier) a1;
- emit("Identifier '" + ident.spelling + "' " + ident.posn + " is undeclared.");
- break;
- }
-
- // A public static void main(String[] args) method was not declared
- case MAIN_UNDECLARED: {
- emit("A main function was not declared");
- break;
- }
-
- // Parameter counts of an expression/statement do not match declaration
- case INVALID_PARAM_COUNT: {
- MethodDecl md = (MethodDecl) a2;
- emit("Call to '" + md.name + "' " + a2.posn + " has an invalid parameter count at " + a1.posn);
- break;
- }
-
- // A public static void main(String[] args) was declared more than once
- case MULTIPLE_MAIN: {
- emit("Main function at " + a1.posn + " already declared previously at " + a2.posn);
- break;
- }
-
- // A reference has been made to a non-existant type
- case UNDECLARED_TYPE: {
- if(a1 instanceof Type) {
- String typeName = getTypeName((Type) a1);
- emit("'" + typeName + "' " + a1.posn + " has not been declared previously");
- } else {
- emit("Identifier at " + a1.posn + " could not be identified");
- }
-
- break;
- }
-
- // A Variable Declaration Statement was made as the only statement of a condition
- case SINGLE_VARCOND: {
- emit("Conditional statment cannot be followed by a variable declaration statement exclusively " + a1.posn);
- break;
- }
-
- // An indexed expression must be of an int type
- case INVALID_INDEX: {
- emit("Index expression is not of type int " + a1.posn);
- break;
- }
-
- // A variable declaration identifier was used in a var decl statement
- case VARDECL_USED: {
- emit("Identifier at " + a1.posn + " cannot refer to the variable declaration at " + a2.posn);
- break;
- }
- }
-
- error = true;
+ public static void report(Declaration d1, Declaration d2, String prefix) {
+ emit(prefix + " at " + d1.posn + " previously defined at " + d2.posn);
}
}
diff --git a/src/miniJava/Exceptions/IdentificationException.java b/src/miniJava/Exceptions/IdentificationException.java
deleted file mode 100644
index 167ee93..0000000
--- a/src/miniJava/Exceptions/IdentificationException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package miniJava.Exceptions;
-
-public class IdentificationException extends Exception {
-
- private static final long serialVersionUID = 1L;
-
- public IdentificationException() {
- super("Identification Error!");
- }
-}
diff --git a/src/miniJava/Exceptions/ParsingException.java b/src/miniJava/Exceptions/ParsingException.java
deleted file mode 100644
index f655358..0000000
--- a/src/miniJava/Exceptions/ParsingException.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package miniJava.Exceptions;
-
-import miniJava.SyntacticAnalyzer.Token;
-
-public class ParsingException extends Exception {
-
- private static final long serialVersionUID = 1L;
-
- public ParsingException() {
- super("Unidentified parsing error!");
- }
-
- public ParsingException(Token t) {
- super("Parsing error with " + t.spelling + " at " + t.posn.toString());
- }
-
-}
diff --git a/src/miniJava/Exceptions/ScanningException.java b/src/miniJava/Exceptions/ScanningException.java
deleted file mode 100644
index a24b2e2..0000000
--- a/src/miniJava/Exceptions/ScanningException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package miniJava.Exceptions;
-
-public class ScanningException extends Exception {
-
- private static final long serialVersionUID = 1L;
-
- public ScanningException(int col, int line) {
- super("Scanning error at Column: " + col + ", Line: " + line);
- }
-
-}
diff --git a/src/miniJava/SyntacticAnalyzer/Parser.java b/src/miniJava/SyntacticAnalyzer/Parser.java
index b06176b..524163f 100644
--- a/src/miniJava/SyntacticAnalyzer/Parser.java
+++ b/src/miniJava/SyntacticAnalyzer/Parser.java
@@ -1,28 +1,94 @@
package miniJava.SyntacticAnalyzer;
+import java.io.IOException;
import java.util.LinkedList;
import miniJava.AbstractSyntaxTrees.*;
import miniJava.AbstractSyntaxTrees.Package;
-import miniJava.Exceptions.*;
+/**
+ * Stratified Grammar (original grammar in PA1):
+ *
+ * Program ::= (ClassDeclaration)* eot
+ *
+ * ClassDeclaration ::=
+ * class id {
+ * (Declarators id (; | MethodDeclaration))*
+ * }
+ *
+ * MethodDeclaration ::=
+ * (ParameterList?) {
+ * Statement* (return Expression ;)?
+ * }
+ *
+ * Declarators ::= (public | private)? static? Type
+ *
+ * Type ::= boolean | void | int ([])? | id ([])?
+ *
+ * ParameterList ::= Type id (, Type id)*
+ *
+ * ArgumentList ::= Expression (, Expression)*
+ *
+ * Reference ::= BaseRef (. id ([ Expression])?)*
+ *
+ * BaseRef ::= this | id ([ Expression])?
+ *
+ * Statement ::=
+ * {Statement*}
+ * | Type id = Expression;
+ * | Reference = Expression;
+ * | Reference ( ArgumentList? );
+ * | if (Expression) Statement (else Statement)?
+ * | while (Expression) Statement
+ *
+ * Expression ::=
+ * num | true | false
+ * | ( Expression )
+ * | new (id() | int [ Expression ] | id [ Expression ] )
+ * | Reference ((ArgumentList?))?
+ * | DExpression
+ *
+ * DExpression ::= CExpression (|| CExpression)*
+ *
+ * CExpression ::= EExpression (&& EExpression)*
+ *
+ * EExpression ::= RExpression ((==|!=) RExpression)*
+ *
+ * RExpression ::= AExpression ((<=|<|>|>=) AExpression)*
+ *
+ * AExpression ::= MExpression ((+|-) MExpression)*
+ *
+ * MExpression ::= Expression ((*|/) Expression)*
+ *
+*/
public class Parser {
-
+
private Scanner scanner;
private LinkedList stream;
-
+
+ /**
+ *
+ * @param scanner
+ */
public Parser(Scanner scanner) {
this.scanner = scanner;
this.stream = new LinkedList();
}
-
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // Package
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
/**
- * Program ::= (ClassDeclaration)* eot
+ *
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- public Package parse() throws ParsingException, ScanningException {
+ public Package parse() throws IOException {
+
ClassDeclList decls = new ClassDeclList();
while (peek(1).type == Token.TYPE.CLASS) {
decls.add(parseClassDeclaration());
@@ -31,469 +97,557 @@ public class Parser {
accept(Token.TYPE.EOT);
return new Package(decls, new SourcePosition(0, 0));
}
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // DECLARATIONS
+ //
+ // /////////////////////////////////////////////////////////////////////////////
/**
- * ClassDeclaration ::= class id { (Declarators id (; | MethodDeclaration))* }
+ *
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private ClassDecl parseClassDeclaration() throws ParsingException,
- ScanningException {
-
+ public ClassDecl parseClassDeclaration() throws IOException {
+
// Class Header
Token classToken = accept(Token.TYPE.CLASS);
- String cn = accept(Token.TYPE.ID).spelling;
+ String className = accept(Token.TYPE.ID).spelling;
+
+ // Class Body
accept(Token.TYPE.LBRACKET);
-
- // Setup
+
FieldDeclList fdl = new FieldDeclList();
MethodDeclList mdl = new MethodDeclList();
-
- // Class Body
+
+ // Haven't reached end of body
while (peek(1).type != Token.TYPE.RBRACKET) {
Declarators d = parseDeclarators();
- String name = accept(Token.TYPE.ID).spelling;
- FieldDecl f = new FieldDecl(d.isPrivate, d.isStatic, d.mt, name,
- d.posn);
-
- // Field Declarations
- if (peek(1).type == Token.TYPE.SEMICOLON) {
+ String memberName = accept(Token.TYPE.ID).spelling;
+
+ // Field Declaration
+ FieldDecl fd = new FieldDecl(d, memberName);
+ if(peek(1).type == Token.TYPE.SEMICOLON) {
accept(Token.TYPE.SEMICOLON);
- fdl.add(f);
+ fdl.add(fd);
+ }
+
+ // Method Declaration
+ else {
+ MethodDecl md = parseMethodDeclaration(fd);
+ mdl.add(md);
}
-
- // Method Declarations
- else
- mdl.add(parseMethodDeclaration(f));
}
-
+
accept(Token.TYPE.RBRACKET);
- return new ClassDecl(cn, fdl, mdl, classToken.posn);
+
+ // Build Class
+ ClassDecl decl = new ClassDecl(className, fdl, mdl, classToken.posn);
+ Identifier ident = new Identifier(className, classToken.posn);
+ decl.type = new ClassType(ident, classToken.posn);
+
+ return decl;
}
-
+
/**
- * Declarators ::= (public | private)? static? Type
+ *
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Declarators parseDeclarators() throws ParsingException,
- ScanningException {
-
- // Visibility
- SourcePosition start = null;
+ private Declarators parseDeclarators() throws IOException {
+
+ boolean isStatic = false;
boolean isPrivate = false;
-
+ SourcePosition start = peek(1).posn;
+
+ // Visibility
if (peek(1).type == Token.TYPE.PUBLIC) {
- start = accept(Token.TYPE.PUBLIC).posn;
+ accept(Token.TYPE.PUBLIC);
} else if (peek(1).type == Token.TYPE.PRIVATE) {
isPrivate = true;
- start = accept(Token.TYPE.PRIVATE).posn;
+ accept(Token.TYPE.PRIVATE);
}
-
- // Class Methods
- boolean isStatic = false;
+
+ // Static
if (peek(1).type == Token.TYPE.STATIC) {
isStatic = true;
- if (start == null) {
- start = accept(Token.TYPE.STATIC).posn;
- } else {
- accept(Token.TYPE.STATIC);
- }
+ accept(Token.TYPE.STATIC);
}
- Type t = parseType();
- if (start == null) {
- start = t.posn;
- }
-
- return new Declarators(isPrivate, isStatic, t, start);
+ return new Declarators(isPrivate, isStatic, parseType(), start);
}
-
+
/**
- * MethodDeclaration ::= (ParameterList?) { Statement* (return Expression;)? }
+ *
* @param f
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private MethodDecl parseMethodDeclaration(FieldDecl f)
- throws ParsingException, ScanningException {
-
- // Method Header
+ private MethodDecl parseMethodDeclaration(FieldDecl f) throws IOException {
+
+ Expression returnExpr = null;
+ StatementList stl = new StatementList();
+
+ // Parameters
accept(Token.TYPE.LPAREN);
-
- // Parameter List
+
ParameterDeclList pdl = new ParameterDeclList();
- if (peek(1).type != Token.TYPE.RPAREN)
+ if (peek(1).type != Token.TYPE.RPAREN) {
pdl = parseParameterList();
+ }
accept(Token.TYPE.RPAREN);
- accept(Token.TYPE.LBRACKET);
-
+
// Method Body
- Expression re = null;
- StatementList stl = new StatementList();
+ accept(Token.TYPE.LBRACKET);
+
while (peek(1).type != Token.TYPE.RBRACKET) {
-
if (peek(1).type == Token.TYPE.RETURN) {
accept(Token.TYPE.RETURN);
- re = parseExpression();
+ returnExpr = parseExpression();
accept(Token.TYPE.SEMICOLON);
break;
}
-
+
stl.add(parseStatement());
}
-
+
accept(Token.TYPE.RBRACKET);
- return new MethodDecl(f, pdl, stl, re, f.posn);
+
+ return new MethodDecl(f, pdl, stl, returnExpr, f.posn);
}
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // TYPES
+ //
+ // /////////////////////////////////////////////////////////////////////////////
/**
- * Type ::= boolean | void | int ([])? | id ([])?
+ *
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Type parseType() throws ParsingException, ScanningException {
-
- SourcePosition posn = null;
-
- switch (peek(1).type) {
-
- case BOOLEAN:
- posn = accept(Token.TYPE.BOOLEAN).posn;
- return new BaseType(TypeKind.BOOLEAN, posn);
-
- case VOID:
- posn = accept(Token.TYPE.VOID).posn;
- return new BaseType(TypeKind.VOID, posn);
-
- case INT: {
- posn = accept(Token.TYPE.INT).posn;
- BaseType b = new BaseType(TypeKind.INT, posn);
-
- if (peek(1).type == Token.TYPE.LSQUARE) {
- accept(Token.TYPE.LSQUARE);
- accept(Token.TYPE.RSQUARE);
- return new ArrayType(b, posn);
+ private Type parseType() throws IOException {
+
+ switch(peek(1).type) {
+
+ case VOID: {
+ Token next = accept(Token.TYPE.VOID);
+ return new BaseType(TypeKind.VOID, next.posn);
}
-
- return b;
- }
-
- case ID: {
- Token id = accept(peek(1).type);
- Identifier i = new Identifier(id.spelling, id.posn);
- ClassType c = new ClassType(i, id.posn);
-
- if (peek(1).type == Token.TYPE.LSQUARE) {
- accept(Token.TYPE.LSQUARE);
- accept(Token.TYPE.RSQUARE);
- return new ArrayType(c, id.posn);
+
+ case BOOLEAN: {
+ Token next = accept(Token.TYPE.BOOLEAN);
+ return new BaseType(TypeKind.BOOLEAN, next.posn);
+ }
+
+ case INT: {
+ Token next = accept(Token.TYPE.INT);
+ BaseType bt = new BaseType(TypeKind.INT, next.posn);
+
+ if (peek(1).type == Token.TYPE.LSQUARE) {
+ accept(Token.TYPE.LSQUARE);
+ accept(Token.TYPE.RSQUARE);
+ return new ArrayType(bt, next.posn);
+ }
+
+ return bt;
+ }
+
+ case ID: {
+ Token next = accept(Token.TYPE.ID);
+ Identifier ident = new Identifier(next.spelling, next.posn);
+ ClassType ct = new ClassType(ident, ident.posn);
+
+ if (peek(1).type == Token.TYPE.LSQUARE) {
+ accept(Token.TYPE.LSQUARE);
+ accept(Token.TYPE.RSQUARE);
+ return new ArrayType(ct, ident.posn);
+ }
+
+ return ct;
+ }
+
+ default: {
+ Token next = peek(1);
+ throw new ParsingException(next.posn);
}
-
- return c;
- }
-
- default:
- throw new ParsingException();
}
}
-
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // Arguments
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
/**
- * ParameterList ::= Type id (, Type id)*
+ *
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private ParameterDeclList parseParameterList() throws ParsingException, ScanningException {
-
+ private ParameterDeclList parseParameterList() throws IOException {
+
ParameterDeclList decls = new ParameterDeclList();
// First Parameter
- Type t = parseType();
- Token id = accept(Token.TYPE.ID);
- decls.add(new ParameterDecl(t, id.spelling, id.posn));
+ Type fpt = parseType();
+ Token next = accept(Token.TYPE.ID);
+ decls.add(new ParameterDecl(fpt, next.spelling, fpt.posn));
// Remainder of List
- while (peek(1).type == Token.TYPE.COMMA) {
+ while(peek(1).type == Token.TYPE.COMMA) {
accept(Token.TYPE.COMMA);
- Type nextType = parseType();
- Token nextId = accept(Token.TYPE.ID);
- decls.add(new ParameterDecl(nextType, nextId.spelling, nextId.posn));
+ Type type = parseType();
+ Token id = accept(Token.TYPE.ID);
+ decls.add(new ParameterDecl(type, id.spelling, type.posn));
}
return decls;
}
/**
- * ArgumentList ::= Expression (, Expression)*
+ *
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private ExprList parseArgumentList() throws ParsingException, ScanningException {
- ExprList e = new ExprList();
- e.add(parseExpression());
- while (peek(1).type == Token.TYPE.COMMA) {
+ private ExprList parseArgumentList() throws IOException {
+
+ ExprList el = new ExprList();
+ el.add(parseExpression());
+
+ // Rest of argument list
+ while(peek(1).type == Token.TYPE.COMMA) {
accept(Token.TYPE.COMMA);
- e.add(parseExpression());
+ el.add(parseExpression());
}
- return e;
+ return el;
}
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // REFERENCES
+ //
+ // /////////////////////////////////////////////////////////////////////////////
/**
- * Reference ::= BaseRef (. BaseRef)*
+ *
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Reference parseReference() throws ParsingException, ScanningException {
- Reference r = parseBaseRef();
+ private Reference parseReference() throws IOException {
+
+ Reference ref = parseBaseRef();
+
while (peek(1).type == Token.TYPE.PERIOD) {
accept(Token.TYPE.PERIOD);
- Token tokenId = accept(Token.TYPE.ID);
- Identifier id = new Identifier(tokenId.spelling, tokenId.posn);
- r = new QualifiedRef(r, id, tokenId.posn);
+ Token next = accept(Token.TYPE.ID);
+ Identifier ident = new Identifier(next.spelling, next.posn);
+ ref = new QualifiedRef(ref, ident, next.posn);
+ // Must be indexed
if (peek(1).type == Token.TYPE.LSQUARE) {
accept(Token.TYPE.LSQUARE);
- Expression e = parseExpression();
+ Expression expr = parseExpression();
accept(Token.TYPE.RSQUARE);
- r = new IndexedRef(r, e, tokenId.posn);
+ ref = new IndexedRef(ref, expr, next.posn);
}
}
- return r;
+ return ref;
}
/**
- * BaseRef ::= this | id ([ Expression])?
+ *
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Reference parseBaseRef() throws ParsingException, ScanningException {
-
- switch (peek(1).type) {
- case THIS: {
- Token thisToken = accept(Token.TYPE.THIS);
- return new ThisRef(thisToken.posn);
- }
-
- // id ([ Expression])?
- default: {
- Token id = accept(Token.TYPE.ID);
- Identifier i = new Identifier(id.spelling, id.posn);
- IdRef r = new IdRef(i, id.posn);
-
- if (peek(1).type == Token.TYPE.LSQUARE) {
- accept(Token.TYPE.LSQUARE);
- Expression e = parseExpression();
- accept(Token.TYPE.RSQUARE);
- return new IndexedRef(r, e, id.posn);
- }
-
- return r;
- }
+ private Reference parseBaseRef() throws IOException {
+
+ if(peek(1).type == Token.TYPE.THIS) {
+ Token next = accept(Token.TYPE.THIS);
+ return new ThisRef(next.posn);
}
+
+ Token next = accept(Token.TYPE.ID);
+ Identifier ident = new Identifier(next.spelling, next.posn);
+ IdRef ref = new IdRef(ident, ident.posn);
+
+ // Must be indexed
+ if (peek(1).type == Token.TYPE.LSQUARE) {
+ accept(Token.TYPE.LSQUARE);
+ Expression expr = parseExpression();
+ accept(Token.TYPE.RSQUARE);
+ return new IndexedRef(ref, expr, next.posn);
+ }
+
+ return ref;
}
-
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // STATEMENTS
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
/**
- * Statement ::= {Statement*} | Type id = Expression; | Reference =
- * Expression; | Reference ( ArgumentList? ); | if (Expression) Statement
- * (else Statement)? | while (Expression) Statement
+ *
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Statement parseStatement() throws ParsingException, ScanningException {
+ private Statement parseBlockStatement() throws IOException {
+
+ StatementList stl = new StatementList();
+ Token left = accept(Token.TYPE.LBRACKET);
+
+ while(peek(1).type != Token.TYPE.RBRACKET) {
+ stl.add(parseStatement());
+ }
+
+ accept(Token.TYPE.RBRACKET);
+
+ return new BlockStmt(stl, left.posn);
+ }
+
+ /**
+ *
+ * @return
+ * @throws IOException
+ */
+ private Statement parseIfStatement() throws IOException {
+
+ Token next = accept(Token.TYPE.IF);
+
+ // Conditional
+ accept(Token.TYPE.LPAREN);
+ Expression expr = parseExpression();
+ accept(Token.TYPE.RPAREN);
+
+ // Body
+ Statement s1 = parseStatement();
+
+ // Else Statement
+ if (peek(1).type == Token.TYPE.ELSE) {
+ accept(Token.TYPE.ELSE);
+ Statement s2 = parseStatement();
+ return new IfStmt(expr, s1, s2, next.posn);
+ }
+ return new IfStmt(expr, s1, next.posn);
+ }
+
+ /**
+ *
+ * @return
+ * @throws IOException
+ */
+ private Statement parseWhileStatement() throws IOException {
+
+ Token next = accept(Token.TYPE.WHILE);
+
+ // Conditional
+ accept(Token.TYPE.LPAREN);
+ Expression e = parseExpression();
+ accept(Token.TYPE.RPAREN);
+
+ // Body
+ Statement s = parseStatement();
+
+ return new WhileStmt(e, s, next.posn);
+ }
+
+ /**
+ *
+ * @return
+ * @throws IOException
+ */
+ private Statement parseVarDeclStatement() throws IOException {
+
+ Type type = parseType();
+ String name = accept(Token.TYPE.ID).spelling;
+ VarDecl v = new VarDecl(type, name, type.posn);
+
+ accept(Token.TYPE.EQUALS);
+ Expression expr = parseExpression();
+ accept(Token.TYPE.SEMICOLON);
+
+ return new VarDeclStmt(v, expr, type.posn);
+ }
+
+ /**
+ *
+ * @return
+ * @throws IOException
+ */
+ private Statement parseReferenceStatement() throws IOException {
+
+ Statement stmt = null;
+ Reference ref = parseReference();
+
+ // Reference ( ArgumentList? ) ;
+ if (peek(1).type == Token.TYPE.LPAREN) {
+ ExprList el = new ExprList();
+ accept(Token.TYPE.LPAREN);
+ if(peek(1).type != Token.TYPE.RPAREN) {
+ el = parseArgumentList();
+ }
+ accept(Token.TYPE.RPAREN);
+ stmt = new CallStmt(ref, el, ref.posn);
+ }
+
+ // Reference = Expression;
+ else {
+ accept(Token.TYPE.EQUALS);
+ Expression expr = parseExpression();
+ stmt = new AssignStmt(ref, expr, ref.posn);
+ }
+
+ accept(Token.TYPE.SEMICOLON);
+ return stmt;
+ }
+
+ /**
+ *
+ * @return
+ * @throws IOException
+ */
+ private Statement parseStatement() throws IOException {
+
switch (peek(1).type) {
-
+
// { Statement* }
case LBRACKET: {
- Token leftToken = accept(Token.TYPE.LBRACKET);
- StatementList stl = new StatementList();
- while (peek(1).type != Token.TYPE.RBRACKET) {
- stl.add(parseStatement());
- }
- accept(Token.TYPE.RBRACKET);
-
- return new BlockStmt(stl, leftToken.posn);
+ return parseBlockStatement();
}
-
+
// if (Expression) Statement (else Statement)?
case IF: {
- Token ifToken = accept(Token.TYPE.IF);
- accept(Token.TYPE.LPAREN);
- Expression e = parseExpression();
- accept(Token.TYPE.RPAREN);
- Statement s1 = parseStatement();
- if (peek(1).type == Token.TYPE.ELSE) {
- accept(Token.TYPE.ELSE);
- Statement s2 = parseStatement();
- return new IfStmt(e, s1, s2, ifToken.posn);
- }
-
- return new IfStmt(e, s1, ifToken.posn);
+ return parseIfStatement();
}
-
+
// while (Expression) Statement
case WHILE: {
- Token whileToken = accept(Token.TYPE.WHILE);
- accept(Token.TYPE.LPAREN);
- Expression e = parseExpression();
- accept(Token.TYPE.RPAREN);
- Statement s = parseStatement();
-
- return new WhileStmt(e, s, whileToken.posn);
+ return parseWhileStatement();
}
-
- // Type id = Expression ;
+
+ // Type id = Expression;
case BOOLEAN:
case VOID:
case INT:
case ID: {
-
- // Must be a type though there is a possibility of a reference
- if (peek(1).type != Token.TYPE.ID
- || peek(2).type == Token.TYPE.ID
- || (peek(2).type == Token.TYPE.LSQUARE && peek(3).type == Token.TYPE.RSQUARE)) {
- Type t = parseType();
- String name = accept(Token.TYPE.ID).spelling;
- VarDecl v = new VarDecl(t, name, t.posn);
-
- accept(Token.TYPE.EQUALS);
- Expression e = parseExpression();
- accept(Token.TYPE.SEMICOLON);
-
- return new VarDeclStmt(v, e, t.posn);
+
+ Token.TYPE fst = peek(1).type;
+ Token.TYPE snd = peek(2).type;
+ Token.TYPE thd = peek(3).type;
+
+ if(fst != Token.TYPE.ID || snd == Token.TYPE.ID) {
+ return parseVarDeclStatement();
+ } else if(snd == Token.TYPE.LSQUARE && thd == Token.TYPE.RSQUARE) {
+ return parseVarDeclStatement();
}
-
+
/* Fall Through */
}
-
+
default: {
- Statement s = null;
- Reference r = parseReference();
-
- // Reference ( ArgumentList? ) ;
- if (peek(1).type == Token.TYPE.LPAREN) {
- ExprList e = new ExprList();
- accept(Token.TYPE.LPAREN);
- if (peek(1).type != Token.TYPE.RPAREN) {
- e = parseArgumentList();
- }
- accept(Token.TYPE.RPAREN);
- s = new CallStmt(r, e, r.posn);
- }
-
- // Reference = Expression ;
- else {
- accept(Token.TYPE.EQUALS);
- Expression e = parseExpression();
- s = new AssignStmt(r, e, r.posn);
- }
-
- accept(Token.TYPE.SEMICOLON);
- return s;
+ return parseReferenceStatement();
}
}
}
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // EXPRESSIONS
+ //
+ // /////////////////////////////////////////////////////////////////////////////
- /**
- * Expression ::= Reference | Reference ( ArgumentList? ) | unop Expression
- * | ( Expression ) | num | true | false | new (id() | int [ Expression ] |
- * id [ Expression ] )
- *
- * @return
- * @throws ScanningException
- */
- private Expression parseSingleExpression() throws ParsingException, ScanningException {
+ private Expression parseSingleExpression() throws IOException {
- Expression e = null;
switch (peek(1).type) {
-
- // num
+
case NUM: {
- Token number = accept(Token.TYPE.NUM);
- IntLiteral i = new IntLiteral(number.spelling, number.posn);
- e = new LiteralExpr(i, number.posn);
- break;
+ Token next = accept(Token.TYPE.NUM);
+ IntLiteral il = new IntLiteral(next.spelling, next.posn);
+ return new LiteralExpr(il, next.posn);
}
- // true | false
case TRUE:
case FALSE: {
- Token bool = accept(peek(1).type);
- BooleanLiteral b = new BooleanLiteral(bool.spelling, bool.posn);
- e = new LiteralExpr(b, bool.posn);
- break;
+ Token next = accept(peek(1).type);
+ BooleanLiteral bl = new BooleanLiteral(next.spelling, next.posn);
+ return new LiteralExpr(bl, next.posn);
}
// ( Expression )
case LPAREN: {
accept(Token.TYPE.LPAREN);
- e = parseExpression();
+ Expression expr = parseExpression();
accept(Token.TYPE.RPAREN);
- break;
+
+ return expr;
}
// unop Expression
case UNOP:
case BINOP: {
if (peek(1).spelling.equals("!") || peek(1).spelling.equals("-")) {
- Token opToken = accept(peek(1).type);
- Operator o = new Operator(opToken, opToken.posn);
- e = new UnaryExpr(o, parseSingleExpression(), opToken.posn);
- } else
- throw new ParsingException();
- break;
+ Token next = accept(peek(1).type);
+ Operator o = new Operator(next, next.posn);
+ Expression expr = parseSingleExpression();
+ return new UnaryExpr(o, expr, next.posn);
+ } else {
+ throw new ParsingException(peek(1).posn);
+ }
}
// new ( int [ Expression ] | id ( ) | id [ Expression ] )
case NEW: {
- Token newToken = accept(Token.TYPE.NEW);
+
+ Token next = accept(Token.TYPE.NEW);
if (peek(1).type == Token.TYPE.INT) {
accept(Token.TYPE.INT);
accept(Token.TYPE.LSQUARE);
- Expression e2 = parseExpression();
+ Expression expr = parseExpression();
accept(Token.TYPE.RSQUARE);
- BaseType b = new BaseType(TypeKind.INT, newToken.posn);
- e = new NewArrayExpr(b, e2, newToken.posn);
+ BaseType b = new BaseType(TypeKind.INT, next.posn);
+ return new NewArrayExpr(b, expr, next.posn);
}
else {
Token id = accept(Token.TYPE.ID);
- Identifier i = new Identifier(id.spelling, id.posn);
- ClassType c = new ClassType(i, id.posn);
+ Identifier ident = new Identifier(id.spelling, id.posn);
+ ClassType ct = new ClassType(ident, id.posn);
if (peek(1).type == Token.TYPE.LPAREN) {
accept(Token.TYPE.LPAREN);
accept(Token.TYPE.RPAREN);
- e = new NewObjectExpr(c, id.posn);
+ return new NewObjectExpr(ct, next.posn);
} else {
accept(Token.TYPE.LSQUARE);
- Expression e2 = parseExpression();
+ Expression expr = parseExpression();
accept(Token.TYPE.RSQUARE);
- e = new NewArrayExpr(c, e2, id.posn);
+ return new NewArrayExpr(ct, expr, next.posn);
}
}
-
- break;
}
// Reference ((ArgumentList?))?
case THIS:
case ID: {
- Reference r = parseReference();
+
+ Reference ref = parseReference();
+
if (peek(1).type == Token.TYPE.LPAREN) {
accept(Token.TYPE.LPAREN);
ExprList el = new ExprList();
@@ -501,138 +655,139 @@ public class Parser {
el = parseArgumentList();
}
accept(Token.TYPE.RPAREN);
- e = new CallExpr(r, el, r.posn);
+ return new CallExpr(ref, el, ref.posn);
} else {
- e = new RefExpr(r, r.posn);
+ return new RefExpr(ref, ref.posn);
}
-
- break;
}
- default:
- throw new ParsingException(peek(1));
+ default: throw new ParsingException(peek(1).posn);
}
-
- return e;
}
/**
- * Disjunction & Initial Call: Expression ::= Expression binop Expression
+ * Disjunctive
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Expression parseExpression() throws ParsingException, ScanningException {
-
- Expression e = parseCExpression();
+ private Expression parseExpression() throws IOException {
+
+ Expression expr = parseCExpression();
+
while (peek(1).spelling.equals("||")) {
- Token opToken = accept(Token.TYPE.BINOP);
- Operator o = new Operator(opToken, opToken.posn);
- e = new BinaryExpr(o, e, parseCExpression(), e.posn);
+ Token next = accept(Token.TYPE.BINOP);
+ Operator o = new Operator(next, next.posn);
+ expr = new BinaryExpr(o, expr, parseCExpression(), expr.posn);
}
- return e;
+ return expr;
}
/**
- * Conjunction
+ * Conjunctive
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Expression parseCExpression() throws ParsingException, ScanningException {
+ private Expression parseCExpression() throws IOException {
- Expression e = parseEExpression();
+ Expression expr = parseEExpression();
+
while (peek(1).spelling.equals("&&")) {
- Token opToken = accept(Token.TYPE.BINOP);
- Operator o = new Operator(opToken, opToken.posn);
- e = new BinaryExpr(o, e, parseEExpression(), e.posn);
+ Token next = accept(Token.TYPE.BINOP);
+ Operator o = new Operator(next, next.posn);
+ expr = new BinaryExpr(o, expr, parseEExpression(), expr.posn);
}
- return e;
+ return expr;
}
/**
* Equality
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Expression parseEExpression() throws ParsingException, ScanningException {
+ private Expression parseEExpression() throws IOException {
- Expression e = parseRExpression();
+ Expression expr = parseRExpression();
+
while (peek(1).spelling.equals("==") || peek(1).spelling.equals("!=")) {
- Token opToken = accept(Token.TYPE.BINOP);
- Operator o = new Operator(opToken, opToken.posn);
- e = new BinaryExpr(o, e, parseRExpression(), e.posn);
+ Token next = accept(Token.TYPE.BINOP);
+ Operator o = new Operator(next, next.posn);
+ expr = new BinaryExpr(o, expr, parseRExpression(), expr.posn);
}
- return e;
+ return expr;
}
-
+
/**
* Relational
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Expression parseRExpression() throws ParsingException, ScanningException {
+ private Expression parseRExpression() throws IOException {
- Expression e = parseAExpression();
- while (peek(1).spelling.equals("<") || peek(1).spelling.equals("<=")
- || peek(1).spelling.equals(">")
- || peek(1).spelling.equals(">=")) {
- Token opToken = accept(Token.TYPE.BINOP);
- Operator o = new Operator(opToken, opToken.posn);
- e = new BinaryExpr(o, e, parseAExpression(), e.posn);
+ Expression expr = parseAExpression();
+
+ while(peek(1).spelling.equals("<") || peek(1).spelling.equals("<=")
+ || peek(1).spelling.equals(">") || peek(1).spelling.equals(">=")) {
+ Token next = accept(Token.TYPE.BINOP);
+ Operator o = new Operator(next, next.posn);
+ expr = new BinaryExpr(o, expr, parseAExpression(), expr.posn);
}
- return e;
+ return expr;
}
/**
* Additive
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Expression parseAExpression() throws ParsingException, ScanningException {
+ private Expression parseAExpression() throws IOException {
- Expression e = parseMExpression();
+ Expression expr = parseMExpression();
+
while (peek(1).spelling.equals("+") || peek(1).spelling.equals("-")) {
- Token opToken = accept(Token.TYPE.BINOP);
- Operator o = new Operator(opToken, opToken.posn);
- e = new BinaryExpr(o, e, parseMExpression(), e.posn);
+ Token next = accept(Token.TYPE.BINOP);
+ Operator o = new Operator(next, next.posn);
+ expr = new BinaryExpr(o, expr, parseMExpression(), expr.posn);
}
- return e;
+ return expr;
}
/**
* Multiplicative
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Expression parseMExpression() throws ParsingException, ScanningException {
-
- Expression e = parseSingleExpression();
+ private Expression parseMExpression() throws IOException {
+
+ Expression expr = parseSingleExpression();
+
while (peek(1).spelling.equals("*") || peek(1).spelling.equals("/")) {
- Token opToken = accept(Token.TYPE.BINOP);
- Operator o = new Operator(opToken, opToken.posn);
- e = new BinaryExpr(o, e, parseSingleExpression(), e.posn);
+ Token next = accept(Token.TYPE.BINOP);
+ Operator o = new Operator(next, next.posn);
+ expr = new BinaryExpr(o, expr, parseSingleExpression(), expr.posn);
}
- return e;
+ return expr;
}
-
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // Convenience Methods
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
/**
- * Sees what the next token is, caching the result.
+ *
* @param lookahead
* @return
- * @throws ScanningException
+ * @throws IOException
*/
- private Token peek(int lookahead) throws ScanningException {
+ private Token peek(int lookahead) throws IOException {
// Cache tokens
while (stream.size() < lookahead) {
@@ -644,16 +799,16 @@ public class Parser {
}
/**
- * Consumes token or throws exception.
+ *
* @param type
* @return
- * @throws ParsingException
- * @throws ScanningException
+ * @throws IOException
*/
- private Token accept(Token.TYPE type) throws ParsingException, ScanningException {
+ private Token accept(Token.TYPE type) throws IOException {
+
Token next = peek(1);
if(next.type == type) stream.poll();
- else throw new ParsingException(next);
+ else throw new ParsingException(next.posn);
return next;
}
diff --git a/src/miniJava/SyntacticAnalyzer/ParsingException.java b/src/miniJava/SyntacticAnalyzer/ParsingException.java
new file mode 100644
index 0000000..635e52d
--- /dev/null
+++ b/src/miniJava/SyntacticAnalyzer/ParsingException.java
@@ -0,0 +1,16 @@
+package miniJava.SyntacticAnalyzer;
+
+import java.io.IOException;
+
+/**
+ *
+ */
+public class ParsingException extends IOException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ParsingException(SourcePosition posn) {
+ super("Parsing error at " + posn);
+ }
+
+}
\ No newline at end of file
diff --git a/src/miniJava/SyntacticAnalyzer/Scanner.java b/src/miniJava/SyntacticAnalyzer/Scanner.java
index 3cd0aa8..e3ff840 100644
--- a/src/miniJava/SyntacticAnalyzer/Scanner.java
+++ b/src/miniJava/SyntacticAnalyzer/Scanner.java
@@ -1,313 +1,306 @@
package miniJava.SyntacticAnalyzer;
import java.io.*;
-import miniJava.Exceptions.*;
public class Scanner {
private int col = 1;
private int line = 1;
+ private boolean predefined;
private BufferedReader input;
-
- public Scanner(BufferedReader input) {
- this.input = input;
- }
-
- public Scanner(String input) {
- StringReader reader = new StringReader(input);
- this.input = new BufferedReader(reader);
- }
-
+
+ /**
+ *
+ * @param input
+ */
+ public Scanner(BufferedReader input) {
+ this(input, false);
+ }
+
+ /**
+ *
+ * @param input
+ * @param predefined
+ */
+ public Scanner(String input, boolean predefined) {
+ this(new BufferedReader(new StringReader(input)), predefined);
+ }
+
+ /**
+ *
+ * @param input
+ * @param predefined
+ */
+ public Scanner(BufferedReader input, boolean predefined) {
+ this.input = input;
+ this.predefined = predefined;
+ }
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // Scanning
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
/**
- * Scans in input, returning next token.
*
* @return
* @throws IOException
*/
- public Token scan() throws ScanningException {
-
- String attr = "";
+ public Token scan() throws IOException {
Token token = null;
-
+ String spelling = "";
+
while (token == null) {
-
- // Check for EOF
+
int c = read();
- if (c == -1)
- return new Token("", Token.TYPE.EOT);
+ SourcePosition posn = new SourcePosition(col, line);
+
+ if(c == -1) {
+ token = new Token("", Token.TYPE.EOT, posn);
+ } else {
+ spelling += (char) c;
+
+ switch(c) {
- // Setup
- attr += (char) c;
-
- switch (c) {
-
- // Operators
- case '*':
- token = new Token(attr, Token.TYPE.BINOP);
- break;
-
- case '+':
- if (peek('+'))
- throw new ScanningException(col, line);
- token = new Token(attr, Token.TYPE.BINOP);
- break;
-
- case '-':
- if (peek('-'))
- throw new ScanningException(col, line);
- token = new Token(attr, Token.TYPE.BINOP);
- break;
-
- // Check for comment
- case '/':
- if (peek('*')) {
- read();
- readComment();
- attr = "";
- } else if (peek('/')) {
- readLine();
- attr = "";
- } else
- token = new Token(attr, Token.TYPE.BINOP);
- break;
-
- // Check for c or c=
- case '>':
- case '<':
- if (peek('='))
- attr += (char) read();
- token = new Token(attr, Token.TYPE.BINOP);
- break;
-
- // Check for ! or !=
- case '!':
- if (!peek('='))
- token = new Token(attr, Token.TYPE.UNOP);
- else {
- attr += (char) read();
- token = new Token(attr, Token.TYPE.BINOP);
- }
- break;
-
- // Check for && or ||
- case '&':
- case '|':
- if (!peek((char) c))
- throw new ScanningException(col, line);
- else {
- attr += (char) read();
- token = new Token(attr, Token.TYPE.BINOP);
- }
- break;
-
- // Other Operators
- case '=':
- if (!peek('='))
- token = new Token(attr, Token.TYPE.EQUALS);
- else {
- attr += (char) read();
- token = new Token(attr, Token.TYPE.BINOP);
- }
- break;
-
- case '.':
- token = new Token(attr, Token.TYPE.PERIOD);
- break;
-
- case ',':
- token = new Token(attr, Token.TYPE.COMMA);
- break;
-
- case '[':
- token = new Token(attr, Token.TYPE.LSQUARE);
- break;
-
- case ']':
- token = new Token(attr, Token.TYPE.RSQUARE);
- break;
-
- case '{':
- token = new Token(attr, Token.TYPE.LBRACKET);
- break;
-
- case '}':
- token = new Token(attr, Token.TYPE.RBRACKET);
- break;
-
- case '(':
- token = new Token(attr, Token.TYPE.LPAREN);
- break;
-
- case ')':
- token = new Token(attr, Token.TYPE.RPAREN);
- break;
-
- case ';':
- token = new Token(attr, Token.TYPE.SEMICOLON);
- break;
-
- default:
-
- // Identifier or Keyword
- if (isAlpha((char) c)) {
- for (char n = peek(); isAlpha(n) || isDigit(n);) {
- attr += (char) read();
- n = peek();
+ // Operators
+ case '*':
+ case '+':
+ case '-': {
+ if(peek(c)) throw new ScanningException(posn);
+ token = new Token(spelling, Token.TYPE.BINOP, posn);
+ break;
}
+
+ // Comment
+ case '/': {
+ if(peek('*')) {
+ read();
+ readMultiLineComment();
+ spelling = "";
+ } else if(peek('/')) {
+ readSingleLineComment();
+ spelling = "";
+ } else {
+ token = new Token(spelling, Token.TYPE.BINOP, posn);
+ }
+
+ break;
+ }
+
+ // Relational
+ case '>':
+ case '<': {
+ if (peek('=')) spelling += (char) read();
+ token = new Token(spelling, Token.TYPE.BINOP, posn);
+ break;
+ }
+
+ // Negation
+ case '!': {
+ if(peek('=')) {
+ spelling += (char) read();
+ token = new Token(spelling, Token.TYPE.BINOP, posn);
+ } else {
+ token = new Token(spelling, Token.TYPE.UNOP, posn);
+ }
+
+ break;
+ }
+
+ // Logical
+ case '&':
+ case '|': {
+ if(!peek(c)) {
+ throw new ScanningException(posn);
+ } else {
+ spelling += (char) read();
+ token = new Token(spelling, Token.TYPE.BINOP, posn);
+ }
+
+ break;
+ }
+
+ // Other Operators
+ case '=': {
+ if(peek('=')) {
+ spelling += (char) read();
+ token = new Token(spelling, Token.TYPE.BINOP, posn);
+ } else {
+ token = new Token(spelling, Token.TYPE.EQUALS, posn);
+ }
+
+ break;
+ }
+
+ // Miscellaneous
+ case '.':
+ case ',':
+ case '[':
+ case ']':
+ case '{':
+ case '}':
+ case '(':
+ case ')':
+ case ';': {
+ token = new Token(spelling, Token.symbols.get(c), posn);
+ break;
+ }
+
+ default: {
+
+ // Identifier or keyword
+ if(isAlpha(c)) {
+ int next = peek();
+ while(isAlpha(next) || isDigit(next) || next == '_') {
+ spelling += (char) read();
+ next = peek();
+ }
+
+ if(Token.keywords.containsKey(spelling)) {
+ token = new Token(spelling, Token.keywords.get(spelling), posn);
+ } else {
+ token = new Token(spelling, Token.TYPE.ID, posn);
+ }
+ }
+
+ // Number
+ else if(isDigit(c)) {
+ int next = peek();
+ while(isDigit(next)) {
+ spelling += (char) read();
+ next = peek();
+ }
- if (Token.keywords.containsKey(attr)) {
- token = new Token(attr, Token.keywords.get(attr));
- } else {
- token = new Token(attr, Token.TYPE.ID);
+ token = new Token(spelling, Token.TYPE.NUM, posn);
+ }
+
+ // Whitespace
+ else if(isWhitespace(c)) {
+ spelling = "";
+ }
+
+ // Unrecognized Character
+ else {
+ throw new ScanningException(posn);
+ }
}
}
-
- // Number
- else if (isDigit((char) c)) {
- for (char n = peek(); isDigit(n);) {
- attr += (char) read();
- n = peek();
- }
-
- token = new Token(attr, Token.TYPE.NUM);
- }
-
- // Whitespace
- else if (isWhitespace((char) c)) {
- attr = "";
- }
-
- // Unrecognized Character
- else
- throw new ScanningException(col, line);
- ;
-
- break;
}
}
- token.posn = new SourcePosition(line, col - token.spelling.length());
return token;
}
+
+
+ // /////////////////////////////////////////////////////////////////////////////
+ //
+ // Convenience Methods
+ //
+ // /////////////////////////////////////////////////////////////////////////////
+
/**
- * Looks at next character in stream without consuming.
- *
- * @return
- * @throws IOException
- */
- private char peek() throws ScanningException {
- try {
- input.mark(1);
- int next = input.read();
- input.reset();
-
- return next == -1 ? '\0' : (char) next;
- } catch (IOException e) {
- throw new ScanningException(col, line);
- }
- }
-
- /**
- * Returns whether passed character is next in stream.
- *
- * @param c
- * @return
- * @throws IOException
- */
- private boolean peek(char c) throws ScanningException {
- try {
- input.mark(1);
- int next = input.read();
- input.reset();
-
- return c == next;
- } catch (IOException e) {
- throw new ScanningException(col, line);
- }
- }
-
- /**
- * Alternative reading that keeps track of position.
- *
- * @return
- * @throws IOException
- */
- private int read() throws ScanningException {
- try {
- int next = input.read();
- if (next != '\n' && next != '\r')
- col += 1;
- else {
- col = 1;
- line += 1;
- if (peek('\r') || peek('\n'))
- next = input.read();
- }
-
- return next;
- } catch (IOException e) {
- throw new ScanningException(col, line);
- }
- }
-
- /**
- * Consumes input until an end of comment has been reached.
- *
- * @throws IOException
- */
- private void readComment() throws ScanningException {
- char prev = '\0', current = '\0';
- while (prev != '*' || current != '/') {
-
- prev = current;
-
- int next = read();
- if (next == -1)
- throw new ScanningException(col, line);
- else
- current = (char) next;
- }
- }
-
- /**
- * Consumes input until the end of line is reached
- *
- * @throws IOException
- */
- private void readLine() throws ScanningException {
- for (int n = 0; n != '\n' && n != '\r' && n != -1; n = read()) {
- }
- }
-
- /**
- * Tells whether character is alphabetical.
*
* @param c
* @return
*/
- private boolean isAlpha(char c) {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
+ private boolean isAlpha(int c) {
+ return (c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (predefined && c == '_');
}
-
+
/**
- * Tells whether character is numerical.
*
* @param c
* @return
*/
- private boolean isDigit(char c) {
+ private boolean isDigit(int c) {
return c >= '0' && c <= '9';
}
-
+
/**
- * Tells wheter character is whitespace.
*
* @param c
* @return
*/
- private boolean isWhitespace(char c) {
+ private boolean isWhitespace(int c) {
return c == ' ' || c == '\n' || c == '\r' || c == '\t';
}
+
+ /**
+ *
+ * @return
+ * @throws IOException
+ */
+ private int peek() throws IOException {
+ input.mark(1);
+ int next = input.read();
+ input.reset();
+ return next;
+ }
+
+ /**
+ *
+ * @param c
+ * @return
+ * @throws IOException
+ */
+ private boolean peek(int c) throws IOException {
+ input.mark(1);
+ int next = input.read();
+ input.reset();
+
+ return c == next;
+ }
+
+ /**
+ *
+ * @return
+ * @throws IOException
+ */
+ private int read() throws IOException {
+ int next = input.read();
+ if(next == '\n' || next == '\r') {
+ col = 1;
+ line += 1;
+ } else {
+ col += 1;
+ }
+
+ return next;
+ }
+
+ /**
+ *
+ * @throws IOException
+ */
+ private void readSingleLineComment() throws IOException {
+ col = 1;
+ line += 1;
+ input.readLine();
+ }
+
+ /**
+ *
+ * @throws IOException
+ */
+ private void readMultiLineComment() throws IOException {
+ int prev = '\0';
+ int current = '\0';
+
+ while(prev != '*' || current != '/') {
+ prev = current;
+ current = read();
+
+ // Unterminated
+ if(current == -1) {
+ SourcePosition posn = new SourcePosition(line, col);
+ throw new ScanningException(posn);
+ }
+ }
+ }
}
diff --git a/src/miniJava/SyntacticAnalyzer/ScanningException.java b/src/miniJava/SyntacticAnalyzer/ScanningException.java
new file mode 100644
index 0000000..6f29677
--- /dev/null
+++ b/src/miniJava/SyntacticAnalyzer/ScanningException.java
@@ -0,0 +1,16 @@
+package miniJava.SyntacticAnalyzer;
+
+import java.io.IOException;
+
+/**
+ *
+ */
+public class ScanningException extends IOException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ScanningException(SourcePosition posn) {
+ super("Scanning error at " + posn);
+ }
+
+}
diff --git a/src/miniJava/SyntacticAnalyzer/SourcePosition.java b/src/miniJava/SyntacticAnalyzer/SourcePosition.java
index 272acc4..072d8fe 100644
--- a/src/miniJava/SyntacticAnalyzer/SourcePosition.java
+++ b/src/miniJava/SyntacticAnalyzer/SourcePosition.java
@@ -1,11 +1,14 @@
package miniJava.SyntacticAnalyzer;
+/**
+ *
+ */
public class SourcePosition {
public final int col;
public final int line;
- public SourcePosition(int line, int col) {
+ public SourcePosition(int col, int line) {
this.col = col;
this.line = line;
}
diff --git a/src/miniJava/SyntacticAnalyzer/Token.java b/src/miniJava/SyntacticAnalyzer/Token.java
index 08f5abb..ddd35f1 100644
--- a/src/miniJava/SyntacticAnalyzer/Token.java
+++ b/src/miniJava/SyntacticAnalyzer/Token.java
@@ -2,26 +2,51 @@ package miniJava.SyntacticAnalyzer;
import java.util.HashMap;
+/**
+ *
+ */
public class Token {
public enum TYPE {
-
- // Possible Terminals
- ID, NUM, UNOP, BINOP,
+
+ // Terminals
+ ID,
+ NUM,
+ UNOP,
+ BINOP,
+ EQUALS,
+ PERIOD,
+ COMMA,
+ LPAREN,
+ RPAREN,
+ LSQUARE,
+ RSQUARE,
+ LBRACKET,
+ RBRACKET,
+ SEMICOLON,
// Keywords
- IF, ELSE, NEW, INT, VOID, THIS, TRUE, FALSE, CLASS, WHILE, RETURN, BOOLEAN,
-
- // Declarators
- STATIC, PUBLIC, PRIVATE,
-
- // Other Terminals
- EQUALS, PERIOD, COMMA, LPAREN, RPAREN, LSQUARE, RSQUARE, LBRACKET, RBRACKET, SEMICOLON,
+ IF,
+ ELSE,
+ NEW,
+ INT,
+ VOID,
+ THIS,
+ TRUE,
+ FALSE,
+ CLASS,
+ WHILE,
+ RETURN,
+ BOOLEAN,
+ STATIC,
+ PUBLIC,
+ PRIVATE,
// End of Token Stream
EOT
};
+ // Pair words with enumeration
public final static HashMap keywords;
static {
keywords = new HashMap();
@@ -41,14 +66,29 @@ public class Token {
keywords.put("false", TYPE.FALSE);
keywords.put("new", TYPE.NEW);
}
+
+ // Pair symbols with enumeration
+ public final static HashMap symbols;
+ static {
+ symbols = new HashMap();
+ symbols.put((int) '.', TYPE.PERIOD);
+ symbols.put((int) ',', TYPE.COMMA);
+ symbols.put((int) '[', TYPE.LSQUARE);
+ symbols.put((int) ']', TYPE.RSQUARE);
+ symbols.put((int) '{', TYPE.LBRACKET);
+ symbols.put((int) '}', TYPE.RBRACKET);
+ symbols.put((int) '(', TYPE.LPAREN);
+ symbols.put((int) ')', TYPE.RPAREN);
+ symbols.put((int) ';', TYPE.SEMICOLON);
+ }
public final TYPE type;
- public SourcePosition posn;
public final String spelling;
+ public final SourcePosition posn;
- public Token(String spelling, TYPE type) {
+ public Token(String spelling, TYPE type, SourcePosition posn) {
this.type = type;
- this.posn = null;
+ this.posn = posn;
this.spelling = spelling;
}
}
diff --git a/src/tester/Checkpoint1.java b/src/tester/Checkpoint1.java
new file mode 100644
index 0000000..64410e8
--- /dev/null
+++ b/src/tester/Checkpoint1.java
@@ -0,0 +1,71 @@
+package tester;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Scanner;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/* Automated regression tester for Checkpoint 1 tests
+ * Created by Max Beckman-Harned
+ * Put your tests in "tests/pa1_tests" folder in your Eclipse workspace directory
+ */
+public class Checkpoint1 {
+
+ static ExecutorService threadPool = Executors.newCachedThreadPool();
+
+ public static void main(String[] args) throws IOException, InterruptedException {
+ File testDir = new File(System.getProperty("java.class.path")
+ + "/../tests/pa1_tests");
+ int failures = 0;
+ for (File x : testDir.listFiles()) {
+ int returnCode = runTest(x);
+ if (x.getName().indexOf("pass") != -1) {
+ if (returnCode == 0)
+ System.out.println(x.getName() + " passed successfully!");
+ else {
+ failures++;
+ System.err.println(x.getName()
+ + " failed but should have passed!");
+ }
+ } else {
+ if (returnCode == 4)
+ System.out.println(x.getName() + " failed successfully!");
+ else {
+ System.err.println(x.getName() + " did not fail properly!");
+ failures++;
+ }
+ }
+ }
+ System.out.println(failures + " failures in all.");
+ }
+
+ private static int runTest(File x) throws IOException, InterruptedException {
+ ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path")));
+ Process p = pb.start();
+ threadPool.execute(new ProcessOutputter(p.getInputStream(), false));
+ p.waitFor();
+ return p.exitValue();
+ }
+
+ static class ProcessOutputter implements Runnable {
+ private Scanner processOutput;
+ private boolean output;
+
+ public ProcessOutputter(InputStream _processStream, boolean _output) {
+ processOutput = new Scanner(_processStream);
+ output = _output;
+ }
+ @Override
+ public void run() {
+ while(processOutput.hasNextLine()) {
+ String line = processOutput.nextLine();
+ if (output)
+ System.out.println(line);
+ }
+ }
+
+
+ }
+}
diff --git a/src/tester/Checkpoint2.java b/src/tester/Checkpoint2.java
new file mode 100644
index 0000000..d9d7711
--- /dev/null
+++ b/src/tester/Checkpoint2.java
@@ -0,0 +1,98 @@
+package tester;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.util.Scanner;
+
+/* Automated regression tester for Checkpoint 2 tests
+ * Created by Max Beckman-Harned
+ * Put your tests in "tests/pa2_tests" folder in your Eclipse workspace directory
+ * If you preface your error messages / exceptions with ERROR or *** then they will be displayed if they appear during processing
+ */
+
+public class Checkpoint2 {
+
+ private static class ReturnInfo {
+ int returnCode;
+ String ast;
+ public ReturnInfo(int _returnCode, String _ast) {
+ returnCode = _returnCode;
+ ast = _ast;
+ }
+ }
+
+ public static void main(String[] args) throws IOException, InterruptedException {
+ File testDir = new File(System.getProperty("java.class.path")
+ + "/../tests/pa2_tests");
+ int failures = 0;
+ for (File x : testDir.listFiles()) {
+ if (x.getName().endsWith("out") || x.getName().startsWith("."))
+ continue;
+ ReturnInfo info = runTest(x);
+ int returnCode = info.returnCode;
+ String ast = info.ast;
+ if (x.getName().indexOf("pass") != -1) {
+ if (returnCode == 0) {
+ String actualAST = getAST(new FileInputStream(x.getPath() + ".out"));
+ if (actualAST.equals(ast))
+ System.out.println(x.getName() + " parsed successfully and has a correct AST!");
+ else {
+ System.err.println(x.getName() + " parsed successfully but has an incorrect AST!");
+ failures++;
+ }
+ }
+ else {
+ failures++;
+ System.err.println(x.getName()
+ + " failed to be parsed!");
+ }
+ } else {
+ if (returnCode == 4)
+ System.out.println(x.getName() + " failed successfully!");
+ else {
+ System.err.println(x.getName() + " did not fail properly!");
+ failures++;
+ }
+ }
+ }
+ System.out.println(failures + " failures in all.");
+ }
+
+ private static ReturnInfo runTest(File x) throws IOException, InterruptedException {
+ ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path")));
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+
+ String ast = getAST(p.getInputStream());
+ p.waitFor();
+ int exitValue = p.exitValue();
+ return new ReturnInfo(exitValue, ast);
+ }
+
+
+ public static String getAST(InputStream stream) {
+ Scanner scan = new Scanner(stream);
+ String ast = null;
+ while (scan.hasNextLine()) {
+ String line = scan.nextLine();
+ if (line.equals("======= AST Display =========================")) {
+ line = scan.nextLine();
+ while(scan.hasNext() && !line.equals("=============================================")) {
+ ast += line + "\n";
+ line = scan.nextLine();
+ }
+ }
+ if (line.startsWith("*** "))
+ System.out.println(line);
+ if (line.startsWith("ERROR")) {
+ System.out.println(line);
+ while(scan.hasNext())
+ System.out.println(scan.next());
+ }
+ }
+ scan.close();
+ return ast;
+ }
+}
diff --git a/src/tester/Checkpoint3.java b/src/tester/Checkpoint3.java
new file mode 100644
index 0000000..760e1f1
--- /dev/null
+++ b/src/tester/Checkpoint3.java
@@ -0,0 +1,73 @@
+package tester;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Scanner;
+
+
+/* Automated regression tester for Checkpoint 3 tests
+ * Created by Max Beckman-Harned
+ * Put your tests in "tests/pa3_tests" folder in your Eclipse workspace directory
+ * If you preface your error messages / exceptions with ERROR or *** then they will be displayed if they appear during processing
+ */
+
+public class Checkpoint3 {
+
+
+ public static void main(String[] args) throws IOException, InterruptedException {
+ File testDir = new File(System.getProperty("java.class.path")
+ + "/../tests/pa3_tests");
+ int failures = 0;
+ for (File x : testDir.listFiles()) {
+ if (x.getName().endsWith("out") || x.getName().startsWith(".") || x.getName().endsWith("mJAM") || x.getName().endsWith("asm"))
+ continue;
+ int returnCode = runTest(x);
+ if (x.getName().indexOf("pass") != -1) {
+ if (returnCode == 0) {
+ System.out.println(x.getName() + " processed successfully!");
+ }
+ else {
+ failures++;
+ System.err.println(x.getName()
+ + " failed to be processed!");
+ }
+ } else {
+ if (returnCode == 4)
+ System.out.println(x.getName() + " failed successfully!");
+ else {
+ System.err.println(x.getName() + " did not fail properly!");
+ failures++;
+ }
+ }
+ }
+ System.out.println(failures + " failures in all.");
+ }
+
+ private static int runTest(File x) throws IOException, InterruptedException {
+ ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path")));
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+
+ processStream(p.getInputStream());
+ p.waitFor();
+ int exitValue = p.exitValue();
+ return exitValue;
+ }
+
+
+ public static void processStream(InputStream stream) {
+ Scanner scan = new Scanner(stream);
+ while (scan.hasNextLine()) {
+ String line = scan.nextLine();
+ if (line.startsWith("*** "))
+ System.out.println(line);
+ if (line.startsWith("ERROR")) {
+ System.out.println(line);
+ //while(scan.hasNext())
+ //System.out.println(scan.next());
+ }
+ }
+ scan.close();
+ }
+}
diff --git a/src/tester/Checkpoint4.java b/src/tester/Checkpoint4.java
new file mode 100644
index 0000000..9ff8089
--- /dev/null
+++ b/src/tester/Checkpoint4.java
@@ -0,0 +1,112 @@
+package tester;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Scanner;
+
+
+/* Automated regression tester for Checkpoint 4 tests
+ * Created by Max Beckman-Harned
+ * Put your tests in "tests/pa4_tests" folder in your Eclipse workspace directory
+ * If you preface your compiler error messages / exceptions with ERROR or *** then they will be displayed if they appear during processing
+ */
+
+public class Checkpoint4 {
+
+
+ public static void main(String[] args) throws IOException, InterruptedException {
+ File testDir = new File(System.getProperty("java.class.path")
+ + "/../tests/pa4_tests");
+ int failures = 0;
+ for (File x : testDir.listFiles()) {
+ if (x.getName().startsWith(".") || x.getName().endsWith("mJAM") || x.getName().endsWith("asm"))
+ continue;
+ int returnCode = runTest(x);
+ if (x.getName().indexOf("pass") != -1) {
+ if (returnCode == 0) {
+ try {
+ int val = executeTest(x);
+ int expected = Integer.parseInt(x.getName().substring(5,7));
+ if (val == expected)
+ System.out.println(x.getName() + " ran successfully!");
+ else {
+ failures++;
+ System.err.println(x.getName() + " compiled but did not run successfully--got output " + val);
+ }
+ }
+ catch(Exception ex) {
+ failures++;
+ System.err.println(x.getName() + " did not output correctly.");
+ }
+ }
+ else {
+ failures++;
+ System.err.println(x.getName()
+ + " failed to be processed!");
+ }
+ } else {
+ if (returnCode == 4)
+ System.out.println(x.getName() + " failed successfully!");
+ else {
+ System.err.println(x.getName() + " did not fail properly!");
+ failures++;
+ }
+ }
+ }
+ System.out.println(failures + " failures in all.");
+ }
+
+ private static int runTest(File x) throws IOException, InterruptedException {
+ ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path")));
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+
+ processStream(p.getInputStream());
+ p.waitFor();
+ int exitValue = p.exitValue();
+ return exitValue;
+ }
+
+ private static int executeTest(File x) throws IOException, InterruptedException {
+ ProcessBuilder pb = new ProcessBuilder("java", "mJAM.Interpreter", x.getPath().replace(".java", ".mJAM")).directory(new File(System.getProperty("java.class.path")));
+ Process process = pb.start();
+
+ Scanner scan = new Scanner(process.getInputStream());
+ int num = -1;
+ while (scan.hasNextLine()) {
+ String line = scan.nextLine();
+ if (line.startsWith(">>> ")) {
+ num = Integer.parseInt(line.substring(4));
+ System.out.println("Result = " + num);
+ break;
+ }
+ }
+ while (scan.hasNextLine()) {
+ String line = scan.nextLine();
+ if (line.startsWith("*** ")) {
+ System.out.println(line);
+ break;
+ }
+ }
+ scan.close();
+
+ return num;
+ }
+
+
+ public static void processStream(InputStream stream) {
+ Scanner scan = new Scanner(stream);
+ while (scan.hasNextLine()) {
+ String line = scan.nextLine();
+ if (line.startsWith("*** "))
+ System.out.println(line);
+ if (line.startsWith("ERROR")) {
+ System.out.println(line);
+ //while(scan.hasNext())
+ //System.out.println(scan.next());
+ }
+ }
+ scan.close();
+ }
+}
\ No newline at end of file