From bf6f89740efc60f11223bf6d284d8eed533dace5 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Mon, 31 Jul 2006 08:07:23 +0000 Subject: [PATCH] Fixed lots of bugs with increment operations and +=/etc... Added a test case --- Robust/src/IR/AssignOperation.java | 14 ++ Robust/src/IR/Flat/BuildCode.java | 8 - Robust/src/IR/Flat/BuildFlat.java | 213 +++++++++++++++++++++----- Robust/src/IR/Tree/BuildIR.java | 18 ++- Robust/src/IR/Tree/SemanticCheck.java | 19 ++- Robust/src/Tests/DoTests | 1 + Robust/src/Tests/IncTest.java | 28 ++++ Robust/src/Tests/Test.java | 8 +- 8 files changed, 251 insertions(+), 58 deletions(-) create mode 100644 Robust/src/Tests/IncTest.java diff --git a/Robust/src/IR/AssignOperation.java b/Robust/src/IR/AssignOperation.java index 2abd7c8e..1a4e2a2b 100644 --- a/Robust/src/IR/AssignOperation.java +++ b/Robust/src/IR/AssignOperation.java @@ -13,6 +13,8 @@ public class AssignOperation { public static final int ANDEQ=10; public static final int XOREQ=11; public static final int OREQ=12; + public static final int POSTINC=13; + public static final int POSTDEC=14; private int operation; public AssignOperation(int op) { @@ -47,6 +49,10 @@ public class AssignOperation { return new Operation(Operation.BIT_XOR); case OREQ: return new Operation(Operation.BIT_OR); + case POSTINC: + return new Operation(Operation.POSTINC); + case POSTDEC: + return new Operation(Operation.POSTDEC); } throw new Error(); } @@ -74,6 +80,10 @@ public class AssignOperation { return XOREQ; else if (st.equals("oreq")) return OREQ; + else if (st.equals("postinc")) + return POSTINC; + else if (st.equals("postdec")) + return POSTDEC; else throw new Error(); } @@ -100,6 +110,10 @@ public class AssignOperation { return "^="; else if (operation==OREQ) return "|="; + else if (operation==POSTINC) + return "postinc"; + else if (operation==POSTDEC) + return "postdec"; else throw new Error(); } diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 76e209f5..ccebda63 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -685,14 +685,6 @@ public class BuildCode { output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";"); else if (fon.getOp().getOp()==Operation.LOGIC_NOT) output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";"); - else if (fon.getOp().getOp()==Operation.POSTINC) - output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+"++;"); - else if (fon.getOp().getOp()==Operation.POSTDEC) - output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+"--;"); - else if (fon.getOp().getOp()==Operation.PREINC) - output.println(generateTemp(fm, fon.getDest())+" = ++"+generateTemp(fm, fon.getLeft())+";"); - else if (fon.getOp().getOp()==Operation.PREDEC) - output.println(generateTemp(fm, fon.getDest())+" = --"+generateTemp(fm, fon.getLeft())+";"); else output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";"); } diff --git a/Robust/src/IR/Flat/BuildFlat.java b/Robust/src/IR/Flat/BuildFlat.java index a5cfe5fa..f47fdeeb 100644 --- a/Robust/src/IR/Flat/BuildFlat.java +++ b/Robust/src/IR/Flat/BuildFlat.java @@ -289,34 +289,68 @@ public class BuildFlat { // left side is array Operation base=an.getOperation().getBaseOp(); - TempDescriptor src_tmp=TempDescriptor.tempFactory("src",an.getSrc().getType()); - NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp); - FlatNode last=np_src.getEnd(); - if (base!=null) { - TempDescriptor src_tmp2=TempDescriptor.tempFactory("tmp", an.getDest().getType()); - NodePair np_dst_init=flattenExpressionNode(an.getDest(),src_tmp2); - last.addNext(np_dst_init.getBegin()); - TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst_tmp",an.getDest().getType()); - FlatOpNode fon=new FlatOpNode(dst_tmp, src_tmp,src_tmp2, base); - np_dst_init.getEnd().addNext(fon); - last=fon; - src_tmp=dst_tmp; + boolean pre=base==null||(base.getOp()!=Operation.POSTINC&&base.getOp()!=Operation.POSTDEC); + + if (!pre) { + //rewrite the base operation + base=base.getOp()==Operation.POSTINC?new Operation(Operation.ADD):new Operation(Operation.SUB); + } + FlatNode first=null; + FlatNode last=null; + TempDescriptor src_tmp=an.getSrc()==null?TempDescriptor.tempFactory("srctmp",an.getDest().getType()):TempDescriptor.tempFactory("srctmp",an.getSrc().getType()); + + //Get src value + if (an.getSrc()!=null) { + NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp); + first=np_src.getBegin(); + last=np_src.getEnd(); + } else if (!pre) { + FlatLiteralNode fln=new FlatLiteralNode(new TypeDescriptor(TypeDescriptor.INT) ,new Integer(1),src_tmp); + first=fln; + last=fln; } if (an.getDest().kind()==Kind.FieldAccessNode) { //We are assigning an object field + FieldAccessNode fan=(FieldAccessNode)an.getDest(); ExpressionNode en=fan.getExpression(); TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType()); NodePair np_baseexp=flattenExpressionNode(en, dst_tmp); - last.addNext(np_baseexp.getBegin()); + if (first==null) + first=np_baseexp.getBegin(); + else + last.addNext(np_baseexp.getBegin()); + last=np_baseexp.getEnd(); + + //See if we need to perform an operation + if (base!=null) { + //If it is a preinc we need to store the initial value + TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp; + TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType()); + + FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2); + last.addNext(ffn); + last=ffn; + FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base); + src_tmp=tmp; + last.addNext(fon); + last=fon; + } + FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp); - np_baseexp.getEnd().addNext(fsfn); - FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN)); - fsfn.addNext(fon2); - return new NodePair(np_src.getBegin(), fon2); + last.addNext(fsfn); + last=fsfn; + if (pre) { + FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN)); + fsfn.addNext(fon2); + last=fon2; + } + return new NodePair(first, last); } else if (an.getDest().kind()==Kind.ArrayAccessNode) { //We are assigning an array element + + ArrayAccessNode aan=(ArrayAccessNode)an.getDest(); ExpressionNode en=aan.getExpression(); ExpressionNode enindex=aan.getIndex(); @@ -324,13 +358,38 @@ public class BuildFlat { TempDescriptor index_tmp=TempDescriptor.tempFactory("index",enindex.getType()); NodePair np_baseexp=flattenExpressionNode(en, dst_tmp); NodePair np_indexexp=flattenExpressionNode(enindex, index_tmp); - last.addNext(np_baseexp.getBegin()); + if (first==null) + first=np_baseexp.getBegin(); + else + last.addNext(np_baseexp.getBegin()); np_baseexp.getEnd().addNext(np_indexexp.getBegin()); + last=np_indexexp.getEnd(); + + //See if we need to perform an operation + if (base!=null) { + //If it is a preinc we need to store the initial value + TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp; + TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType()); + + FlatElementNode fen=new FlatElementNode(dst_tmp, index_tmp, src_tmp2); + last.addNext(fen); + last=fen; + FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base); + src_tmp=tmp; + last.addNext(fon); + last=fon; + } + + FlatSetElementNode fsen=new FlatSetElementNode(dst_tmp, index_tmp, src_tmp); - np_indexexp.getEnd().addNext(fsen); - FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN)); - fsen.addNext(fon2); - return new NodePair(np_src.getBegin(), fon2); + last.addNext(fsen); + last=fsen; + if (pre) { + FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN)); + fsen.addNext(fon2); + last=fon2; + } + return new NodePair(first, last); } else if (an.getDest().kind()==Kind.NameNode) { //We could be assigning a field or variable NameNode nn=(NameNode)an.getDest(); @@ -340,27 +399,109 @@ public class BuildFlat { ExpressionNode en=fan.getExpression(); TempDescriptor dst_tmp=TempDescriptor.tempFactory("dst",en.getType()); NodePair np_baseexp=flattenExpressionNode(en, dst_tmp); - last.addNext(np_baseexp.getBegin()); + if (first==null) + first=np_baseexp.getBegin(); + else + last.addNext(np_baseexp.getBegin()); + last=np_baseexp.getEnd(); + + //See if we need to perform an operation + if (base!=null) { + //If it is a preinc we need to store the initial value + TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp; + TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType()); + + FlatFieldNode ffn=new FlatFieldNode(fan.getField(), dst_tmp, src_tmp2); + last.addNext(ffn); + last=ffn; + FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base); + src_tmp=tmp; + last.addNext(fon); + last=fon; + } + + FlatSetFieldNode fsfn=new FlatSetFieldNode(dst_tmp, fan.getField(), src_tmp); - np_baseexp.getEnd().addNext(fsfn); - FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN)); - fsfn.addNext(fon2); - return new NodePair(np_src.getBegin(), fon2); + last.addNext(fsfn); + last=fsfn; + if (pre) { + FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN)); + fsfn.addNext(fon2); + last=fon2; + } + return new NodePair(first, last); } else { if (nn.getField()!=null) { //It is a field + //Get src value + + //See if we need to perform an operation + if (base!=null) { + //If it is a preinc we need to store the initial value + TempDescriptor src_tmp2=pre?TempDescriptor.tempFactory("src",an.getDest().getType()):out_temp; + TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType()); + + FlatFieldNode ffn=new FlatFieldNode(nn.getField(), getTempforVar(nn.getVar()), src_tmp2); + if (first==null) + first=ffn; + else { + last.addNext(ffn); + } + last=ffn; + FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base); + src_tmp=tmp; + last.addNext(fon); + last=fon; + } + FlatSetFieldNode fsfn=new FlatSetFieldNode(getTempforVar(nn.getVar()), nn.getField(), src_tmp); - last.addNext(fsfn); - FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN)); - fsfn.addNext(fon2); - return new NodePair(np_src.getBegin(), fon2); + if (first==null) { + first=fsfn; + } else { + last.addNext(fsfn); + } + last=fsfn; + if (pre) { + FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN)); + fsfn.addNext(fon2); + last=fon2; + } + return new NodePair(first, last); } else { //It is a variable + //See if we need to perform an operation + + if (base!=null) { + //If it is a preinc we need to store the initial value + TempDescriptor src_tmp2=getTempforVar(nn.getVar()); + TempDescriptor tmp=TempDescriptor.tempFactory("srctmp3",an.getDest().getType()); + if (!pre) { + FlatOpNode fon=new FlatOpNode(out_temp, src_tmp2, null, new Operation(Operation.ASSIGN)); + if (first==null) + first=fon; + else + last.addNext(fon); + last=fon; + } + + FlatOpNode fon=new FlatOpNode(tmp, src_tmp2, src_tmp, base); + if (first==null) + first=fon; + else + last.addNext(fon); + src_tmp=tmp; + last=fon; + } + FlatOpNode fon=new FlatOpNode(getTempforVar(nn.getVar()), src_tmp, null, new Operation(Operation.ASSIGN)); last.addNext(fon); - FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN)); - fon.addNext(fon2); - return new NodePair(np_src.getBegin(),fon2); + last=fon; + if (pre) { + FlatOpNode fon2=new FlatOpNode(out_temp, src_tmp, null, new Operation(Operation.ASSIGN)); + fon.addNext(fon2); + last=fon2; + } + return new NodePair(first, last); } } } @@ -387,6 +528,8 @@ 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|| @@ -409,7 +552,7 @@ public class BuildFlat { NodePair assign=flattenAssignmentNode(an,out_temp); return assign; } - } + } */ NodePair left=flattenExpressionNode(on.getLeft(),temp_left); NodePair right; diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index e5292e64..9bebc91d 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -273,14 +273,22 @@ public class BuildIR { return new OpNode(parseExpression(left),parseExpression(right),op); } else if (isNode(pn,"unaryplus")|| isNode(pn,"unaryminus")|| - isNode(pn,"postinc")|| - isNode(pn,"postdec")|| - isNode(pn,"preinc")|| - isNode(pn,"not")|| - isNode(pn,"predec")) { + isNode(pn,"not")) { ParseNode left=pn.getFirstChild(); Operation op=new Operation(pn.getLabel()); return new OpNode(parseExpression(left),op); + } else if (isNode(pn,"postinc")|| + isNode(pn,"postdec")) { + ParseNode left=pn.getFirstChild(); + AssignOperation op=new AssignOperation(pn.getLabel()); + return new AssignmentNode(parseExpression(left),null,op); + + } else if (isNode(pn,"preinc")|| + isNode(pn,"predec")) { + ParseNode left=pn.getFirstChild(); + AssignOperation op=isNode(pn,"preinc")?new AssignOperation(AssignOperation.PLUSEQ):new AssignOperation(AssignOperation.MINUSEQ); + return new AssignmentNode(parseExpression(left), + new LiteralNode("integer",new Integer(1)),op); } else if (isNode(pn,"literal")) { String literaltype=pn.getTerminal(); ParseNode literalnode=pn.getChild(literaltype); diff --git a/Robust/src/IR/Tree/SemanticCheck.java b/Robust/src/IR/Tree/SemanticCheck.java index a6e07f5a..9be66a38 100644 --- a/Robust/src/IR/Tree/SemanticCheck.java +++ b/Robust/src/IR/Tree/SemanticCheck.java @@ -414,7 +414,14 @@ public class SemanticCheck { } void checkAssignmentNode(Descriptor md, SymbolTable nametable, AssignmentNode an, TypeDescriptor td) { - checkExpressionNode(md, nametable, an.getSrc() ,td); + boolean postinc=true; + if (an.getOperation().getBaseOp()==null|| + (an.getOperation().getBaseOp().getOp()!=Operation.POSTINC&& + an.getOperation().getBaseOp().getOp()!=Operation.POSTDEC)) + postinc=false; + + if (!postinc) + checkExpressionNode(md, nametable, an.getSrc() ,td); //TODO: Need check on validity of operation here if (!((an.getDest() instanceof FieldAccessNode)|| (an.getDest() instanceof ArrayAccessNode)|| @@ -433,7 +440,7 @@ public class SemanticCheck { } } - if (!typeutil.isSuperorType(an.getDest().getType(),an.getSrc().getType())) { + if (!postinc&&!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)); } } @@ -767,10 +774,10 @@ public class SemanticCheck { throw new Error(); case Operation.UNARYPLUS: case Operation.UNARYMINUS: - case Operation.POSTINC: - case Operation.POSTDEC: - case Operation.PREINC: - case Operation.PREDEC: + /* case Operation.POSTINC: + case Operation.POSTDEC: + case Operation.PREINC: + case Operation.PREDEC:*/ if (!ltd.isNumber()) throw new Error(); //5.6.1 Unary Numeric Promotion diff --git a/Robust/src/Tests/DoTests b/Robust/src/Tests/DoTests index 1b2356ba..b044ba58 100755 --- a/Robust/src/Tests/DoTests +++ b/Robust/src/Tests/DoTests @@ -9,3 +9,4 @@ dotest BoundsFail4 BoundsFail4.java dotest StringTest StringTest.java dotest Test Test.java dotest virtualcalltest virtualcalltest.java +dotest IncTest IncTest.java diff --git a/Robust/src/Tests/IncTest.java b/Robust/src/Tests/IncTest.java new file mode 100644 index 00000000..bedb3d65 --- /dev/null +++ b/Robust/src/Tests/IncTest.java @@ -0,0 +1,28 @@ +public class IncTest { + + public static void main() { + int x[]=new int[20]; + for(int i=0;i<10;) { + x[i++]++; + } + for(int i=0;i<20;i++) { + System.printInt(x[i]); + System.printString("\n"); + } + System.printString("----------------\n"); + + x=new int[20]; + for(int i=0;i<10;) { + x[++i]+=1; + } + for(int i=0;i<20;i++) { + System.printInt(x[i]); + System.printString("\n"); + } + + + } + + + +} diff --git a/Robust/src/Tests/Test.java b/Robust/src/Tests/Test.java index 09fc88cc..85b9c8d4 100644 --- a/Robust/src/Tests/Test.java +++ b/Robust/src/Tests/Test.java @@ -6,12 +6,12 @@ public class Test { public static void main() { Test t=new Test(); for(int i=3;i<10000;i++) { - boolean flag=true; - for(int j=2;flag&&j