]> git.mdlowis.com Git - proto/obnc.git/commitdiff
added parsing rules for array types
authorMichael D. Lowis <mike.lowis@gentex.com>
Thu, 29 Apr 2021 17:59:24 +0000 (13:59 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Thu, 29 Apr 2021 17:59:24 +0000 (13:59 -0400)
cerise/oberon0/OSP.Mod
cerise/src/grammar.c
cerise/tests/Module.m

index 7b0fb376888599f7d1775e672c2794fa9eacb7f5..ef157dca9fcfe8b8b36ff07692bdc5f28a15d907 100644 (file)
@@ -372,6 +372,7 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
         ELSE\r
           OSS.Mark("END?")\r
         END\r
+\r
       ELSIF sym = OSS.while THEN\r
         OSS.Get(sym);\r
         L := OSG.pc;\r
@@ -383,6 +384,7 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
         OSG.BJump(L);\r
         OSG.FixLink(x.a);\r
         Check(OSS.end, "no END")\r
+\r
       ELSIF sym = OSS.repeat THEN\r
         OSS.Get(sym);\r
         L := OSG.pc;\r
@@ -392,6 +394,7 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
           expression(x);\r
           CheckBool(x);\r
           OSG.CBJump(x, L)\r
+\r
         ELSE\r
           OSS.Mark("missing UNTIL");\r
           OSS.Get(sym)\r
@@ -424,33 +427,68 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
   PROCEDURE Type(VAR type: OSG.Type);\r
     VAR obj, first: OSG.Object; x: OSG.Item; tp: OSG.Type;\r
   BEGIN type := OSG.intType; (*sync*)\r
-    IF (sym # OSS.ident) & (sym < OSS.array) THEN OSS.Mark("type?");\r
+    IF (sym # OSS.ident) & (sym < OSS.array) THEN\r
+      OSS.Mark("type?");\r
       REPEAT OSS.Get(sym) UNTIL (sym = OSS.ident) OR (sym >= OSS.array)\r
     END ;\r
+\r
     IF sym = OSS.ident THEN\r
-      find(obj); OSS.Get(sym);\r
-      IF obj.class = OSG.Typ THEN type := obj.type ELSE OSS.Mark("type?") END\r
+      find(obj);\r
+      OSS.Get(sym);\r
+      IF obj.class = OSG.Typ THEN\r
+        type := obj.type\r
+      ELSE\r
+        OSS.Mark("type?")\r
+      END\r
+\r
     ELSIF sym = OSS.array THEN\r
-      OSS.Get(sym); expression(x);\r
-      IF (x.mode # OSG.Const) OR (x.a < 0) THEN OSS.Mark("bad index") END ;\r
-      IF sym = OSS.of THEN OSS.Get(sym) ELSE OSS.Mark("OF?") END ;\r
-      Type(tp); NEW(type); type.form := OSG.Array; type.base := tp;\r
-      type.len := x.a; type.size := type.len * tp.size\r
+      OSS.Get(sym);\r
+      expression(x);\r
+      IF (x.mode # OSG.Const) OR (x.a < 0) THEN\r
+        OSS.Mark("bad index")\r
+      END ;\r
+      IF sym = OSS.of THEN\r
+        OSS.Get(sym)\r
+      ELSE\r
+        OSS.Mark("OF?")\r
+      END ;\r
+      Type(tp);\r
+      NEW(type);\r
+      type.form := OSG.Array;\r
+      type.base := tp;\r
+      type.len := x.a;\r
+      type.size := type.len * tp.size\r
+\r
     ELSIF sym = OSS.record THEN\r
-      OSS.Get(sym); NEW(type); type.form := OSG.Record; type.size := 0; OpenScope;\r
+      OSS.Get(sym);\r
+      NEW(type);\r
+      type.form := OSG.Record;\r
+      type.size := 0;\r
+      OpenScope;\r
       REPEAT\r
         IF sym = OSS.ident THEN\r
-          IdentList(OSG.Fld, first); Type(tp); obj := first;\r
+          IdentList(OSG.Fld, first);\r
+          Type(tp);\r
+          obj := first;\r
           WHILE obj # NIL DO\r
-            obj.type := tp; obj.val := type.size; type.size := type.size + obj.type.size; obj := obj.next\r
+            obj.type := tp;\r
+            obj.val := type.size;\r
+            type.size := type.size + obj.type.size;\r
+            obj := obj.next\r
           END\r
         END ;\r
-        IF sym = OSS.semicolon THEN OSS.Get(sym)\r
-        ELSIF sym = OSS.ident THEN OSS.Mark("; ?")\r
+        IF sym = OSS.semicolon THEN\r
+          OSS.Get(sym)\r
+        ELSIF sym = OSS.ident THEN\r
+          OSS.Mark("; ?")\r
         END\r
       UNTIL sym # OSS.ident;\r
-      type.dsc := topScope.next; CloseScope; Check(OSS.end, "no END")\r
-    ELSE OSS.Mark("ident?")\r
+      type.dsc := topScope.next;\r
+      CloseScope;\r
+      Check(OSS.end, "no END")\r
+\r
+    ELSE\r
+      OSS.Mark("ident?")\r
     END\r
   END Type;\r
 \r
@@ -482,9 +520,15 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
     IF sym = OSS.type THEN\r
       OSS.Get(sym);\r
       WHILE sym = OSS.ident DO\r
-        NewObj(obj, OSG.Typ); OSS.Get(sym);\r
-        IF sym = OSS.eql THEN OSS.Get(sym) ELSE OSS.Mark("=?") END ;\r
-        Type(obj.type); Check(OSS.semicolon, "; expected")\r
+        NewObj(obj, OSG.Typ);\r
+        OSS.Get(sym);\r
+        IF sym = OSS.eql THEN\r
+            OSS.Get(sym)\r
+        ELSE\r
+          OSS.Mark("=?")\r
+        END ;\r
+        Type(obj.type);\r
+        Check(OSS.semicolon, "; expected")\r
       END\r
     END ;\r
 \r
index 58e941192e520e72204ad5587816e0cb03f0c9bc..d0f81871b74528176821be3c26a86794f108d560 100644 (file)
@@ -253,6 +253,32 @@ RULE(expression)
     }
 }
 
+RULE(type)
+{
+    (void)item;
+    if (matches(p, IDENT))
+    {
+        expect(p, IDENT);
+    }
+    else if (accept(p, ARRAY))
+    {
+        expression(p, item);
+        if (item->mode != ITEM_CONST)
+        {
+            error(p, "non-constant array size");
+        }
+        expect(p, OF);
+        type(p, item);
+    }
+    else if (accept(p, RECORD))
+    {
+    }
+    else
+    {
+        error(p, "expected a type");
+    }
+}
+
 RULE(var_decl)
 {
     (void)item;
@@ -299,7 +325,26 @@ RULE(var_decl)
 
 RULE(type_decl)
 {
-    (void)p, (void)item;
+    char* name = NULL;
+    bool export = false;
+    Symbol* sym = NULL;
+
+    while (1)
+    {
+        name = expect_text(p, IDENT);
+        export = accept(p, '*');
+        sym = symbol_new(p, name, SYM_TYPE, export);
+        expect(p, '=');
+        type(p, item);
+//        expression(p, item);
+//        sym->imm = item->imm;
+//        sym->type = item->type;
+
+        if (!matches(p, IDENT))
+        {
+            break;
+        }
+    }
 }
 
 RULE(const_decl)
@@ -313,6 +358,7 @@ RULE(const_decl)
         name = expect_text(p, IDENT);
         export = accept(p, '*');
         sym = symbol_new(p, name, SYM_CONST, export);
+
         expect(p, '=');
         expression(p, item);
         sym->imm = item->imm;
@@ -450,6 +496,11 @@ RULE(module)
         expect(p, END);
     }
     codegen_endproc(p);
+
+    if (!matches(p, END_FILE))
+    {
+        error(p, "expected end of file");
+    }
 }
 
 static inline char* file_load(char* path)
@@ -523,10 +574,10 @@ TEST_SUITE(Grammar)
 {
     TEST(Should parse basic module syntax)
     {
-        parse_module("Empty", "module Empty; end Empty;");
-        parse_module("ModA",  "module ModA; import ModB; end ModA;");
-        parse_module("ModA",  "module ModA; const FOO = 42; end ModA;");
-        parse_module("ModA",  "module ModA; var foo : Int; end ModA;");
+        parse_module("Empty", "module Empty");
+        parse_module("ModA",  "module ModA import ModB");
+        parse_module("ModA",  "module ModA const FOO = 42");
+        parse_module("ModA",  "module ModA var foo : Int");
     }
 
     TEST(Should parse imports)
index 57fcc0541480626f3342de70c5f018229d8bb4f9..d73b8e4be51f836377684ccfc01d31ebedad6950 100644 (file)
@@ -1,58 +1,65 @@
 module Module
 
 #import
-#    A = Foo
-#    B = Bar
+#  A = Foo
+#  B = Bar
 
 const
-    A = true
-    B = 42
+  A = true
+  B = 42
+
+type
+  TypeA = Int
+  TypeB = array 5 of Int
+  TypeC = array 5 of
+        array 10 of Int
+  TypeD = record
 
 var
-    a : Bool
-    b : Int
-    c : Int
+  a : Bool
+  b : Int
+  c : Int
 
 begin
-#    a = true;
-#    a = A;
-#    b = 24;
-#    b = B;
+#  a = true;
+#  a = A;
+#  b = 24;
+#  b = B;
 #
-#    # Unary ops
-#    b = +b;
-#    b = -b;
+#  # Unary ops
+#  b = +b;
+#  b = -b;
 #
-#    # Arithmetic ops
-#    c = b + 1;
-#    c = b - 1;
-#    c = b * 1;
-#    c = b / 1;
-#    c = b % 1;
+#  # Arithmetic ops
+#  c = b + 1;
+#  c = b - 1;
+#  c = b * 1;
+#  c = b / 1;
+#  c = b % 1;
 #
-#    # Comparison ops
-#    c = b == 1;
-#    c = b != 1;
-#    c = b < 1;
-#    c = b > 1;
-#    c = b <= 1;
-#    c = b >= 1;
+#  # Comparison ops
+#  c = b == 1;
+#  c = b != 1;
+#  c = b < 1;
+#  c = b > 1;
+#  c = b <= 1;
+#  c = b >= 1;
 #
-#    # Register ops
-#    c = 1 + b;
-#    c = 1 - b;
-#    c = 1 * b;
+#  # Register ops
+#  c = 1 + b;
+#  c = 1 - b;
+#  c = 1 * b;
 #
-#    c = b + b;
+#  c = b + b;
 #
-#    # Complex arithmetic
-#    c = b + b * b + b;
-
-    if 1 == 1 then
-        c = 1;
-    elsif 2 == 2 then
-        c = 2;
-    else
-        c = 3;
-    end
+#  # Complex arithmetic
+#  c = b + b * b + b;
+#
+  if 1 == 1 then
+    c = 1;
+  elsif 2 == 2 then
+    c = 2;
+  else
+    c = 3;
+  end
 end