]> git.mdlowis.com Git - proto/obnc.git/commitdiff
started parsing procedure declarations
authormike lowis <mike@mdlowis.com>
Tue, 4 May 2021 02:48:53 +0000 (22:48 -0400)
committermike lowis <mike@mdlowis.com>
Tue, 4 May 2021 02:48:53 +0000 (22:48 -0400)
cerise/oberon0/OSP.Mod
cerise/src/grammar.c
cerise/tests/Module.m

index 2997d6afc9f5af0f4335af9f5f9b36ac73c7d1cf..9f37943b1d66fb77b2fd78035aaed6b5014c78c2 100644 (file)
@@ -104,26 +104,35 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
     VAR x: OSG.Item; varpar: BOOLEAN;\r
   BEGIN\r
     expression(x);\r
-    IF par # NIL THEN\r
+\r
       varpar := par.class = OSG.Par;\r
       IF CompTypes(par.type, x.type) THEN\r
-        IF ~varpar THEN OSG.ValueParam(x)\r
-        ELSE OSG.VarParam(x, par.type)\r
+        IF ~varpar THEN\r
+          OSG.ValueParam(x)\r
+        ELSE\r
+          OSG.VarParam(x, par.type)\r
         END\r
+\r
       ELSIF (x.type.form = OSG.Array) & (par.type.form = OSG.Array) &\r
           (x.type.base.form = par.type.base.form) & (par.type.len < 0) THEN\r
         OSG.OpenArrayParam(x)\r
-      ELSE OSS.Mark("incompatible parameters")\r
+\r
+      ELSE\r
+        OSS.Mark("incompatible parameters")\r
       END\r
-    END\r
+\r
   END Parameter;\r
 \r
   PROCEDURE ParamList(VAR obj: OSG.Object);\r
     VAR n: INTEGER; par: OSG.Object;\r
-  BEGIN par := obj.dsc; n := 0;\r
+  BEGIN\r
+    par := obj.dsc;\r
+    n := 0;\r
+\r
     IF sym # OSS.rparen THEN\r
       Parameter(par);\r
       n := 1;\r
+\r
       WHILE sym <= OSS.comma DO\r
         Check(sym, "comma?");\r
         IF par # NIL THEN\r
@@ -132,10 +141,12 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
         INC(n);\r
         Parameter(par)\r
       END ;\r
+\r
       Check(OSS.rparen, ") missing")\r
     ELSE\r
       OSS.Get(sym);\r
     END ;\r
+\r
     IF n < obj.nofpar THEN\r
       OSS.Mark("too few params")\r
     ELSIF n > obj.nofpar THEN\r
@@ -614,33 +625,70 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
   BEGIN (* ProcedureDecl *)\r
     OSS.Get(sym);\r
     IF sym = OSS.ident THEN\r
-      procid := OSS.id; NewObj(proc, OSG.Proc); OSS.Get(sym); parblksize := marksize; nofpar := 0;\r
-    (* Texts.Write(W, "%"); Texts.WriteInt(W, sym, 4); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); *)\r
-      OpenScope;  INC(level); proc.val := -1;\r
-      IF sym = OSS.times THEN proc.comd := TRUE; OSS.Get(sym) ELSE proc.comd := FALSE END ;\r
+      procid := OSS.id;\r
+      NewObj(proc, OSG.Proc);\r
+      OSS.Get(sym);\r
+      parblksize := marksize;\r
+      nofpar := 0;\r
+      OpenScope;\r
+      INC(level);\r
+      proc.val := -1;\r
+\r
+      IF sym = OSS.times THEN\r
+        proc.comd := TRUE;\r
+        OSS.Get(sym)\r
+      ELSE\r
+        proc.comd := FALSE\r
+      END ;\r
+\r
       IF sym = OSS.lparen THEN\r
         OSS.Get(sym);\r
-        IF sym = OSS.rparen THEN OSS.Get(sym)\r
-        ELSE FPSection(parblksize, nofpar);\r
-          WHILE sym = OSS.semicolon DO OSS.Get(sym); FPSection(parblksize, nofpar) END ;\r
-          IF sym = OSS.rparen THEN OSS.Get(sym) ELSE OSS.Mark(")?") END ;\r
-          IF proc.comd THEN OSS.Mark("no params allowed") END\r
+        IF sym = OSS.rparen THEN\r
+          OSS.Get(sym)\r
+        ELSE\r
+          FPSection(parblksize, nofpar);\r
+          WHILE sym = OSS.semicolon DO\r
+            OSS.Get(sym);\r
+            FPSection(parblksize, nofpar)\r
+          END ;\r
+          IF sym = OSS.rparen THEN\r
+            OSS.Get(sym)\r
+          ELSE\r
+            OSS.Mark(")?")\r
+          END ;\r
+          IF proc.comd THEN\r
+            OSS.Mark("no params allowed")\r
+          END\r
         END\r
       END ;\r
-      locblksize := parblksize; proc.type := NIL; proc.dsc := topScope.next; proc.nofpar := nofpar;\r
+\r
+      locblksize := parblksize;\r
+      proc.type := NIL;\r
+      proc.dsc := topScope.next;\r
+      proc.nofpar := nofpar;\r
       Check(OSS.semicolon, "; expected");\r
-      Declarations(locblksize); proc.dsc := topScope.next;\r
+      Declarations(locblksize);\r
+      proc.dsc := topScope.next;\r
       WHILE sym = OSS.procedure DO\r
-        ProcedureDecl; Check(OSS.semicolon, "; expected")\r
+        ProcedureDecl;\r
+        Check(OSS.semicolon, "; expected")\r
+      END ;\r
+      proc.val := OSG.pc * 4;\r
+      OSG.Enter(parblksize, locblksize, proc.comd);\r
+      IF sym = OSS.begin THEN\r
+        OSS.Get(sym);\r
+        StatSequence\r
       END ;\r
-      proc.val := OSG.pc * 4; OSG.Enter(parblksize, locblksize, proc.comd);\r
-      IF sym = OSS.begin THEN OSS.Get(sym); StatSequence END ;\r
       Check(OSS.end, "no END");\r
       IF sym = OSS.ident THEN\r
-        IF procid # OSS.id THEN OSS.Mark("no match") END ;\r
+        IF procid # OSS.id THEN\r
+          OSS.Mark("no match")\r
+        END ;\r
         OSS.Get(sym)\r
       END ;\r
-      OSG.Return(locblksize); DEC(level); CloseScope\r
+      OSG.Return(locblksize);\r
+      DEC(level);\r
+      CloseScope\r
     END\r
   END ProcedureDecl;\r
 \r
index 1d02b99eac480aaa75a4fd0f770a1628e46db8a7..d0287d0183a69cd8d2a430ae5a7942a8d92e2388 100644 (file)
@@ -61,19 +61,31 @@ static void init_item(Item* item, Symbol* sym)
  *****************************************************************************/
 static void expression(Parser* p, Item* item);
 
-RULE(expr_list)
+RULE(param)
+{
+    (void)item;
+    Item arg = {0};
+    expression(p, &arg);
+    // if check_types()
+//    codegen_setarg(p, &arg);
+    // else check_array_type()
+}
+
+RULE(param_list)
 {
     (void)item;
     int nargs = 0;
     Item arg = {0};
     if (!matches(p, ')'))
     {
-        expression(p, &arg);
+        // arg = <get from item>
+        param(p, &arg);
         nargs++;
         while (!matches(p, ')'))
         {
             expect(p, ',');
-            expression(p, &arg);
+            // arg = <get from item>
+            param(p, &arg);
             nargs++;
         }
     }
@@ -178,10 +190,9 @@ RULE(factor)
             designator(p, item);
             if (accept(p, '('))
             {
-                //Item call = {0};
-                // check item is a procedure
-                expr_list(p, item);
-                //codegen_call(p, &call);
+                // TODO: check item is a procedure
+                param_list(p, item);
+                //codegen_call(p, item);
                 expect(p, ')');
             }
             break;
@@ -299,6 +310,93 @@ RULE(type)
     }
 }
 
+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))
+        {
+            expect(p, IF);
+            expression(p, item);
+            check_bool(p, item);
+            codegen_if(p, item);
+            expect(p, THEN);
+            statement_seq(p, &(Item){0});
+            int elsifs = 0;
+            while (accept(p, ELSIF))
+            {
+                elsifs++;
+                codegen_else(p, item);
+                expression(p, item);
+                check_bool(p, item);
+                codegen_if(p, item);
+                expect(p, THEN);
+                statement_seq(p, &(Item){0});
+            }
+            if (accept(p, ELSE))
+            {
+                codegen_else(p, item);
+                statement_seq(p, &(Item){0});
+            }
+            codegen_endif(p, elsifs, item);
+            expect(p, END);
+        }
+        else
+        {
+            error(p, "expected a statement");
+        }
+    }
+    while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN));
+}
+
+RULE(proc_decl)
+{
+    expect(p, PROCEDURE);
+    (void)expect_text(p, IDENT);
+    (void)accept(p, '*');
+    expect(p, '(');
+    while (!matches(p, ')'))
+    {
+        (void)expect_text(p, IDENT);
+        expect(p, ':');
+        type(p, item);
+    }
+    expect(p, ')');
+    if (accept(p, ':'))
+    {
+        type(p, item);
+    }
+    expect(p, BEGIN);
+    statement_seq(p, item);
+    if (accept(p, RETURN))
+    {
+        expression(p, item);
+        expect(p, ';');
+    }
+    expect(p, END);
+}
+
 RULE(var_decl)
 {
     (void)item;
@@ -373,66 +471,6 @@ RULE(const_decl)
     while (matches(p, IDENT));
 }
 
-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))
-        {
-            expect(p, IF);
-            expression(p, item);
-            check_bool(p, item);
-            codegen_if(p, item);
-            expect(p, THEN);
-            statement_seq(p, &(Item){0});
-            int elsifs = 0;
-            while (accept(p, ELSIF))
-            {
-                elsifs++;
-                codegen_else(p, item);
-                expression(p, item);
-                check_bool(p, item);
-                codegen_if(p, item);
-                expect(p, THEN);
-                statement_seq(p, &(Item){0});
-            }
-            if (accept(p, ELSE))
-            {
-                codegen_else(p, item);
-                statement_seq(p, &(Item){0});
-            }
-            codegen_endif(p, elsifs, item);
-            expect(p, END);
-        }
-        else
-        {
-            error(p, "expected a statement");
-        }
-    }
-    while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF));
-}
-
 RULE(import_list)
 {
     (void)item;
@@ -489,6 +527,11 @@ RULE(module)
         var_decl(p, item);
     }
 
+    while (matches(p, PROCEDURE))
+    {
+        proc_decl(p, item);
+    }
+
     codegen_startproc(p, NULL, true);
     if (accept(p, BEGIN))
     {
index 00e319350204cef854bb99ee9d598f46666f9b1d..2cd4ebad1171f10c6fd824e72c1ad9f2114813f8 100644 (file)
@@ -19,12 +19,18 @@ var
   b : Int
   c : Int
 
+procedure Foo*(e : Int)
 begin
-#  a = true;
-#  a = A;
-#  b = 24;
-#  b = B;
-#
+  c = b * b;
+  return c;
+end
+
+begin
+  a = true;
+  a = A;
+  b = 24;
+  b = B;
+
 #  # Unary ops
 #  b = +b;
 #  b = -b;
@@ -82,5 +88,5 @@ begin
 #    c = 3;
 #  end
 
-    c = c(1,2,3);
+#    c = c(1,2,3);
 end