From daf806e7d73845c6410e86950b154e452599cba2 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Sat, 3 Nov 2007 03:37:10 +0000 Subject: [PATCH] This update: Adds support for using the "+" operator to combine strings... --- Robust/src/ClassLibrary/String.java | 22 +++++++++- Robust/src/IR/Flat/BuildCode.java | 17 ++++---- Robust/src/IR/Flat/BuildFlat.java | 35 ++++----------- Robust/src/IR/Operation.java | 1 + Robust/src/IR/Tree/BuildIR.java | 3 ++ Robust/src/IR/Tree/SemanticCheck.java | 61 ++++++++++++++------------- Robust/src/IR/TypeDescriptor.java | 10 +++++ Robust/src/IR/TypeUtil.java | 53 ++++++++++++++++++++++- Robust/src/Lex/Keyword.java | 1 + Robust/src/Lex/Lexer.java | 3 +- Robust/src/Parse/java14.cup | 6 +++ 11 files changed, 144 insertions(+), 68 deletions(-) diff --git a/Robust/src/ClassLibrary/String.java b/Robust/src/ClassLibrary/String.java index 689d3cf9..4d4dfc50 100644 --- a/Robust/src/ClassLibrary/String.java +++ b/Robust/src/ClassLibrary/String.java @@ -15,7 +15,7 @@ public class String { this.count=str.length; this.offset=0; } - + public String(byte str[]) { char charstr[]=new char[str.length]; for(int i=0;i0;i--) if (this.charAt(i)==ch) @@ -141,7 +156,10 @@ public class String { } public static String valueOf(Object o) { - return o.toString(); + if (o==null) + return "null"; + else + return o.toString(); } public static String valueOf(int x) { diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 2d8db249..789db3ed 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -754,7 +754,7 @@ public class BuildCode { for(int i=0;i 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); @@ -836,7 +836,7 @@ public class BuildCode { 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); @@ -846,7 +846,7 @@ public class BuildCode { 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()+"))"); } @@ -1663,8 +1663,7 @@ public class BuildCode { 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()) { @@ -1832,7 +1831,9 @@ public class BuildCode { 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)+";"); } diff --git a/Robust/src/IR/Flat/BuildFlat.java b/Robust/src/IR/Flat/BuildFlat.java index a651fb1b..d873cbe8 100644 --- a/Robust/src/IR/Flat/BuildFlat.java +++ b/Robust/src/IR/Flat/BuildFlat.java @@ -618,32 +618,7 @@ public class BuildFlat { 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) { @@ -680,6 +655,14 @@ public class BuildFlat { 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); diff --git a/Robust/src/IR/Operation.java b/Robust/src/IR/Operation.java index 274c0414..1ea7a3e7 100644 --- a/Robust/src/IR/Operation.java +++ b/Robust/src/IR/Operation.java @@ -26,6 +26,7 @@ public class Operation { 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; diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index 5f17f23b..08c113d2 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -431,6 +431,9 @@ public class BuildIR { } 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); diff --git a/Robust/src/IR/Tree/SemanticCheck.java b/Robust/src/IR/Tree/SemanticCheck.java index 5e1c2d23..84e18d9b 100644 --- a/Robust/src/IR/Tree/SemanticCheck.java +++ b/Robust/src/IR/Tree/SemanticCheck.java @@ -609,14 +609,14 @@ public class SemanticCheck { 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"); } @@ -630,27 +630,6 @@ public class SemanticCheck { } - /** 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;i0) + return false; + if (!getSymbol().equals(TypeUtil.StringClass)) + return false; + return true; + } + public int hashCode() { int hashcode=type^arraycount; if (type==CLASS) diff --git a/Robust/src/IR/TypeUtil.java b/Robust/src/IR/TypeUtil.java index e5ce84bc..dae65785 100644 --- a/Robust/src/IR/TypeUtil.java +++ b/Robust/src/IR/TypeUtil.java @@ -72,6 +72,55 @@ public class TypeUtil { 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