Adds support for using the "+" operator to combine strings...
this.count=str.length;
this.offset=0;
}
-
+
public String(byte str[]) {
char charstr[]=new char[str.length];
for(int i=0;i<str.length;i++)
return this.lastindexOf(ch, count - 1);
}
+ public String concat(String str) {
+ String newstr=new String();
+ newstr.count=this.count+str.count;
+ char charstr[]=new char[newstr.count];
+ newstr.value=charstr;
+ newstr.offset=0;
+ for(int i=0;i<count;i++) {
+ charstr[i]=value[i+offset];
+ }
+ for(int i=0;i<str.count;i++) {
+ charstr[i+count]=str.value[i+str.offset];
+ }
+ return newstr;
+ }
+
public int lastindexOf(int ch, int fromIndex) {
for(int i=fromIndex;i>0;i--)
if (this.charAt(i)==ch)
}
public static String valueOf(Object o) {
- return o.toString();
+ if (o==null)
+ return "null";
+ else
+ return o.toString();
}
public static String valueOf(int x) {
for(int i=0;i<fm.numParameters();i++) {
TempDescriptor temp=fm.getParameter(i);
TypeDescriptor type=temp.getType();
- if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
+ if (type.isPtr()&&GENERATEPRECISEGC)
objectparams.addPtr(temp);
else
objectparams.addPrim(temp);
for(int i=0;i<writes.length;i++) {
TempDescriptor temp=writes[i];
TypeDescriptor type=temp.getType();
- if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
+ if (type.isPtr()&&GENERATEPRECISEGC)
objecttemps.addPtr(temp);
else
objecttemps.addPrim(temp);
for(Iterator<TempDescriptor> tmpit=backuptable.values().iterator();tmpit.hasNext();) {
TempDescriptor tmp=tmpit.next();
TypeDescriptor type=tmp.getType();
- if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
+ if (type.isPtr()&&GENERATEPRECISEGC)
objecttemps.addPtr(tmp);
else
objecttemps.addPrim(tmp);
TypeDescriptor type=fd.getType();
if (state.DSM&&fd.isGlobal()) //Don't GC the global objects for now
continue;
- if (type.isPtr()||type.isArray())
+ if (type.isPtr())
count++;
}
output.print(count);
TypeDescriptor type=fd.getType();
if (state.DSM&&fd.isGlobal()) //Don't GC the global objects for now
continue;
- if (type.isPtr()||type.isArray()) {
+ if (type.isPtr()) {
output.println(",");
output.print("((unsigned int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
}
String src=generateTemp(fm, ffn.getSrc(),lb);
String dst=generateTemp(fm, ffn.getDst(),lb);
- if (ffn.getField().getType().isPtr()||
- ffn.getField().getType().isArray()) {
+ if (ffn.getField().getType().isPtr()) {
//TODO: Uncomment this when we have runtime support
//if (ffn.getSrc()==ffn.getDst()) {
output.println(generateTemp(fm, fon.getDest(),lb)+" = -"+generateTemp(fm, fon.getLeft(),lb)+";");
else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
output.println(generateTemp(fm, fon.getDest(),lb)+" = !"+generateTemp(fm, fon.getLeft(),lb)+";");
- else
+ else if (fon.getOp().getOp()==Operation.ISAVAILABLE) {
+ output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+"->fses==NULL;");
+ } else
output.println(generateTemp(fm, fon.getDest(),lb)+fon.getOp().toString()+generateTemp(fm, fon.getLeft(),lb)+";");
}
TempDescriptor temp_right=null;
Operation op=on.getOp();
- /* We've moved this to assignment nodes
-
- if (op.getOp()==Operation.POSTINC||
- op.getOp()==Operation.POSTDEC||
- op.getOp()==Operation.PREINC||
- op.getOp()==Operation.PREDEC) {
- LiteralNode ln=new LiteralNode("int",new Integer(1));
- ln.setType(new TypeDescriptor(TypeDescriptor.INT));
-
- AssignmentNode an=new AssignmentNode(on.getLeft(),
- new OpNode(on.getLeft(),ln,
- new Operation((op.getOp()==Operation.POSTINC||op.getOp()==Operation.PREINC)?Operation.PLUS:Operation.MINUS))
- );
- if (op.getOp()==Operation.POSTINC||
- op.getOp()==Operation.POSTDEC) {
- //Can't do, this could have side effects
- NodePair left=flattenExpressionNode(on.getLeft(),out_temp);
- NodePair assign=flattenAssignmentNode(an,temp_left);
- left.getEnd().addNext(assign.getBegin());
- return new NodePair(left.getBegin(),assign.getEnd());
- } else {
- NodePair assign=flattenAssignmentNode(an,out_temp);
- return assign;
- }
- } */
-
+
NodePair left=flattenExpressionNode(on.getLeft(),temp_left);
NodePair right;
if (on.getRight()!=null) {
fcb.addFalseNext(fon1);
fon1.addNext(fnop);
return new NodePair(left.getBegin(), fnop);
+ } else if (op.getOp()==Operation.ADD&&on.getLeft().getType().isString()) {
+ //We have a string concatenate
+ ClassDescriptor stringcd=typeutil.getClass(TypeUtil.StringClass);
+ MethodDescriptor concatmd=typeutil.getMethod(stringcd, "concat", new TypeDescriptor[] {new TypeDescriptor(stringcd)});
+ FlatCall fc=new FlatCall(concatmd, out_temp, temp_left, new TempDescriptor[] {temp_right});
+ left.getEnd().addNext(right.getBegin());
+ right.getEnd().addNext(fc);
+ return new NodePair(left.getBegin(), fc);
}
FlatOpNode fon=new FlatOpNode(out_temp,temp_left,temp_right,op);
public static final int PREINC=23;
public static final int PREDEC=24;
public static final int LOGIC_NOT=25;
+ public static final int ISAVAILABLE=26;
/* Flat Operations */
public static final int ASSIGN=100;
} else if (isNode(pn,"this")) {
NameDescriptor nd=new NameDescriptor("this");
return new NameNode(nd);
+ } else if (isNode(pn,"isavailable")) {
+ NameDescriptor nd=new NameDescriptor(pn.getTerminal());
+ return new OpNode(new NameNode(nd),null,new Operation(Operation.ISAVAILABLE));
} else if (isNode(pn,"methodinvoke1")) {
NameDescriptor nd=parseName(pn.getChild("name"));
Vector args=parseArgumentList(pn);
if (bestmd==null)
bestmd=currmd;
else {
- if (isMoreSpecific(currmd,bestmd)) {
+ if (typeutil.isMoreSpecific(currmd,bestmd)) {
bestmd=currmd;
} else if (con.isGlobal()&&match(currmd, bestmd)) {
if (currmd.isGlobal()&&!bestmd.isGlobal())
bestmd=currmd;
else if (currmd.isGlobal()&&bestmd.isGlobal())
throw new Error();
- } else if (!isMoreSpecific(bestmd, currmd)) {
+ } else if (!typeutil.isMoreSpecific(bestmd, currmd)) {
throw new Error("No method is most specific");
}
}
- /** Check to see if md1 is more specific than md2... Informally
- if md2 could always be called given the arguments passed into
- md1 */
-
- boolean isMoreSpecific(MethodDescriptor md1, MethodDescriptor md2) {
- /* Checks if md1 is more specific than md2 */
- if (md1.numParameters()!=md2.numParameters())
- throw new Error();
- for(int i=0;i<md1.numParameters();i++) {
- if (!typeutil.isSuperorType(md2.getParamType(i), md1.getParamType(i)))
- return false;
- }
- if (!typeutil.isSuperorType(md2.getReturnType(), md1.getReturnType()))
- return false;
-
- if (!typeutil.isSuperorType(md2.getClassDesc(), md1.getClassDesc()))
- return false;
-
- return true;
- }
-
/** Check to see if md1 is the same specificity as md2.*/
boolean match(MethodDescriptor md1, MethodDescriptor md2) {
if (bestmd==null)
bestmd=currmd;
else {
- if (isMoreSpecific(currmd,bestmd)) {
+ if (typeutil.isMoreSpecific(currmd,bestmd)) {
bestmd=currmd;
- } else if (!isMoreSpecific(bestmd, currmd))
+ } else if (!typeutil.isMoreSpecific(bestmd, currmd))
throw new Error("No method is most specific");
/* Is this more specific than bestmd */
on.setType(lefttype);
break;
+ case Operation.ISAVAILABLE:
+ if (!(ltd.isPtr())) {
+ throw new Error("Can't use isavailable on non-pointers/non-parameters.");
+ }
+ lefttype=ltd;
+ on.setLeftType(lefttype);
+ on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
+ break;
case Operation.EQUAL:
case Operation.NOTEQUAL:
// 5.6.2 Binary Numeric Promotion
if (!(ltd.isBoolean()&&rtd.isBoolean()))
throw new Error();
righttype=lefttype=new TypeDescriptor(TypeDescriptor.BOOLEAN);
- } else if (ltd.isPtr()||ltd.isArray()||rtd.isPtr()||rtd.isArray()) {
- if (!((ltd.isPtr()||ltd.isArray())&&(rtd.isPtr()||rtd.isArray())))
+ } else if (ltd.isPtr()||rtd.isPtr()) {
+ if (!(ltd.isPtr()&&rtd.isPtr()))
throw new Error();
righttype=rtd;
lefttype=ltd;
break;
case Operation.ADD:
- //TODO: Need special case for strings eventually
-
+ if (ltd.isString()||rtd.isString()) {
+ ClassDescriptor stringcl=typeutil.getClass(TypeUtil.StringClass);
+ TypeDescriptor stringtd=new TypeDescriptor(stringcl);
+ NameDescriptor nd=new NameDescriptor("String");
+ NameDescriptor valuend=new NameDescriptor(nd, "valueOf");
+ MethodInvokeNode leftmin=new MethodInvokeNode(valuend);
+ MethodInvokeNode rightmin=new MethodInvokeNode(valuend);
+ leftmin.addArgument(on.getLeft());
+ rightmin.addArgument(on.getRight());
+ on.left=leftmin;
+ on.right=rightmin;
+ checkExpressionNode(md, nametable, on.getLeft(), null);
+ checkExpressionNode(md, nametable, on.getRight(), null);
+ on.setLeftType(stringtd);
+ on.setRightType(stringtd);
+ on.setType(stringtd);
+ break;
+ }
case Operation.SUB:
case Operation.MULT:
return false;
}
+ public boolean isString() {
+ if (type!=CLASS)
+ return false;
+ if (arraycount>0)
+ return false;
+ if (!getSymbol().equals(TypeUtil.StringClass))
+ return false;
+ return true;
+ }
+
public int hashCode() {
int hashcode=type^arraycount;
if (type==CLASS)
throw new Error(cd+" has no main");
}
+ /** Check to see if md1 is more specific than md2... Informally
+ if md2 could always be called given the arguments passed into
+ md1 */
+
+ public boolean isMoreSpecific(MethodDescriptor md1, MethodDescriptor md2) {
+ /* Checks if md1 is more specific than md2 */
+ if (md1.numParameters()!=md2.numParameters())
+ throw new Error();
+ for(int i=0;i<md1.numParameters();i++) {
+ if (!this.isSuperorType(md2.getParamType(i), md1.getParamType(i)))
+ return false;
+ }
+ if (!this.isSuperorType(md2.getReturnType(), md1.getReturnType()))
+ return false;
+
+ if (!this.isSuperorType(md2.getClassDesc(), md1.getClassDesc()))
+ return false;
+
+ return true;
+ }
+
+ public MethodDescriptor getMethod(ClassDescriptor cd, String name, TypeDescriptor[] types) {
+ Set methoddescriptorset=cd.getMethodTable().getSet(name);
+ MethodDescriptor bestmd=null;
+ NextMethod:
+ for(Iterator methodit=methoddescriptorset.iterator();methodit.hasNext();) {
+ MethodDescriptor currmd=(MethodDescriptor)methodit.next();
+ /* Need correct number of parameters */
+ if (types.length!=currmd.numParameters())
+ continue;
+ for(int i=0;i<types.length;i++) {
+ if (!this.isSuperorType(currmd.getParamType(i),types[i]))
+ continue NextMethod;
+ }
+ /* Method okay so far */
+ if (bestmd==null)
+ bestmd=currmd;
+ else {
+ if (isMoreSpecific(currmd,bestmd)) {
+ bestmd=currmd;
+ } else if (!isMoreSpecific(bestmd, currmd))
+ throw new Error("No method is most specific");
+
+ /* Is this more specific than bestmd */
+ }
+ }
+ return bestmd;
+ }
+
public void createFullTable() {
subclasstable=new Hashtable();
return false;
} else if (possiblesuper.isPrimitive()&&(!possiblesuper.isArray())&&
- (cd2.isArray()||cd2.isPtr()))
+ cd2.isPtr())
return false;
else if (cd2.isPrimitive()&&(!cd2.isArray())&&
- (possiblesuper.isArray()||possiblesuper.isPtr()))
+ possiblesuper.isPtr())
return false;
else
throw new Error("Case not handled:"+possiblesuper+" "+cd2);
key_table.put("import", new Integer(Sym.IMPORT));
key_table.put("instanceof", new Integer(Sym.INSTANCEOF));
key_table.put("int", new Integer(Sym.INT));
+ key_table.put("isavailable", new Integer(Sym.ISAVAILABLE));
key_table.put("long", new Integer(Sym.LONG));
key_table.put("native", new Integer(Sym.NATIVE));
key_table.put("new", new Integer(Sym.NEW));
"extends", "external", "final", "finally",
"flag", //keyword for failure aware computation
"float", "for", "global", "goto", "if",
- "implements", "import", "instanceof", "int", "interface", "long",
+ "implements", "import", "instanceof", "int", "interface", "isavailable",
+ "long",
"native", "new", "optional", "package", "private", "protected", "public",
"return", "short", "static", "strictfp", "super", "switch", "synchronized",
"tag", "task", "taskexit", //keywords for failure aware computation
//failure aware computation keywords
terminal FLAG;
terminal OPTIONAL;
+terminal ISAVAILABLE;
terminal EXTERNAL;
terminal TAG;
terminal TASK;
| field_access:exp {: RESULT=exp; :}
| method_invocation:exp {: RESULT=exp; :}
| array_access:exp {: RESULT=exp; :}
+ | ISAVAILABLE LPAREN IDENTIFIER:id RPAREN {:
+ ParseNode pn=new ParseNode("isavailable");
+ pn.addChild(id);
+ RESULT=pn;
+ :}
// | primitive_type DOT CLASS
// | VOID DOT CLASS
// | array_type DOT CLASS