Hack the compiler to support 'abstract' keyword for mgc version. Abstract classes...
authorjzhou <jzhou>
Mon, 25 Oct 2010 22:49:57 +0000 (22:49 +0000)
committerjzhou <jzhou>
Mon, 25 Oct 2010 22:49:57 +0000 (22:49 +0000)
Robust/src/IR/ClassDescriptor.java
Robust/src/IR/MethodDescriptor.java
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/Tree/Modifiers.java
Robust/src/IR/Tree/SemanticCheck.java
Robust/src/Parse/java14.cup
Robust/src/Tests/AbstractTest.java [new file with mode: 0644]

index b7862990f118dde2cdc7562ff89ada5d430778a5..f9d1959589536fd89f7150fc33a9fc9648342e61 100644 (file)
@@ -168,4 +168,8 @@ public class ClassDescriptor extends Descriptor {
   public int getNumStaticFields() {
     return this.numstaticfields;
   }
+  
+  public boolean isAbstract() {
+    return this.modifiers.isAbstract();
+  }
 }
index cda2616d738b4472993ad9af8eb1100e4ec74a7d..beaee6be6fa4e3f6e34bc009312e9d722933474c 100644 (file)
@@ -121,6 +121,10 @@ public class MethodDescriptor extends Descriptor {
   public boolean isStatic() {
     return modifier.isStatic();
   }
+  
+  public boolean isAbstract() {
+    return modifier.isAbstract();
+  }
 
   public boolean isConstructor() {
     return (returntype==null);
index e5f888eab0bf72427b83c045c0d80f6b0a610197..5cef8cc2b73a79a7dd3210da89b6c522c24b0618 100644 (file)
@@ -920,6 +920,8 @@ public class BuildIR {
          m.addModifier(Modifiers.SYNCHRONIZED);
        else if (isNode(modn,"atomic"))
          m.addModifier(Modifiers.ATOMIC);
+    else if (isNode(modn,"abstract"))
+      m.addModifier(Modifiers.ABSTRACT);
        else throw new Error("Unrecognized Modifier");
       }
     }
index 7f2ae46ef570c934350dec97c461ed9fabad42b6..441d2b3a17faf9353823a37d35062e75af29edb2 100644 (file)
@@ -5,7 +5,7 @@ public class Modifiers {
   public static final int PROTECTED=2;
   public static final int PRIVATE=4;
   public static final int STATIC=8;
-//     ABSTRACT=16
+  public static final int ABSTRACT=16;
   public static final int FINAL=32;
   public static final int NATIVE=64;
   public static final int SYNCHRONIZED=128;
@@ -34,6 +34,10 @@ public class Modifiers {
   public boolean isAtomic() {
     return ((value&ATOMIC)!=0);
   }
+  
+  public boolean isAbstract() {
+    return ((value&ABSTRACT)!=0);
+  }
 
   public boolean isSynchronized() {
     return ((value&SYNCHRONIZED)!=0);
@@ -69,6 +73,8 @@ public class Modifiers {
       st+="synchronized ";
     if ((value&ATOMIC)!=0)
       st+="atomic ";
+    if ((value&ABSTRACT)!=0)
+      st+="abstract ";
     return st;
   }
 }
index 0159051f78143d15c85de3118feed1cf959ccb13..ba8467048bcf6cfefaea51d4573dbfb1540284e9 100644 (file)
@@ -214,6 +214,15 @@ public class SemanticCheck {
   }
 
   public void checkMethod(ClassDescriptor cd, MethodDescriptor md) {
+    if(state.MGC) {
+      // 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());
+        }
+      }
+    }
     /* Check return type */
     if (!md.isConstructor())
       if (!md.getReturnType().isVoid())
index 477ea95a40263ebfe0a2ba66befabc4d01ac169b..718ef76d564075e4592450f7cd4628247df31b48 100644 (file)
@@ -715,7 +715,7 @@ modifier ::=
        PROTECTED {: RESULT=new ParseNode("protected"); :}|
        PRIVATE {: RESULT=new ParseNode("private"); :}|
        STATIC {: RESULT=new ParseNode("static"); :} |
-//     ABSTRACT |
+       ABSTRACT {: RESULT=new ParseNode("abstract"); :}  |
        FINAL {: RESULT=new ParseNode("final"); :}|
        NATIVE {: RESULT=new ParseNode("native"); :} |
        SYNCHRONIZED {: RESULT=new ParseNode("synchronized"); :} |
diff --git a/Robust/src/Tests/AbstractTest.java b/Robust/src/Tests/AbstractTest.java
new file mode 100644 (file)
index 0000000..044f856
--- /dev/null
@@ -0,0 +1,88 @@
+//: interfaces/music4/Music4.java
+// Abstract classes and methods.
+
+abstract class Instrument {
+  public Instrument(){}
+  private int i; // Storage allocated for each
+  public abstract void play(int n);
+  public String what() { return "Instrument"; }
+  public abstract void adjust();
+}
+
+class Wind extends Instrument {
+  public Wind(){}
+  public void play(int n) {
+    System.out.println("Wind.play() " + n);
+  }
+  public String what() { return "Wind"; }
+  public void adjust() {}
+}
+
+class Percussion extends Instrument {
+  public Percussion(){}
+  public void play(int n) {
+    System.out.println("Percussion.play() " + n);
+  }
+  public String what() { return "Percussion"; }
+  public void adjust() {}
+}
+
+class Stringed extends Instrument {
+  public Stringed(){}
+  public void play(int n) {
+    System.out.println("Stringed.play() " + n);
+  }
+  public String what() { return "Stringed"; }
+  public void adjust() {}
+}
+
+class Brass extends Wind {
+  public Brass(){}
+  public void play(int n) {
+    System.out.println("Brass.play() " + n);
+  }
+  public void adjust() { System.out.println("Brass.adjust()"); }
+}
+
+class Woodwind extends Wind {
+  public Woodwind(){}
+  public void play(int n) {
+    System.out.println("Woodwind.play() " + n);
+  }
+  public String what() { return "Woodwind"; }
+}
+
+
+public class AbstractTest {
+  
+  public AbstractTest() {}
+  
+  // 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[] 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
+Brass.play() MIDDLE_C
+Woodwind.play() MIDDLE_C
+*///:~