Further upgrades to semantic checker
authorbdemsky <bdemsky>
Thu, 2 Mar 2006 20:04:17 +0000 (20:04 +0000)
committerbdemsky <bdemsky>
Thu, 2 Mar 2006 20:04:17 +0000 (20:04 +0000)
Robust/src/IR/ClassDescriptor.java
Robust/src/IR/Tree/CastNode.java
Robust/src/IR/Tree/FieldAccessNode.java
Robust/src/IR/Tree/LiteralNode.java
Robust/src/IR/Tree/NameNode.java
Robust/src/IR/Tree/SemanticCheck.java
Robust/src/IR/TypeDescriptor.java
Robust/src/IR/TypeUtil.java

index f9af871cb7b0caf1e9ea57ab60738550171d6fb2..173db73b385e665ce9e2ce70a01857ea94865084 100644 (file)
@@ -17,6 +17,8 @@ public class ClassDescriptor extends Descriptor {
 
     String classname;
     String superclass;
+    ClassDescriptor superdesc;
+
     Modifiers modifiers;
 
     SymbolTable fields;
@@ -35,6 +37,10 @@ public class ClassDescriptor extends Descriptor {
        return fields;
     }
 
+    public SymbolTable getMethodTable() {
+       return methods;
+    }
+
     public String printTree(State state) {
        int indent;
        String st=modifiers.toString()+"class "+classname;
@@ -82,7 +88,15 @@ public class ClassDescriptor extends Descriptor {
        this.superclass=superclass;
     }
 
-    protected String getSuper() {
+    public ClassDescriptor getSuperDesc() {
+       return superdesc;
+    }
+
+    public void setSuper(ClassDescriptor scd) {
+       this.superdesc=scd;
+    }
+
+    public String getSuper() {
        return superclass;
     }
 }
index 4e7dd8ddedd8e199c83d4f7e19885d42b8ea1bae..911bd64c11e8d2c6e426e0205dcbbc58169414f1 100644 (file)
@@ -26,6 +26,14 @@ public class CastNode extends ExpressionNode  {
        return exp;
     }
 
+    public void setType(TypeDescriptor td) {
+       this.td=td;
+    }
+
+    public NameNode getTypeName() {
+       return (NameNode) etd;
+    }
+
     public String printNode(int indentlevel) {
        if (etd==null)
            return "("+td.toString()+")"+exp.printNode(indentlevel);
index eee8ffb4f6f78f27de44cb428146f3e03f38e79d..7f97562c281e687cc12c9254bbefad72ab4ec644 100644 (file)
@@ -1,5 +1,6 @@
 package IR.Tree;
 import IR.FieldDescriptor;
+import IR.TypeDescriptor;
 
 public class FieldAccessNode extends ExpressionNode {
     ExpressionNode left;
@@ -15,6 +16,10 @@ public class FieldAccessNode extends ExpressionNode {
        field=fd;
     }
 
+    public String getFieldName() {
+       return fieldname;
+    }
+
     public FieldDescriptor getField() {
        return field;
     }
@@ -29,4 +34,8 @@ public class FieldAccessNode extends ExpressionNode {
     public int kind() {
        return Kind.FieldAccessNode;
     }
+    public TypeDescriptor getType() {
+       return getField().getType();
+    }
+
 }
index f3b71f01f8a99c42562e848a12bbaf4f213d8b11..9d9a10e569d08a501826a1a45d1d140feed65e3a 100644 (file)
@@ -21,6 +21,10 @@ public class LiteralNode extends ExpressionNode {
        type=null;
     }
 
+    public String getTypeString() {
+       return typestr;
+    }
+
     public TypeDescriptor getType() {
        return type;
     }
index 79885640a6894de4bb61743fdaf09839fdfba5ad..b46df0671a8848dfcabad2fd756374be4e0f9f70 100644 (file)
@@ -1,15 +1,32 @@
 package IR.Tree;
 import IR.NameDescriptor;
+import IR.VarDescriptor;
+import IR.TypeDescriptor;
 
 public class NameNode extends ExpressionNode {
     NameDescriptor name;
+    VarDescriptor vd;
+
     public NameNode(NameDescriptor nd) {
        this.name=nd;
     }
 
+    public void setVar(VarDescriptor vd) {
+       this.vd=vd;
+    }
+
+    public TypeDescriptor getType() {
+       return vd.getType();
+    }
+
+    NameDescriptor getName() {
+       return name;
+    }
+
     public String printNode(int indent) {
        return name.toString();
     }
+
     public int kind() {
        return Kind.NameNode;
     }
index fcec66abc6ee9afdc50761b411481c4269de495c..7086d6dad72094ace6305d64489ec997b2544989 100644 (file)
@@ -15,20 +15,38 @@ public class SemanticCheck {
     public void semanticCheck() {
        SymbolTable classtable=state.getClassSymbolTable();
        Iterator it=classtable.getDescriptorsIterator();
+       // Do descriptors first
        while(it.hasNext()) {
            ClassDescriptor cd=(ClassDescriptor)it.next();
            System.out.println("Checking class: "+cd);
+           //Set superclass link up
+           if (cd.getSuper()!=null) {
+               cd.setSuper(typeutil.getClass(cd.getSuper()));
+               // Link together Field and Method tables
+               cd.getFieldTable().setParent(cd.getSuperDesc().getFieldTable());
+               cd.getMethodTable().setParent(cd.getSuperDesc().getMethodTable());
+           }
+           
            for(Iterator field_it=cd.getFields();field_it.hasNext();) {
                FieldDescriptor fd=(FieldDescriptor)field_it.next();
                System.out.println("Checking field: "+fd);
                checkField(cd,fd);
            }
-
            for(Iterator method_it=cd.getMethods();method_it.hasNext();) {
                MethodDescriptor md=(MethodDescriptor)method_it.next();
                checkMethod(cd,md);
            }
        }
+
+       it=classtable.getDescriptorsIterator();
+       // Do descriptors first
+       while(it.hasNext()) {
+           ClassDescriptor cd=(ClassDescriptor)it.next();
+           for(Iterator method_it=cd.getMethods();method_it.hasNext();) {
+               MethodDescriptor md=(MethodDescriptor)method_it.next();
+               checkMethodBody(cd,md);
+           }
+       }
     }
 
     public void checkTypeDescriptor(TypeDescriptor td) {
@@ -57,9 +75,12 @@ public class SemanticCheck {
            TypeDescriptor param_type=md.getParamType(i);
            checkTypeDescriptor(param_type);
        }
-       BlockNode bn=state.getMethodBody(md);
        /* Link the naming environments */
        md.getParameterTable().setParent(cd.getFieldTable());
+    }
+
+    public void checkMethodBody(ClassDescriptor cd, MethodDescriptor md) {
+       BlockNode bn=state.getMethodBody(md);
        checkBlockNode(md, md.getParameterTable(),bn);
     }
     
@@ -162,32 +183,134 @@ public class SemanticCheck {
        throw new Error();
     }
 
-    void checkAssignmentNode(MethodDescriptor md, SymbolTable nametable, AssignmentNode an, TypeDescriptor td) {
-       
-    }
-
     void checkCastNode(MethodDescriptor md, SymbolTable nametable, CastNode cn, TypeDescriptor td) {
-    }
+       /* Get type descriptor */
+       if (cn.getType()==null) {
+           NameDescriptor typenamed=cn.getTypeName().getName();
+           String typename=typenamed.toString();
+           TypeDescriptor ntd=new TypeDescriptor(typeutil.getClass(typename));
+           cn.setType(ntd);
+       }
 
-    void checkCreateObjectNode(MethodDescriptor md, SymbolTable nametable, CreateObjectNode con, TypeDescriptor td) {
+       /* Check the type descriptor */
+       TypeDescriptor cast_type=cn.getType();
+       checkTypeDescriptor(cast_type);
+
+       /* Type check */
+       if (td!=null) {
+           if (!typeutil.isSuperorType(td,cast_type))
+               throw new Error("Cast node returns "+cast_type+", but need "+td);
+       }
+
+       ExpressionNode en=cn.getExpression();
+       checkExpressionNode(md, nametable, en, null);
+       TypeDescriptor etd=en.getType();
+       if (typeutil.isSuperorType(cast_type,etd)) /* Cast trivially succeeds */
+           return;
+
+       if (typeutil.isSuperorType(etd,cast_type)) /* Cast may succeed */
+           return;
+
+       /* Different branches */
+       /* TODO: change if add interfaces */
+       throw new Error("Cast will always fail\n"+cn.printNode(0));
     }
 
     void checkFieldAccessNode(MethodDescriptor md, SymbolTable nametable, FieldAccessNode fan, TypeDescriptor td) {
+       ExpressionNode left=fan.getExpression();
+       checkExpressionNode(md,nametable,left,null);
+       TypeDescriptor ltd=left.getType();
+       String fieldname=fan.getFieldName();
+       FieldDescriptor fd=(FieldDescriptor) ltd.getClassDesc().getFieldTable().get(fieldname);
+       if (fd==null)
+           throw new Error("Unknown field "+fieldname);
+       fan.setField(fd);
+       if (td!=null)
+           if (!typeutil.isSuperorType(td,fan.getType()))
+               throw new Error("Field node returns "+fan.getType()+", but need "+td);
     }
 
     void checkLiteralNode(MethodDescriptor md, SymbolTable nametable, LiteralNode ln, TypeDescriptor td) {
-       
-    }
+       /* Resolve the type */
+       Object o=ln.getValue();
+       if (ln.getTypeString().equals("null")) {
+           ln.setType(new TypeDescriptor(TypeDescriptor.NULL));
+       } else if (o instanceof Integer) {
+           ln.setType(new TypeDescriptor(TypeDescriptor.INT));
+       } else if (o instanceof Long) {
+           ln.setType(new TypeDescriptor(TypeDescriptor.LONG));
+       } else if (o instanceof Float) {
+           ln.setType(new TypeDescriptor(TypeDescriptor.FLOAT));
+       } else if (o instanceof Double) {
+           ln.setType(new TypeDescriptor(TypeDescriptor.DOUBLE));
+       } else if (o instanceof Character) {
+           ln.setType(new TypeDescriptor(TypeDescriptor.CHAR));
+       } else if (o instanceof String) {
+           ln.setType(new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass)));
+       } 
 
-    void checkMethodInvokeNode(MethodDescriptor md, SymbolTable nametable, MethodInvokeNode min, TypeDescriptor td) {
+       if (td!=null)
+           if (!typeutil.isSuperorType(td,ln.getType()))
+               throw new Error("Field node returns "+ln.getType()+", but need "+td);
     }
 
     void checkNameNode(MethodDescriptor md, SymbolTable nametable, NameNode nn, TypeDescriptor td) {
+       NameDescriptor nd=nn.getName();
+       String varname=nd.toString();
+       VarDescriptor vd=(VarDescriptor)nametable.get(varname);
+       if (vd==null) {
+           throw new Error("Variable "+varname+" undefined");
+       }
+       nn.setVar(vd);
+       if (td!=null)
+           if (!typeutil.isSuperorType(td,nn.getType()))
+               throw new Error("Field node returns "+nn.getType()+", but need "+td);
     }
 
-    void checkOpNode(MethodDescriptor md, SymbolTable nametable, OpNode on,TypeDescriptor td) {
+    void checkAssignmentNode(MethodDescriptor md, SymbolTable nametable, AssignmentNode an, TypeDescriptor td) {
+       checkExpressionNode(md, nametable, an.getSrc() ,td);
+       //TODO: Need check on validity of operation here
+       if (!((an.getDest() instanceof FieldAccessNode)||
+             (an.getDest() instanceof NameNode)))
+           throw new Error("Bad lside in "+an.printNode(0));
+       checkExpressionNode(md, nametable, an.getDest(), null);
+       if (!typeutil.isSuperorType(an.getDest().getType(),an.getSrc().getType()))
+           throw new Error("Type of rside not compatible with type of lside"+an.printNode(0));
     }
 
     void checkLoopNode(MethodDescriptor md, SymbolTable nametable, LoopNode ln) {
+       if (ln.getType()==LoopNode.WHILELOOP||ln.getType()==LoopNode.DOWHILELOOP) {
+           checkExpressionNode(md, nametable, ln.getCondition(), new TypeDescriptor(TypeDescriptor.BOOLEAN));
+           checkBlockNode(md, nametable, ln.getBody());
+       } else {
+           //For loop case
+           /* Link in the initializer naming environment */
+           BlockNode bn=ln.getInitializer();
+           bn.getVarTable().setParent(nametable);
+           for(int i=0;i<bn.size();i++) {
+               BlockStatementNode bsn=bn.get(i);
+               checkBlockStatementNode(md, bn.getVarTable(),bsn);
+           }
+           //check the condition
+           checkExpressionNode(md, bn.getVarTable(), ln.getCondition(), new TypeDescriptor(TypeDescriptor.BOOLEAN));
+           checkBlockNode(md, bn.getVarTable(), ln.getBody());
+           checkBlockNode(md, bn.getVarTable(), ln.getUpdate());
+       }
+    }
+
+
+    void checkCreateObjectNode(MethodDescriptor md, SymbolTable nametable, CreateObjectNode con, TypeDescriptor td) {
+       
+    }
+
+
+    void checkMethodInvokeNode(MethodDescriptor md, SymbolTable nametable, MethodInvokeNode min, TypeDescriptor td) {
+
     }
+
+
+    void checkOpNode(MethodDescriptor md, SymbolTable nametable, OpNode on,TypeDescriptor td) {
+    }
+
+
 }
index 1832c5719678b196554e9be4c190d799580723d7..14bb96e0dc06c8fa49d8d87596cb4a4862d6eaf4 100644 (file)
@@ -22,7 +22,6 @@ public class TypeDescriptor extends Descriptor {
 
 
     int type;
-    NameDescriptor name_desc;
     ClassDescriptor class_desc;
 
     public void setClassDescriptor(ClassDescriptor cd) {
@@ -44,10 +43,19 @@ public class TypeDescriptor extends Descriptor {
     public TypeDescriptor(NameDescriptor name) {
        super(name.toString());
        this.type=CLASS;
-       this.name_desc=name;
        this.class_desc=null;
     }
 
+    public ClassDescriptor getClassDesc() {
+       return class_desc;
+    }
+
+    public TypeDescriptor(ClassDescriptor cd) {
+       super(cd.getSymbol());
+       this.type=CLASS;
+       this.class_desc=cd;
+    }
+
     public TypeDescriptor(int t) {
        super(decodeInt(t));
        this.type=t;
@@ -55,7 +63,7 @@ public class TypeDescriptor extends Descriptor {
 
     public String toString() {
        if (type==CLASS)
-           return name_desc.toString();
+           return name;
        else 
            return decodeInt(type);
     }
index 99123806fb26a7468b33ba6b043129b15a793aaf..fa43bed9437ad3ad7b1143bcbbf420280cc3c8d5 100644 (file)
@@ -33,6 +33,14 @@ public class TypeUtil {
        return (ClassDescriptor)supertable.get(cd);
     }
 
+    public boolean isSuperorType(TypeDescriptor possiblesuper, TypeDescriptor cd2) {
+       if ((possiblesuper.getClassDesc()==null)||
+           cd2.getClassDesc()==null)
+           throw new Error();
+       return isSuperorType(possiblesuper.getClassDesc(), cd2.getClassDesc());
+    }
+
+
     public boolean isSuperorType(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
        if (possiblesuper==cd2)
            return true;