From: bdemsky Date: Thu, 2 Mar 2006 20:04:17 +0000 (+0000) Subject: Further upgrades to semantic checker X-Git-Tag: preEdgeChange~965 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b1054c61b3034d4ccdf1dc795ee48af3c6e6cd3c;p=IRC.git Further upgrades to semantic checker --- diff --git a/Robust/src/IR/ClassDescriptor.java b/Robust/src/IR/ClassDescriptor.java index f9af871c..173db73b 100644 --- a/Robust/src/IR/ClassDescriptor.java +++ b/Robust/src/IR/ClassDescriptor.java @@ -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; } } diff --git a/Robust/src/IR/Tree/CastNode.java b/Robust/src/IR/Tree/CastNode.java index 4e7dd8dd..911bd64c 100644 --- a/Robust/src/IR/Tree/CastNode.java +++ b/Robust/src/IR/Tree/CastNode.java @@ -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); diff --git a/Robust/src/IR/Tree/FieldAccessNode.java b/Robust/src/IR/Tree/FieldAccessNode.java index eee8ffb4..7f97562c 100644 --- a/Robust/src/IR/Tree/FieldAccessNode.java +++ b/Robust/src/IR/Tree/FieldAccessNode.java @@ -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(); + } + } diff --git a/Robust/src/IR/Tree/LiteralNode.java b/Robust/src/IR/Tree/LiteralNode.java index f3b71f01..9d9a10e5 100644 --- a/Robust/src/IR/Tree/LiteralNode.java +++ b/Robust/src/IR/Tree/LiteralNode.java @@ -21,6 +21,10 @@ public class LiteralNode extends ExpressionNode { type=null; } + public String getTypeString() { + return typestr; + } + public TypeDescriptor getType() { return type; } diff --git a/Robust/src/IR/Tree/NameNode.java b/Robust/src/IR/Tree/NameNode.java index 79885640..b46df067 100644 --- a/Robust/src/IR/Tree/NameNode.java +++ b/Robust/src/IR/Tree/NameNode.java @@ -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; } diff --git a/Robust/src/IR/Tree/SemanticCheck.java b/Robust/src/IR/Tree/SemanticCheck.java index fcec66ab..7086d6da 100644 --- a/Robust/src/IR/Tree/SemanticCheck.java +++ b/Robust/src/IR/Tree/SemanticCheck.java @@ -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