BlockNode bn=state.getMethodBody(md);
FlatNode fn=flattenBlockNode(bn).getBegin();
FlatMethod fm=new FlatMethod(md, fn);
+ System.out.println(fm.printMethod());
state.addFlatCode(md,fm);
}
}
end=np_end;
}
}
- return new NodePair(begin,end);
+ if (begin==null) {
+ end=begin=new FlatNop();
+ }
+ return new NodePair(begin,end);
}
private NodePair flattenBlockExpressionNode(BlockExpressionNode en) {
if (an.getDest().kind()==Kind.FieldAccessNode) {
FieldAccessNode fan=(FieldAccessNode)an.getDest();
-
-
- // Need to assign field
+ ExpressionNode en=fan.getExpression();
+ TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst");
+ NodePair np_baseexp=flattenExpressionNode(en, dst_tmp);
+ last.addNext(np_baseexp.getBegin());
+ FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp);
+ np_baseexp.getEnd().addNext(fsfn);
+ return new NodePair(np_src.getBegin(), fsfn);
} else if (an.getDest().kind()==Kind.NameNode) {
-
- }
- throw new Error();
+
+ //TODO: FIXME
+ FlatNop nop=new FlatNop();
+ return new NodePair(nop,nop);
+ } else throw new Error();
}
private NodePair flattenNameNode(NameNode nn,TempDescriptor out_temp) {
- throw new Error();
+ if (nn.getField()!=null) {
+ TempDescriptor tmp=getTempforVar(nn.getVar());
+ FlatFieldNode ffn=new FlatFieldNode(nn.getField(), tmp, out_temp);
+ return new NodePair(ffn,ffn);
+ } else {
+ TempDescriptor tmp=getTempforVar(nn.getVar());
+ FlatOpNode fon=new FlatOpNode(out_temp, tmp, null, new Operation(Operation.ASSIGN));
+ return new NodePair(fon,fon);
+ }
}
private NodePair flattenOpNode(OpNode on,TempDescriptor out_temp) {
private NodePair flattenDeclarationNode(DeclarationNode dn) {
VarDescriptor vd=dn.getVarDescriptor();
TempDescriptor td=getTempforVar(vd);
- return flattenExpressionNode(dn.getExpression(),td);
+ if (dn.getExpression()!=null)
+ return flattenExpressionNode(dn.getExpression(),td);
+ else {
+ FlatNop fn=new FlatNop();
+ return new NodePair(fn,fn);
+ }
}
private TempDescriptor getTempforVar(VarDescriptor vd) {
}
public void addTrueNext(FlatNode n) {
+ if (next.size()==0)
+ next.setSize(1);
next.setElementAt(n,0);
n.addPrev(this);
}
public void addFalseNext(FlatNode n) {
+ next.setSize(2);
next.setElementAt(n,1);
n.addPrev(this);
}
}
public String toString() {
- return dst.toString()+"="+src.toString()+"."+field.toString();
+ return dst.toString()+"="+src.toString()+"."+field.getSymbol();
}
}
return value;
}
- public String printNode(int indent) {
- /* if (type==NULL)
+ public String toString() {
+ if (value==null)
return dst+"=null";
- if (type==STRING) {
- return dst+"="+'"'+escapeString(value.toString())+'"';
- }*/
- //return dst+"="+"/*"+getType()+ "*/"+value.toString();
- return "";
+ else
+ return dst+"="+escapeString(value.toString());
}
private static String escapeString(String st) {
String new_st="";
}
public String printMethod() {
- String st="";
+ String st=method+"\n";
HashSet tovisit=new HashSet();
HashSet visited=new HashSet();
int labelindex=0;
tovisit=new HashSet();
visited=new HashSet();
tovisit.add(method_entry);
- while(!tovisit.isEmpty()) {
+ while(current_node!=null||!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) {
+ st+=" "+current_node.toString()+"\n";
current_node=null;
} else if(current_node.numNext()==1) {
+ st+=" "+current_node.toString()+"\n";
FlatNode nextnode=current_node.getNext(0);
if (visited.contains(nextnode)) {
st+="goto L"+nodetolabel.get(nextnode)+"\n";
current_node=nextnode;
} else if (current_node.numNext()==2) {
/* Branch */
- st+=((FlatCondBranch)current_node).toString("L"+nodetolabel.get(current_node.getNext(1)));
+ st+=" "+((FlatCondBranch)current_node).toString("L"+nodetolabel.get(current_node.getNext(1)))+"\n";
+ if (!visited.contains(current_node.getNext(1)))
+ tovisit.add(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;
}
public String toString() {
- return dest.toString()+"="+left.toString()+op.toString()+right.toString();
+ if (right!=null)
+ return dest.toString()+"="+left.toString()+op.toString()+right.toString();
+ else if (op.getOp()==Operation.ASSIGN)
+ return dest.toString()+" = "+left.toString();
+ else
+ return dest.toString()+" "+op.toString() +" "+left.toString();
}
}
--- /dev/null
+package IR.Flat;
+import IR.FieldDescriptor;
+
+public class FlatSetFieldNode extends FlatNode {
+ TempDescriptor src;
+ TempDescriptor dst;
+ FieldDescriptor field;
+
+ public FlatSetFieldNode(TempDescriptor dst, FieldDescriptor field, TempDescriptor src) {
+ this.field=field;
+ this.src=src;
+ this.dst=dst;
+ }
+
+ public FieldDescriptor getField() {
+ return field;
+ }
+
+ public String toString() {
+ return dst.toString()+"."+field.getSymbol()+"="+src.toString();
+ }
+}
else
st=modifier.toString()+" "+identifier+"(";
for(int i=0;i<params.size();i++) {
- st+=getParamName(i)+" "+getParamType(i);
+ st+=getParamType(i)+" "+getParamName(i);
if ((i+1)!=params.size())
st+=", ";
}
public static final int UNARYMINUS=20;
public static final int POSTINC=21;
public static final int POSTDEC=22;
- public static final int PREINC=21;
- public static final int PREDEC=22;
+ public static final int PREINC=23;
+ public static final int PREDEC=24;
+
+ /* Flat Operations */
+ public static final int ASSIGN=100;
private int operation;
public Operation(int op) {
this.operation=parseOp(op);
}
+ public int getOp() {
+ return operation;
+ }
+
public static int parseOp(String st) {
if (st.equals("logical_or"))
return LOGIC_OR;
return "preinc";
else if (operation==PREDEC)
return "predec";
+ else if (operation==ASSIGN)
+ return "assign";
else throw new Error();
}
this.fd=fd;
}
+ public FieldDescriptor getField() {
+ return fd;
+ }
+
+ public VarDescriptor getVar() {
+ return vd;
+ }
+
public TypeDescriptor getType() {
- if (vd!=null)
- return vd.getType();
- else
+ if (fd!=null)
return fd.getType();
+ else
+ return vd.getType();
}
NameDescriptor getName() {
ExpressionNode right;
Operation op;
TypeDescriptor td;
+ TypeDescriptor lefttype;
+ TypeDescriptor righttype;
public OpNode(ExpressionNode l, ExpressionNode r, Operation o) {
left=l;
return left.printNode(indent)+" "+op.toString()+" "+right.printNode(indent);
}
+ public void setLeftType(TypeDescriptor argtype) {
+ this.lefttype=argtype;
+ }
+
+ public TypeDescriptor getLeftType() {
+ return lefttype;
+ }
+
+ public void setRightType(TypeDescriptor argtype) {
+ this.righttype=argtype;
+ }
+
+ public TypeDescriptor getRightType() {
+ return righttype;
+ }
+
public TypeDescriptor getType() {
return td;
}
checkTypeDescriptor(param_type);
}
/* Link the naming environments */
- md.getParameterTable().setParent(cd.getFieldTable());
+ if (!md.isStatic()) /* Fields aren't accessible directly in a static method, so don't link in this table */
+ md.getParameterTable().setParent(cd.getFieldTable());
md.setClassDesc(cd);
if (!md.isStatic()) {
VarDescriptor thisvd=new VarDescriptor(new TypeDescriptor(cd),"this");
}
public void checkMethodBody(ClassDescriptor cd, MethodDescriptor md) {
+ System.out.println("Processing method:"+md);
BlockNode bn=state.getMethodBody(md);
checkBlockNode(md, md.getParameterTable(),bn);
}
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());
+ if (isn.getFalseBlock()!=null)
+ checkBlockNode(md, nametable, isn.getFalseBlock());
}
void checkExpressionNode(MethodDescriptor md, SymbolTable nametable, ExpressionNode en, TypeDescriptor td) {
nn.setVar((VarDescriptor)d);
} else if (d instanceof FieldDescriptor) {
nn.setField((FieldDescriptor)d);
+ nn.setVar((VarDescriptor)nametable.get("this")); /* Need a pointer to this */
}
if (td!=null)
if (!typeutil.isSuperorType(td,nn.getType()))
(an.getDest() instanceof NameNode)))
throw new Error("Bad lside in "+an.printNode(0));
checkExpressionNode(md, nametable, an.getDest(), null);
- if (!typeutil.isSuperorType(an.getDest().getType(),an.getSrc().getType()))
- throw new Error("Type of rside not compatible with type of lside"+an.printNode(0));
+ if (!typeutil.isSuperorType(an.getDest().getType(),an.getSrc().getType())) {
+ throw new Error("Type of rside ("+an.getSrc().getType()+") not compatible with type of lside ("+an.getDest().getType()+")"+an.printNode(0));
+ }
}
void checkLoopNode(MethodDescriptor md, SymbolTable nametable, LoopNode ln) {
checkExpressionNode(md, nametable, on.getRight(), null);
TypeDescriptor ltd=on.getLeft().getType();
TypeDescriptor rtd=on.getRight()!=null?on.getRight().getType():null;
- TypeDescriptor thistype=null;
- if (rtd!=null) {
+ TypeDescriptor lefttype=null;
+ TypeDescriptor righttype=null;
+ Operation op=on.getOp();
+
+ switch(op.getOp()) {
+ case Operation.LOGIC_OR:
+ case Operation.LOGIC_AND:
+ if (!(ltd.isBoolean()&&rtd.isBoolean()))
+ throw new Error();
+ //no promotion
+ on.setLeftType(ltd);
+ on.setRightType(rtd);
+ on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
+ break;
+
+ case Operation.BIT_OR:
+ case Operation.BIT_XOR:
+ case Operation.BIT_AND:
+ // 5.6.2 Binary Numeric Promotion
+ //TODO unboxing of reference objects
+ if (ltd.isDouble()||rtd.isDouble())
+ throw new Error();
+ else if (ltd.isFloat()||rtd.isFloat())
+ throw new Error();
+ else if (ltd.isLong()||rtd.isLong())
+ lefttype=new TypeDescriptor(TypeDescriptor.LONG);
+ else
+ lefttype=new TypeDescriptor(TypeDescriptor.INT);
+ righttype=lefttype;
+
+ on.setLeftType(lefttype);
+ on.setRightType(righttype);
+ on.setType(lefttype);
+ break;
+
+ case Operation.EQUAL:
+ case Operation.NOTEQUAL:
+ // 5.6.2 Binary Numeric Promotion
+ //TODO unboxing of reference objects
+ if (ltd.isBoolean()||rtd.isBoolean()) {
+ if (!(ltd.isBoolean()&&rtd.isBoolean()))
+ throw new Error();
+ righttype=lefttype=new TypeDescriptor(TypeDescriptor.BOOLEAN);
+ } else if (ltd.isPtr()||rtd.isPtr()) {
+ if (!(ltd.isPtr()&&rtd.isPtr()))
+ throw new Error();
+ righttype=rtd;
+ lefttype=ltd;
+ } else if (ltd.isDouble()||rtd.isDouble())
+ righttype=lefttype=new TypeDescriptor(TypeDescriptor.DOUBLE);
+ else if (ltd.isFloat()||rtd.isFloat())
+ righttype=lefttype=new TypeDescriptor(TypeDescriptor.FLOAT);
+ else if (ltd.isLong()||rtd.isLong())
+ righttype=lefttype=new TypeDescriptor(TypeDescriptor.LONG);
+ else
+ righttype=lefttype=new TypeDescriptor(TypeDescriptor.INT);
+
+ on.setLeftType(lefttype);
+ on.setRightType(righttype);
+ on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
+ break;
+
+
+
+ case Operation.LT:
+ case Operation.GT:
+ case Operation.LTE:
+ case Operation.GTE:
// 5.6.2 Binary Numeric Promotion
//TODO unboxing of reference objects
+ if (!ltd.isNumber()||!rtd.isNumber())
+ throw new Error();
+
if (ltd.isDouble()||rtd.isDouble())
- thistype=new TypeDescriptor(TypeDescriptor.DOUBLE);
+ lefttype=new TypeDescriptor(TypeDescriptor.DOUBLE);
else if (ltd.isFloat()||rtd.isFloat())
- thistype=new TypeDescriptor(TypeDescriptor.FLOAT);
+ lefttype=new TypeDescriptor(TypeDescriptor.FLOAT);
else if (ltd.isLong()||rtd.isLong())
- thistype=new TypeDescriptor(TypeDescriptor.LONG);
+ lefttype=new TypeDescriptor(TypeDescriptor.LONG);
else
- thistype=new TypeDescriptor(TypeDescriptor.INT);
+ lefttype=new TypeDescriptor(TypeDescriptor.INT);
+ righttype=lefttype;
+ on.setLeftType(lefttype);
+ on.setRightType(righttype);
+ on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
+ break;
+
+ case Operation.ADD:
+ //TODO: Need special case for strings eventually
- } else {
+
+ case Operation.SUB:
+ case Operation.MULT:
+ case Operation.DIV:
+ case Operation.MOD:
+ // 5.6.2 Binary Numeric Promotion
+ //TODO unboxing of reference objects
+ if (!ltd.isNumber()||!rtd.isNumber())
+ throw new Error("Error in "+on.printNode(0));
+
+ if (ltd.isDouble()||rtd.isDouble())
+ lefttype=new TypeDescriptor(TypeDescriptor.DOUBLE);
+ else if (ltd.isFloat()||rtd.isFloat())
+ lefttype=new TypeDescriptor(TypeDescriptor.FLOAT);
+ else if (ltd.isLong()||rtd.isLong())
+ lefttype=new TypeDescriptor(TypeDescriptor.LONG);
+ else
+ lefttype=new TypeDescriptor(TypeDescriptor.INT);
+ righttype=lefttype;
+ on.setLeftType(lefttype);
+ on.setRightType(righttype);
+ on.setType(lefttype);
+ break;
+
+ case Operation.LEFTSHIFT:
+ case Operation.RIGHTSHIFT:
+ if (!rtd.isIntegerType())
+ throw new Error();
+ //5.6.1 Unary Numeric Promotion
+ if (rtd.isByte()||rtd.isShort()||rtd.isInt())
+ righttype=new TypeDescriptor(TypeDescriptor.INT);
+ else
+ righttype=rtd;
+
+ on.setRightType(righttype);
+ if (!ltd.isIntegerType())
+ throw new Error();
+ case Operation.UNARYPLUS:
+ case Operation.UNARYMINUS:
+ case Operation.POSTINC:
+ case Operation.POSTDEC:
+ case Operation.PREINC:
+ case Operation.PREDEC:
+ if (!ltd.isNumber())
+ throw new Error();
//5.6.1 Unary Numeric Promotion
if (ltd.isByte()||ltd.isShort()||ltd.isInt())
- thistype=new TypeDescriptor(TypeDescriptor.INT);
+ lefttype=new TypeDescriptor(TypeDescriptor.INT);
else
- thistype=ltd;
+ lefttype=ltd;
+ on.setLeftType(lefttype);
+ on.setType(lefttype);
+ break;
+ default:
+ throw new Error();
}
- on.setType(thistype);
+
+
+
if (td!=null)
- if (!typeutil.isSuperorType(td, thistype))
+ if (!typeutil.isSuperorType(td, on.getType())) {
+ System.out.println(td);
+ System.out.println(on.getType());
throw new Error("Type of rside not compatible with type of lside"+on.printNode(0));
+ }
}
-
-
}
int type;
ClassDescriptor class_desc;
+ public boolean isNumber() {
+ return (isIntegerType()||isFloat()||isDouble());
+ }
+
public boolean isByte() {
return type==BYTE;
}
+ public boolean isNull() {
+ return type==NULL;
+ }
public boolean isShort() {
return type==SHORT;
}
public boolean isDouble() {
return type==DOUBLE;
}
+ public boolean isVoid() {
+ return type==VOID;
+ }
+
+ public boolean isPtr() {
+ return (isClass()||isNull());
+ }
+
+ public boolean isIntegerType() {
+ return (isInt()||isLong()||isShort()||isChar()||isByte());
+ }
public void setClassDescriptor(ClassDescriptor cd) {
class_desc=cd;
}
- public boolean isVoid() {
- return type==VOID;
- }
-
public boolean isPrimitive() {
return ((type>=BYTE)&&(type<=DOUBLE));
}
import java.util.*;
public class TypeUtil {
- public static final String StringClass="java.lang.String";
+ public static final String StringClass="String";
State state;
Hashtable supertable;
}
public boolean isSuperorType(TypeDescriptor possiblesuper, TypeDescriptor cd2) {
- if ((possiblesuper.getClassDesc()==null)||
- cd2.getClassDesc()==null)
- throw new Error();
- return isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc());
+ if (possiblesuper.isClass()&&
+ cd2.isClass())
+ return isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc());
+ else if (possiblesuper.isClass()&&
+ cd2.isNull())
+ return true;
+ else if (possiblesuper.isNull())
+ throw new Error(); //not sure when this case would occur
+ else if (possiblesuper.isPrimitive()&&
+ cd2.isPrimitive()) {
+ ///Primitive widenings from 5.1.2
+ if (cd2.isByte()&&(possiblesuper.isByte()||possiblesuper.isShort()||
+ possiblesuper.isInt()||possiblesuper.isLong()||
+ possiblesuper.isFloat()||possiblesuper.isDouble()))
+ return true;
+ if (cd2.isShort()&&(possiblesuper.isShort()||
+ possiblesuper.isInt()||possiblesuper.isLong()||
+ possiblesuper.isFloat()||possiblesuper.isDouble()))
+ return true;
+ if (cd2.isChar()&&(possiblesuper.isChar()||
+ possiblesuper.isInt()||possiblesuper.isLong()||
+ possiblesuper.isFloat()||possiblesuper.isDouble()))
+ return true;
+ if (cd2.isInt()&&(possiblesuper.isInt()||possiblesuper.isLong()||
+ possiblesuper.isFloat()||possiblesuper.isDouble()))
+ return true;
+ if (cd2.isLong()&&(possiblesuper.isLong()||
+ possiblesuper.isFloat()||possiblesuper.isDouble()))
+ return true;
+ if (cd2.isFloat()&&(possiblesuper.isFloat()||possiblesuper.isDouble()))
+ return true;
+ if (cd2.isDouble()&&possiblesuper.isDouble())
+
+ return true;
+ if (cd2.isBoolean()&&possiblesuper.isBoolean())
+ return true;
+
+ return false;
+ } else throw new Error();
}