this.operation=parseOp(op);
}
+ public Operation getBaseOp() {
+ switch(operation) {
+ case EQ:
+ return null;
+ case MULTEQ:
+ return new Operation(Operation.MULT);
+ case DIVEQ:
+ return new Operation(Operation.DIV);
+ case MODEQ:
+ return new Operation(Operation.MOD);
+ case PLUSEQ:
+ return new Operation(Operation.ADD);
+ case MINUSEQ:
+ return new Operation(Operation.SUB);
+ case LSHIFTEQ:
+ return new Operation(Operation.LEFTSHIFT);
+ case RSHIFTEQ:
+ return new Operation(Operation.RIGHTSHIFT);
+ case ANDEQ:
+ return new Operation(Operation.BIT_AND);
+ case XOREQ:
+ return new Operation(Operation.BIT_XOR);
+ case OREQ:
+ return new Operation(Operation.BIT_OR);
+ }
+ throw new Error();
+ }
+
public static int parseOp(String st) {
if (st.equals("eq"))
return EQ;
package IR;
import java.util.*;
import IR.Tree.*;
+import IR.SymbolTable;
import IR.FieldDescriptor;
import IR.MethodDescriptor;
import IR.NameDescriptor;
-public class ClassDescriptor {
- public ClassDescriptor() {
- classname=null;
+public class ClassDescriptor extends Descriptor {
+ public ClassDescriptor(String classname) {
+ super(classname);
+ this.classname=classname;
superclass=null;
- fields=new Vector();
- methods=new Vector();
+ fields=new SymbolTable();
+ methods=new SymbolTable();
}
+
String classname;
- NameDescriptor superclass;
+ String superclass;
Modifiers modifiers;
- Vector fields;
- Vector methods;
+
+ SymbolTable fields;
+ SymbolTable methods;
+
public Iterator getMethods() {
- return methods.iterator();
+ return methods.getDescriptorsIterator();
+ }
+
+ public Iterator getFields() {
+ return fields.getDescriptorsIterator();
}
+ public SymbolTable getFieldTable() {
+ return fields;
+ }
+
public String printTree(State state) {
int indent;
String st=modifiers.toString()+"class "+classname;
st+="extends "+superclass.toString();
st+=" {\n";
indent=TreeNode.INDENT;
- for(int i=0;i<fields.size();i++) {
- FieldDescriptor fd=(FieldDescriptor)fields.get(i);
+
+ for(Iterator it=getFields();it.hasNext();) {
+ FieldDescriptor fd=(FieldDescriptor)it.next();
st+=TreeNode.printSpace(indent)+fd.toString()+"\n";
}
if (fields.size()>0)
st+="\n";
- for(int i=0;i<methods.size();i++) {
- MethodDescriptor md=(MethodDescriptor)methods.get(i);
+ for(Iterator it=getMethods();it.hasNext();) {
+ MethodDescriptor md=(MethodDescriptor)it.next();
st+=TreeNode.printSpace(indent)+md.toString()+" ";
BlockNode bn=state.getMethodBody(md);
st+=bn.printNode(indent)+"\n\n";
}
public void addField(FieldDescriptor fd) {
+ if (fields.contains(fd.getSymbol()))
+ throw new Error(fd.getSymbol()+" already defined");
fields.add(fd);
}
classname=name;
}
- public void setSuper(NameDescriptor superclass) {
+ public void setSuper(String superclass) {
this.superclass=superclass;
}
}
this.uniqueid=count++;
}
+ public TypeDescriptor getType() {
+ return td;
+ }
+
public String toString() {
if (en==null)
return modifier.toString()+td.toString()+" "+identifier+";";
}
public void buildFlat() {
- Iterator it=state.classset.iterator();
+ Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
while(it.hasNext()) {
ClassDescriptor cn=(ClassDescriptor)it.next();
flattenClass(cn);
return flattenExpressionNode(en.getExpression(),tmp);
}
- private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
- throw new Error();
+ private NodePair flattenCastNode(CastNode cn,TempDescriptor out_temp) {
+ TempDescriptor tmp=TempDescriptor.tempFactory("tocast");
+ NodePair np=flattenExpressionNode(cn.getExpression(), tmp);
+ FlatCastNode fcn=new FlatCastNode(cn.getType(), tmp, out_temp);
+ np.getEnd().addNext(fcn);
+ return new NodePair(np.getBegin(),fcn);
}
- private NodePair flattenCastNode(CastNode cn,TempDescriptor out_temp) {
- throw new Error();
+ private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
+ FlatLiteralNode fln=new FlatLiteralNode(ln.getType(), ln.getValue(), out_temp);
+ return new NodePair(fln,fln);
}
+
private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
- throw new Error();
+ TypeDescriptor td=con.getType();
+ FlatNew fn=new FlatNew(td, out_temp);
+ TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
+ FlatNode last=fn;
+ //Build arguments
+ for(int i=0;i<con.numArgs();i++) {
+ ExpressionNode en=con.getArg(i);
+ TempDescriptor tmp=TempDescriptor.tempFactory("arg");
+ temps[i]=tmp;
+ NodePair np=flattenExpressionNode(en, tmp);
+ last.addNext(np.getBegin());
+ last=np.getEnd();
+ }
+ MethodDescriptor md=con.getConstructor();
+ //Call to constructor
+ FlatCall fc=new FlatCall(md, null, out_temp, temps);
+ last.addNext(fc);
+ return new NodePair(fn,fc);
}
- private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
- throw new Error();
+ private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
+ TempDescriptor[] temps=new TempDescriptor[min.numArgs()];
+ FlatNode first=null;
+ FlatNode last=null;
+ TempDescriptor thisarg=null;
+
+ if (min.getExpression()==null) {
+ thisarg=TempDescriptor.tempFactory("thisarg");
+ NodePair np=flattenExpressionNode(min.getExpression(),temps[0]);
+ first=np.getBegin();
+ last=np.getEnd();
+ }
+
+ //Build arguments
+ for(int i=0;i<min.numArgs();i++) {
+ ExpressionNode en=min.getArg(i);
+ TempDescriptor td=TempDescriptor.tempFactory("arg");
+ temps[i]=td;
+ NodePair np=flattenExpressionNode(en, td);
+ if (first==null)
+ first=np.getBegin();
+ else
+ last.addNext(np.getBegin());
+ last=np.getEnd();
+ }
+
+ MethodDescriptor md=min.getMethod();
+
+ //Call to constructor
+ FlatCall fc=new FlatCall(md, out_temp, thisarg, temps);
+ if (first==null) {
+ first=fc;
+ } else
+ last.addNext(fc);
+ return new NodePair(first,fc);
}
- private NodePair flattenLiteralNode(LiteralNode ln,TempDescriptor out_temp) {
- throw new Error();
+ private NodePair flattenFieldAccessNode(FieldAccessNode fan,TempDescriptor out_temp) {
+ TempDescriptor tmp=TempDescriptor.tempFactory("temp");
+ NodePair npe=flattenExpressionNode(fan.getExpression(),tmp);
+ FlatFieldNode fn=new FlatFieldNode(fan.getField(),tmp,out_temp);
+ npe.getEnd().addNext(fn);
+ return new NodePair(npe.getBegin(),fn);
}
- private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
+ private NodePair flattenAssignmentNode(AssignmentNode an,TempDescriptor out_temp) {
+ // Two cases:
+ // left side is variable
+ // left side is field
+
+ Operation base=an.getOperation().getBaseOp();
+ TempDescriptor src_tmp=TempDescriptor.tempFactory("src");
+ NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
+ FlatNode last=np_src.getEnd();
+ if (base!=null) {
+ TempDescriptor src_tmp2=TempDescriptor.tempFactory("tmp");
+ NodePair np_dst_init=flattenExpressionNode(an.getDest(),src_tmp2);
+ last.addNext(np_dst_init.getBegin());
+ TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst_tmp");
+ FlatOpNode fon=new FlatOpNode(dst_tmp, src_tmp,src_tmp2, base);
+ np_dst_init.getEnd().addNext(fon);
+ last=fon;
+ src_tmp=dst_tmp;
+ }
+
+ if (an.getDest().kind()==Kind.FieldAccessNode) {
+ FieldAccessNode fan=(FieldAccessNode)an.getDest();
+
+
+ // Need to assign field
+ } else if (an.getDest().kind()==Kind.NameNode) {
+
+ }
throw new Error();
}
--- /dev/null
+package IR.Flat;
+import IR.MethodDescriptor;
+
+public class FlatCall extends FlatNode {
+ TempDescriptor args[];
+ TempDescriptor this_temp;
+ TempDescriptor dst;
+ MethodDescriptor method;
+
+ public FlatCall(MethodDescriptor md, TempDescriptor dst, TempDescriptor this_temp, TempDescriptor[] args) {
+ this.method=md;
+ this.dst=dst;
+ this.this_temp=this_temp;
+ this.args=args;
+ }
+
+ public String toString() {
+ String st=dst+"="+method.toString()+"("+this_temp;
+ for(int i=0;i<args.length;i++) {
+ st+=args[i].toString();
+ if ((i+1)<args.length)
+ st+=", ";
+ }
+ return st+")";
+ }
+}
--- /dev/null
+package IR.Flat;
+import IR.TypeDescriptor;
+
+public class FlatCastNode extends FlatNode {
+ TempDescriptor src;
+ TempDescriptor dst;
+ TypeDescriptor type;
+
+ public FlatCastNode(TypeDescriptor type, TempDescriptor src, TempDescriptor dst) {
+ this.type=type;
+ this.src=src;
+ this.dst=dst;
+ }
+
+ public String toString() {
+ return dst.toString()+"=("+type.toString()+")"+src.toString();
+ }
+}
public void addTrueNext(FlatNode n) {
next.setElementAt(n,0);
+ n.addPrev(this);
}
public void addFalseNext(FlatNode n) {
next.setElementAt(n,1);
+ n.addPrev(this);
+ }
+
+ public String toString() {
+ return "conditional branch";
+ }
+
+ public String toString(String negjump) {
+ return "if (!"+test_cond.toString()+") goto "+negjump;
}
public void addNext(FlatNode n) {
--- /dev/null
+package IR.Flat;
+import IR.FieldDescriptor;
+
+public class FlatFieldNode extends FlatNode {
+ TempDescriptor src;
+ TempDescriptor dst;
+ FieldDescriptor field;
+
+ public FlatFieldNode(FieldDescriptor field, TempDescriptor src, TempDescriptor dst) {
+ this.field=field;
+ this.src=src;
+ this.dst=dst;
+ }
+
+ public FieldDescriptor getField() {
+ return field;
+ }
+
+ public String toString() {
+ return dst.toString()+"="+src.toString()+"."+field.toString();
+ }
+}
--- /dev/null
+package IR.Flat;
+import IR.TypeDescriptor;
+
+public class FlatLiteralNode extends FlatNode {
+ Object value;
+ TypeDescriptor type;
+ TempDescriptor dst;
+
+ public FlatLiteralNode(TypeDescriptor type, Object o, TempDescriptor dst) {
+ this.type=type;
+ value=o;
+ this.dst=dst;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public String printNode(int indent) {
+ /* if (type==NULL)
+ return dst+"=null";
+ if (type==STRING) {
+ return dst+"="+'"'+escapeString(value.toString())+'"';
+ }*/
+ //return dst+"="+"/*"+getType()+ "*/"+value.toString();
+ return "";
+ }
+ private static String escapeString(String st) {
+ String new_st="";
+ for(int i=0;i<st.length();i++) {
+ char x=st.charAt(i);
+ if (x=='\n')
+ new_st+="\\n";
+ else if (x=='"')
+ new_st+="'"+'"'+"'";
+ else new_st+=x;
+ }
+ return new_st;
+ }
+}
package IR.Flat;
import IR.MethodDescriptor;
+import java.util.*;
public class FlatMethod extends FlatNode {
FlatNode method_entry;
}
public String toString() {
- return method.toString()+"\n"+method_entry.toString();
+ return method.toString();
}
+
+ public String printMethod() {
+ String st="";
+ HashSet tovisit=new HashSet();
+ HashSet visited=new HashSet();
+ int labelindex=0;
+ Hashtable nodetolabel=new Hashtable();
+ tovisit.add(method_entry);
+ FlatNode current_node=null;
+ //Assign labels 1st
+ //Node needs a label if it is
+ while(!tovisit.isEmpty()) {
+ FlatNode fn=(FlatNode)tovisit.iterator().next();
+ tovisit.remove(fn);
+ visited.add(fn);
+ for(int i=0;i<fn.numNext();i++) {
+ FlatNode nn=fn.getNext(i);
+ if(i>0) {
+ //1) Edge >1 of node
+ nodetolabel.put(nn,new Integer(labelindex++));
+ }
+ if (!visited.contains(nn)) {
+ tovisit.add(nn);
+ } else {
+ //2) Join point
+ nodetolabel.put(nn,new Integer(labelindex++));
+ }
+ }
+ }
+
+ //Do the actual printing
+ tovisit=new HashSet();
+ visited=new HashSet();
+ tovisit.add(method_entry);
+ while(!tovisit.isEmpty()) {
+ if (current_node==null) {
+ current_node=(FlatNode)tovisit.iterator().next();
+ tovisit.remove(current_node);
+ }
+ visited.add(current_node);
+ if (nodetolabel.containsKey(current_node))
+ st+="L"+nodetolabel.get(current_node)+":\n";
+ st+=current_node.toString();
+ if (current_node.numNext()==0) {
+ current_node=null;
+ } else if(current_node.numNext()==1) {
+ FlatNode nextnode=current_node.getNext(0);
+ if (visited.contains(nextnode)) {
+ st+="goto L"+nodetolabel.get(nextnode)+"\n";
+ current_node=null;
+ } else
+ current_node=nextnode;
+ } else if (current_node.numNext()==2) {
+ /* Branch */
+ st+=((FlatCondBranch)current_node).toString("L"+nodetolabel.get(current_node.getNext(1)));
+ if (visited.contains(current_node.getNext(0))) {
+ st+="goto L"+nodetolabel.get(current_node.getNext(0))+"\n";
+ current_node=null;
+ } else
+ current_node=current_node.getNext(0);
+ if (!visited.contains(current_node.getNext(1)))
+ tovisit.add(current_node.getNext(1));
+ } else throw new Error();
+ }
+ return st;
+ }
+
}
--- /dev/null
+package IR.Flat;
+import IR.TypeDescriptor;
+
+public class FlatNew extends FlatNode {
+ TempDescriptor dst;
+ TypeDescriptor type;
+
+ public FlatNew(TypeDescriptor type, TempDescriptor dst) {
+ this.type=type;
+ this.dst=dst;
+ }
+
+ public String toString() {
+ return dst.toString()+"= NEW "+type.toString();
+ }
+}
import java.util.Vector;
public class FlatNode {
- Vector next;
-
+ protected Vector next;
+ protected Vector prev;
public String toString() {
throw new Error();
}
+ public int numNext() {
+ return next.size();
+ }
+ public FlatNode getNext(int i) {
+ return (FlatNode) next.get(i);
+ }
+
+ public int numPrev() {
+ return prev.size();
+ }
+ public FlatNode getPrev(int i) {
+ return (FlatNode) prev.get(i);
+ }
+
public void addNext(FlatNode n) {
next.add(n);
+ n.addPrev(this);
+ }
+ protected void addPrev(FlatNode p) {
+ prev.add(p);
}
}
protected String identifier;
protected Vector param_name;
protected Vector param_type;
+ protected SymbolTable paramtable;
public MethodDescriptor(Modifiers m, TypeDescriptor rt, String identifier) {
super(identifier);
this.uniqueid=count++;
param_name=new Vector();
param_type=new Vector();
+ paramtable=new SymbolTable();
}
+ public TypeDescriptor getReturnType() {
+ return returntype;
+ }
+
+ public SymbolTable getParameterTable() {
+ return paramtable;
+ }
+
public void addParameter(TypeDescriptor type, String paramname) {
param_name.add(paramname);
param_type.add(type);
+ if (paramtable.getFromSameScope(paramname)!=null) {
+ throw new Error("Parameter "+paramname+" already defined");
+ }
+ paramtable.add(paramname,type);
+ }
+
+ public int numParameters() {
+ return param_name.size();
+ }
+
+ public String getParamName(int i) {
+ return (String) param_name.get(i);
+ }
+
+ public TypeDescriptor getParamType(int i) {
+ return (TypeDescriptor) param_type.get(i);
}
public String toString() {
public class State {
public State(ParseNode parsetree) {
- globals=new SymbolTable();
this.parsetree=parsetree;
- this.classset=new HashSet();
+ this.classes=new SymbolTable();
this.treemethodmap=new Hashtable();
this.flatmethodmap=new Hashtable();
}
- public SymbolTable globals;
+ public SymbolTable classes;
public ParseNode parsetree;
- public HashSet classset;
public Hashtable treemethodmap;
public Hashtable flatmethodmap;
}
public void addClass(ClassDescriptor tdn) {
- classset.add(tdn);
+ if (classes.contains(tdn.getSymbol()))
+ throw new Error("Class "+tdn.getSymbol()+" defined twice");
+ classes.add(tdn);
}
public BlockNode getMethodBody(MethodDescriptor md) {
return (BlockNode)treemethodmap.get(md);
-
+ }
+
+ public SymbolTable getClassSymbolTable() {
+ return classes;
}
public FlatMethod getMethodFlat(MethodDescriptor md) {
this.parent = parent;
}
- //public void add(String name, Descriptor d) {
- //table.put(name, d);
- //}
-
public void add(Descriptor d) {
- table.put(d.getSymbol(), d);
+ add(d.getSymbol(), d);
}
public void add(String name, Descriptor d) {
table.put(name, d);
-
}
public void dump() {
return table.keys();
}
+ public Iterator getNamesIterator() {
+ return table.keySet().iterator();
+ }
+
public Enumeration getDescriptors() {
return table.elements();
}
+ public Iterator getDescriptorsIterator() {
+ return table.values().iterator();
+ }
+
public Iterator descriptors() {
return table.values().iterator();
}
right=r;
this.op=op;
}
+
+ public ExpressionNode getDest() {
+ return left;
+ }
+
+ public ExpressionNode getSrc() {
+ return right;
+ }
+
+ public AssignOperation getOperation() {
+ return op;
+ }
public String printNode(int indent) {
return left.printNode(indent)+" "+op.toString()+" "+right.printNode(indent);
package IR.Tree;
import java.util.Vector;
+import IR.*;
public class BlockNode extends TreeNode {
Vector blockstatements;
int printStyle=0;
+ protected SymbolTable table;
+
public final static int NORMAL=0;
public final static int NOBRACES=1;
public final static int EXPRLIST=2;
public BlockNode() {
blockstatements=new Vector();
+ table=new SymbolTable();
+ }
+
+ public SymbolTable getVarTable() {
+ return table;
}
public void addBlockStatement(BlockStatementNode bsn) {
public ClassDescriptor parseTypeDecl(ParseNode pn) {
if (isNode(pn, "class_declaration")) {
- ClassDescriptor cn=new ClassDescriptor();
- cn.setName(pn.getChild("name").getTerminal());
+ ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal());
if (!isEmpty(pn.getChild("super").getTerminal())) {
/* parse superclass name */
+ ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
+ NameDescriptor nd=parseName(snn);
+ cn.setSuper(nd.toString());
}
cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
parseClassBody(cn, pn.getChild("classbody"));
ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
blockstatements.add(new LoopNode(init,condition,update,body));
+ } else if (isNode(pn,"whilestatement")) {
+ ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
+ BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
+ blockstatements.add(new LoopNode(condition,body,LoopNode.WHILELOOP));
+ } else if (isNode(pn,"dowhilestatement")) {
+ ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
+ BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
+ blockstatements.add(new LoopNode(condition,body,LoopNode.DOWHILELOOP));
} else {
System.out.println("---------------");
System.out.println(pn.PPrint(3,true));
this.etd=type;
}
+ public TypeDescriptor getType() {
+ return td;
+ }
+
+ public ExpressionNode getExpression() {
+ return exp;
+ }
+
public String printNode(int indentlevel) {
if (etd==null)
return "("+td.toString()+")"+exp.printNode(indentlevel);
package IR.Tree;
import java.util.Vector;
import IR.TypeDescriptor;
+import IR.MethodDescriptor;
public class CreateObjectNode extends ExpressionNode {
TypeDescriptor td;
Vector argumentlist;
+ MethodDescriptor md;
public CreateObjectNode(TypeDescriptor type) {
td=type;
argumentlist.add(en);
}
+ public void setConstructor(MethodDescriptor md) {
+ this.md=md;
+ }
+
+ public MethodDescriptor getConstructor() {
+ return md;
+ }
+
+ public TypeDescriptor getType() {
+ return td;
+ }
+
+ public int numArgs() {
+ return argumentlist.size();
+ }
+
+ public ExpressionNode getArg(int i) {
+ return (ExpressionNode) argumentlist.get(i);
+ }
+
public String printNode(int indent) {
String st="new "+td.toString()+"(";
for(int i=0;i<argumentlist.size();i++) {
package IR.Tree;
+import IR.TypeDescriptor;
public class ExpressionNode extends TreeNode {
+ public TypeDescriptor getType() {
+ throw new Error();
+ }
public String printNode(int indentlevel) {
return null;
package IR.Tree;
+import IR.FieldDescriptor;
public class FieldAccessNode extends ExpressionNode {
ExpressionNode left;
String fieldname;
+ FieldDescriptor field;
public FieldAccessNode(ExpressionNode l, String field) {
fieldname=field;
left=l;
}
+ public void setField(FieldDescriptor fd) {
+ field=fd;
+ }
+
+ public FieldDescriptor getField() {
+ return field;
+ }
+
+ public ExpressionNode getExpression() {
+ return left;
+ }
+
public String printNode(int indent) {
return left.printNode(indent)+"."+fieldname;
}
public final static int STRING=5;
public final static int NULL=6;
-
Object value;
int type;
value=o;
}
+ public Object getValue() {
+ return value;
+ }
+
private static int parseType(String type) {
if (type.equals("integer"))
return INTEGER;
else throw new Error();
}
- private String getType() {
+ private String getStringType() {
if (type==INTEGER)
return "integer";
else if (type==FLOAT)
package IR.Tree;
import java.util.Vector;
import IR.NameDescriptor;
+import IR.MethodDescriptor;
public class MethodInvokeNode extends ExpressionNode {
NameDescriptor nd;
Vector argumentlist;
String methodid;
ExpressionNode en;
+ MethodDescriptor md;
public MethodInvokeNode(NameDescriptor name) {
nd=name;
argumentlist=new Vector();
methodid=null;
en=null;
+ md=null;
}
public MethodInvokeNode(String methodid, ExpressionNode exp) {
this.en=exp;
nd=null;
argumentlist=new Vector();
+ md=null;
+ }
+
+ public ExpressionNode getExpression() {
+ return en;
+ }
+
+ public void setMethod(MethodDescriptor md) {
+ this.md=md;
+ }
+
+ public MethodDescriptor getMethod() {
+ return md;
}
public void addArgument(ExpressionNode en) {
argumentlist.add(en);
}
+ public int numArgs() {
+ return argumentlist.size();
+ }
+
+ public ExpressionNode getArg(int i) {
+ return (ExpressionNode) argumentlist.get(i);
+ }
+
public String printNode(int indent) {
String st;
if (nd==null) {
--- /dev/null
+package IR.Tree;
+
+import java.util.*;
+import IR.*;
+
+public class SemanticCheck {
+ State state;
+
+ public SemanticCheck(State state) {
+ this.state=state;
+ }
+
+ public void semanticCheck() {
+ SymbolTable classtable=state.getClassSymbolTable();
+ Iterator it=classtable.getDescriptorsIterator();
+ while(it.hasNext()) {
+ ClassDescriptor cd=(ClassDescriptor)it.next();
+ System.out.println("Checking class: "+cd);
+ for(Iterator field_it=cd.getFields();field_it.hasNext();) {
+ FieldDescriptor fd=(FieldDescriptor)field_it.next();
+ System.out.println("Checking field: "+fd);
+ checkField(cd,fd);
+ }
+
+ for(Iterator method_it=cd.getMethods();method_it.hasNext();) {
+ MethodDescriptor md=(MethodDescriptor)method_it.next();
+ checkMethod(cd,md);
+ }
+ }
+ }
+
+ public void checkTypeDescriptor(TypeDescriptor td) {
+ if (td.isPrimitive())
+ return; /* Done */
+ if (td.isClass()) {
+ String name=td.toString();
+ ClassDescriptor field_cd=(ClassDescriptor)state.getClassSymbolTable().get(name);
+ if (field_cd==null)
+ throw new Error("Undefined class "+name);
+ td.setClassDescriptor(field_cd);
+ return;
+ }
+ throw new Error();
+ }
+
+ public void checkField(ClassDescriptor cd, FieldDescriptor fd) {
+ checkTypeDescriptor(fd.getType());
+ }
+
+ public void checkMethod(ClassDescriptor cd, MethodDescriptor md) {
+ /* Check return type */
+ if (!md.getReturnType().isVoid())
+ checkTypeDescriptor(md.getReturnType());
+ for(int i=0;i<md.numParameters();i++) {
+ TypeDescriptor param_type=md.getParamType(i);
+ checkTypeDescriptor(param_type);
+ }
+ BlockNode bn=state.getMethodBody(md);
+ /* Link the naming environments */
+ md.getParameterTable().setParent(cd.getFieldTable());
+ checkBlockNode(md, md.getParameterTable(),bn);
+ }
+
+ public void checkBlockNode(MethodDescriptor md, SymbolTable nametable, BlockNode bn) {
+ /* Link in the naming environment */
+ bn.getVarTable().setParent(nametable);
+ for(int i=0;i<bn.size();i++) {
+ BlockStatementNode bsn=bn.get(i);
+ checkBlockStatementNode(md, bn.getVarTable(),bsn);
+ }
+ }
+
+ public void checkBlockStatementNode(MethodDescriptor md, SymbolTable nametable, BlockStatementNode bsn) {
+ switch(bsn.kind()) {
+ case Kind.BlockExpressionNode:
+ checkBlockExpressionNode(md, nametable,(BlockExpressionNode)bsn);
+ return;
+
+ case Kind.DeclarationNode:
+ checkDeclarationNode(md, nametable, (DeclarationNode)bsn);
+ return;
+
+ case Kind.IfStatementNode:
+ checkIfStatementNode(md, nametable, (IfStatementNode)bsn);
+ return;
+
+ case Kind.LoopNode:
+ checkLoopNode(md, nametable, (LoopNode)bsn);
+ return;
+
+ case Kind.ReturnNode:
+ checkReturnNode(md, nametable, (ReturnNode)bsn);
+ return;
+
+ case Kind.SubBlockNode:
+ checkSubBlockNode(md, nametable, (SubBlockNode)bsn);
+ return;
+ }
+ throw new Error();
+ }
+
+ void checkBlockExpressionNode(MethodDescriptor md, SymbolTable nametable, BlockExpressionNode ben) {
+ checkExpressionNode(md, nametable, ben.getExpression(), null);
+ }
+
+ void checkDeclarationNode(MethodDescriptor md, SymbolTable nametable, DeclarationNode dn) {
+ VarDescriptor vd=dn.getVarDescriptor();
+ checkTypeDescriptor(vd.getType());
+ Descriptor d=nametable.get(vd.getSymbol());
+ if ((d==null)||
+ (d instanceof FieldDescriptor)) {
+ nametable.add(vd);
+ } else
+ throw new Error(vd.getSymbol()+" defined a second time");
+ checkExpressionNode(md, nametable, dn.getExpression(), vd.getType());
+ }
+
+ void checkSubBlockNode(MethodDescriptor md, SymbolTable nametable, SubBlockNode sbn) {
+ checkBlockNode(md, nametable, sbn.getBlockNode());
+ }
+
+ void checkReturnNode(MethodDescriptor md, SymbolTable nametable, ReturnNode rn) {
+ checkExpressionNode(md, nametable, rn.getReturnExpression(), md.getReturnType());
+ }
+
+ void checkIfStatementNode(MethodDescriptor md, SymbolTable nametable, IfStatementNode isn) {
+ checkExpressionNode(md, nametable, isn.getCondition(), new TypeDescriptor(TypeDescriptor.BOOLEAN));
+ checkBlockNode(md, nametable, isn.getTrueBlock());
+ checkBlockNode(md, nametable, isn.getFalseBlock());
+ }
+
+ void checkExpressionNode(MethodDescriptor md, SymbolTable nametable, ExpressionNode en, TypeDescriptor td) {
+ switch(en.kind()) {
+ case Kind.AssignmentNode:
+ checkAssignmentNode(md,nametable,(AssignmentNode)en,td);
+ return;
+ case Kind.CastNode:
+ checkCastNode(md,nametable,(CastNode)en,td);
+ return;
+ case Kind.CreateObjectNode:
+ checkCreateObjectNode(md,nametable,(CreateObjectNode)en,td);
+ return;
+ case Kind.FieldAccessNode:
+ checkFieldAccessNode(md,nametable,(FieldAccessNode)en,td);
+ return;
+ case Kind.LiteralNode:
+ checkLiteralNode(md,nametable,(LiteralNode)en,td);
+ return;
+ case Kind.MethodInvokeNode:
+ checkMethodInvokeNode(md,nametable,(MethodInvokeNode)en,td);
+ return;
+ case Kind.NameNode:
+ checkNameNode(md,nametable,(NameNode)en,td);
+ return;
+ case Kind.OpNode:
+ checkOpNode(md,nametable,(OpNode)en,td);
+ return;
+ }
+ throw new Error();
+ }
+
+ void checkAssignmentNode(MethodDescriptor md, SymbolTable nametable, AssignmentNode an, TypeDescriptor td) {
+
+ }
+
+ void checkCastNode(MethodDescriptor md, SymbolTable nametable, CastNode cn, TypeDescriptor td) {
+ }
+
+ void checkCreateObjectNode(MethodDescriptor md, SymbolTable nametable, CreateObjectNode con, TypeDescriptor td) {
+ }
+
+ void checkFieldAccessNode(MethodDescriptor md, SymbolTable nametable, FieldAccessNode fan, TypeDescriptor td) {
+ }
+
+ void checkLiteralNode(MethodDescriptor md, SymbolTable nametable, LiteralNode ln, TypeDescriptor td) {
+ }
+
+ void checkMethodInvokeNode(MethodDescriptor md, SymbolTable nametable, MethodInvokeNode min, TypeDescriptor td) {
+ }
+
+ void checkNameNode(MethodDescriptor md, SymbolTable nametable, NameNode nn, TypeDescriptor td) {
+ }
+
+ void checkOpNode(MethodDescriptor md, SymbolTable nametable, OpNode on,TypeDescriptor td) {
+ }
+
+ void checkLoopNode(MethodDescriptor md, SymbolTable nametable, LoopNode ln) {
+ }
+}
public static final int FLOAT=7;
public static final int DOUBLE=8;
public static final int VOID=9;
- public static final int CLASS=10;
+ public static final int NULL=10;
+ public static final int CLASS=11;
+
int type;
NameDescriptor name_desc;
-
+ ClassDescriptor class_desc;
+
+ public void setClassDescriptor(ClassDescriptor cd) {
+ class_desc=cd;
+ }
+
+ public boolean isVoid() {
+ return type==VOID;
+ }
+
+ public boolean isPrimitive() {
+ return ((type>=BYTE)&&(type<=DOUBLE));
+ }
+
+ public boolean isClass() {
+ return type==CLASS;
+ }
+
public TypeDescriptor(NameDescriptor name) {
super(name.toString());
this.type=CLASS;
this.name_desc=name;
+ this.class_desc=null;
}
public TypeDescriptor(int t) {
return "double";
else if (type==VOID)
return "void";
+ else if (type==NULL)
+ return "null";
else throw new Error();
}
}
return identifier;
}
+ public TypeDescriptor getType() {
+ return td;
+ }
+
public String toString() {
return td.toString()+" "+identifier;
}
import java.io.FileReader;
import IR.Tree.ParseNode;
import IR.Tree.BuildIR;
+import IR.Tree.SemanticCheck;
import IR.Flat.BuildFlat;
import IR.State;
ParseNode p=(ParseNode) g./*debug_*/parse().value;
// System.out.println(p.PPrint(2,true));
State state=new State(p);
+
BuildIR bir=new BuildIR(state);
bir.buildtree();
+
+ SemanticCheck sc=new SemanticCheck(state);
+ sc.semanticCheck();
BuildFlat bf=new BuildFlat(state);
bf.buildFlat();
//non terminal ParseNode switch_block_statement_group;
//non terminal ParseNode switch_labels, switch_label;
non terminal ParseNode while_statement, while_statement_no_short_if;
-//non terminal ParseNode do_statement;
+non terminal ParseNode do_statement;
non terminal ParseNode for_statement, for_statement_no_short_if;
non terminal ParseNode for_init_opt, for_init;
non terminal ParseNode for_update_opt, for_update;
| empty_statement:st {: RESULT=st; :}
| expression_statement:st {: RESULT=st; :}
// | switch_statement
-// | do_statement
+ | do_statement
| break_statement:st {: RESULT=st; :}
| continue_statement:st {: RESULT=st; :}
| return_statement:st {: RESULT=st; :}
RESULT=pn;
:}
;
-//do_statement ::=
-// DO statement WHILE LPAREN expression RPAREN SEMICOLON
-// ;
+do_statement ::=
+ DO statement:st WHILE LPAREN expression:exp RPAREN SEMICOLON {:
+ ParseNode pn=new ParseNode("dowhilestatement");
+ pn.addChild("condition").addChild(exp);
+ pn.addChild("statement").addChild(st);
+ RESULT=pn;
+ :}
+ ;
for_statement ::=
FOR LPAREN for_init_opt:init SEMICOLON expression_opt:exp SEMICOLON
for_update_opt:update RPAREN statement:st {:
}
+public class String {}
+
+public class ParseNodeVector {}
+
+public class Object {}