]> git.mdlowis.com Git - proto/obnc.git/commitdiff
started adding array indexing
authorMichael D. Lowis <mike.lowis@gentex.com>
Fri, 7 May 2021 20:52:26 +0000 (16:52 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Fri, 7 May 2021 20:52:26 +0000 (16:52 -0400)
cerise/backend/c99/codegen.c
cerise/backend/test/codegen.c
cerise/backend/x86_64/codegen.c
cerise/inc/cerise.h
cerise/oberon0/OSG.Mod
cerise/oberon0/OSP.Mod
cerise/src/grammar.c
cerise/src/type_checks.c
cerise/tests/Module.m

index 6c1fd3d5a9727463a0bb0662fa9bf5775d90d3ec..9c3636f99f3620efde080fbc94c0cb1c4cf89fe3 100644 (file)
@@ -286,3 +286,19 @@ void codegen_return(Parser* p, Item* item)
         printf("    return _T%d;\n", item->reg);
     }
 }
+
+void codegen_rangecheck(Parser* p, long length, Item* index)
+{
+//    codegen_binop(p, '*', index, base);
+    if (index->mode == ITEM_CONST)
+    {
+        if (index->type->form != FORM_INT)
+        {
+            error(p, "array indexes must be of integral type");
+        }
+        else if (index->imm.i >= length)
+        {
+            error(p, "array index out of bounds");
+        }
+    }
+}
index ad2db8be3ce4e87415f4302928fcdac2e72cebd3..78e13a8a17642372b454dab3027100daf824fe7c 100644 (file)
@@ -120,3 +120,8 @@ void codegen_return(Parser* p, Item* item)
 {
     (void)p, (void)item;
 }
+
+void codegen_rangecheck(Parser* p, long length, Item* index)
+{
+    (void)p, (void)length, (void)index;
+}
index dccec0c4595bf419474f520ed074428285d1ea61..fb3ea6a0ec2267b15e43ebde0d7747063359a58c 100644 (file)
@@ -348,3 +348,8 @@ void codegen_return(Parser* p, Item* item)
 {
     (void)p, (void)item;
 }
+
+void codegen_rangecheck(Parser* p, long length, Item* index)
+{
+    (void)p, (void)length, (void)index;
+}
index de6938f8f8b297c140a94e40b2082cbae97b8024..ec2181d96eb72a2fd3b0f139afe16e3ef66d998b 100644 (file)
@@ -120,6 +120,7 @@ typedef struct Item {
     Symbol* sym;
     Type* type;
     int reg;
+    int offset;
     ImmValue imm;
 } Item;
 
@@ -223,6 +224,7 @@ void codegen_prepcall(Parser* p, Item* item);
 void codegen_call(Parser* p, Item* item, Item* args);
 void codegen_setarg(Parser* p, Item* item, bool firstarg);
 void codegen_return(Parser* p, Item* item);
+void codegen_rangecheck(Parser* p, long length, Item* index);
 
 /*
 
index f75fb1e5d0e6a759920e732b093c5d4e02ccf43e..c8a226c8261859e51f97af869dc65ffb662f9c77 100644 (file)
@@ -92,7 +92,11 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
   END CheckRegs;\r
 \r
   PROCEDURE SetCC(VAR x: Item; n: LONGINT);\r
-  BEGIN x.mode := Cond; x.a := 0; x.b := 0; x.r := n\r
+  BEGIN\r
+    x.mode := Cond;\r
+    x.a := 0;\r
+    x.b := 0;\r
+    x.r := n\r
   END SetCC;\r
 \r
   PROCEDURE TestRange(x: LONGINT);\r
@@ -180,11 +184,23 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
   PROCEDURE loadAdr(VAR x: Item);\r
   BEGIN\r
     IF x.mode = Var THEN\r
-      IF x.r > 0 THEN (*local*) Put1(Add, RH, SP, x.a); x.r := RH ELSE GetSB; Put1(Add, RH, SB, x.a) END ;\r
+      IF x.r > 0 THEN (*local*)\r
+        Put1(Add, RH, SP, x.a);\r
+        x.r := RH\r
+      ELSE\r
+        GetSB;\r
+        Put1(Add, RH, SB, x.a)\r
+      END ;\r
+      incR\r
+    ELSIF x.mode = Par THEN\r
+      Put2(Ldw, RH, SP, x.a);\r
+      Put1(Add, RH, RH, x.b);\r
+      x.r := RH;\r
       incR\r
-    ELSIF x.mode = Par THEN Put2(Ldw, RH, SP, x.a); Put1(Add, RH, RH, x.b); x.r := RH; incR\r
-    ELSIF (x.mode = RegI) & (x.a # 0) THEN Put1(Add, x.r, x.r, x.a)\r
-    ELSE OSS.Mark("address error")\r
+    ELSIF (x.mode = RegI) & (x.a # 0) THEN\r
+      Put1(Add, x.r, x.r, x.a)\r
+    ELSE\r
+      OSS.Mark("address error")\r
     END ;\r
     x.mode := Reg\r
   END loadAdr;\r
@@ -192,9 +208,19 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
   PROCEDURE loadCond(VAR x: Item);\r
   BEGIN\r
     IF x.type.form = Boolean THEN\r
-      IF x.mode = Const THEN x.r := 15 - x.a*8 ELSE load(x); Put1(Cmp, x.r, x.r, 0); x.r := NE; DEC(RH) END ;\r
-      x.mode := Cond; x.a := 0; x.b := 0\r
-    ELSE OSS.Mark("not Boolean")\r
+      IF x.mode = Const THEN\r
+        x.r := 15 - x.a*8\r
+      ELSE\r
+        load(x);\r
+        Put1(Cmp, x.r, x.r, 0);\r
+        x.r := NE;\r
+        DEC(RH)\r
+      END ;\r
+      x.mode := Cond;\r
+      x.a := 0;\r
+      x.b := 0\r
+    ELSE\r
+      OSS.Mark("not Boolean")\r
     END\r
   END loadCond;\r
 \r
@@ -203,8 +229,12 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
   BEGIN\r
     IF L0 # 0 THEN\r
       L3 := L0;\r
-      REPEAT L2 := L3; L3 := code[L2] MOD 40000H UNTIL L3 = 0;\r
-      code[L2] := code[L2] + L1; L1 := L0\r
+      REPEAT\r
+        L2 := L3;\r
+        L3 := code[L2] MOD 40000H\r
+      UNTIL L3 = 0;\r
+      code[L2] := code[L2] + L1;\r
+      L1 := L0\r
     END ;\r
     RETURN L1\r
   END merged;\r
@@ -212,7 +242,8 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
   (*-----------------------------------------------*)\r
 \r
   PROCEDURE IncLevel*(n: INTEGER);\r
-  BEGIN curlev := curlev + n\r
+  BEGIN\r
+    curlev := curlev + n\r
   END IncLevel;\r
 \r
   PROCEDURE MakeConstItem*(VAR x: Item; typ: Type; val: LONGINT);\r
@@ -240,8 +271,14 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
 \r
   PROCEDURE Field*(VAR x: Item; y: Object);   (* x := x.y *)\r
   BEGIN\r
-    IF (x.mode = Var) OR (x.mode = RegI) THEN x.a := x.a + y.val\r
-    ELSIF x.mode = Par THEN Put2(Ldw, RH, x.r, x.a); x.mode := RegI; x.r := RH; x.a := y.val; incR\r
+    IF (x.mode = Var) OR (x.mode = RegI) THEN\r
+      x.a := x.a + y.val\r
+    ELSIF x.mode = Par THEN\r
+      Put2(Ldw, RH, x.r, x.a);\r
+      x.mode := RegI;\r
+      x.r := RH;\r
+      x.a := y.val;\r
+      incR\r
     END\r
   END Field;\r
 \r
@@ -249,18 +286,42 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX  9.5.2017*)
     VAR s: LONGINT;\r
   BEGIN\r
     IF y.mode = Const THEN\r
-      IF (y.a < 0) OR (y.a >= x.type.len) THEN OSS.Mark("bad index") END ;\r
-      IF x.mode = Par THEN Put2(Ldw, RH, x.r, x.a); x.mode := RegI; x.a := 0 END ;\r
+      IF (y.a < 0) OR (y.a >= x.type.len) THEN\r
+        OSS.Mark("bad index")\r
+      END ;\r
+      IF x.mode = Par THEN\r
+        Put2(Ldw, RH, x.r, x.a);\r
+        x.mode := RegI;\r
+        x.a := 0\r
+      END ;\r
       x.a := x.a + y.a * x.type.base.size\r
-    ELSE s := x.type.base.size;\r
-      IF y.mode # Reg THEN load(y) END ;\r
-      IF s = 4 THEN Put1(Lsl, y.r, y.r, 2) ELSE Put1(Mul, y.r, y.r, s) END ;\r
+    ELSE\r
+      s := x.type.base.size;\r
+      IF y.mode # Reg THEN\r
+        load(y)\r
+      END ;\r
+      IF s = 4 THEN\r
+        Put1(Lsl, y.r, y.r, 2)\r
+      ELSE\r
+        Put1(Mul, y.r, y.r, s)\r
+      END ;\r
       IF x.mode = Var THEN\r
-        IF x.r > 0 THEN Put0(Add, y.r, SP, y.r) ELSE GetSB; Put0(Add, y.r, SB, y.r) END ;\r
-        x.mode := RegI; x.r := y.r\r
+        IF x.r > 0 THEN\r
+          Put0(Add, y.r, SP, y.r)\r
+        ELSE\r
+          GetSB;\r
+          Put0(Add, y.r, SB, y.r)\r
+        END ;\r
+        x.mode := RegI;\r
+        x.r := y.r\r
       ELSIF x.mode = Par THEN\r
-        Put2(Ldw, RH, SP, x.a); Put0(Add, y.r, RH, y.r); x.mode := RegI; x.r := y.r\r
-      ELSIF x.mode = RegI THEN Put0(Add, x.r, x.r, y.r); DEC(RH)\r
+        Put2(Ldw, RH, SP, x.a);\r
+        Put0(Add, y.r, RH, y.r);\r
+        x.mode := RegI;\r
+        x.r := y.r\r
+      ELSIF x.mode = RegI THEN\r
+        Put0(Add, x.r, x.r, y.r);\r
+        DEC(RH)\r
       END\r
     END\r
   END Index;\r
index ecaf363f961923d29a8536910b7f4e21e78e4ff9..503d84ae5cab602f53d616e0dc640ebbf9cd50e0 100644 (file)
@@ -108,12 +108,15 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
     VAR y: OSG.Item; obj: OSG.Object;\r
   BEGIN\r
     WHILE (sym = OSS.lbrak) OR (sym = OSS.period) DO\r
-\r
       IF sym = OSS.lbrak THEN\r
-        OSS.Get(sym); expression(y);\r
+        OSS.Get(sym);\r
+        expression(y);\r
         IF x.type.form = OSG.Array THEN\r
-          CheckInt(y); OSG.Index(x, y); x.type := x.type.base\r
-        ELSE OSS.Mark("not an array")\r
+          CheckInt(y);\r
+          OSG.Index(x, y);\r
+          x.type := x.type.base\r
+        ELSE\r
+          OSS.Mark("not an array")\r
         END ;\r
         Check(OSS.rbrak, "no ]")\r
 \r
@@ -196,12 +199,22 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
   BEGIN\r
     IF sym = OSS.lparen THEN\r
       OSS.Get(sym);\r
-      IF fctno = 0 THEN (*ORD*) expression(x); OSG.Ord(x)\r
-      ELSIF fctno = 1 THEN (*eot*) OSG.eot(x)\r
-      ELSE (*fctno = 2*) OSG.Switch(x)\r
+      IF fctno = 0 THEN (*ORD*)\r
+        expression(x);\r
+        OSG.Ord(x)\r
+      ELSIF fctno = 1 THEN (*eot*)\r
+        OSG.eot(x)\r
+      ELSE (*fctno = 2*)\r
+        OSG.Switch(x)\r
       END ;\r
-      IF sym = OSS.rparen THEN OSS.Get(sym) ELSE OSS.Mark("rparen expected") END\r
-    ELSE OSS.Mark("param missing"); OSG.MakeConstItem(x, OSG.intType, 0)\r
+      IF sym = OSS.rparen THEN\r
+        OSS.Get(sym)\r
+      ELSE\r
+        OSS.Mark("rparen expected")\r
+      END\r
+    ELSE\r
+      OSS.Mark("param missing");\r
+      OSG.MakeConstItem(x, OSG.intType, 0)\r
     END\r
   END StandF\unc;\r
 \r
@@ -343,20 +356,39 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
   PROCEDURE StandProc(pno: LONGINT);\r
     VAR x, y: OSG.Item;\r
   BEGIN\r
-    IF pno = 0 THEN  OSG.OpenInput\r
+    IF pno = 0 THEN\r
+      OSG.OpenInput\r
     ELSIF pno IN {1, 2, 3, 5} THEN\r
-      IF sym = OSS.lparen THEN OSS.Get(sym); expression(x);\r
-        IF pno = 1 THEN OSG.ReadInt(x);\r
+      IF sym = OSS.lparen THEN\r
+        OSS.Get(sym);\r
+        expression(x);\r
+        IF pno = 1 THEN\r
+          OSG.ReadInt(x);\r
         ELSIF pno = 2 THEN\r
-          IF sym = OSS.comma THEN OSS.Get(sym); expression(y); OSG.WriteInt(x, y) ELSE OSS.Mark("no comma") END\r
-        ELSIF pno = 3 THEN OSG.WriteChar(x)\r
-        ELSIF pno = 5 THEN OSG.LED(x)\r
-            END ;\r
-            IF sym = OSS.rparen THEN OSS.Get(sym) ELSE OSS.Mark("no rparen") END\r
-          ELSE OSS.Mark(" missing lparen")\r
+          IF sym = OSS.comma THEN\r
+            OSS.Get(sym);\r
+            expression(y);\r
+            OSG.WriteInt(x, y)\r
+          ELSE\r
+            OSS.Mark("no comma")\r
           END\r
-    ELSIF pno = 4 THEN  OSG.WriteLn\r
-    ELSE OSS.Mark("undef proc")\r
+        ELSIF pno = 3 THEN\r
+          OSG.WriteChar(x)\r
+        ELSIF pno = 5 THEN\r
+          OSG.LED(x)\r
+        END ;\r
+        IF sym = OSS.rparen THEN\r
+          OSS.Get(sym)\r
+        ELSE\r
+          OSS.Mark("no rparen")\r
+        END\r
+      ELSE\r
+        OSS.Mark(" missing lparen")\r
+      END\r
+    ELSIF pno = 4 THEN\r
+      OSG.WriteLn\r
+    ELSE\r
+      OSS.Mark("undef proc")\r
     END\r
   END StandProc;\r
 \r
@@ -430,6 +462,7 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
         Check(OSS.then, "no THEN");\r
         StatSequence;\r
         L := 0;\r
+\r
         WHILE sym = OSS.elsif DO\r
           OSS.Get(sym);\r
           OSG.FJump(L);\r
@@ -444,6 +477,7 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
           END ;\r
           StatSequence\r
         END ;\r
+\r
         IF sym = OSS.else THEN\r
           OSS.Get(sym);\r
           OSG.FJump(L);\r
@@ -452,7 +486,9 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
         ELSE\r
           OSG.FixLink(x.a)\r
         END ;\r
+\r
         OSG.FixLink(L);\r
+\r
         IF sym = OSS.end THEN\r
           OSS.Get(sym)\r
         ELSE\r
@@ -486,7 +522,9 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
           OSS.Get(sym)\r
         END\r
       END ;\r
+\r
       OSG.CheckRegs;\r
+\r
       IF sym = OSS.semicolon THEN\r
         OSS.Get(sym)\r
       ELSIF sym < OSS.semicolon THEN\r
index 414005140d4862b4eda957200d69381e169285df..c90a8954e97df414c7edc084982be6da4bb71d0d 100644 (file)
@@ -111,22 +111,16 @@ RULE(designator)
 //        case '.':
 //            expect(p, IDENT);
 //            break;
-//
+
         case '[':
         {
             expect(p, '[');
             Type* type = item->type;
-            while (type && type->form == FORM_ARRAY)
-            {
-                Item expr = {0};
-                expression(p, &expr);
-                check_int(p, &expr);
-                type = type->base;
-                if (type->form == FORM_ARRAY)
-                {
-                    expect(p, ',');
-                }
-            }
+            Item index = {0};
+            expression(p, &index);
+            codegen_rangecheck(p, item->type->size, &index);
+            //codegen_binop(p, '*', &index, &base);
+            item->type = item->type->base;
             expect(p, ']');
             break;
         }
@@ -352,28 +346,29 @@ RULE(statement_seq)
 {
     do
     {
-        if (matches(p, IDENT))
-        {
-            Item right = { 0 };
-            char* text = expect_text(p, IDENT);
-            if (accept(p, '='))
-            {
-                Symbol* sym = symbol_get(p, SYM_VAR, text);
-                init_item(item, sym);
-                item->imm.s = sym->name;
-
-                expression(p, &right);
-                check_types(p, item, &right);
-                codegen_store(p, item, &right);
-            }
-            else
-            {
-                /* TODO: add function calls and other complex stuff */
-                error(p, "expected assignment");
-            }
-            expect(p, ';');
-        }
-        else if (matches(p, IF))
+//        if (matches(p, IDENT))
+//        {
+//            Item right = { 0 };
+//            char* text = expect_text(p, IDENT);
+//            if (accept(p, '='))
+//            {
+//                Symbol* sym = symbol_get(p, SYM_VAR, text);
+//                init_item(item, sym);
+//                item->imm.s = sym->name;
+//
+//                expression(p, &right);
+//                check_types(p, item, &right);
+//                codegen_store(p, item, &right);
+//            }
+//            else
+//            {
+//                /* TODO: add function calls and other complex stuff */
+//                error(p, "expected assignment");
+//            }
+//            expect(p, ';');
+//        }
+//        else
+        if (matches(p, IF))
         {
             expect(p, IF);
             expression(p, item);
@@ -400,9 +395,17 @@ RULE(statement_seq)
             codegen_endif(p, elsifs, item);
             expect(p, END);
         }
-        else
+        else /* assignments/expressions */
         {
-            error(p, "expected a statement");
+            expression(p, item);
+            if (accept(p, '='))
+            {
+                Item right = { 0 };
+                expression(p, &right);
+                check_types(p, item, &right);
+                codegen_store(p, item, &right);
+            }
+            expect(p, ';');
         }
     }
     while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN));
index a50130efd5c411cbb62317f49608a707e4061364..b7285d6807d41484d0a1bf749ab8a5fbc45f9633 100644 (file)
@@ -81,6 +81,9 @@ void check_types(Parser* p, Item* a, Item* b)
     {
         check_bools(p, a, b);
     }
+//    else if (a->type->form == FORM_ARRAY)
+//    {
+//    }
     else
     {
         error(p, "type mismatch");
index fc74734d3acd27db1e45603ed58e727bf5cbe291..d7d932861396ba52885421242b144b40701b5623 100644 (file)
@@ -102,5 +102,7 @@ begin
 #
   # Function calls
 #  c = Foo(1,2);
+#  e[0] = 1;
+#  Foo(1,2);
   e[0] = 1;
 end