MethodDescriptor currmd;
TypeUtil typeutil;
+ HashSet breakset;
+ HashSet continueset;
+
public BuildFlat(State st, TypeUtil typeutil) {
state=st;
temptovar=new Hashtable();
this.typeutil=typeutil;
+ this.breakset=new HashSet();
+ this.continueset=new HashSet();
}
public Hashtable getMap() {
end=np_end;
} else {
end.addNext(np_begin);
- end=np_end;
+ if (np_end==null) {
+ return new NodePair(begin, null);
+ } else
+ end=np_end;
}
}
if (begin==null) {
cond.getEnd().addNext(fcb);
fcb.addTrueNext(true_np.getBegin());
fcb.addFalseNext(false_np.getBegin());
- true_np.getEnd().addNext(nopend);
- false_np.getEnd().addNext(nopend);
+ if (true_np.getEnd()!=null)
+ true_np.getEnd().addNext(nopend);
+ if (false_np.getEnd()!=null)
+ false_np.getEnd().addNext(nopend);
return new NodePair(cond.getBegin(), nopend);
}
FlatNop nop2=new FlatNop();
initializer.getEnd().addNext(nop2);
nop2.addNext(condition.getBegin());
- body.getEnd().addNext(update.getBegin());
+ if (body.getEnd()!=null)
+ body.getEnd().addNext(update.getBegin());
update.getEnd().addNext(backedge);
backedge.addNext(condition.getBegin());
condition.getEnd().addNext(fcb);
fcb.addFalseNext(nopend);
fcb.addTrueNext(body.getBegin());
+ for(Iterator contit=continueset.iterator();contit.hasNext();) {
+ FlatNode fn=(FlatNode)contit.next();
+ contit.remove();
+ fn.addNext(update.getBegin());
+ }
+ for(Iterator breakit=breakset.iterator();breakit.hasNext();) {
+ FlatNode fn=(FlatNode)breakit.next();
+ breakit.remove();
+ fn.addNext(nopend);
+ }
+
return new NodePair(begin,nopend);
} else if (ln.getType()==LoopNode.WHILELOOP) {
TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
condition.getEnd().addNext(fcb);
fcb.addFalseNext(nopend);
fcb.addTrueNext(body.getBegin());
+
+ for(Iterator contit=continueset.iterator();contit.hasNext();) {
+ FlatNode fn=(FlatNode)contit.next();
+ contit.remove();
+ fn.addNext(backedge);
+ }
+ for(Iterator breakit=breakset.iterator();breakit.hasNext();) {
+ FlatNode fn=(FlatNode)breakit.next();
+ breakit.remove();
+ fn.addNext(nopend);
+ }
return new NodePair(begin,nopend);
} else if (ln.getType()==LoopNode.DOWHILELOOP) {
TempDescriptor cond_temp=TempDescriptor.tempFactory("condition", new TypeDescriptor(TypeDescriptor.BOOLEAN));
fcb.addFalseNext(nopend);
fcb.addTrueNext(backedge);
backedge.addNext(body.getBegin());
+
+ for(Iterator contit=continueset.iterator();contit.hasNext();) {
+ FlatNode fn=(FlatNode)contit.next();
+ contit.remove();
+ fn.addNext(condition.getBegin());
+ }
+ for(Iterator breakit=breakset.iterator();breakit.hasNext();) {
+ FlatNode fn=(FlatNode)breakit.next();
+ breakit.remove();
+ fn.addNext(nopend);
+ }
return new NodePair(begin,nopend);
} else throw new Error();
}
return new NodePair(fsexn, fsexn);
}
+ private NodePair flattenContinueBreakNode(ContinueBreakNode cbn) {
+ FlatNop fn=new FlatNop();
+ if (cbn.isBreak())
+ breakset.add(fn);
+ else
+ continueset.add(fn);
+ return new NodePair(fn,null);
+ }
+
private NodePair flattenBlockStatementNode(BlockStatementNode bsn) {
switch(bsn.kind()) {
case Kind.BlockExpressionNode:
case Kind.SESENode:
return flattenSESENode((SESENode)bsn);
+
+ case Kind.ContinueBreakNode:
+ return flattenContinueBreakNode((ContinueBreakNode)bsn);
}
throw new Error();
}
public class SemanticCheck {
State state;
TypeUtil typeutil;
+ Stack loopstack;
+
public SemanticCheck(State state, TypeUtil tu) {
this.state=state;
this.typeutil=tu;
+ this.loopstack=new Stack();
}
public void semanticCheck() {
checkAtomicNode(md, nametable, (AtomicNode)bsn);
return;
+ case Kind.ContinueBreakNode:
+ checkContinueBreakNode(md, nametable, (ContinueBreakNode) bsn);
+ return;
+
case Kind.SESENode:
// do nothing, no semantic check for SESEs
return;
checkBlockNode(md, nametable, sbn.getBlockNode());
}
+ void checkContinueBreakNode(Descriptor md, SymbolTable nametable, ContinueBreakNode cbn) {
+ if (loopstack.empty())
+ throw new Error("continue/break outside of loop");
+ LoopNode ln=(LoopNode)loopstack.peek();
+ cbn.setLoop(ln);
+ }
+
void checkReturnNode(Descriptor d, SymbolTable nametable, ReturnNode rn) {
if (d instanceof TaskDescriptor)
throw new Error("Illegal return appears in Task: "+d.getSymbol());
}
void checkLoopNode(Descriptor md, SymbolTable nametable, LoopNode ln) {
+ loopstack.push(ln);
if (ln.getType()==LoopNode.WHILELOOP||ln.getType()==LoopNode.DOWHILELOOP) {
checkExpressionNode(md, nametable, ln.getCondition(), new TypeDescriptor(TypeDescriptor.BOOLEAN));
checkBlockNode(md, nametable, ln.getBody());
checkBlockNode(md, bn.getVarTable(), ln.getBody());
checkBlockNode(md, bn.getVarTable(), ln.getUpdate());
}
+ loopstack.pop();
}