summaryrefslogtreecommitdiff
path: root/boil/library
diff options
context:
space:
mode:
Diffstat (limited to 'boil/library')
-rw-r--r--boil/library/BoilSimp.java758
-rw-r--r--boil/library/TypeFactory.java25
2 files changed, 783 insertions, 0 deletions
diff --git a/boil/library/BoilSimp.java b/boil/library/BoilSimp.java
new file mode 100644
index 0000000..b5ea518
--- /dev/null
+++ b/boil/library/BoilSimp.java
@@ -0,0 +1,758 @@
+package boil.library;
+
+import syntaxtree.*;
+import visitor.*;
+import st.*;
+import misc.*;
+import java.util.*;
+
+public class BoilSimp extends GJDepthFirst<String,SymbolTable> {
+
+ TypeFactory tf = new TypeFactory();
+
+ //
+ // Auto class visitors--probably don't need to be overridden.
+ //
+ public String visit(NodeList n, SymbolTable symt) {
+ String mod = "";
+ int _count=0;
+ for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) {
+ mod += e.nextElement().accept(this,symt);
+ _count++;
+ }
+ return mod;
+ }
+
+ public String visit(NodeListOptional n, SymbolTable symt) {
+ String mod = "";
+ if ( n.present() ) {
+ int _count=0;
+ for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) {
+ mod += e.nextElement().accept(this,symt);
+ _count++;
+ }
+ return mod;
+ }
+ else
+ return "";
+ }
+
+ public String visit(NodeOptional n, SymbolTable symt) {
+ if ( n.present() )
+ return n.node.accept(this,symt);
+ else
+ return "";
+ }
+
+ public String visit(NodeSequence n, SymbolTable symt) {
+ String mod = "";
+ int _count=0;
+ for ( Enumeration<Node> e = n.elements(); e.hasMoreElements(); ) {
+ mod += e.nextElement().accept(this,symt);
+ _count++;
+ }
+ return mod;
+ }
+
+ public String visit(NodeToken n, SymbolTable symt) { return ""; }
+
+ //
+ // User-generated visitor methods below
+ //
+
+ /**
+ * f0 -> MainClass()
+ * f1 -> ( TypeDeclaration() )*
+ * f2 -> <EOF>
+ */
+ public String visit(Goal n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "class"
+ * f1 -> Identifier()
+ * f2 -> "{"
+ * f3 -> "public"
+ * f4 -> "static"
+ * f5 -> "void"
+ * f6 -> "main"
+ * f7 -> "("
+ * f8 -> "String"
+ * f9 -> "["
+ * f10 -> "]"
+ * f11 -> Identifier()
+ * f12 -> ")"
+ * f13 -> "{"
+ * f14 -> ( VarDeclaration() )*
+ * f15 -> ( Statement() )*
+ * f16 -> "}"
+ * f17 -> "}"
+ */
+ public String visit(MainClass n, SymbolTable symt) {
+ String id = n.f1.f0.tokenImage;
+
+ symt.setActive(TypeEnum.classname, id);
+ symt.setActive(TypeEnum.method, "main");
+ this.tf.reset();
+ String mod = "";
+ mod += "func Main()\n";
+
+ mod += n.f0.accept(this, symt);
+ n.f1.accept(this, symt); // throw class name away
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ mod += n.f4.accept(this, symt);
+ mod += n.f5.accept(this, symt);
+ mod += n.f6.accept(this, symt);
+ mod += n.f7.accept(this, symt);
+ mod += n.f8.accept(this, symt);
+ mod += n.f9.accept(this, symt);
+ mod += n.f10.accept(this, symt);
+ n.f11.accept(this, symt); // throw boiler 'args' variable away
+ mod += n.f12.accept(this, symt);
+ mod += n.f13.accept(this, symt);
+ mod += n.f14.accept(this, symt); // FIXME
+ mod += n.f15.accept(this, symt);
+ mod += n.f16.accept(this, symt);
+ mod += n.f17.accept(this, symt);
+
+ mod += " goto :exit\nerror:\n" +
+ " Error(\"Mem exhausted\")\n goto :exit\n" +
+ "exit:\n ret\n\n";
+
+ symt.removeActive(TypeEnum.method);
+ return mod;
+ }
+
+ /**
+ * f0 -> ClassDeclaration()
+ * | ClassExtendsDeclaration()
+ */
+ public String visit(TypeDeclaration n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "class"
+ * f1 -> Identifier()
+ * f2 -> "{"
+ * f3 -> ( VarDeclaration() )*
+ * f4 -> ( MethodDeclaration() )*
+ * f5 -> "}"
+ */
+ public String visit(ClassDeclaration n, SymbolTable symt) {
+ String id = n.f1.f0.tokenImage;
+ symt.setActive(TypeEnum.classname, id);
+ String mod = "";
+
+ mod += n.f0.accept(this, symt);
+ n.f1.accept(this, symt);
+ mod += String.format("const functable_%s\n", id);
+ for (MethodInstance mtd : symt.getClass(id).getMethods()) {
+ mod += String.format(" :%s_%s\n", id, mtd);
+ }
+ mod += "\n";
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ mod += n.f4.accept(this, symt);
+ mod += n.f5.accept(this, symt);
+
+ return mod;
+ }
+
+ /**
+ * f0 -> "class"
+ * f1 -> Identifier()
+ * f2 -> "extends"
+ * f3 -> Identifier()
+ * f4 -> "{"
+ * f5 -> ( VarDeclaration() )*
+ * f6 -> ( MethodDeclaration() )*
+ * f7 -> "}"
+ */
+ public String visit(ClassExtendsDeclaration n, SymbolTable symt) {
+ String id = n.f1.f0.tokenImage;
+ symt.setActive(TypeEnum.classname, id);
+ String mod = "";
+
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ mod += n.f4.accept(this, symt);
+ mod += n.f5.accept(this, symt);
+ mod += n.f6.accept(this, symt);
+ mod += n.f7.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> Type()
+ * f1 -> Identifier()
+ * f2 -> ";"
+ */
+ public String visit(VarDeclaration n, SymbolTable symt) {
+ String mod = "";
+
+ n.f0.accept(this, symt);
+ String id = n.f1.accept(this, symt);
+ mod += String.format(" %s = HeapAllocZ(32)\n",
+ this.tf.addNewAlias(symt.getType(id))); // FIXME add proper allocation size
+ mod += String.format(" if0 %s goto :error\n",
+ this.tf.retrieveAlias(symt.getType(id)));
+ mod += n.f2.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "public"
+ * f1 -> Type()
+ * f2 -> Identifier()
+ * f3 -> "("
+ * f4 -> ( FormalParameterList() )?
+ * f5 -> ")"
+ * f6 -> "{"
+ * f7 -> ( VarDeclaration() )*
+ * f8 -> ( Statement() )*
+ * f9 -> "return"
+ * f10 -> Expression()
+ * f11 -> ";"
+ * f12 -> "}"
+ */
+ public String visit(MethodDeclaration n, SymbolTable symt) {
+ String id = n.f2.f0.tokenImage;
+ symt.setActive(TypeEnum.method, id);
+ this.tf.reset();
+ String mod = "";
+
+ mod += n.f0.accept(this, symt);
+ n.f1.accept(this, symt);
+ n.f2.accept(this, symt);
+ mod += "func " + symt.getActive(TypeEnum.classname) + "_" + id + "(this";
+ mod += n.f3.accept(this, symt);
+ String args = n.f4.accept(this, symt);
+ mod += String.format("%s)\n", args);
+ mod += n.f5.accept(this, symt);
+ mod += n.f6.accept(this, symt);
+ mod += n.f7.accept(this, symt);
+ mod += n.f8.accept(this, symt);
+ mod += n.f9.accept(this, symt);
+ n.f10.accept(this, symt); // FIXME
+ mod += n.f11.accept(this, symt);
+ mod += n.f12.accept(this, symt);
+
+ mod += " ret\n\n";
+
+
+ symt.removeActive(TypeEnum.method);
+ return mod;
+ }
+
+ /**
+ * f0 -> FormalParameter()
+ * f1 -> ( FormalParameterRest() )*
+ */
+ public String visit(FormalParameterList n, SymbolTable symt) {
+ String mod = "";
+ String arg = n.f0.accept(this, symt);
+ if (arg != null)
+ mod += " " + arg;
+ mod += n.f1.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> Type()
+ * f1 -> Identifier()
+ */
+ public String visit(FormalParameter n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> ","
+ * f1 -> FormalParameter()
+ */
+ public String visit(FormalParameterRest n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ String arg = n.f1.accept(this, symt);
+ if (arg != null)
+ mod += " " + arg;
+ return mod;
+ }
+
+ /**
+ * f0 -> ArrayType()
+ * | BooleanType()
+ * | IntegerType()
+ * | Identifier()
+ */
+ public String visit(Type n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "int"
+ * f1 -> "["
+ * f2 -> "]"
+ */
+ public String visit(ArrayType n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "boolean"
+ */
+ public String visit(BooleanType n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "int"
+ */
+ public String visit(IntegerType n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);;
+ return mod;
+ }
+
+ /**
+ * f0 -> Block()
+ * | AssignmentStatement()
+ * | ArrayAssignmentStatement()
+ * | IfStatement()
+ * | WhileStatement()
+ * | PrintStatement()
+ */
+ public String visit(Statement n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "{"
+ * f1 -> ( Statement() )*
+ * f2 -> "}"
+ */
+ public String visit(Block n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> Identifier()
+ * f1 -> "="
+ * f2 -> Expression()
+ * f3 -> ";"
+ */
+ public String visit(AssignmentStatement n, SymbolTable symt) {
+ String mod = "";
+
+ String id = n.f0.accept(this, symt);
+ mod += String.format(" [%s] = ", this.tf.retrieveAlias(symt.getType(id)));
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> Identifier()
+ * f1 -> "["
+ * f2 -> Expression()
+ * f3 -> "]"
+ * f4 -> "="
+ * f5 -> Expression()
+ * f6 -> ";"
+ */
+ public String visit(ArrayAssignmentStatement n, SymbolTable symt) {
+ String mod = "";
+ n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ mod += n.f4.accept(this, symt);
+ mod += n.f5.accept(this, symt);
+ mod += n.f6.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "if"
+ * f1 -> "("
+ * f2 -> Expression()
+ * f3 -> ")"
+ * f4 -> Statement()
+ * f5 -> "else"
+ * f6 -> Statement()
+ */
+ public String visit(IfStatement n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ mod += n.f4.accept(this, symt);
+ mod += n.f5.accept(this, symt);
+ mod += n.f6.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "while"
+ * f1 -> "("
+ * f2 -> Expression()
+ * f3 -> ")"
+ * f4 -> Statement()
+ */
+ public String visit(WhileStatement n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ mod += n.f4.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "System.out.println"
+ * f1 -> "("
+ * f2 -> Expression()
+ * f3 -> ")"
+ * f4 -> ";"
+ */
+ public String visit(PrintStatement n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ mod += n.f4.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> AndExpression()
+ * | CompareExpression()
+ * | PlusExpression()
+ * | MinusExpression()
+ * | TimesExpression()
+ * | ArrayLookup()
+ * | ArrayLength()
+ * | MessageSend()
+ * | PrimaryExpression()
+ */
+ public String visit(Expression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> PrimaryExpression()
+ * f1 -> "&&"
+ * f2 -> PrimaryExpression()
+ */
+ public String visit(AndExpression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> PrimaryExpression()
+ * f1 -> "<"
+ * f2 -> PrimaryExpression()
+ */
+ public String visit(CompareExpression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> PrimaryExpression()
+ * f1 -> "+"
+ * f2 -> PrimaryExpression()
+ */
+ public String visit(PlusExpression n, SymbolTable symt) {
+ String mod = "";
+ String oper1 = n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ String oper2 = n.f2.accept(this, symt);
+ TypeInstance tp1 = new TypeInstance("tp1", TypeEnum.ERROR);
+
+ mod += String.format(" %s = AddS(%s %s)\n",
+ this.tf.addNewAlias(tp1),
+ oper1,
+ oper2);
+
+ return mod;
+ }
+
+ /**
+ * f0 -> PrimaryExpression()
+ * f1 -> "-"
+ * f2 -> PrimaryExpression()
+ */
+ public String visit(MinusExpression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> PrimaryExpression()
+ * f1 -> "*"
+ * f2 -> PrimaryExpression()
+ */
+ public String visit(TimesExpression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> PrimaryExpression()
+ * f1 -> "["
+ * f2 -> PrimaryExpression()
+ * f3 -> "]"
+ */
+ public String visit(ArrayLookup n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> PrimaryExpression()
+ * f1 -> "."
+ * f2 -> "length"
+ */
+ public String visit(ArrayLength n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> PrimaryExpression()
+ * f1 -> "."
+ * f2 -> Identifier()
+ * f3 -> "("
+ * f4 -> ( ExpressionList() )?
+ * f5 -> ")"
+ */
+ public String visit(MessageSend n, SymbolTable symt) {
+ String mod = "";
+ String id = n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ String id2 = n.f2.accept(this, symt);
+ TypeInstance tp1 = new TypeInstance("tp1", TypeEnum.ERROR); // TypeFactory likes to know who it's renting to
+ TypeInstance tp2 = new TypeInstance("tp2", TypeEnum.ERROR);
+
+ TypeInstance cur = symt.getType(id);
+ int mtdIndex = cur.getClassInstance()
+ .getMethods().indexOf(symt.getMethod(id2)) * 4;
+
+ mod += String.format(" %s = [%s+%d]\n",
+ this.tf.addNewAlias(tp1),
+ this.tf.retrieveAlias(cur),
+ 0);
+
+ mod += String.format(" %s = [%s+%d]\n",
+ this.tf.addNewAlias(tp2),
+ this.tf.retrieveAlias(tp1),
+ mtdIndex);
+
+ mod += n.f3.accept(this, symt);
+ mod = n.f4.accept(this, symt);
+ mod += n.f5.accept(this, symt);
+
+ mod += String.format(" call %s(%s)\n",
+ this.tf.retrieveAlias(tp2),
+ this.tf.retrieveAlias(cur));
+
+ return mod;
+ }
+
+ /**
+ * f0 -> Expression()
+ * f1 -> ( ExpressionRest() )*
+ */
+ public String visit(ExpressionList n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> ","
+ * f1 -> Expression()
+ */
+ public String visit(ExpressionRest n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> IntegerLiteral()
+ * | TrueLiteral()
+ * | FalseLiteral()
+ * | Identifier()
+ * | ThisExpression()
+ * | ArrayAllocationExpression()
+ * | AllocationExpression()
+ * | NotExpression()
+ * | BracketExpression()
+ */
+ public String visit(PrimaryExpression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> <INTEGER_LITERAL>
+ */
+ public String visit(IntegerLiteral n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.tokenImage;
+ return mod;
+ }
+
+ /**
+ * f0 -> "true"
+ */
+ public String visit(TrueLiteral n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "false"
+ */
+ public String visit(FalseLiteral n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> <IDENTIFIER>
+ */
+ public String visit(Identifier n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.tokenImage;
+ return mod;
+ }
+
+ /**
+ * f0 -> "this"
+ */
+ public String visit(ThisExpression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "new"
+ * f1 -> "int"
+ * f2 -> "["
+ * f3 -> Expression()
+ * f4 -> "]"
+ */
+ public String visit(ArrayAllocationExpression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ mod += n.f4.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "new"
+ * f1 -> Identifier()
+ * f2 -> "("
+ * f3 -> ")"
+ */
+ public String visit(AllocationExpression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ String cls = n.f1.accept(this, symt);
+ mod += String.format(":functable_%s\n", cls);
+
+ mod += n.f2.accept(this, symt);
+ mod += n.f3.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "!"
+ * f1 -> Expression()
+ */
+ public String visit(NotExpression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ return mod;
+ }
+
+ /**
+ * f0 -> "("
+ * f1 -> Expression()
+ * f2 -> ")"
+ */
+ public String visit(BracketExpression n, SymbolTable symt) {
+ String mod = "";
+ mod += n.f0.accept(this, symt);
+ mod += n.f1.accept(this, symt);
+ mod += n.f2.accept(this, symt);
+ return mod;
+ }
+
+}
diff --git a/boil/library/TypeFactory.java b/boil/library/TypeFactory.java
new file mode 100644
index 0000000..8dd910e
--- /dev/null
+++ b/boil/library/TypeFactory.java
@@ -0,0 +1,25 @@
+package boil.library;
+
+import java.util.HashMap;
+import st.TypeInstance;
+
+public class TypeFactory {
+
+ private int type_num;
+ private HashMap<TypeInstance,String> map;
+
+ public void reset() {
+ this.type_num = 0;
+ this.map = new HashMap<>();
+ }
+
+ public String addNewAlias(TypeInstance t) {
+ String alias = String.format("t.%d", this.type_num++);
+ this.map.put(t, alias);
+ return alias;
+ }
+
+ public String retrieveAlias(TypeInstance t) {
+ return this.map.get(t);
+ }
+}