From 5fa82beb2b420cc63111c186a670abcb674ba373 Mon Sep 17 00:00:00 2001 From: Iru Cai Date: Mon, 3 Nov 2014 01:46:06 +0800 Subject: piglet to spiglet --- src/piglet/piglet2spiglet/GenSpigletCtl.java | 25 ++ src/piglet/piglet2spiglet/Main.java | 11 +- src/piglet/piglet2spiglet/PigletExpr.java | 19 ++ src/piglet/visitor/GenSpigletVisitor.java | 382 +++++++++++++++++++++++++++ src/piglet/visitor/ScanTempVisitor.java | 234 ++++++++++++++++ 5 files changed, 667 insertions(+), 4 deletions(-) create mode 100644 src/piglet/piglet2spiglet/GenSpigletCtl.java create mode 100644 src/piglet/piglet2spiglet/PigletExpr.java create mode 100644 src/piglet/visitor/GenSpigletVisitor.java create mode 100644 src/piglet/visitor/ScanTempVisitor.java diff --git a/src/piglet/piglet2spiglet/GenSpigletCtl.java b/src/piglet/piglet2spiglet/GenSpigletCtl.java new file mode 100644 index 0000000..a95dcc4 --- /dev/null +++ b/src/piglet/piglet2spiglet/GenSpigletCtl.java @@ -0,0 +1,25 @@ +package piglet.piglet2spiglet; + +import java.util.Vector; + +public class GenSpigletCtl { + /* DEFAULT: return a PigletExpr + * PRINT: used with procedure, print the StmtExp + * LIST: used with call, add things to list, return null + */ + public enum Control { DEFAULT, PRINT, LIST }; + Control c; + public Vector call_list; + + public GenSpigletCtl(Control _c) { + c = _c; + call_list = new Vector(); + } + public boolean isPrint() { + return c==Control.PRINT; + } + + public boolean isList() { + return c==Control.LIST; + } +} diff --git a/src/piglet/piglet2spiglet/Main.java b/src/piglet/piglet2spiglet/Main.java index db68b6a..7c3d01b 100644 --- a/src/piglet/piglet2spiglet/Main.java +++ b/src/piglet/piglet2spiglet/Main.java @@ -6,6 +6,8 @@ import piglet.PigletParser; import piglet.TokenMgrError; import piglet.syntaxtree.Node; import piglet.visitor.GJDepthFirst; +import piglet.visitor.GenSpigletVisitor; +import piglet.visitor.ScanTempVisitor; public class Main { @@ -17,10 +19,11 @@ public class Main { * TODO: Implement your own Visitors and other classes. * */ - GJDepthFirst v = new GJDepthFirst() { - }; - //Traverse the Abstract Grammar Tree - root.accept(v,null); + ScanTempVisitor vt = new ScanTempVisitor(); + root.accept(vt); + GenSpigletVisitor gen = new GenSpigletVisitor(); + gen.nTemp = Math.max(vt.maxtmp, 20); + root.accept(gen, null); } catch(TokenMgrError e){ //Handle Lexical Errors diff --git a/src/piglet/piglet2spiglet/PigletExpr.java b/src/piglet/piglet2spiglet/PigletExpr.java new file mode 100644 index 0000000..a8289e6 --- /dev/null +++ b/src/piglet/piglet2spiglet/PigletExpr.java @@ -0,0 +1,19 @@ +package piglet.piglet2spiglet; + +public class PigletExpr { + public enum Expr_t { Temp, Int, Label, Other }; + public Expr_t type; + public String s; + public PigletExpr(Expr_t t, String _s) { + type = t; + s = _s; + } + + public boolean isSimple() { + return type==Expr_t.Temp || type==Expr_t.Int || type==Expr_t.Label; + } + + public String toString() { + return s; + } +} diff --git a/src/piglet/visitor/GenSpigletVisitor.java b/src/piglet/visitor/GenSpigletVisitor.java new file mode 100644 index 0000000..779edf9 --- /dev/null +++ b/src/piglet/visitor/GenSpigletVisitor.java @@ -0,0 +1,382 @@ +package piglet.visitor; +import java.util.Enumeration; +import java.util.Vector; + +import piglet.piglet2spiglet.GenSpigletCtl; +import piglet.piglet2spiglet.PigletExpr; +import piglet.syntaxtree.BinOp; +import piglet.syntaxtree.CJumpStmt; +import piglet.syntaxtree.Call; +import piglet.syntaxtree.ErrorStmt; +import piglet.syntaxtree.Exp; +import piglet.syntaxtree.Goal; +import piglet.syntaxtree.HAllocate; +import piglet.syntaxtree.HLoadStmt; +import piglet.syntaxtree.HStoreStmt; +import piglet.syntaxtree.IntegerLiteral; +import piglet.syntaxtree.JumpStmt; +import piglet.syntaxtree.Label; +import piglet.syntaxtree.MoveStmt; +import piglet.syntaxtree.NoOpStmt; +import piglet.syntaxtree.Node; +import piglet.syntaxtree.NodeList; +import piglet.syntaxtree.NodeListOptional; +import piglet.syntaxtree.NodeOptional; +import piglet.syntaxtree.NodeSequence; +import piglet.syntaxtree.NodeToken; +import piglet.syntaxtree.Operator; +import piglet.syntaxtree.PrintStmt; +import piglet.syntaxtree.Procedure; +import piglet.syntaxtree.Stmt; +import piglet.syntaxtree.StmtExp; +import piglet.syntaxtree.StmtList; +import piglet.syntaxtree.Temp; + +/** + * Provides default methods which visit each node in the tree in depth-first + * order. Your visitors may extend this class. + */ +public class GenSpigletVisitor extends GJDepthFirst { + + public int nTemp; + final GenSpigletCtl Default = new GenSpigletCtl(GenSpigletCtl.Control.DEFAULT); + final GenSpigletCtl Print = new GenSpigletCtl(GenSpigletCtl.Control.PRINT); + final String BinOPs[] = {"LT", "PLUS", "MINUS", "TIMES" }; + + String expr_to_tmp(PigletExpr e) { + if (e.type==PigletExpr.Expr_t.Temp) { + return e.toString(); + } else { + nTemp++; + System.out.println("MOVE TEMP " + nTemp + " " + e.toString()); + return "TEMP " + nTemp; + } + } + + String expr_to_simple(PigletExpr e) { + if (e.isSimple()) { + return e.toString(); + } else { + nTemp++; + System.out.println("MOVE TEMP " + nTemp + " " + e.toString()); + return "TEMP " + nTemp; + } + } + // + // User-generated visitor methods below + // + + /** + * f0 -> "MAIN" + * f1 -> StmtList() + * f2 -> "END" + * f3 -> ( Procedure() )* + * f4 -> + */ + public PigletExpr visit(Goal n, GenSpigletCtl argu) { + System.out.println("MAIN"); + n.f1.accept(this, argu); + System.out.println("END"); + n.f3.accept(this, argu); + return null; + } + + /** + * f0 -> ( ( Label() )? Stmt() )* + */ + public PigletExpr visit(StmtList n, GenSpigletCtl argu) { + n.f0.accept(this, argu); + return null; + } + + /** + * f0 -> Label() + * f1 -> "[" + * f2 -> IntegerLiteral() + * f3 -> "]" + * f4 -> StmtExp() + */ + public PigletExpr visit(Procedure n, GenSpigletCtl argu) { + String lb = n.f0.f0.toString(); + String numarg = n.f2.f0.toString(); + System.out.println(lb + " [ " + numarg + " ]"); + n.f4.accept(this, Print); + return null; + } + + /** + * f0 -> NoOpStmt() + * | ErrorStmt() + * | CJumpStmt() + * | JumpStmt() + * | HStoreStmt() + * | HLoadStmt() + * | MoveStmt() + * | PrintStmt() + */ + public PigletExpr visit(Stmt n, GenSpigletCtl argu) { + n.f0.accept(this, argu); + return null; + } + + /** + * f0 -> "NOOP" + */ + public PigletExpr visit(NoOpStmt n, GenSpigletCtl argu) { + System.out.println("NOOP"); + return null; + } + + /** + * f0 -> "ERROR" + */ + public PigletExpr visit(ErrorStmt n, GenSpigletCtl argu) { + System.out.println("ERROR"); + return null; + } + + /** + * f0 -> "CJUMP" + * f1 -> Exp() + * f2 -> Label() + */ + public PigletExpr visit(CJumpStmt n, GenSpigletCtl argu) { + PigletExpr e = n.f1.accept(this, Default); + String lb = n.f2.f0.toString(); + String tmpstr; + if (e.type==PigletExpr.Expr_t.Temp) { + tmpstr = e.toString(); + } else { + nTemp++; + System.out.println("MOVE TEMP " + nTemp + " " + e.toString()); + tmpstr = "TEMP " + nTemp; + } + System.out.println("CJUMP " + tmpstr + " " + lb); + return null; + } + + /** + * f0 -> "JUMP" + * f1 -> Label() + */ + public PigletExpr visit(JumpStmt n, GenSpigletCtl argu) { + String lb = n.f1.f0.toString(); + System.out.println("JUMP " + lb); + return null; + } + + /** + * f0 -> "HSTORE" + * f1 -> Exp() + * f2 -> IntegerLiteral() + * f3 -> Exp() + */ + public PigletExpr visit(HStoreStmt n, GenSpigletCtl argu) { + PigletExpr e1 = n.f1.accept(this, Default); + PigletExpr e2 = n.f3.accept(this, Default); + String t1, t2; + String offs = n.f2.f0.toString(); + t1 = expr_to_tmp(e1); + t2 = expr_to_tmp(e2); + System.out.println("HSTORE " + t1 + " " + offs + " " + t2); + return null; + } + + /** + * f0 -> "HLOAD" + * f1 -> Temp() + * f2 -> Exp() + * f3 -> IntegerLiteral() + */ + public PigletExpr visit(HLoadStmt n, GenSpigletCtl argu) { + PigletExpr e = n.f2.accept(this, Default); + String s; + String t = n.f1.accept(this, Default).toString(); + String i = n.f3.f0.toString(); + s = expr_to_tmp(e); + System.out.println("HLOAD " + t + " " + s + " " + i); + return null; + } + + /** + * f0 -> "MOVE" + * f1 -> Temp() + * f2 -> Exp() + */ + public PigletExpr visit(MoveStmt n, GenSpigletCtl argu) { + PigletExpr t = n.f1.accept(this, Default); + PigletExpr e = n.f2.accept(this, Default); + System.out.println("MOVE " + t.toString() + " " + e.toString()); + return null; + } + + /** + * f0 -> "PRINT" + * f1 -> Exp() + */ + public PigletExpr visit(PrintStmt n, GenSpigletCtl argu) { + PigletExpr e = n.f1.accept(this, Default); + String s = expr_to_simple(e); + System.out.println("PRINT " + s); + return null; + } + + /** + * f0 -> StmtExp() + * | Call() + * | HAllocate() + * | BinOp() + * | Temp() + * | IntegerLiteral() + * | Label() + */ + public PigletExpr visit(Exp n, GenSpigletCtl argu) { + PigletExpr e_result = n.f0.accept(this, argu); + if (argu.isList()) { + argu.call_list.add(e_result); + return null; + } else { + return e_result; + } + } + + /** + * f0 -> "BEGIN" + * f1 -> StmtList() + * f2 -> "RETURN" + * f3 -> Exp() + * f4 -> "END" + */ + public PigletExpr visit(StmtExp n, GenSpigletCtl argu) { + /* a normal expression or a function body */ + if (argu.isPrint()) { + // a function body + System.out.println("BEGIN"); + /* statement list */ + n.f1.accept(this, null); + /* return */ + PigletExpr e = n.f3.accept(this, Default); + String ret = expr_to_simple(e); + System.out.println("RETURN " + ret); + System.out.println("END"); + return null; + } else { + // a normal expression, going to turn to a simpler expression + n.f1.accept(this, null); + return n.f3.accept(this, Default); + } + } + + /** + * f0 -> "CALL" + * f1 -> Exp() + * f2 -> "(" + * f3 -> ( Exp() )* + * f4 -> ")" + */ + public PigletExpr visit(Call n, GenSpigletCtl argu) { + String result = ""; + /* process the method */ + PigletExpr m = n.f1.accept(this, Default); + String tm = expr_to_tmp(m); + /* process the arguments */ + GenSpigletCtl ctl = new GenSpigletCtl(GenSpigletCtl.Control.LIST); + n.f3.accept(this, ctl); + Vector args = new Vector(); + for (int i=0; i "HALLOCATE" + * f1 -> Exp() + */ + public PigletExpr visit(HAllocate n, GenSpigletCtl argu) { + PigletExpr e = n.f1.accept(this, Default); + String s; + if (!e.isSimple()) { + nTemp++; + System.out.println("MOVE TEMP " + nTemp + " " + e.toString()); + s = "TEMP " + nTemp; + } else { + s = e.toString(); + } + return new PigletExpr(PigletExpr.Expr_t.Other, + "HALLOCATE " + s); + } + + /** + * f0 -> Operator() + * f1 -> Exp() + * f2 -> Exp() + */ + public PigletExpr visit(BinOp n, GenSpigletCtl argu) { + String op = BinOPs[n.f0.f0.which]; + String s1, s2; + PigletExpr t1 = n.f1.accept(this, Default); + PigletExpr t2 = n.f2.accept(this, Default); + /* the first expr can only be temp */ + if (!(t1.type==PigletExpr.Expr_t.Temp)) { + nTemp++; + System.out.println("MOVE TEMP " + nTemp + " " + t1.toString()); + s1 = "TEMP " + nTemp; + } else { + s1 = t1.toString(); + } + if (!t2.isSimple()) { + nTemp++; + System.out.println("MOVE TEMP " + nTemp + " " + t2.toString()); + s2 = "TEMP " + nTemp; + } else { + s2 = t2.toString(); + } + return new PigletExpr(PigletExpr.Expr_t.Other, + op + " " + s1 + " " + s2); + } + + /** + * f0 -> "LT" + * | "PLUS" + * | "MINUS" + * | "TIMES" + */ + public PigletExpr visit(Operator n, GenSpigletCtl argu) { + return null; + } + + /* the following are simple expressions + * these visitors return the expression string + */ + + /** + * f0 -> "TEMP" + * f1 -> IntegerLiteral() + */ + public PigletExpr visit(Temp n, GenSpigletCtl argu) { + return new PigletExpr(PigletExpr.Expr_t.Temp, + "TEMP " + n.f1.f0.toString()); + } + + /** + * f0 -> + */ + public PigletExpr visit(IntegerLiteral n, GenSpigletCtl argu) { + return new PigletExpr(PigletExpr.Expr_t.Int, n.f0.toString()); + } + + /** + * f0 -> + */ + public PigletExpr visit(Label n, GenSpigletCtl argu) { + return new PigletExpr(PigletExpr.Expr_t.Label, n.f0.toString()); + } + +} diff --git a/src/piglet/visitor/ScanTempVisitor.java b/src/piglet/visitor/ScanTempVisitor.java new file mode 100644 index 0000000..333c354 --- /dev/null +++ b/src/piglet/visitor/ScanTempVisitor.java @@ -0,0 +1,234 @@ +package piglet.visitor; + +import piglet.syntaxtree.BinOp; +import piglet.syntaxtree.CJumpStmt; +import piglet.syntaxtree.Call; +import piglet.syntaxtree.ErrorStmt; +import piglet.syntaxtree.Exp; +import piglet.syntaxtree.Goal; +import piglet.syntaxtree.HAllocate; +import piglet.syntaxtree.HLoadStmt; +import piglet.syntaxtree.HStoreStmt; +import piglet.syntaxtree.IntegerLiteral; +import piglet.syntaxtree.JumpStmt; +import piglet.syntaxtree.Label; +import piglet.syntaxtree.MoveStmt; +import piglet.syntaxtree.NoOpStmt; +import piglet.syntaxtree.Operator; +import piglet.syntaxtree.PrintStmt; +import piglet.syntaxtree.Procedure; +import piglet.syntaxtree.Stmt; +import piglet.syntaxtree.StmtExp; +import piglet.syntaxtree.StmtList; +import piglet.syntaxtree.Temp; + +public class ScanTempVisitor extends DepthFirstVisitor { + public int maxtmp = 0; + + /** + * f0 -> "MAIN" + * f1 -> StmtList() + * f2 -> "END" + * f3 -> ( Procedure() )* + * f4 -> + */ + public void visit(Goal n) { + n.f1.accept(this); + n.f3.accept(this); + } + + /** + * f0 -> ( ( Label() )? Stmt() )* + */ + public void visit(StmtList n) { + n.f0.accept(this); + } + + /** + * f0 -> Label() + * f1 -> "[" + * f2 -> IntegerLiteral() + * f3 -> "]" + * f4 -> StmtExp() + */ + public void visit(Procedure n) { + n.f4.accept(this); + } + + /** + * f0 -> NoOpStmt() + * | ErrorStmt() + * | CJumpStmt() + * | JumpStmt() + * | HStoreStmt() + * | HLoadStmt() + * | MoveStmt() + * | PrintStmt() + */ + public void visit(Stmt n) { + n.f0.accept(this); + } + + /** + * f0 -> "NOOP" + */ + public void visit(NoOpStmt n) { + return; + } + + /** + * f0 -> "ERROR" + */ + public void visit(ErrorStmt n) { + return; + } + + /** + * f0 -> "CJUMP" + * f1 -> Exp() + * f2 -> Label() + */ + public void visit(CJumpStmt n) { + n.f1.accept(this); + } + + /** + * f0 -> "JUMP" + * f1 -> Label() + */ + public void visit(JumpStmt n) { + return; + } + + /** + * f0 -> "HSTORE" + * f1 -> Exp() + * f2 -> IntegerLiteral() + * f3 -> Exp() + */ + public void visit(HStoreStmt n) { + n.f1.accept(this); + n.f3.accept(this); + } + + /** + * f0 -> "HLOAD" + * f1 -> Temp() + * f2 -> Exp() + * f3 -> IntegerLiteral() + */ + public void visit(HLoadStmt n) { + n.f1.accept(this); + n.f2.accept(this); + } + + /** + * f0 -> "MOVE" + * f1 -> Temp() + * f2 -> Exp() + */ + public void visit(MoveStmt n) { + n.f1.accept(this); + n.f2.accept(this); + } + + /** + * f0 -> "PRINT" + * f1 -> Exp() + */ + public void visit(PrintStmt n) { + n.f1.accept(this); + } + + /** + * f0 -> StmtExp() + * | Call() + * | HAllocate() + * | BinOp() + * | Temp() + * | IntegerLiteral() + * | Label() + */ + public void visit(Exp n) { + n.f0.accept(this); + } + + /** + * f0 -> "BEGIN" + * f1 -> StmtList() + * f2 -> "RETURN" + * f3 -> Exp() + * f4 -> "END" + */ + public void visit(StmtExp n) { + n.f1.accept(this); + n.f3.accept(this); + } + + /** + * f0 -> "CALL" + * f1 -> Exp() + * f2 -> "(" + * f3 -> ( Exp() )* + * f4 -> ")" + */ + public void visit(Call n) { + n.f1.accept(this); + n.f3.accept(this); + } + + /** + * f0 -> "HALLOCATE" + * f1 -> Exp() + */ + public void visit(HAllocate n) { + n.f1.accept(this); + } + + /** + * f0 -> Operator() + * f1 -> Exp() + * f2 -> Exp() + */ + public void visit(BinOp n) { + n.f1.accept(this); + n.f2.accept(this); + } + + /** + * f0 -> "LT" + * | "PLUS" + * | "MINUS" + * | "TIMES" + */ + public void visit(Operator n) { + return; + } + + /** + * f0 -> "TEMP" + * f1 -> IntegerLiteral() + */ + public void visit(Temp n) { + int x = Integer.parseInt(n.f1.f0.tokenImage); + //System.out.println(x); + if (x>maxtmp) { + maxtmp = x; + } + } + + /** + * f0 -> + */ + public void visit(IntegerLiteral n) { + return; + } + + /** + * f0 -> + */ + public void visit(Label n) { + return; + } + +} -- cgit v1.2.3