Enable interface for mgc version.
authorjzhou <jzhou>
Wed, 27 Oct 2010 22:07:37 +0000 (22:07 +0000)
committerjzhou <jzhou>
Wed, 27 Oct 2010 22:07:37 +0000 (22:07 +0000)
12 files changed:
Robust/src/IR/ClassDescriptor.java
Robust/src/IR/Flat/BuildCode.java
Robust/src/IR/Flat/BuildCodeMGC.java
Robust/src/IR/SymbolTable.java
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/Tree/SemanticCheck.java
Robust/src/IR/TypeUtil.java
Robust/src/IR/Virtual.java
Robust/src/Lex/Keyword.java
Robust/src/Lex/Lexer.java
Robust/src/Parse/java14.cup
Robust/src/Tests/InterfaceTest.java [new file with mode: 0644]

index f9d1959589536fd89f7150fc33a9fc9648342e61..6c3735b283105feae79bcbf61546ce79cf7ac6a6 100644 (file)
@@ -19,6 +19,11 @@ public class ClassDescriptor extends Descriptor {
   
   int numstaticblocks = 0;
   int numstaticfields = 0;
+  
+  // for interfaces
+  boolean isInterface=false;
+  Vector<String> superinterfaces;
+  SymbolTable superIFdesc;
 
   public ClassDescriptor(String classname) {
     this("", classname);
@@ -33,6 +38,8 @@ public class ClassDescriptor extends Descriptor {
     methods=new SymbolTable();
     classid=UIDCount++;
     this.packagename=packagename;
+    superinterfaces = new Vector<String>();
+    superIFdesc = new SymbolTable();
   }
 
   public int getId() {
@@ -50,6 +57,10 @@ public class ClassDescriptor extends Descriptor {
   public Iterator getFlags() {
     return flags.getDescriptorsIterator();
   }
+  
+  public Iterator getSuperInterfaces() {
+    return this.superIFdesc.getDescriptorsIterator();
+  }
 
   public SymbolTable getFieldTable() {
     return fields;
@@ -66,6 +77,10 @@ public class ClassDescriptor extends Descriptor {
   public SymbolTable getMethodTable() {
     return methods;
   }
+  
+  public SymbolTable getSuperInterfaceTable() {
+    return this.superIFdesc;
+  }
 
   public String getSafeDescriptor() {
     return "L"+safename.replace('.','/');
@@ -76,6 +91,17 @@ public class ClassDescriptor extends Descriptor {
     String st=modifiers.toString()+"class "+getSymbol();
     if (superclass!=null)
       st+="extends "+superclass.toString();
+    if(this.superinterfaces != null) {
+      st += "implements ";
+      boolean needcomma = false;
+      for(int i = 0; i < this.superinterfaces.size(); i++) {
+        if(needcomma) {
+          st += ", ";
+        }
+        st += this.superinterfaces.elementAt(i);
+        needcomma = true;
+      }
+    }
     st+=" {\n";
     indent=TreeNode.INDENT;
     boolean printcr=false;
@@ -153,6 +179,18 @@ public class ClassDescriptor extends Descriptor {
     return superclass;
   }
   
+  public void addSuperInterface(String superif) {
+    this.superinterfaces.addElement(superif);
+  }
+  
+  public Vector<String> getSuperInterface() {
+    return this.superinterfaces;
+  }
+  
+  public void addSuperInterfaces(ClassDescriptor sif) {
+    this.superIFdesc.add(sif);
+  }
+  
   public void incStaticBlocks() {
     this.numstaticblocks++;
   }
@@ -172,4 +210,12 @@ public class ClassDescriptor extends Descriptor {
   public boolean isAbstract() {
     return this.modifiers.isAbstract();
   }
+  
+  public boolean isInterface() {
+    return this.isInterface;
+  }
+  
+  public void setAsInterface() {
+    this.isInterface = true;
+  }
 }
index 35ce9bccc5b7b256a688cbd104324913496e794e..52108168f29deb14edcb185a0336787483aff4cc 100644 (file)
@@ -394,7 +394,9 @@ public class BuildCode {
       while(it_sclasses.hasNext()) {
         ClassDescriptor cd = (ClassDescriptor)it_sclasses.next();
         MethodDescriptor md = (MethodDescriptor)cd.getMethodTable().get("staticblocks");
-        tovisit.add(md);
+        if(md != null) {
+          tovisit.add(md);
+        }
       }
 
       while(!tovisit.isEmpty()) {
@@ -1191,6 +1193,14 @@ public class BuildCode {
     /* Get inherited methods */
     if (cd.getSuperDesc()!=null)
       fillinRow(cd.getSuperDesc(), virtualtable, rownum);
+    if(state.MGC) {
+      // TODO add version for normal Java later
+      Iterator it_sifs = cd.getSuperInterfaces();
+      while(it_sifs.hasNext()) {
+        ClassDescriptor superif = (ClassDescriptor)it_sifs.next();
+        fillinRow(superif, virtualtable, rownum);
+      }
+    }
     /* Override them with our methods */
     for(Iterator it=cd.getMethods(); it.hasNext();) {
       MethodDescriptor md=(MethodDescriptor)it.next();
index 52dc69c8aa149ea0fc851b1995af7314fe725553..2e1211d883fcbbe16c2399d4979aec040158df9b 100644 (file)
@@ -189,15 +189,17 @@ public class BuildCodeMGC extends BuildCode {
           // TODO may need to invoke static field initialization here
         }
         MethodDescriptor t_md = (MethodDescriptor)t_cd.getMethodTable().get("staticblocks");
-        outmethod.println("   {");
-        if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
-          outmethod.print("       struct "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={");
-          outmethod.println("1, NULL};");
-          outmethod.println("     "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);");
-        } else {
-          outmethod.println("     "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
+        if(t_md != null) {
+          outmethod.println("   {");
+          if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+            outmethod.print("       struct "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={");
+            outmethod.println("1, NULL};");
+            outmethod.println("     "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);");
+          } else {
+            outmethod.println("     "+t_cd.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
+          }
+          outmethod.println("   }");
         }
-        outmethod.println("   }");
       }
       outmethod.println("#undef MGC_STATIC_INIT_CHECK");
     }
index ed1d1337c2d81791be6249bb0c477e6885e0c311..6532671f1bdee658db1f34c730cbf4478a8affec 100644 (file)
@@ -7,11 +7,14 @@ public class SymbolTable {
   private Hashtable table;
   private SymbolTable parent;
   private HashSet valueset;
+  
+  private Vector<SymbolTable> parentIFs;
 
   public SymbolTable() {
     table = new Hashtable();
     valueset = new HashSet();
     this.parent = null;
+    this.parentIFs = null;
   }
 
   public SymbolTable(SymbolTable parent) {
@@ -99,6 +102,11 @@ public class SymbolTable {
       hs=(HashSet) parent.getAllValueSet();
     else
       hs=new HashSet();
+    if (this.parentIFs != null) {
+      for(int i = 0; i < this.parentIFs.size(); i++) {
+        hs.addAll(this.parentIFs.elementAt(i).getAllValueSet());
+      }
+    }
     hs.addAll(valueset);
     return hs;
   }
@@ -118,6 +126,18 @@ public class SymbolTable {
   public void setParent(SymbolTable parent) {
     this.parent = parent;
   }
+  
+  public Vector<SymbolTable> getParentIFs() {
+    return this.parentIFs;
+  }
+
+  public void addParentIF(SymbolTable parentif) {
+    if(this.parentIFs == null) {
+      this.parentIFs = new Vector<SymbolTable>();
+    }
+    this.parentIFs.addElement(parentif);
+  }
+
 
   public String toString() {
     return "ST: " + table.toString();
index 5cef8cc2b73a79a7dd3210da89b6c522c24b0618..ddae6ac02042445defe27975d8d093e6caef9381 100644 (file)
@@ -60,12 +60,94 @@ public class BuildIR {
          if (toanalyze!=null)
            toanalyze.add(td);
          state.addTask(td);
-       } else {
+       } else if ((state.MGC) && isNode(type_pn,"interface_declaration")) {
+      // TODO add version for normal Java later
+      ClassDescriptor cn = parseInterfaceDecl(type_pn);
+      if (toanalyze!=null)
+        toanalyze.add(cn);
+      state.addClass(cn);
+    } else {
          throw new Error(type_pn.getLabel());
        }
       }
     }
   }
+  
+  public ClassDescriptor parseInterfaceDecl(ParseNode pn) {
+    ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal());
+    cn.setAsInterface();
+    if (!isEmpty(pn.getChild("superIF").getTerminal())) {
+      /* parse inherited interface name */
+      ParseNode snlist=pn.getChild("superIF").getChild("extend_interface_list");
+      ParseNodeVector pnv=snlist.getChildren();
+      for(int i=0; i<pnv.size(); i++) {
+        ParseNode decl=pnv.elementAt(i);
+        if (isNode(decl,"type")) {
+          NameDescriptor nd=parseName(decl.getChild("class").getChild("name"));
+          cn.addSuperInterface(nd.toString());
+        }
+      }
+    }
+    cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
+    parseInterfaceBody(cn, pn.getChild("interfacebody"));
+    return cn;
+  }
+  
+  private void parseInterfaceBody(ClassDescriptor cn, ParseNode pn) {
+    assert(cn.isInterface());
+    ParseNode decls=pn.getChild("interface_member_declaration_list");
+    if (decls!=null) {
+      ParseNodeVector pnv=decls.getChildren();
+      for(int i=0; i<pnv.size(); i++) {
+        ParseNode decl=pnv.elementAt(i);
+        if (isNode(decl,"constant")) {
+          parseInterfaceConstant(cn,decl);
+        } else if (isNode(decl,"method")) {
+          parseInterfaceMethod(cn,decl.getChild("method_declaration"));
+        } else throw new Error();
+      }
+    }
+  }
+  
+  private void parseInterfaceConstant(ClassDescriptor cn, ParseNode pn) {
+    if (pn!=null) {
+      parseFieldDecl(cn,pn.getChild("field_declaration"));
+      return;
+    }
+    throw new Error();
+  }
+  
+  private void parseInterfaceMethod(ClassDescriptor cn, ParseNode pn) {
+    ParseNode headern=pn.getChild("header");
+    ParseNode bodyn=pn.getChild("body");
+    MethodDescriptor md=parseMethodHeader(headern.getChild("method_header"));
+    md.getModifiers().addModifier(Modifiers.PUBLIC);
+    md.getModifiers().addModifier(Modifiers.ABSTRACT);
+    try {
+      BlockNode bn=parseBlock(bodyn);
+      cn.addMethod(md);
+      state.addTreeCode(md,bn);
+
+      // this is a hack for investigating new language features
+      // at the AST level, someday should evolve into a nice compiler
+      // option *wink*
+      //if( cn.getSymbol().equals( ***put a class in here like:     "Test" ) &&
+      //    md.getSymbol().equals( ***put your method in here like: "main" ) 
+      //) {
+      //  bn.setStyle( BlockNode.NORMAL );
+      //  System.out.println( bn.printNode( 0 ) );
+      //}
+
+    } catch (Exception e) {
+      System.out.println("Error with method:"+md.getSymbol());
+      e.printStackTrace();
+      throw new Error();
+    } catch (Error e) {
+      System.out.println("Error with method:"+md.getSymbol());
+      e.printStackTrace();
+      throw new Error();
+    }
+  }
 
   public TaskDescriptor parseTaskDecl(ParseNode pn) {
     TaskDescriptor td=new TaskDescriptor(pn.getChild("name").getTerminal());
@@ -236,6 +318,19 @@ public class BuildIR {
             cn.getSymbol().equals(TypeUtil.TagClass)))
        cn.setSuper(TypeUtil.ObjectClass);
     }
+    // check inherited interfaces
+    if (!isEmpty(pn.getChild("superIF").getTerminal())) {
+      /* parse inherited interface name */
+      ParseNode snlist=pn.getChild("superIF").getChild("interface_type_list");
+      ParseNodeVector pnv=snlist.getChildren();
+      for(int i=0; i<pnv.size(); i++) {
+        ParseNode decl=pnv.elementAt(i);
+        if (isNode(decl,"type")) {
+          NameDescriptor nd=parseName(decl.getChild("class").getChild("name"));
+          cn.addSuperInterface(nd.toString());
+        }
+      }
+    }
     cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
     parseClassBody(cn, pn.getChild("classbody"));
     return cn;
@@ -339,6 +434,17 @@ public class BuildIR {
   private void parseFieldDecl(ClassDescriptor cn,ParseNode pn) {
     ParseNode mn=pn.getChild("modifier");
     Modifiers m=parseModifiersList(mn);
+    if((state.MGC) && cn.isInterface()) {
+      // TODO add version for normal Java later
+      // Can only be PUBLIC or STATIC or FINAL
+      if((m.isAbstract()) || (m.isAtomic()) || (m.isNative()) 
+          || (m.isSynchronized())) {
+        throw new Error("Error: field in Interface " + cn.getSymbol() + "can only be PUBLIC or STATIC or FINAL");
+      }
+      m.addModifier(Modifiers.PUBLIC);
+      m.addModifier(Modifiers.STATIC);
+      m.addModifier(Modifiers.FINAL);
+    }
 
     ParseNode tn=pn.getChild("type");
     TypeDescriptor t=parseTypeDescriptor(tn);
index ba8467048bcf6cfefaea51d4573dbfb1540284e9..7fa1899c85717ec67cfc243cbc198fe406218843 100644 (file)
@@ -38,6 +38,18 @@ public class SemanticCheck {
        cd.getFieldTable().setParent(cd.getSuperDesc().getFieldTable());
        cd.getMethodTable().setParent(cd.getSuperDesc().getMethodTable());
        cd.getFlagTable().setParent(cd.getSuperDesc().getFlagTable());
+    if(state.MGC) {
+      // TODO add version for normal Java later
+      // Link together Field, Method tables do classes inherit these from 
+      // their ancestor interfaces
+      Vector<String> sifv = cd.getSuperInterface();
+      for(int i = 0; i < sifv.size(); i++) {
+        ClassDescriptor superif = getClass(sifv.elementAt(i));
+        cd.addSuperInterfaces(superif);
+        cd.getFieldTable().addParentIF(superif.getFieldTable());
+        cd.getMethodTable().addParentIF(superif.getMethodTable());
+      }
+    }
       }
       
       /* Check to see that fields are well typed */
@@ -218,8 +230,8 @@ public class SemanticCheck {
       // TODO add version for normal Java later
       /* Check for abstract methods */
       if(md.isAbstract()) {
-        if(!cd.isAbstract()) {
-          throw new Error("Error! The non-abstract Class " + cd.getSymbol() + "contains an abstract method " + md.getSymbol());
+        if(!cd.isAbstract() && !cd.isInterface()) {
+          throw new Error("Error! The non-abstract Class " + cd.getSymbol() + " contains an abstract method " + md.getSymbol());
         }
       }
     }
index d289a9535e8d20ba2956d174d2826fbc65460b41..72d8405105a3aab469b97530f4d4d5082c9bee7c 100644 (file)
@@ -1,5 +1,7 @@
 package IR;
 import java.util.*;
+
+import IR.Flat.FlatNode;
 import IR.Tree.*;
 import java.io.File;
 import Main.Main;
@@ -15,6 +17,9 @@ public class TypeUtil {
   Hashtable supertable;
   Hashtable subclasstable;
   BuildIR bir;
+  
+  // for interfaces
+  Hashtable superIFtbl;
 
   public TypeUtil(State state, BuildIR bir) {
     this.state=state;
@@ -63,11 +68,23 @@ public class TypeUtil {
        supertable.put(cd,cd_super);
       }
     }
+    if (!this.superIFtbl.containsKey(cd)) {
+      // add inherited interfaces
+      superIFtbl.put(cd,new HashSet());
+      HashSet hs=(HashSet)superIFtbl.get(cd);
+      Vector<String> superifv = cd.getSuperInterface();
+      for(int i = 0; i < superifv.size(); i++) {
+        String superif = superifv.elementAt(i);
+        ClassDescriptor if_super = getClass(superif, todo);
+        hs.add(if_super);
+      }
+    }
     return cd;
   }
 
   private void createTables() {
     supertable=new Hashtable();
+    superIFtbl = new Hashtable();
   }
 
   public ClassDescriptor getMainClass() {
@@ -181,18 +198,69 @@ NextMethod:
 
   public void createFullTable() {
     subclasstable=new Hashtable();
+    //subIFclasstable = new Hashtable();
+    HashSet tovisit=new HashSet();
+    HashSet visited=new HashSet();
 
     Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
     while(classit.hasNext()) {
       ClassDescriptor cd=(ClassDescriptor)classit.next();
       ClassDescriptor tmp=cd.getSuperDesc();
+      
+      if(state.MGC) {
+        // TODO add version for normal Java later
+        // check tmp's interface ancestors
+        Iterator it_sifs = cd.getSuperInterfaces();
+        while(it_sifs.hasNext()) {
+          ClassDescriptor cdt = (ClassDescriptor)it_sifs.next();
+          if(!tovisit.contains(cdt)){
+            tovisit.add(cdt);
+          }
+        }
+      }
 
       while(tmp!=null) {
-       if (!subclasstable.containsKey(tmp))
-         subclasstable.put(tmp,new HashSet());
-       HashSet hs=(HashSet)subclasstable.get(tmp);
-       hs.add(cd);
-       tmp=tmp.getSuperDesc();
+        if (!subclasstable.containsKey(tmp))
+          subclasstable.put(tmp,new HashSet());
+        HashSet hs=(HashSet)subclasstable.get(tmp);
+        hs.add(cd);
+        if(state.MGC) {
+          // TODO add version for normal Java later
+          // check tmp's interface ancestors
+          Iterator it_sifs = tmp.getSuperInterfaces();
+          while(it_sifs.hasNext()) {
+            ClassDescriptor cdt = (ClassDescriptor)it_sifs.next();
+            if(!tovisit.contains(cdt)){
+              tovisit.add(cdt);
+            }
+          }
+        }
+        tmp=tmp.getSuperDesc();
+      }
+      
+      if(state.MGC) {
+        // TODO add version for normal Java later
+        while(!tovisit.isEmpty()) {
+          ClassDescriptor sif = (ClassDescriptor)tovisit.iterator().next();
+          tovisit.remove(sif);
+          
+          if(!visited.contains(sif)) {
+            if(!this.subclasstable.containsKey(sif)) {
+              this.subclasstable.put(sif, new HashSet());
+            }
+            HashSet hs = (HashSet)this.subclasstable/*subIFclasstable*/.get(sif);
+            hs.add(cd);
+            
+            Iterator it_sifs = sif.getSuperInterfaces();
+            while(it_sifs.hasNext()) {
+              ClassDescriptor siftmp = (ClassDescriptor)it_sifs.next();
+              if(!tovisit.contains(siftmp)){
+                tovisit.add(siftmp);
+              }
+            }
+            visited.add(sif);
+          }
+        }
       }
     }
   }
@@ -204,6 +272,10 @@ NextMethod:
   public ClassDescriptor getSuper(ClassDescriptor cd) {
     return (ClassDescriptor)supertable.get(cd);
   }
+  
+  public Set getSuperIFs(ClassDescriptor cd) {
+    return (Set)this.superIFtbl.get(cd);
+  }
 
   public boolean isCastable(TypeDescriptor original, TypeDescriptor casttype) {
     if (original.isChar()&&
@@ -327,11 +399,65 @@ NextMethod:
   }
 
   private boolean isSuper(ClassDescriptor possiblesuper, ClassDescriptor cd2) {
+    HashSet tovisit=new HashSet();
+    HashSet visited=new HashSet();
+    
+    if(state.MGC) {
+      // TODO add version for normal Java later
+      // check cd2's interface ancestors
+      Iterator it_sifs = getSuperIFs(cd2).iterator();
+      while(it_sifs.hasNext()) {
+        ClassDescriptor cd = (ClassDescriptor)it_sifs.next();
+        if(cd == possiblesuper) {
+          return true;
+        } else if(!tovisit.contains(cd)){
+          tovisit.add(cd);
+        }
+      }
+    }
 
     while(cd2!=null) {
       cd2=getSuper(cd2);
       if (cd2==possiblesuper)
        return true;
+      
+      if(state.MGC) {
+        // TODO add version for normal Java later
+        // check cd2's interface ancestors
+        if(cd2 != null) {
+          Iterator it_sifs = getSuperIFs(cd2).iterator();
+          while(it_sifs.hasNext()) {
+            ClassDescriptor cd = (ClassDescriptor)it_sifs.next();
+            if(cd == possiblesuper) {
+              return true;
+            } else if(!tovisit.contains(cd)){
+              tovisit.add(cd);
+            }
+          }
+        }
+      }
+    }
+    
+    if(state.MGC) {
+      // TODO add version for normal Java later
+      while(!tovisit.isEmpty()) {
+        ClassDescriptor cd = (ClassDescriptor)tovisit.iterator().next();
+        tovisit.remove(cd);
+        
+        if(!visited.contains(cd)) {
+          Iterator it_sifs = getSuperIFs(cd).iterator();
+          while(it_sifs.hasNext()) {
+            ClassDescriptor cdt = (ClassDescriptor)it_sifs.next();
+            if(cdt == possiblesuper) {
+              return true;
+            } else if(!tovisit.contains(cdt)){
+              tovisit.add(cdt);
+            }
+          }
+          visited.add(cd);
+        }
+      }
+        
     }
     return false;
   }
index aea9ac7f14053f896a61b9420740e7e0f96688c1..907ce865c8e4ac7a29a5f18c23cf587fcb09bc3a 100644 (file)
@@ -97,6 +97,15 @@ public class Virtual {
     int start=0;
     if (superdesc!=null)
       start=numberMethods(superdesc);
+    if(state.MGC) {
+      // TODO add version for normal Java later
+      // check the inherited interfaces
+      Iterator it_sifs = cd.getSuperInterfaces();
+      while(it_sifs.hasNext()) {
+        ClassDescriptor superif = (ClassDescriptor)it_sifs.next();
+        start += numberMethods(superif); // TODO Can there be duplicated methods from multiple ancestors?
+      }
+    }
     for(Iterator it=cd.getMethods(); it.hasNext();) {
       MethodDescriptor md=(MethodDescriptor)it.next();
       if (md.isStatic()||md.getReturnType()==null)
@@ -113,6 +122,26 @@ public class Virtual {
            break;
          }
        }
+    if(state.MGC) {
+      // TODO add version for normal Java later
+      if(!foundmatch) {
+        // check if there is a matched method in inherited interfaces
+        Iterator it_sifs = cd.getSuperInterfaces();
+        while(it_sifs.hasNext() && !foundmatch) {
+          ClassDescriptor superif = (ClassDescriptor)it_sifs.next();
+          Set possiblematches_if=superif.getMethodTable().getSet(md.getSymbol());
+          for(Iterator matchit=possiblematches_if.iterator(); matchit.hasNext();) {
+            MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
+            if (md.matches(matchmd)) {
+              int num=((Integer)methodnumber.get(matchmd)).intValue();
+              methodnumber.put(md, new Integer(num));
+              foundmatch=true;
+              break;
+            }
+          }
+        }
+      }
+    }
        if (!foundmatch)
          methodnumber.put(md, new Integer(start++));
       } else {
index 3b830c8d0ff3fafa6b8b7a0894b1f0517baecbe6..b10d949c391365373371aa78121b8cc2e02cb1c7 100644 (file)
@@ -88,5 +88,8 @@ class Keyword extends Token {
     //Keywords for coarse-grain parallelization
     key_table.put("sese", new Integer(Sym.SESE));
     key_table.put("rblock", new Integer(Sym.RBLOCK));
+    // Keywords for interface of mgc
+    key_table.put("interface", new Integer(Sym.INTERFACE));
+    key_table.put("implements", new Integer(Sym.IMPLEMENTS));
   }
 }
index 34f24fdef0c523dfcbc492e2e8c33f0396dd6453..14a25697c39a02e0e0f958b0c1e789160c07638f 100644 (file)
@@ -262,9 +262,9 @@ public class Lexer {
     "extends", "external", "final", "finally",
     "flag", //keyword for failure aware computation
     "float", "for", "genreach", "getoffset", "global", "goto", "if",
-    //"implements",
+    "implements",
     "import", "instanceof", "int",
-    //"interface",
+    "interface",
     "isavailable",
     "long",
     "native", "new", "optional", "package", "private", "protected", "public", 
index 718ef76d564075e4592450f7cd4628247df31b48..c1b5470aec617a09116e123087745fcced8e694e 100644 (file)
@@ -52,11 +52,11 @@ terminal STATIC; // modifier
 terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE;
 terminal CLASS; // class_declaration
 terminal EXTENDS; // super
-//terminal IMPLEMENTS; // interfaces
+terminal IMPLEMENTS; // interfaces
 terminal VOID; // method_header
 terminal THROWS; // throws
 terminal THIS, SUPER; // explicit_constructor_invocation
-//terminal INTERFACE; // interface_declaration
+terminal INTERFACE; // interface_declaration
 terminal IF, ELSE; // if_then_statement, if_then_else_statement
 terminal SWITCH; // switch_statement
 terminal CASE, DEFAULT; // switch_label
@@ -117,7 +117,7 @@ non terminal ParseNode integral_type, floating_point_type;
 non terminal ParseNode reference_type;
 non terminal ParseNode class_or_interface_type;
 non terminal ParseNode class_type;
-//non terminal ParseNode interface_type;
+non terminal ParseNode interface_type;
 non terminal ParseNode array_type;
 // 19.5) Names
 non terminal ParseNode name, simple_name, qualified_name;
@@ -134,7 +134,7 @@ non terminal ParseNode type_declaration;
 non terminal ParseNode modifiers_opt, modifiers, modifier;
 // 19.8.1) Class Declaration
 non terminal ParseNode class_declaration, super, super_opt;
-//non terminal interfaces, interfaces_opt, interface_type_list;
+non terminal ParseNode interfaces, interfaces_opt, interface_type_list;
 non terminal ParseNode class_body;
 non terminal ParseNode class_body_declarations, class_body_declarations_opt;
 non terminal ParseNode class_body_declaration, class_member_declaration;
@@ -157,12 +157,12 @@ non terminal ParseNode constructor_declaration, constructor_declarator;
 non terminal ParseNode constructor_body;
 non terminal ParseNode explicit_constructor_invocation;
 // 19.9.1) Interface Declarations
-//non terminal ParseNode interface_declaration;
-//non terminal ParseNode extends_interfaces_opt, extends_interfaces;
-//non terminal ParseNode interface_body;
-//non terminal ParseNode interface_member_declarations_opt, interface_member_declarations;
-//non terminal ParseNode interface_member_declaration, constant_declaration;
-//non terminal ParseNode abstract_method_declaration;
+non terminal ParseNode interface_declaration;
+non terminal ParseNode extends_interfaces_opt, extends_interfaces;
+non terminal ParseNode interface_body;
+non terminal ParseNode interface_member_declarations_opt, interface_member_declarations;
+non terminal ParseNode interface_member_declaration, constant_declaration;
+non terminal ParseNode abstract_method_declaration;
 // 19.10) Arrays
 non terminal ParseNode array_initializer;
 non terminal ParseNode variable_initializers;
@@ -569,7 +569,7 @@ class_or_interface_type ::= name:name {:
        :};
 
 class_type ::= class_or_interface_type:type {: RESULT=type; :};
-//interface_type ::= class_or_interface_type;
+interface_type ::= class_or_interface_type:type {: RESULT=type; :};
 
 array_type ::= primitive_type:prim dims:dims {: 
                ParseNode pn=(new ParseNode("type")).addChild("array");
@@ -689,7 +689,10 @@ type_declaration ::=
                {:
                        RESULT=td;
                :}
-//      |       interface_declaration
+    |   interface_declaration:in
+        {:
+                       RESULT=in;
+               :}
        |       SEMICOLON {: RESULT=new ParseNode("empty"); :}
        ;
 
@@ -730,13 +733,14 @@ modifier ::=
 
 // 19.8.1) Class Declaration:
 class_declaration ::= 
-       modifiers_opt:mo CLASS IDENTIFIER:id super_opt:so //interfaces_opt
-class_body:body 
+       modifiers_opt:mo CLASS IDENTIFIER:id super_opt:so interfaces_opt:ifo 
+       class_body:body 
        {:
        ParseNode pn=new ParseNode("class_declaration");
        pn.addChild("modifiers").addChild(mo);
        pn.addChild("name").addChild(id);
        pn.addChild("super").addChild(so);
+       pn.addChild("superIF").addChild(ifo);
        pn.addChild("classbody").addChild(body);
        RESULT=pn;
        :}
@@ -752,15 +756,23 @@ super_opt ::=
        :}
        ;
 
-//interfaces ::= IMPLEMENTS interface_type_list
-//       ;
-//interfaces_opt::=
-//       |       interfaces
-//       ;
-//interface_type_list ::=
-//               interface_type
-//       |       interface_type_list COMMA interface_type
-//       ;
+interfaces ::= IMPLEMENTS interface_type_list:iftl {: RESULT=iftl; :}
+       ;
+interfaces_opt ::=
+       {: RESULT=new ParseNode("empty"); :}
+       |       interfaces:ifs {: RESULT=ifs; :}
+       ;
+interface_type_list ::=
+               interface_type:ift {: 
+                       ParseNode pn=new ParseNode("interface_type_list");
+                       pn.addChild(ift);
+                       RESULT=pn;
+               :}
+       |       interface_type_list:iftl COMMA interface_type:ift {: 
+                       iftl.addChild(ift);
+                       RESULT=iftl;
+               :}
+       ;
 
 class_body ::= LBRACE class_body_declarations_opt:cbdo RBRACE {: RESULT=cbdo; :}
        ;
@@ -809,7 +821,9 @@ class_member_declaration ::=
        :}
        /* repeat the prod for 'class_declaration' here: */
 //     |       modifiers_opt CLASS IDENTIFIER super_opt class_body
-//      |       interface_declaration
+    |       interface_declaration:interfaced {: 
+       RESULT=(new ParseNode("interface")).addChild(interfaced).getRoot(); 
+       :}
        |       SEMICOLON       {: RESULT=new ParseNode("empty"); :}
        ;
 
@@ -1048,43 +1062,81 @@ SUPER LPAREN argument_list_opt:alo RPAREN SEMICOLON {:
 // 19.9) Interfaces
 
 // 19.9.1) Interface Declarations
-//interface_declaration ::=
-//               modifiers_opt INTERFACE IDENTIFIER extends_interfaces_opt
-//                       interface_body
-//       ;
-//extends_interfaces_opt ::=
-//       |       extends_interfaces
-//       ;
-//extends_interfaces ::=
-//               EXTENDS interface_type
-//       |       extends_interfaces COMMA interface_type
-//       ;
-//interface_body ::=
-//               LBRACE interface_member_declarations_opt RBRACE
-//       ;
-//interface_member_declarations_opt ::=
-//       |       interface_member_declarations
-//       ;
-//interface_member_declarations ::=
-//               interface_member_declaration
-//       |       interface_member_declarations interface_member_declaration
-//       ;
-//interface_member_declaration ::=
-//               constant_declaration
-//       |       abstract_method_declaration
-//       |       class_declaration
-//       |       interface_declaration
-//       |       SEMICOLON
-//       ;
-//constant_declaration ::=
-//               field_declaration
-//       // need to semantically check that modifiers of field declaration
-//       // include only PUBLIC, STATIC, or FINAL.  Other modifiers are
-//       // disallowed.
-//       ;
-//abstract_method_declaration ::=
-//               method_header SEMICOLON
-//       ;
+interface_declaration ::=
+               modifiers_opt:mo INTERFACE IDENTIFIER:id extends_interfaces_opt:io
+                       interface_body:body
+       {:
+       ParseNode pn=new ParseNode("interface_declaration");
+       pn.addChild("modifiers").addChild(mo);
+       pn.addChild("name").addChild(id);
+       pn.addChild("superIF").addChild(io);
+       pn.addChild("interfacebody").addChild(body);
+       RESULT=pn;
+       :}
+       ;
+extends_interfaces_opt ::=
+       {: RESULT=new ParseNode("empty"); :}
+       |       extends_interfaces:eifs {: RESULT=eifs; :}
+       ;
+extends_interfaces ::=
+               EXTENDS interface_type:ift 
+               {: 
+               ParseNode pn=new ParseNode("extend_interface_list");
+               pn.addChild(ift);
+               RESULT=pn; 
+               :}
+     |       extends_interfaces:eifs COMMA interface_type:ift
+             {:
+             eifs.addChild(ift);
+             RESULT=eifs;
+             :}
+       ;
+interface_body ::=
+               LBRACE interface_member_declarations_opt:imdo RBRACE
+               {: RESULT=imdo; :}
+       ;
+interface_member_declarations_opt ::=
+       {: RESULT=new ParseNode("empty"); :}
+       |       interface_member_declarations:imd {: RESULT=imd; :}
+       ;
+interface_member_declarations ::=
+               interface_member_declaration:imd {: 
+                       ParseNode pn=new ParseNode("interface_member_declaration_list");
+                       pn.addChild(imd);
+                       RESULT=pn;
+               :}
+       |       interface_member_declarations:imds interface_member_declaration:imd {: 
+                       imds.addChild(imd);
+                       RESULT=imds;
+               :}
+       ;
+interface_member_declaration ::=
+               constant_declaration:constant {: 
+               RESULT=(new ParseNode("constant")).addChild(constant).getRoot();
+       :}
+       |       abstract_method_declaration:method {:
+       RESULT=(new ParseNode("method")).addChild(method).getRoot(); 
+       :}
+//       |       class_declaration:class 
+//       |       interface_declaration:interface 
+       |       SEMICOLON {: 
+       RESULT=new ParseNode("empty"); 
+       :}
+       ;
+constant_declaration ::=
+               field_declaration:fd {: RESULT=fd; :}
+       // need to semantically check that modifiers of field declaration
+       // include only PUBLIC, STATIC, or FINAL.  Other modifiers are
+       // disallowed.
+       ;
+abstract_method_declaration ::=
+               method_header:header SEMICOLON {:
+               ParseNode pn=new ParseNode("method_declaration");
+               pn.addChild("header").addChild(header);
+               pn.addChild("body").addChild(new ParseNode("empty"));
+               RESULT=pn;
+       :}
+       ;
 
 
 // 19.10) Arrays
diff --git a/Robust/src/Tests/InterfaceTest.java b/Robust/src/Tests/InterfaceTest.java
new file mode 100644 (file)
index 0000000..80eec8f
--- /dev/null
@@ -0,0 +1,78 @@
+public interface Instrument {
+  // Compile-time constant:
+  int VALUE;// = 5; // static & final
+  // Cannot have method definitions:
+  void play(int n); // Automatically public
+  void adjust();
+}
+
+class Wind implements Instrument {
+  public Wind(){}
+  public void play(int n) {
+    System.out.println("Wind.play() " + n);
+  }
+  public String what() { return "Wind"; }
+  public void adjust() { System.out.println("Wind.adjust()"); }
+}
+
+class Percussion implements Instrument {
+  public Percussion(){}
+  public void play(int n) {
+    System.out.println("Percussion.play() " + n);
+  }
+  public String what() { return "Percussion"; }
+  public void adjust() { System.out.println("Percussion.adjust()"); }
+}
+
+class Stringed implements Instrument {
+  public Stringed(){}
+  public void play(int n) {
+    System.out.println("Stringed.play() " + n);
+  }
+  public String what() { return "Stringed"; }
+  public void adjust() { System.out.println("Stringed.adjust()"); }
+}
+
+class Brass extends Wind {
+  public Brass(){}
+  public String what() { return "Brass"; }
+}
+
+class Woodwind extends Wind {
+  public Woodwind(){}
+  public String what() { return "Woodwind"; }
+}
+
+public class InterfaceTest {
+  public InterfaceTest(){}
+  
+  // Doesn’t care about type, so new types
+  // added to the system still work right:
+  static void tune(Instrument i) {
+    // ...
+    i.play(9);
+  }
+  static void tuneAll(Instrument[] e) {
+    for(int k = 0; k < e.length; k++) {
+      Instrument i = e[k];
+      tune(i);
+    }
+  }
+  public static void main(String[] args) {
+    // Upcasting during addition to the array:
+    Instrument.VALUE=5;
+    Instrument[] orchestra = new Instrument[5];
+    orchestra[0] = new Wind();
+    orchestra[1] = new Percussion();
+    orchestra[2] = new Stringed();
+    orchestra[3] = new Brass();
+    orchestra[4] = new Woodwind();
+    tuneAll(orchestra);
+  }
+} /* Output:
+Wind.play() MIDDLE_C
+Percussion.play() MIDDLE_C
+Stringed.play() MIDDLE_C
+Wind.play() MIDDLE_C  //Brass.play() MIDDLE_C
+Wind.play() MIDDLE_C  //Woodwind.play() MIDDLE_C
+*///:~