- public void checkFlagEffects(TaskDescriptor td, Vector vfe) {
- if (vfe==null)
- return; /* No flag effects to check */
- for(int i=0;i<vfe.size();i++) {
- FlagEffects fe=(FlagEffects) vfe.get(i);
- String varname=fe.getName();
- //Make sure the variable is declared as a parameter to the task
- VarDescriptor vd=(VarDescriptor)td.getParameterTable().get(varname);
- if (vd==null)
- throw new Error("Parameter "+varname+" in Flag Effects not declared");
- fe.setVar(vd);
-
- //Make sure it correspods to a class
- TypeDescriptor type_d=vd.getType();
- if (!type_d.isClass())
- throw new Error("Cannot have non-object argument for flag_effect");
-
- ClassDescriptor cd=type_d.getClassDesc();
- for(int j=0;j<fe.numEffects();j++) {
- FlagEffect flag=fe.getEffect(j);
- String name=flag.getName();
- FlagDescriptor flag_d=(FlagDescriptor)cd.getFlagTable().get(name);
- //Make sure the flag is declared
- if (flag_d==null)
- throw new Error("Flag descriptor "+name+" undefined in class: "+cd.getSymbol());
- if (flag_d.getExternal())
- throw new Error("Attempting to modify external flag: "+name);
- flag.setFlag(flag_d);
- }
- }
+ throw new Error();
+ }
+
+ void checkBlockExpressionNode(Descriptor md, SymbolTable nametable, BlockExpressionNode ben) {
+ checkExpressionNode(md, nametable, ben.getExpression(), null);
+ }
+
+ void checkDeclarationNode(Descriptor md, SymbolTable nametable, DeclarationNode dn) {
+ VarDescriptor vd=dn.getVarDescriptor();
+ checkTypeDescriptor(((md instanceof MethodDescriptor)?((MethodDescriptor)md).getClassDesc():null), vd.getType());
+ Descriptor d=nametable.get(vd.getSymbol());
+ if ((d==null)||
+ (d instanceof FieldDescriptor)) {
+ nametable.add(vd);
+ } else
+ throw new Error(vd.getSymbol()+" in "+md+" defined a second time");
+ if (dn.getExpression()!=null)
+ checkExpressionNode(md, nametable, dn.getExpression(), vd.getType());
+ }
+
+ void checkTagDeclarationNode(Descriptor md, SymbolTable nametable, TagDeclarationNode dn) {
+ TagVarDescriptor vd=dn.getTagVarDescriptor();
+ Descriptor d=nametable.get(vd.getSymbol());
+ if ((d==null)||
+ (d instanceof FieldDescriptor)) {
+ nametable.add(vd);
+ } else
+ throw new Error(vd.getSymbol()+" defined a second time");
+ }
+
+ void checkSubBlockNode(Descriptor md, SymbolTable nametable, SubBlockNode sbn) {
+ checkBlockNode(md, nametable, sbn.getBlockNode());
+ }
+
+ void checkAtomicNode(Descriptor md, SymbolTable nametable, AtomicNode sbn) {
+ checkBlockNode(md, nametable, sbn.getBlockNode());
+ }
+
+ void checkSynchronizedNode(Descriptor md, SymbolTable nametable, SynchronizedNode sbn) {
+ checkBlockNode(md, nametable, sbn.getBlockNode());
+ //todo this could be Object
+ checkExpressionNode(md, nametable, sbn.getExpr(), null);
+ }
+
+ void checkContinueBreakNode(Descriptor md, SymbolTable nametable, ContinueBreakNode cbn) {
+ if (loopstack.empty())
+ throw new Error("continue/break outside of loop");
+ Object o = loopstack.peek();
+ if(o instanceof LoopNode) {
+ LoopNode ln=(LoopNode)o;
+ 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());
+ MethodDescriptor md=(MethodDescriptor)d;
+ if (rn.getReturnExpression()!=null)
+ if (md.getReturnType()==null)
+ throw new Error("Constructor can't return something.");
+ else if (md.getReturnType().isVoid())
+ throw new Error(md+" is void");
+ else
+ checkExpressionNode(md, nametable, rn.getReturnExpression(), md.getReturnType());
+ else
+ if (md.getReturnType()!=null&&!md.getReturnType().isVoid())
+ throw new Error("Need to return something for "+md);
+ }
+
+ void checkTaskExitNode(Descriptor md, SymbolTable nametable, TaskExitNode ten) {
+ if (md instanceof MethodDescriptor)
+ throw new Error("Illegal taskexit appears in Method: "+md.getSymbol());
+ checkFlagEffects((TaskDescriptor)md, ten.getFlagEffects(),nametable);
+ checkConstraintCheck((TaskDescriptor) md, nametable, ten.getChecks());
+ }
+
+ void checkIfStatementNode(Descriptor md, SymbolTable nametable, IfStatementNode isn) {
+ checkExpressionNode(md, nametable, isn.getCondition(), new TypeDescriptor(TypeDescriptor.BOOLEAN));
+ checkBlockNode(md, nametable, isn.getTrueBlock());
+ if (isn.getFalseBlock()!=null)
+ checkBlockNode(md, nametable, isn.getFalseBlock());
+ }
+
+ void checkSwitchStatementNode(Descriptor md, SymbolTable nametable, SwitchStatementNode ssn) {
+ checkExpressionNode(md, nametable, ssn.getCondition(), new TypeDescriptor(TypeDescriptor.INT));
+
+ BlockNode sbn = ssn.getSwitchBody();
+ boolean hasdefault = false;
+ for(int i = 0; i < sbn.size(); i++) {
+ boolean containdefault = checkSwitchBlockNode(md, nametable, (SwitchBlockNode)sbn.get(i));
+ if(hasdefault && containdefault) {
+ throw new Error("Error: duplicate default branch in switch-case statement in Method: " + md.getSymbol());
+ }
+ hasdefault = containdefault;
+ }
+ }
+
+ boolean checkSwitchBlockNode(Descriptor md, SymbolTable nametable, SwitchBlockNode sbn) {
+ Vector<SwitchLabelNode> slnv = sbn.getSwitchConditions();
+ int defaultb = 0;
+ for(int i = 0; i < slnv.size(); i++) {
+ if(slnv.elementAt(i).isdefault) {
+ defaultb++;
+ } else {
+ checkConstantExpressionNode(md, nametable, slnv.elementAt(i).getCondition(), new TypeDescriptor(TypeDescriptor.INT));
+ }