Add beginning of support for dsm
[IRC.git] / Robust / src / IR / Tree / SemanticCheck.java
index 00c89724d2e96c0e6f23c8ea4dbc90a6c0db32fe..af01c8861d89642ae9d29232572c2719d0a78cdc 100644 (file)
@@ -18,7 +18,7 @@ public class SemanticCheck {
        // Do descriptors first
        while(it.hasNext()) {
            ClassDescriptor cd=(ClassDescriptor)it.next();
-           System.out.println("Checking class: "+cd);
+           //System.out.println("Checking class: "+cd);
            //Set superclass link up
            if (cd.getSuper()!=null) {
                cd.setSuper(typeutil.getClass(cd.getSuper()));
@@ -32,7 +32,7 @@ public class SemanticCheck {
            /* Check to see that fields are well typed */
            for(Iterator field_it=cd.getFields();field_it.hasNext();) {
                FieldDescriptor fd=(FieldDescriptor)field_it.next();
-               System.out.println("Checking field: "+fd);
+               //System.out.println("Checking field: "+fd);
                checkField(cd,fd);
            }
 
@@ -70,8 +70,10 @@ public class SemanticCheck {
                throw new Error("Undefined class "+name);
            td.setClassDescriptor(field_cd);
            return;
-       }
-       throw new Error();
+       } else if (td.isTag())
+           return;
+       else
+           throw new Error();
     }
 
     public void checkField(ClassDescriptor cd, FieldDescriptor fd) {
@@ -91,7 +93,7 @@ public class SemanticCheck {
        }
     }
 
-    public void checkFlagEffects(TaskDescriptor td, Vector vfe) {
+    public void checkFlagEffects(TaskDescriptor td, Vector vfe, SymbolTable nametable) {
        if (vfe==null)
            return; /* No flag effects to check */
        for(int i=0;i<vfe.size();i++) {
@@ -120,6 +122,17 @@ public class SemanticCheck {
                    throw new Error("Attempting to modify external flag: "+name);
                flag.setFlag(flag_d);
            }
+           for(int j=0;j<fe.numTagEffects();j++) {
+               TagEffect tag=fe.getTagEffect(j);
+               String name=tag.getName();
+               
+               Descriptor d=(Descriptor)nametable.get(name);
+               if (d==null)
+                   throw new Error("Tag descriptor "+name+" undeclared");
+               else if (!(d instanceof TagVarDescriptor))
+                   throw new Error(name+" is not a tag descriptor");
+               tag.setTag((TagVarDescriptor)d);
+           }
        }
     }
 
@@ -134,13 +147,14 @@ public class SemanticCheck {
            if (!param_type.isClass())
                throw new Error("Cannot have non-object argument to a task");
            ClassDescriptor cd=param_type.getClassDesc();
-           checkFlagExpressionNode(cd, fen);
-           checkFlagEffects(td, td.getFlagEffects());
-
-           /* Check that the task code is valid */
-           BlockNode bn=state.getMethodBody(td);
-           checkBlockNode(td, td.getParameterTable(),bn);
+           if (fen!=null)
+               checkFlagExpressionNode(cd, fen);
        }
+
+       checkFlagEffects(td, td.getFlagEffects(),td.getParameterTable());
+       /* Check that the task code is valid */
+       BlockNode bn=state.getMethodBody(td);
+       checkBlockNode(td, td.getParameterTable(),bn);
     }
 
     public void checkFlagExpressionNode(ClassDescriptor cd, FlagExpressionNode fen) {
@@ -189,7 +203,7 @@ public class SemanticCheck {
     }
 
     public void checkMethodBody(ClassDescriptor cd, MethodDescriptor md) {
-       System.out.println("Processing method:"+md);
+       //System.out.println("Processing method:"+md);
        BlockNode bn=state.getMethodBody(md);
        checkBlockNode(md, md.getParameterTable(),bn);
     }
@@ -212,6 +226,10 @@ public class SemanticCheck {
        case Kind.DeclarationNode:
            checkDeclarationNode(md, nametable, (DeclarationNode)bsn);
            return;
+
+       case Kind.TagDeclarationNode:
+           checkTagDeclarationNode(md, nametable, (TagDeclarationNode)bsn);
+           return;
            
        case Kind.IfStatementNode:
            checkIfStatementNode(md, nametable, (IfStatementNode)bsn);
@@ -232,6 +250,10 @@ public class SemanticCheck {
        case Kind.SubBlockNode:
            checkSubBlockNode(md, nametable, (SubBlockNode)bsn);
            return;
+
+       case Kind.AtomicNode:
+           checkAtomicNode(md, nametable, (AtomicNode)bsn);
+           return;
        }
        throw new Error();
     }
@@ -252,11 +274,25 @@ public class SemanticCheck {
        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 checkReturnNode(Descriptor d, SymbolTable nametable, ReturnNode rn) {
        if (d instanceof TaskDescriptor)
            throw new Error("Illegal return appears in Task: "+d.getSymbol());
@@ -276,7 +312,7 @@ public class SemanticCheck {
     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());
+       checkFlagEffects((TaskDescriptor)md, ten.getFlagEffects(),nametable);
        checkConstraintCheck((TaskDescriptor) md, nametable, ten.getChecks());
     }
 
@@ -367,7 +403,7 @@ public class SemanticCheck {
        else
            fd=(FieldDescriptor) ltd.getClassDesc().getFieldTable().get(fieldname);
        if (fd==null)
-           throw new Error("Unknown field "+fieldname);
+           throw new Error("Unknown field "+fieldname + " in "+fan.printNode(0));
        fan.setField(fd);
        if (td!=null)
            if (!typeutil.isSuperorType(td,fan.getType()))
@@ -427,11 +463,13 @@ public class SemanticCheck {
                throw new Error("Name "+varname+" undefined");
            }
            if (d instanceof VarDescriptor) {
-               nn.setVar((VarDescriptor)d);
+               nn.setVar(d);
            } else if (d instanceof FieldDescriptor) {
                nn.setField((FieldDescriptor)d);
                nn.setVar((VarDescriptor)nametable.get("this")); /* Need a pointer to this */
-           }
+           } else if (d instanceof TagVarDescriptor) {
+               nn.setVar(d);
+           } else throw new Error("Wrong type of descriptor");
            if (td!=null)
                if (!typeutil.isSuperorType(td,nn.getType()))
                    throw new Error("Field node returns "+nn.getType()+", but need "+td);
@@ -502,6 +540,11 @@ public class SemanticCheck {
        TypeDescriptor typetolookin=con.getType();
        checkTypeDescriptor(typetolookin);
 
+       if (td!=null&&!typeutil.isSuperorType(td, typetolookin))
+           throw new Error(typetolookin + " isn't a "+td);
+
+
+
        /* Check flag effects */
        if (con.getFlagEffects()!=null) {
            FlagEffects fe=con.getFlagEffects();
@@ -518,6 +561,17 @@ public class SemanticCheck {
                    throw new Error("Attempting to modify external flag: "+name);
                flag.setFlag(flag_d);
            }
+           for(int j=0;j<fe.numTagEffects();j++) {
+               TagEffect tag=fe.getTagEffect(j);
+               String name=tag.getName();
+               
+               Descriptor d=(Descriptor)nametable.get(name);
+               if (d==null)
+                   throw new Error("Tag descriptor "+name+" undeclared");
+               else if (!(d instanceof TagVarDescriptor))
+                   throw new Error(name+" is not a tag descriptor");
+               tag.setTag((TagVarDescriptor)d);
+           }
        }
 
 
@@ -527,8 +581,8 @@ public class SemanticCheck {
        if (!typetolookin.isArray()) {
            //Array's don't need constructor calls
            ClassDescriptor classtolookin=typetolookin.getClassDesc();
-           System.out.println("Looking for "+typetolookin.getSymbol());
-           System.out.println(classtolookin.getMethodTable());
+           //System.out.println("Looking for "+typetolookin.getSymbol());
+           //System.out.println(classtolookin.getMethodTable());
            
            Set methoddescriptorset=classtolookin.getMethodTable().getSet(typetolookin.getSymbol());
            MethodDescriptor bestmd=null;
@@ -536,7 +590,7 @@ public class SemanticCheck {
            for(Iterator methodit=methoddescriptorset.iterator();methodit.hasNext();) {
                MethodDescriptor currmd=(MethodDescriptor)methodit.next();
                /* Need correct number of parameters */
-               System.out.println("Examining: "+currmd);
+               //System.out.println("Examining: "+currmd);
                if (con.numArgs()!=currmd.numParameters())
                    continue;
                for(int i=0;i<con.numArgs();i++) {
@@ -576,6 +630,10 @@ public class SemanticCheck {
        }
        if (!typeutil.isSuperorType(md2.getReturnType(), md1.getReturnType()))
                return false;
+
+       if (!typeutil.isSuperorType(md2.getClassDesc(), md1.getClassDesc()))
+               return false;
+
        return true;
     }
 
@@ -624,9 +682,10 @@ public class SemanticCheck {
            throw new Error("Unknown method call to "+min.getMethodName()+"in task"+md.getSymbol());
        }
        if (!typetolookin.isClass()) 
-           throw new Error();
+           throw new Error("Error with method call to "+min.getMethodName());
        ClassDescriptor classtolookin=typetolookin.getClassDesc();
-       System.out.println("Method name="+min.getMethodName());
+       //System.out.println("Method name="+min.getMethodName());
+
        Set methoddescriptorset=classtolookin.getMethodTable().getSet(min.getMethodName());
        MethodDescriptor bestmd=null;
        NextMethod:
@@ -654,6 +713,9 @@ public class SemanticCheck {
        if (bestmd==null)
            throw new Error("No method found for :"+min.printNode(0));
        min.setMethod(bestmd);
+
+       if ((td!=null)&&(min.getType()!=null)&&!typeutil.isSuperorType(td,  min.getType()))
+           throw new Error(min.getType()+ " is not equal to or a subclass of "+td);
        /* Check whether we need to set this parameter to implied this */
        if (!bestmd.isStatic()) {
            if (min.getExpression()==null) {
@@ -662,7 +724,6 @@ public class SemanticCheck {
                checkExpressionNode(md, nametable, min.getExpression(), null);
            }
        }
-
     }
 
 
@@ -679,11 +740,15 @@ public class SemanticCheck {
        switch(op.getOp()) {
        case Operation.LOGIC_OR:
        case Operation.LOGIC_AND:
-           if (!(ltd.isBoolean()&&rtd.isBoolean()))
+           if (!(rtd.isBoolean()))
+               throw new Error();
+           on.setRightType(rtd);
+       case Operation.LOGIC_NOT:
+           if (!(ltd.isBoolean()))
                throw new Error();
            //no promotion
            on.setLeftType(ltd);
-           on.setRightType(rtd);
+
            on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
            break;
 
@@ -816,7 +881,7 @@ public class SemanticCheck {
            on.setType(lefttype);
            break;
        default:
-           throw new Error();
+           throw new Error(op.toString());
        }
    
        if (td!=null)