// Translatorvisitor.java
package semant;
import syntaxtree.*;
import util.*;
public class TranslatorVisitor extends visitor.ExpDepthFirstVisitor {
tree.Exp exp1 = null;
private SymbolTable classTable;
private frame.Frame currFrame;
private ClassInfo currClass;
private MethodInfo currMethod;
private tree.Exp currThis;
private Frag frags; // Linked list of accumlated fragments.
private boolean optimize; // Do we want to optimize?
public TranslatorVisitor(SymbolTable t, frame.Frame f, boolean optim) {
classTable = t;
currFrame = f;
currClass = null;
currMethod = null;
currThis = null;
frags = null;
optimize = optim;
}
public Frag getResult() {
// Reverse frags and return it.
Frag old = frags;
frags = null;
while (old != null) {
Frag temp = old.next;
old.next = frags;
frags = old;
old = temp;
}
return frags;
}
// Identifier i1,i2;
// Statement s;
public semant.Exp visit(MainClass n) {
String id = n.i1.toString();
System.err.println("Main CLass: "+n.i1.toString()+":"+n.i2.toString());
currClass = classTable.get(id);
currFrame = currFrame.newFrame(new temp.Label("main"), null);
semant.Exp body = n.s.accept(this);
procEntryExit(body, currFrame);
return null;
}
// int i;
public semant.Exp visit(IntegerLiteral n) {
return new Ex(new tree.CONST(n.i));
}
// Identifier i;
// Exp e;
public semant.Exp visit(Assign n){
tree.Exp exp1 = (n.e.accept(this)).unEx();
tree.Exp exp2 = (n.i.accept(this)).unEx();
VariableInfo vi;
return new Nx(new tree.MOVE(new tree.MEM(exp2), exp1));
}
// Exp e;
public semant.Exp visit(Print n) {
if (exp1 != null)
{
exp1 = (n.e.accept(this)).unEx();
}
//CALL to printInt
return new Ex(currFrame.externalCall("printInt", new tree.ExpList(exp1,null) ) );
}
// Identifier i;
// Exp e1,e2;
public semant.Exp visit(ArrayAssign n) {
tree.Exp exp1 = (n.e1.accept(this)).unEx();
tree.Exp exp2 = (n.e2.accept(this)).unEx();
tree.Exp expId = (n.i.accept(this)).unEx();
return new Nx(new tree.MOVE(new tree.BINOP(tree.BINOP.PLUS,new tree.MEM(expId), new tree.BINOP(tree.BINOP.MUL,exp1,new tree.CONST(4))), exp2));
}
// Now we have some auxiliary functions:
// Create a fragment for a function and add it to the front of frags.
private void procEntryExit(Exp body, frame.Frame funcFrame) {
if(funcFrame == null) {System.err.println("funcFrame is null");}
if(body == null) {System.err.println("body is null");}
//Body could be null !
if(body!=null){
}
else{
}
try{
Frag func = new ProcFrag(funcFrame.procEntryExit1(body.unNx()), funcFrame);
func.next = frags;
frags = func;
}
catch(Exception e){
System.err.println("Error Occured: "+e);
}
}
//********************************
/*
Identifier i;
Listvariables vl;
MethodDeclList ml;
*/
public semant.Exp visit(ClassDeclSimple n) {
String id = n.i.toString();
currClass = classTable.get(id);
currFrame = currFrame.newFrame(new temp.Label(id), null);
System.out.println("Before the for >>>>>>>>>>>>>>>>>>>>>>>>> ");
if (currClass == null)
{
System.out.println("Is NULL ***************************************** ");
// currClass = "EXP(CONST 0)";
}
if ((this != null)&&(currClass != null))
{
System.out.println("Is Not - Not NULL ====================================== ");
//Add field access info to symbol table
for (int i = 0; i < n.vl.size(); i++)
{
System.out.println("Inside the for --------------------------------- ");
// (currClass.getField(((VarDecl)n.vl.elementAt(i)).i.toString())).access = new InHeap(i * 4);//4 is the size
//System.out.println("Print the Access info: ------------->>>>>>>>>>>>>>> ");
//(currClass.getField(((VarDecl)n.vl.elementAt(i)).i.toString())).access = currFrame.FP();
}
for (int i = 0; i < n.ml.size(); i++)
{
semant.Exp methods = n.ml.elementAt(i).accept(this);
}
}
currClass = null;
return null;
}
// Exp e1,e2;
public semant.Exp visit(Minus n) {
tree.Exp exp1 = (n.e1.accept(this)).unEx();
tree.Exp exp2 = (n.e2.accept(this)).unEx();
return new Ex(new tree.BINOP(tree.BINOP.MINUS, exp1, exp2));
}
// Exp e1,e2;
public semant.Exp visit(Plus n) {
tree.Exp exp1 = (n.e1.accept(this)).unEx();
tree.Exp exp2 = (n.e2.accept(this)).unEx();
return new Ex(new tree.BINOP(tree.BINOP.PLUS, exp1, exp2));
}
// Exp e1,e2;
public semant.Exp visit(Times n) {
tree.Exp exp1 = (n.e1.accept(this)).unEx();
tree.Exp exp2 = (n.e2.accept(this)).unEx();
return new Ex(new tree.BINOP(tree.BINOP.MUL, exp1, exp2));
}
// Exp e1,e2;
/*public semant.Exp visit(LessThan n) {
Semant.Exp exp1 = n.e1.accept(this);
Semant.Exp exp2 = n.e2.accept(this);
return new Ex(new Tree.BINOP(Tree.BINOP.LT, exp1, exp2));
}*/
// Type t;
// Identifier i;
// FormalList fl;
// VarDeclList vl;
// StatementList sl;
// Exp e;
public semant.Exp visit(MethodDecl n) {
String id = n.i.toString();
currMethod = currClass.getMethod(id);
String fullName = currClass.getName() + "$" + id;
//RESET IT TO PRIOR FRAME AFTERWARDS?
System.out.println("---- step 1 ---- ");
currFrame.newFrame(new temp.Label(fullName), new BoolList(false, createFalseList(n.fl.size())) );
//STEP 2 fill in access info for formals and currThis
//currThis = new InHeap(0);//No Offset
for (int i = 0; i < n.fl.size(); i++)
{
System.out.println("---- step 2 ---- ");
//(currClass.getField(((Formal)n.fl.elementAt(i)).i.toString())).access = new InHeap(i * 4);//4 is the size
//semant.Exp expTemp = n.fl.elementAt(i).accept(this);
}
//STEP 3 call allocLocal(false) for all local variables then add this access to the symbol table
for (int ii = 0; ii < n.vl.size(); ii++)
{
System.out.println("---- step 3 ---- ");
// (currClass.getField(((VarDecl)n.vl.elementAt(ii)).i.toString())).access = currFrame.allocLocal(false);
//call allocLocal
//semant.Exp expTemp = n.vl.elementAt(i).accept(this);
}
//STEP 4 translate the body put it all in a SEQ and at the end add the MOVE for the return Exp e
for ( int i = 0; i < n.sl.size(); i++ ) {
//semant.Exp expTemp = n.sl.elementAt(i).accept(this);
}
//ASSUME EMPTY BLOCK
//STEP 5 generate a move to return the value to RVCallee()
//Exp body = new tree.SEQ(new tree.EXP(new tree.CONST(0)), new tree.MOVE( new tree.TEMP(currFrame.RVCallee()), (n.e.accept(this)).unEx() ));
//STEP 6 Call procEntryExit to add the code to the frags
//procEntryExit(body, currFrame);
return null;
}
//Creates a long SEQ
/*tree.SEQ createSEQList(StatementList sl, int size) {
if (size == 0) return new tree.SEQ(new tree.CONST(0));
else if (size == 1) return new tree.SEQ(sl.elementAt(0).accept(this));
}*/
//CReates all false boollist for formals
BoolList createFalseList(int size) {
if (size == 0) return null;
else return new BoolList(false, createFalseList(size-1));
}
// // // // //
private tree.Exp plus(tree.Exp e1, tree.Exp e2) {
return new tree.BINOP(tree.BINOP.PLUS, e1, e2);
}
private tree.Exp mul(tree.Exp e1, tree.Exp e2) {
return new tree.BINOP(tree.BINOP.MUL, e1, e2);
}
private tree.Exp minus(tree.Exp e1, tree.Exp e2){
return new tree.BINOP(tree.BINOP.MINUS, e1, e2);
}
/*
public tree.Exp visit(syntaxtree.True n) {
return new tree.CONST(1);
}
*/
// Finally, we have several nested auxiliary classes:
class InHeap extends frame.Access {
int offset;
InHeap(int o) {offset=o;}
// Here the base pointer will be the "this" pointer to the object.
public tree.Exp exp(tree.Exp basePtr) {
return new tree.MEM(plus(basePtr, new tree.CONST(offset)));
}
}
// The subclasses of semant.Exp (Ex, Nx, Cx, RelCx, IfThenElseExp, ...)
// naturally represent the various phrases of the abstract syntax.
// They let us hold off on generating tree code for a phrase until
// we see the *context* in which it is used.
class Ex extends Exp { // page 141
tree.Exp exp;
Ex(tree.Exp e) {exp=e;}
tree.Exp unEx() {return exp;}
tree.Stm unNx() {return new tree.EXP(exp);}
tree.Stm unCx(temp.Label t, temp.Label f) {
return new tree.CJUMP(tree.CJUMP.NE, exp, new tree.CONST(0), t, f);
}
}
class Nx extends Exp { // page 141
tree.Stm stm;
Nx(tree.Stm s) {stm=s;}
tree.Exp unEx() {throw new Error("unEx applied to Nx");}
tree.Stm unNx() {return stm;}
tree.Stm unCx(temp.Label t, temp.Label f) {
throw new Error("unCx applied to Nx");
}
}
abstract class Cx extends Exp { // page 142
tree.Exp unEx() {
temp.Temp r = new temp.Temp();
temp.Label t = new temp.Label();
temp.Label f = new temp.Label();
return new tree.ESEQ(
new tree.SEQ(new tree.MOVE(new tree.TEMP(r), new tree.CONST(1)),
new tree.SEQ(this.unCx(t,f),
new tree.SEQ(new tree.LABEL(f),
new tree.SEQ(new tree.MOVE(new tree.TEMP(r), new tree.CONST(0)),
new tree.LABEL(t))))),
new tree.TEMP(r));
}
abstract tree.Stm unCx(temp.Label t, temp.Label f);
tree.Stm unNx() {
temp.Label join = new temp.Label();
return new tree.SEQ(unCx(join, join),new tree.LABEL(join));
}
}
class RelCx extends Cx { // page 149
int relop;
tree.Exp left;
tree.Exp right;
RelCx(int rel, tree.Exp l, tree.Exp r) {relop=rel; left=l; right=r;}
tree.Stm unCx(temp.Label t, temp.Label f) {
return new tree.CJUMP(relop, left, right, t, f);
}
}
class IfThenElseExp extends Exp { // page 150
Exp cond, a, b;
temp.Label t = new temp.Label();
temp.Label f = new temp.Label();
temp.Label join = new temp.Label();
IfThenElseExp(Exp cc, Exp aa, Exp bb) {cond=cc; a=aa; b=bb;}
private tree.Stm SEQ(tree.Stm left, tree.Stm right) {
if (left == null)
return right;
if (right == null)
return left;
return new tree.SEQ(left, right);
}
private tree.LABEL LABEL(temp.Label l) {
return new tree.LABEL(l);
}
private tree.Exp ESEQ(tree.Stm stm, tree.Exp exp) {
if (stm == null) return exp;
return new tree.ESEQ(stm, exp);
}
private tree.Stm MOVE(tree.Exp dst, tree.Exp src) {
return new tree.MOVE(dst, src);
}
private tree.Stm JUMP(temp.Label l) {
return new tree.JUMP(l);
}
private tree.Exp TEMP(temp.Temp t) {
return new tree.TEMP(t);
}
tree.Exp unEx() {
tree.Exp aExp = a.unEx();
if (aExp == null)
return null;
tree.Exp bExp = b.unEx();
if (bExp == null)
return null;
temp.Temp r = new temp.Temp();
return new tree.ESEQ(new tree.SEQ(new tree.SEQ(cond.unCx(t, f),
new tree.SEQ(new tree.SEQ(new tree.LABEL(t),
new tree.SEQ(new tree.MOVE(new tree.TEMP(r), aExp),
new tree.JUMP(join))),
new tree.SEQ(new tree.LABEL(f),
new tree.SEQ(new tree.MOVE(new tree.TEMP(r), bExp),
new tree.JUMP(join))))),
new tree.LABEL(join)),
new tree.TEMP(r));
}
tree.Stm unNx() {
tree.Stm aStm = a.unNx();
if (aStm == null)
t = join;
else
aStm = SEQ(SEQ(LABEL(t), aStm), JUMP(join));
tree.Stm bStm = b.unNx();
if (bStm == null)
f = join;
else
bStm = SEQ(SEQ(LABEL(f), bStm), JUMP(join));
if (aStm == null && bStm == null)
return cond.unNx();
tree.Stm condStm = cond.unCx(t, f);
if (aStm == null)
return new tree.SEQ(
new tree.SEQ(condStm, bStm),
new tree.LABEL(join));
if (bStm == null)
return new tree.SEQ(new tree.SEQ(condStm, aStm),new tree.LABEL(join));
return new tree.SEQ(new tree.SEQ(condStm, new tree.SEQ(aStm, bStm)), new tree.LABEL(join));
}
tree.Stm unCx(temp.Label tt, temp.Label ff) {
tree.Stm aStm = a.unCx(tt, ff);
if (aStm instanceof tree.JUMP) {
tree.JUMP aJump = (tree.JUMP)aStm;
if (aJump.exp instanceof tree.NAME) {
tree.NAME aName = (tree.NAME)aJump.exp;
aStm = null;
t = aName.label;
}
}
tree.Stm bStm = b.unCx(tt, ff);
if (bStm instanceof tree.JUMP) {
tree.JUMP bJump = (tree.JUMP)bStm;
if (bJump.exp instanceof tree.NAME) {
tree.NAME bName = (tree.NAME)bJump.exp;
bStm = null;
f = bName.label;
}
}
tree.Stm condStm = cond.unCx(t, f);
if (aStm == null && bStm == null)
return condStm;
if (aStm == null)
return new tree.SEQ(condStm, new tree.SEQ(new tree.LABEL(f), bStm));
if (bStm == null)
return new tree.SEQ(condStm, new tree.SEQ(new tree.LABEL(t), aStm));
return new tree.SEQ(condStm,
new tree.SEQ(new tree.SEQ(new tree.LABEL(t), aStm),
new tree.SEQ(new tree.LABEL(f), bStm)));
}
}
}
www.cpccci.com
www.cpcwebsolutions.com
www.cpcwebdevelopment.com