private NodePair flattenCreateObjectNode(CreateObjectNode con,TempDescriptor out_temp) {
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",en.getType());
- temps[i]=tmp;
- NodePair np=flattenExpressionNode(en, tmp);
- last.addNext(np.getBegin());
- last=np.getEnd();
+ if (!td.isArray()) {
+ 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",en.getType());
+ 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);
+ } else {
+ FlatNode first=null;
+ FlatNode last=null;
+ TempDescriptor[] temps=new TempDescriptor[con.numArgs()];
+ for (int i=0;i<con.numArgs();i++) {
+ ExpressionNode en=con.getArg(i);
+ TempDescriptor tmp=TempDescriptor.tempFactory("arg",en.getType());
+ temps[i]=tmp;
+ NodePair np=flattenExpressionNode(en, tmp);
+ if (first==null)
+ first=np.getBegin();
+ else
+ last.addNext(np.getBegin());
+ last=np.getEnd();
+
+ TempDescriptor tmp2=(i==0)?
+ out_temp:
+ TempDescriptor.tempFactory("arg",en.getType());
+ }
+ FlatNew fn=new FlatNew(td, out_temp, temps[0]);
+ last.addNext(fn);
+ NodePair np=generateNewArrayLoop(temps, td.dereference(), out_temp, 0);
+ fn.addNext(np.getBegin());
+ return new NodePair(first,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 generateNewArrayLoop(TempDescriptor[] temparray, TypeDescriptor td, TempDescriptor tmp, int i) {
+ TempDescriptor index=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
+ TempDescriptor tmpone=TempDescriptor.tempFactory("index",new TypeDescriptor(TypeDescriptor.INT));
+ FlatNop fnop=new FlatNop();//last node
+
+ //index=0
+ FlatLiteralNode fln=new FlatLiteralNode(index.getType(),new Integer(0),index);
+ //tmpone=1
+ FlatLiteralNode fln2=new FlatLiteralNode(tmpone.getType(),new Integer(1),tmpone);
+
+ TempDescriptor tmpbool=TempDescriptor.tempFactory("comp",new TypeDescriptor(TypeDescriptor.BOOLEAN));
+
+ FlatOpNode fcomp=new FlatOpNode(tmpbool,index,temparray[i],new Operation(Operation.LT));
+ FlatCondBranch fcb=new FlatCondBranch(tmpbool);
+ //is index<temp[i]
+ TempDescriptor new_tmp=TempDescriptor.tempFactory("tmp",td);
+ FlatNew fn=new FlatNew(td, new_tmp, temparray[i+1]);
+ FlatSetElementNode fsen=new FlatSetElementNode(tmp,index,new_tmp);
+ // index=index+1
+ FlatOpNode fon=new FlatOpNode(index,index,tmpone,new Operation(Operation.ADD));
+ //jump out
+ fln.addNext(fln2);
+ fln2.addNext(fcomp);
+ fcomp.addNext(fcb);
+ fcb.addTrueNext(fn);
+ fcb.addFalseNext(fnop);
+ fn.addNext(fsen);
+ //Recursive call here
+ if ((i+1)<temparray.length) {
+ NodePair np2=generateNewArrayLoop(temparray, td.dereference(), new_tmp, i+1);
+ fsen.addNext(np2.getBegin());
+ np2.getEnd().addNext(fon);
+ } else {
+ fsen.addNext(fon);
+ }
+ fon.addNext(fcomp);
+ return new NodePair(fln, fnop);
}
private NodePair flattenMethodInvokeNode(MethodInvokeNode min,TempDescriptor out_temp) {
public static final int FlatLiteralNode=7;
public static final int FlatReturnNode=8;
public static final int FlatCondBranch=9;
- public static final int FlatNop=10;
+ public static final int FlatNop=10;
+ public static final int FlatSetElementNode=11;
}
public class FlatNew extends FlatNode {
TempDescriptor dst;
TypeDescriptor type;
+ TempDescriptor size;
public FlatNew(TypeDescriptor type, TempDescriptor dst) {
this.type=type;
this.dst=dst;
+ this.size=null;
+ }
+
+ public FlatNew(TypeDescriptor type, TempDescriptor dst, TempDescriptor size) {
+ this.type=type;
+ this.dst=dst;
+ this.size=size;
}
public String toString() {
- return dst.toString()+"= NEW "+type.toString();
+ if (size==null)
+ return dst.toString()+"= NEW "+type.toString();
+ else
+ return dst.toString()+"= NEW "+type.toString()+"["+size.toString()+"]";
}
public int kind() {
return new TempDescriptor[] {dst};
}
+ public TempDescriptor [] readsTemps() {
+ if (size!=null)
+ return new TempDescriptor[] {size};
+ else
+ return new TempDescriptor[0];
+ }
+
public TempDescriptor getDst() {
return dst;
}
} else if(type_st.equals("class")) {
ParseNode nn=tn.getChild("class");
return state.getTypeDescriptor(parseName(nn.getChild("name")));
+ } else if(type_st.equals("array")) {
+ ParseNode nn=tn.getChild("array");
+ TypeDescriptor td=parseTypeDescriptor(nn.getChild("basetype"));
+ Integer numdims=(Integer)nn.getChild("dims").getLiteral();
+ for(int i=0;i<numdims.intValue();i++)
+ td=td.makeArray();
+ return td;
} else {
throw new Error();
}
ParseNodeVector pnv=vn.getChildren();
for(int i=0;i<pnv.size();i++) {
ParseNode vardecl=pnv.elementAt(i);
- String identifier=vardecl.getChild("single").getTerminal();
+
+
+ ParseNode tmp=vardecl;
+ TypeDescriptor arrayt=t;
+ while (tmp.getChild("single")==null) {
+ arrayt=arrayt.makeArray();
+ tmp=tmp.getChild("array");
+ }
+ String identifier=tmp.getChild("single").getTerminal();
+
ParseNode epn=vardecl.getChild("initializer");
ExpressionNode en=null;
if (epn!=null)
en=parseExpression(epn.getFirstChild());
- cn.addField(new FieldDescriptor(m,t,identifier, en));
+ cn.addField(new FieldDescriptor(m,arrayt,identifier, en));
}
}
con.addArgument((ExpressionNode)args.get(i));
}
return con;
+ } else if (isNode(pn,"createarray")) {
+ TypeDescriptor td=parseTypeDescriptor(pn);
+ Vector args=parseDimExprs(pn);
+ int num=0;
+ if (pn.getChild("dims_opt").getLiteral()!=null)
+ num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue();
+ for(int i=0;i<args.size()+num;i++)
+ td=td.makeArray();
+ CreateObjectNode con=new CreateObjectNode(td);
+ for(int i=0;i<args.size();i++) {
+ con.addArgument((ExpressionNode)args.get(i));
+ }
+ return con;
} else if (isNode(pn,"name")) {
NameDescriptor nd=parseName(pn);
return new NameNode(nd);
}
return min;
} else if (isNode(pn,"fieldaccess")) {
- ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
- String fieldname=pn.getChild("field").getTerminal();
+ ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild()); String fieldname=pn.getChild("field").getTerminal();
return new FieldAccessNode(en,fieldname);
+ } else if (isNode(pn,"arrayaccess")) {
+ ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
+ ExpressionNode index=parseExpression(pn.getChild("index"));
+ return new ArrayAccessNode(en,index);
} else if (isNode(pn,"cast1")) {
return new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild()));
} else if (isNode(pn,"cast2")) {
}
}
+ private Vector parseDimExprs(ParseNode pn) {
+ Vector arglist=new Vector();
+ ParseNode an=pn.getChild("dim_exprs");
+ if (an==null) /* No argument list */
+ return arglist;
+ ParseNodeVector anv=an.getChildren();
+ for(int i=0;i<anv.size();i++) {
+ arglist.add(parseExpression(anv.elementAt(i)));
+ }
+ return arglist;
+ }
+
private Vector parseArgumentList(ParseNode pn) {
Vector arglist=new Vector();
ParseNode an=pn.getChild("argument_list");
ParseNodeVector pnv=vn.getChildren();
for(int i=0;i<pnv.size();i++) {
ParseNode vardecl=pnv.elementAt(i);
- String identifier=vardecl.getChild("single").getTerminal();
- ParseNode epn=vardecl.getChild("initializer");
+
+
+ ParseNode tmp=vardecl;
+ TypeDescriptor arrayt=t;
+ while (tmp.getChild("single")==null) {
+ arrayt=arrayt.makeArray();
+ tmp=tmp.getChild("array");
+ }
+ String identifier=tmp.getChild("single").getTerminal();
+ ParseNode epn=vardecl.getChild("initializer");
+
+
ExpressionNode en=null;
if (epn!=null)
en=parseExpression(epn.getFirstChild());
- blockstatements.add(new DeclarationNode(new VarDescriptor(t,identifier),en));
+ blockstatements.add(new DeclarationNode(new VarDescriptor(arrayt, identifier),en));
}
} else if (isNode(pn,"nop")) {
/* Do Nothing */
for(int i=0;i<pnv.size();i++) {
ParseNode paramn=pnv.elementAt(i);
TypeDescriptor type=parseTypeDescriptor(paramn);
- String paramname=paramn.getChild("single").getTerminal();
+
+ ParseNode tmp=paramn;
+ while (tmp.getChild("single")==null) {
+ type=type.makeArray();
+ tmp=tmp.getChild("array");
+ }
+ String paramname=tmp.getChild("single").getTerminal();
+
md.addParameter(type,paramname);
}
}
td=type;
argumentlist=new Vector();
}
+
public void addArgument(ExpressionNode en) {
argumentlist.add(en);
}
public final static int MethodInvokeNode=13;
public final static int DeclarationNode=14;
public final static int NameNode=15;
+ public final static int ArrayAccessNode=16;
}
public static final int CLASS=11;
-
+ int arraycount;
int type;
ClassDescriptor class_desc;
return false;
}
+ public TypeDescriptor makeArray() {
+ TypeDescriptor td=new TypeDescriptor(getSymbol());
+ td.arraycount=arraycount+1;
+ td.type=type;
+ td.class_desc=class_desc;
+ return td;
+ }
+
+ public boolean isArray() {
+ return arraycount>0;
+ }
+
+ public TypeDescriptor dereference() {
+ TypeDescriptor td=new TypeDescriptor(getSymbol());
+ if (arraycount==0)
+ throw new Error();
+ td.arraycount=arraycount-1;
+ td.type=type;
+ td.class_desc=class_desc;
+ return td;
+ }
public String getSafeSymbol() {
if (isClass())
super(name.toString());
this.type=CLASS;
this.class_desc=null;
+ this.arraycount=0;
+ }
+
+ private TypeDescriptor(String st) {
+ super(st);
}
public ClassDescriptor getClassDesc() {
super(cd.getSymbol());
this.type=CLASS;
this.class_desc=cd;
+ this.arraycount=0;
}
public TypeDescriptor(int t) {
super(decodeInt(t));
this.type=t;
+ this.arraycount=0;
}
public String toString() {
non terminal ParseNode class_or_interface_type;
non terminal ParseNode class_type;
//non terminal ParseNode interface_type;
-//non terminal ParseNode array_type;
+non terminal ParseNode array_type;
// 19.5) Names
non terminal ParseNode name, simple_name, qualified_name;
// 19.6) Packages
non terminal ParseNode primary, primary_no_new_array;
non terminal ParseNode class_instance_creation_expression;
non terminal ParseNode argument_list_opt, argument_list;
-//non terminal ParseNode array_creation_init, array_creation_uninit;
-//non terminal ParseNode dim_exprs, dim_expr, dims_opt, dims;
+//non terminal ParseNode array_creation_init;
+non terminal ParseNode array_creation_uninit;
+non terminal ParseNode dim_exprs, dim_expr;
+non terminal Integer dims_opt, dims;
non terminal ParseNode field_access, method_invocation;
-//non terminal ParseNode array_access;
+non terminal ParseNode array_access;
non terminal ParseNode postfix_expression;
non terminal ParseNode postincrement_expression, postdecrement_expression;
non terminal ParseNode unary_expression, unary_expression_not_plus_minus;
type ::= primitive_type:type {: RESULT=type; :}
| reference_type:type {: RESULT=type; :}
;
+
primitive_type ::=
numeric_type:type {: RESULT=type; :}
| BOOLEAN {: RESULT=(new ParseNode("type")).addChild("boolean").getRoot(); :}
reference_type ::=
class_or_interface_type:type {: RESULT=type; :}
-// | array_type:type {: RESULT=type; :}
+ | array_type:type {: RESULT=type; :}
;
class_or_interface_type ::= name:name {:
RESULT=(new ParseNode("type")).addChild("class").addChild(name).getRoot();
class_type ::= class_or_interface_type:type {: RESULT=type; :};
//interface_type ::= class_or_interface_type;
-//array_type ::= primitive_type dims
-// | name dims
-// ;
+array_type ::= primitive_type:prim dims:dims {:
+ ParseNode pn=(new ParseNode("type")).addChild("array");
+ pn.addChild("basetype").addChild(prim);
+ pn.addChild("dims").setLiteral(dims);
+ RESULT=pn;
+ :}
+ | name:name dims:dims {:
+ ParseNode pn=(new ParseNode("type")).addChild("array");
+ pn.addChild("basetype").addChild("type").addChild("class").addChild(name);
+ pn.addChild("dims").setLiteral(dims);
+ RESULT=pn;
+ :}
+ ;
// 19.5) Names
name ::= simple_name:name {: RESULT=name; :}
variable_declarator_id ::=
IDENTIFIER:id {:
RESULT=(new ParseNode("single")).addChild(id).getRoot();:}
-// | variable_declarator_id:id LBRACK RBRACK {:
-// RESULT=(new ParseNode("array")).addChild(id).getRoot();:}
+ | variable_declarator_id:id LBRACK RBRACK {:
+ RESULT=(new ParseNode("array")).addChild(id).getRoot();:}
;
variable_initializer ::=
expression:exp {: RESULT=exp; :}
// 19.12) Expressions
primary ::= primary_no_new_array:st {:
RESULT=st; :}
-// | array_creation_init
-// | array_creation_uninit
+// | array_creation_init:st {:
+// RESULT=st;
+// :}
+ | array_creation_uninit:st {:
+ RESULT=st;
+ :}
;
primary_no_new_array ::=
literal:lit {: RESULT=lit; :}
| class_instance_creation_expression:exp {: RESULT=exp; :}
| field_access:exp {: RESULT=exp; :}
| method_invocation:exp {: RESULT=exp; :}
-// | array_access
+ | array_access:exp {: RESULT=exp; :}
// | primitive_type DOT CLASS
// | VOID DOT CLASS
// | array_type DOT CLASS
pn.addChild(exp);
RESULT=pn;
:}
- | argument_list:list COMMA expression:exp {:
+ | argument_list:list COMMA expression:exp {:
list.addChild(exp);
RESULT=list;
:}
;
-//array_creation_uninit ::=
-// NEW primitive_type dim_exprs dims_opt
-// | NEW class_or_interface_type dim_exprs dims_opt
-// ;
+array_creation_uninit ::=
+ NEW primitive_type:type dim_exprs:dimexpr dims_opt:dims {:
+ ParseNode pn=new ParseNode("createarray");
+ pn.addChild(type);
+ pn.addChild(dimexpr);
+ pn.addChild("dims_opt").setLiteral(dims);
+ RESULT=pn;
+ :}
+ | NEW class_or_interface_type:type dim_exprs:dimexpr dims_opt:dims {:
+ ParseNode pn=new ParseNode("createarray");
+ pn.addChild(type);
+ pn.addChild(dimexpr);
+ pn.addChild("dims_opt").setLiteral(dims);
+ RESULT=pn;
+ :}
+ ;
//array_creation_init ::=
// NEW primitive_type dims array_initializer
// | NEW class_or_interface_type dims array_initializer
// ;
-//dim_exprs ::= dim_expr
-// | dim_exprs dim_expr
-// ;
-//dim_expr ::= LBRACK expression RBRACK
-// ;
-//dims_opt ::=
-// | dims
-// ;
-//dims ::= LBRACK RBRACK
-// | dims LBRACK RBRACK
-// ;
+dim_exprs ::= dim_expr:exp {:
+ ParseNode pn=new ParseNode("dim_exprs");
+ pn.addChild("expr").addChild(exp);
+ RESULT=exp; :}
+ | dim_exprs:base dim_expr:exp {:
+ base.addChild(exp);
+ RESULT=base;
+ :}
+ ;
+dim_expr ::= LBRACK expression:exp RBRACK {: RESULT=exp; :}
+ ;
+dims_opt ::= {: RESULT=null; :}
+ | dims:dims {: RESULT = dims; :}
+ ;
+
+dims ::= LBRACK RBRACK {: RESULT=new Integer(0); :}
+ | dims:dims LBRACK RBRACK {: RESULT=new Integer(dims.intValue()+1); :}
+ ;
+
field_access ::=
primary:base DOT IDENTIFIER:id {:
ParseNode pn=new ParseNode("fieldaccess");
// | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
// | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN
;
-//array_access ::=
-// name LBRACK expression RBRACK
-// | primary_no_new_array LBRACK expression RBRACK
-// | array_creation_init LBRACK expression RBRACK
-// ;
+array_access ::=
+ name:name LBRACK expression:exp RBRACK {:
+ ParseNode pn=new ParseNode("arrayaccess");
+ pn.addChild("base").addChild(name);
+ pn.addChild("index").addChild(exp);
+ RESULT=pn;
+ :}
+ | primary_no_new_array:base LBRACK expression:exp RBRACK {:
+ ParseNode pn=new ParseNode("arrayaccess");
+ pn.addChild("base").addChild(base);
+ pn.addChild("index").addChild(exp);
+ RESULT=pn;
+ :}
+// | array_creation_init:init LBRACK expression:exp RBRACK {:
+// ParseNode pn=new ParseNode("arrayaccess");
+// pn.addChild("init").addChild(init);
+// pn.addChild("index").addChild(exp);
+// RESULT=pn;
+// :}
+ ;
postfix_expression ::=
primary:exp {:
RESULT=exp; :}