summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2014-11-03 01:46:06 +0800
committerIru Cai <mytbk920423@gmail.com>2014-11-03 01:46:06 +0800
commit5fa82beb2b420cc63111c186a670abcb674ba373 (patch)
tree7c16037088e74216ca0e146602b8653ab1cbf898
parent400909d160c5a348f1f4015add94a69fa1855cfd (diff)
downloadminijava-5fa82beb2b420cc63111c186a670abcb674ba373.tar.xz
piglet to spiglet
-rw-r--r--src/piglet/piglet2spiglet/GenSpigletCtl.java25
-rw-r--r--src/piglet/piglet2spiglet/Main.java11
-rw-r--r--src/piglet/piglet2spiglet/PigletExpr.java19
-rw-r--r--src/piglet/visitor/GenSpigletVisitor.java382
-rw-r--r--src/piglet/visitor/ScanTempVisitor.java234
5 files changed, 667 insertions, 4 deletions
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<PigletExpr> call_list;
+
+ public GenSpigletCtl(Control _c) {
+ c = _c;
+ call_list = new Vector<PigletExpr>();
+ }
+ 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<Object,Object>() {
- };
- //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<PigletExpr, GenSpigletCtl> {
+
+ 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 -> <EOF>
+ */
+ 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<String> args = new Vector<String>();
+ for (int i=0; i<ctl.call_list.size(); i++) {
+ String s = expr_to_tmp(ctl.call_list.elementAt(i));
+ args.add(s);
+ }
+ result += "CALL " + tm + "( ";
+ for (int i=0; i<args.size(); i++) {
+ result += args.elementAt(i) + " ";
+ }
+ result += ")";
+ return new PigletExpr(PigletExpr.Expr_t.Other, result);
+ }
+
+ /**
+ * f0 -> "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 -> <INTEGER_LITERAL>
+ */
+ public PigletExpr visit(IntegerLiteral n, GenSpigletCtl argu) {
+ return new PigletExpr(PigletExpr.Expr_t.Int, n.f0.toString());
+ }
+
+ /**
+ * f0 -> <IDENTIFIER>
+ */
+ 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 -> <EOF>
+ */
+ 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 -> <INTEGER_LITERAL>
+ */
+ public void visit(IntegerLiteral n) {
+ return;
+ }
+
+ /**
+ * f0 -> <IDENTIFIER>
+ */
+ public void visit(Label n) {
+ return;
+ }
+
+}