]> git.mdlowis.com Git - proto/obnc.git/commitdiff
partial overhaul of symbol table...
authormike lowis <mike@mdlowis.com>
Wed, 5 May 2021 02:26:51 +0000 (22:26 -0400)
committermike lowis <mike@mdlowis.com>
Wed, 5 May 2021 02:26:51 +0000 (22:26 -0400)
cerise/inc/cerise.h
cerise/oberon0/OSP.Mod
cerise/src/grammar.c
cerise/src/sym.c

index 21a83e73dce02989d8abc39659c38df9054f0456..37feb3e51f6899f9cfdbbc1ad161bdcb333a6030 100644 (file)
@@ -94,7 +94,7 @@ typedef union {
 typedef struct Symbol {
     struct Symbol* next;
     enum{
-        SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC
+        SYM_SCOPE, SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC
     } class;
     char* name;
     Type* type;
@@ -175,6 +175,8 @@ int consume(Parser* p);
 // src/sym.c
 Symbol* symbol_new(Parser* p, char* name, int class, bool export);
 Symbol* symbol_get(Parser* p, int class, char* name);
+void symbol_openscope(Parser* p);
+void symbol_closescope(Parser* p);
 
 // src/type_checks.c
 void check_int(Parser* p, Item* item);
index 5afc26cf47862b7b04f12c6f2150568aae401c03..dd9022923cef580805daa2dd8c9ce995453cc6bb 100644 (file)
@@ -8,46 +8,83 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
     W: Texts.Writer;\r
 \r
   PROCEDURE NewObj(VAR obj: OSG.Object; class: INTEGER);\r
-    VAR new, x: OSG.Object;\r
-  BEGIN x := topScope;\r
-    WHILE (x.next # NIL) & (x.next.name # OSS.id) DO x := x.next END ;\r
+    VAR\r
+      new, x: OSG.Object;\r
+  BEGIN\r
+    x := topScope;\r
+    WHILE (x.next # NIL) & (x.next.name # OSS.id) DO\r
+      x := x.next\r
+    END ;\r
+\r
     IF x.next = NIL THEN\r
-      NEW(new); new.name := OSS.id; new.class := class; new.next := NIL;\r
-      x.next := new; obj := new\r
-    ELSE obj := x.next; OSS.Mark("mult def")\r
+      NEW(new);\r
+      new.name  := OSS.id;\r
+      new.class := class;\r
+      new.next  := NIL;\r
+      x.next    := new;\r
+      obj       := new\r
+    ELSE\r
+      obj := x.next;\r
+      OSS.Mark("mult def")\r
     END\r
   END NewObj;\r
 \r
   PROCEDURE find(VAR obj: OSG.Object);\r
-    VAR s, x: OSG.Object;\r
-  BEGIN s := topScope;\r
-    REPEAT x := s.next;\r
-      WHILE (x # NIL) & (x.name # OSS.id) DO x := x.next END ;\r
-       s := s.dsc\r
+    VAR\r
+      s, x: OSG.Object;\r
+  BEGIN\r
+    s := topScope;\r
+    REPEAT\r
+      x := s.next;\r
+      WHILE (x # NIL) & (x.name # OSS.id) DO\r
+        x := x.next\r
+      END ;\r
+      s := s.dsc\r
     UNTIL (x # NIL) OR (s = NIL);\r
-    IF x = NIL THEN x := dummy; OSS.Mark("undef") END ;\r
+\r
+    IF x = NIL THEN\r
+      x := dummy;\r
+      OSS.Mark("undef")\r
+    END ;\r
+\r
     obj := x\r
   END find;\r
 \r
   PROCEDURE FindField(VAR obj: OSG.Object; list: OSG.Object);\r
   BEGIN\r
-    WHILE (list # NIL) & (list.name # OSS.id) DO list := list.next END ;\r
-    IF list # NIL THEN obj := list ELSE OSS.Mark("undef"); obj := dummy END\r
+    WHILE (list # NIL) & (list.name # OSS.id) DO\r
+      list := list.next\r
+    END ;\r
+\r
+    IF list # NIL THEN\r
+      obj := list\r
+    ELSE\r
+      OSS.Mark("undef");\r
+      obj := dummy\r
+    END\r
   END FindField;\r
 \r
   PROCEDURE Check(s: INTEGER; msg: ARRAY OF CHAR);\r
   BEGIN\r
-    IF sym = s THEN OSS.Get(sym) ELSE OSS.Mark(msg) END\r
+    IF sym = s THEN\r
+      OSS.Get(sym)\r
+    ELSE\r
+      OSS.Mark(msg)\r
+    END\r
   END Check;\r
 \r
   PROCEDURE CheckInt(VAR x: OSG.Item);\r
   BEGIN\r
-    IF x.type.form # OSG.Integer THEN OSS.Mark("not integer") END\r
+    IF x.type.form # OSG.Integer THEN\r
+      OSS.Mark("not integer")\r
+    END\r
   END CheckInt;\r
 \r
   PROCEDURE CheckBool(VAR x: OSG.Item);\r
   BEGIN\r
-    IF x.type.form # OSG.Boolean THEN OSS.Mark("not Boolean") END\r
+    IF x.type.form # OSG.Boolean THEN\r
+      OSS.Mark("not Boolean")\r
+    END\r
   END CheckBool;\r
 \r
   PROCEDURE OpenScope;\r
@@ -458,11 +495,15 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
     VAR obj: OSG.Object;\r
   BEGIN\r
     IF sym = OSS.ident THEN\r
-      NewObj(first, class); OSS.Get(sym);\r
+      NewObj(first, class);\r
+      OSS.Get(sym);\r
       WHILE sym = OSS.comma DO\r
         OSS.Get(sym);\r
-        IF sym = OSS.ident THEN NewObj(obj, class); OSS.Get(sym)\r
-        ELSE OSS.Mark("ident?")\r
+        IF sym = OSS.ident THEN\r
+          NewObj(obj, class);\r
+          OSS.Get(sym)\r
+        ELSE\r
+          OSS.Mark("ident?")\r
         END\r
       END;\r
       Check(OSS.colon, "no :")\r
@@ -550,13 +591,18 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
     IF sym = OSS.const THEN\r
       OSS.Get(sym);\r
       WHILE sym = OSS.ident DO\r
-        NewObj(obj, OSG.Const); OSS.Get(sym);\r
-        IF sym = OSS.eql THEN OSS.Get(sym) ELSE OSS.Mark("=?") END;\r
+        NewObj(obj, OSG.Const);\r
+        OSS.Get(sym);\r
+        IF sym = OSS.eql THEN\r
+          OSS.Get(sym)\r
+        ELSE\r
+          OSS.Mark("=?")\r
+        END;\r
         expression(x);\r
         IF x.mode = OSG.Const THEN\r
-            obj.val := x.a; obj.type := x.type\r
+          obj.val := x.a; obj.type := x.type\r
         ELSE\r
-            OSS.Mark("expression not constant")\r
+          OSS.Mark("expression not constant")\r
         END ;\r
         Check(OSS.semicolon, "; expected")\r
       END\r
@@ -726,7 +772,10 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017   OSPX*)
       END ;\r
       Check(OSS.semicolon, "; expected");\r
       Declarations(dc);\r
-      WHILE sym = OSS.procedure DO ProcedureDecl; Check(OSS.semicolon, "; expected") END ;\r
+      WHILE sym = OSS.procedure DO\r
+        ProcedureDecl;\r
+        Check(OSS.semicolon, "; expected")\r
+      END ;\r
 \r
       OSG.Header(dc);\r
       IF sym = OSS.begin THEN OSS.Get(sym); StatSequence END ;\r
index 60765272eafffd6652147f957fb4df80fd135d0b..7ff70b7d57e413f2eccbe8d484b847fcc45b5c5a 100644 (file)
@@ -449,6 +449,7 @@ RULE(proc_decl)
     bool export = accept(p, '*');
     Symbol* sym = symbol_new(p, name, SYM_PROC, export);
     Symbol** args = &(sym->desc);
+    symbol_openscope(p);
 
     /* construct the proc type */
     expect(p, '(');
@@ -500,6 +501,7 @@ RULE(proc_decl)
         expect(p, ';');
     }
     expect(p, END);
+    symbol_closescope(p);
 }
 
 
@@ -535,6 +537,8 @@ RULE(import_list)
 
 RULE(module)
 {
+    symbol_openscope(p);
+
     expect(p, MODULE);
     p->name = expect_text(p, IDENT);
         /* TODO: Check that it matches filename here */
@@ -577,6 +581,8 @@ RULE(module)
     {
         error(p, "expected end of file");
     }
+
+    symbol_closescope(p);
 }
 
 static inline char* file_load(char* path)
@@ -623,10 +629,16 @@ void compile(char* fname)
 
 Parser Ctx = {0};
 
+static Symbol InitialScope = {
+    .next  = &IntSym,
+    .class = SYM_SCOPE,
+};
+
+
 static void parse_init(char* fname, char* string)
 {
     memset(&Ctx, 0, sizeof(Ctx));
-    Ctx.scope = &RealSym;
+    Ctx.scope = &InitialScope;
     LexFile* file = calloc(sizeof(LexFile), 1u);
     file->path = strdup(fname);
     file->fbeg = file->fpos = strdup(string);
index bc5f6fa2eb15a3ce8b3ec12db44d72031137e162..2797cccc984c35798b0d7909141a73bd2340d715 100644 (file)
@@ -1,7 +1,44 @@
 #include "cerise.h"
 
+static int sym_matches(Parser* p, int class, char* name, Symbol* sym)
+{
+//    printf("  %s == %s\n", name, sym->name);
+
+    if (sym->name && !strcmp(sym->name, name))
+    {
+        if (class >= 0 && (int)sym->class != class)
+        {
+            switch(class)
+            {
+                case SYM_CONST:
+                    error(p, "'%s' is not a constant", name);
+                    break;
+
+                case SYM_VAR:
+                    error(p, "'%s' is not a variable", name);
+                    break;
+
+                case SYM_TYPE:
+                    error(p, "'%s' is not a type", name);
+                    break;
+
+                default:
+                    assert(!"unknown identifier type");
+                    break;
+            }
+        }
+        return 1;
+    }
+    return 0;
+}
+
 Symbol* symbol_new(Parser* p, char* name, int class, bool export)
 {
+//    Symbol* scope = p->scope;
+//    while ()
+//    {
+//    }
+
     Symbol* sym = calloc(1, sizeof(Symbol));
     sym->name = name;
     sym->class = class;
@@ -13,24 +50,46 @@ Symbol* symbol_new(Parser* p, char* name, int class, bool export)
 
 Symbol* symbol_get(Parser* p, int class, char* name)
 {
-    Symbol* sym = p->scope;
-    for (; sym; sym = sym->next)
+    Symbol* scope = p->scope;
+    Symbol* sym = NULL;
+
+    for (Symbol* scope = p->scope; scope; scope = scope->next)
     {
-        if (!strcmp(sym->name, name))
+        if (scope)
         {
-            if (class >= 0 && (int)sym->class != class)
+            printf("SCOPE:\n");
+        }
+
+        if (sym_matches(p, class, name, scope))
+        {
+            return scope;
+        }
+
+        for (Symbol* sym = scope->desc; sym; sym = sym->next)
+        {
+            printf("    %s == %s %d\n", name, sym->name, sym_matches(p, class, name, scope));
+
+            if (sym_matches(p, class, name, sym))
             {
-                switch(class)
-                {
-                    case SYM_CONST: error(p, "'%s' is not a constant", name); break;
-                    case SYM_VAR:   error(p, "'%s' is not a variable", name); break;
-                    case SYM_TYPE:  error(p, "'%s' is not a type", name);     break;
-                    default:        assert(!"unknown identifier type");       break;
-                }
+                return sym;
             }
-            return sym;
         }
     }
+
     error(p, "unknown identifier '%s'", name);
     return NULL;
 }
+
+void symbol_openscope(Parser* p)
+{
+    Symbol* scope = calloc(1, sizeof(Symbol));
+    scope->class  = SYM_SCOPE;
+    scope->desc   = p->scope;
+    scope->next   = NULL;
+    p->scope      = scope;
+}
+
+void symbol_closescope(Parser* p)
+{
+    p->scope = p->scope->desc;
+}