]> git.mdlowis.com Git - proto/obnc.git/commitdiff
reworking symbol table...very broken
authorMichael D. Lowis <mike.lowis@gentex.com>
Sat, 5 Jun 2021 01:53:56 +0000 (21:53 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Sat, 5 Jun 2021 01:53:56 +0000 (21:53 -0400)
cerise/inc/cerise.h
cerise/ir.md [new file with mode: 0644]
cerise/src/grammar.c
cerise/src/sym.c

index bf5d62a9dfe96a1fc3891cbafb8bcf2c4acf1f01..ebf6fe7c6d96ec73f300790c80ec172deae66746 100644 (file)
@@ -141,10 +141,11 @@ typedef struct {
     LexFile* file;
     Tok tok;
     Module* imports;
-    Symbol* scope;
     char* name;
     int curr_reg;
-    int level;
+    size_t msyms;
+    size_t nsyms;
+    Symbol* syms;
 } Parser;
 
 // src/stdlib.c
@@ -168,11 +169,11 @@ char* expect_text(Parser* p, TokType type);
 int consume(Parser* p);
 
 // src/sym.c
-Symbol* symbol_new(Parser* p, char* name, int class, bool export);
+Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export);
 Symbol* symbol_addfield(Parser* p, Symbol* parent, 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);
+Symbol* symbol_get(Parser* p, char* name, int class);
+size_t symbol_openscope(Parser* p);
+void symbol_closescope(Parser* p, size_t scope);
 
 // src/type_checks.c
 void check_int(Parser* p, Item* item);
diff --git a/cerise/ir.md b/cerise/ir.md
new file mode 100644 (file)
index 0000000..4306f7b
--- /dev/null
@@ -0,0 +1,38 @@
+Entry/Exit:
+    code    Op code
+    mode    Always "control"
+    next    Link to next node
+
+Op:
+    code    Op code
+    mode    Vars, ImmFloat, ImmInt, Control
+    dest    Var
+    arg[2]  Var, Float, or Int
+    next    Link to next node
+
+If:
+    code    Op code
+    mode    Always "control"
+    arg     Var = conditional value
+    br_if   Path for true
+    br_then Path for false
+
+Jump:
+    code    Op code
+    mode    Always "control"
+    arg     Var = Destination address
+    next    Link to next node
+
+Return:
+    code    Op code
+    mode    Always "control"
+    val     Var
+    next    Link to next node
+
+Call:
+    code    Op code
+    mode    Always "control"
+    dest    Var
+    nargs   Number of args
+    args    Array of args
+    next    Link to next node
index d82edbbb35fde5f1756b025aebc3f71822edbdcd..4c3357aabb511700494acb0e22a816461030e1b7 100644 (file)
@@ -100,7 +100,7 @@ static void expression(Parser* p, Item* item);
 RULE(qualident)
 {
     char* name = expect_text(p, IDENT);
-    Symbol* sym = symbol_get(p, -1, name);
+    Symbol* sym = symbol_get(p, name, -1);
     init_item(item, sym);
 
 //    if (accept(p, '.'))
@@ -211,7 +211,7 @@ RULE(factor)
             designator(p, item);
             if (accept(p, '('))
             {
-                Symbol* proc = symbol_get(p, SYM_PROC, item->imm.s);
+                Symbol* proc = symbol_get(p, item->imm.s, SYM_PROC);
                 Symbol* args = proc->desc;
                 Item arglist = {0};
                 Item** currarg = &(arglist.next);
@@ -342,7 +342,7 @@ RULE(type)
     if (matches(p, IDENT))
     {
         char* text = expect_text(p, IDENT);
-        Symbol* sym = symbol_get(p, SYM_TYPE, text);
+        Symbol* sym = symbol_get(p, text, SYM_TYPE);
         item->type = sym->type;
     }
     else if (accept(p, ARRAY))
@@ -471,7 +471,7 @@ RULE(var_decl)
         {
             name = expect_text(p, IDENT);
             export = accept(p, '*');
-            sym = symbol_new(p, name, SYM_VAR, export);
+            sym = symbol_new(p, 0, name, SYM_VAR, export);
             first = (nsyms == 0 ? sym : first);
             sym->global = (p->level <= 1 ? 1 : 0);
             nsyms++;
@@ -503,7 +503,7 @@ RULE(type_decl)
     {
         name = expect_text(p, IDENT);
         export = accept(p, '*');
-        sym = symbol_new(p, name, SYM_TYPE, export);
+        sym = symbol_new(p, 0, name, SYM_TYPE, export);
         expect(p, '=');
         type(p, item);
         sym->type = item->type;
@@ -521,7 +521,7 @@ RULE(const_decl)
     {
         name = expect_text(p, IDENT);
         export = accept(p, '*');
-        sym = symbol_new(p, name, SYM_CONST, export);
+        sym = symbol_new(p, 0, name, SYM_CONST, export);
 
         expect(p, '=');
         expression(p, item);
@@ -536,7 +536,7 @@ RULE(proc_decl)
     expect(p, PROCEDURE);
     char* name = expect_text(p, IDENT);
     bool export = accept(p, '*');
-    Symbol* proc = symbol_new(p, name, SYM_PROC, export);
+    Symbol* proc = symbol_new(p, 0, name, SYM_PROC, export);
 
     /* construct the proc type */
     expect(p, '(');
@@ -561,7 +561,7 @@ RULE(proc_decl)
     }
 
     codegen_startproc(p, proc);
-    symbol_openscope(p);
+    size_t scope = symbol_openscope(p);
 
     /* parse the declarations */
     if (accept(p, CONST))
@@ -604,7 +604,7 @@ RULE(proc_decl)
     expect(p, END);
 
     codegen_endproc(p);
-    symbol_closescope(p);
+    symbol_closescope(p, scope);
 }
 
 RULE(import_list)
@@ -639,7 +639,7 @@ RULE(import_list)
 
 RULE(module)
 {
-    symbol_openscope(p);
+    size_t scope = symbol_openscope(p);
 
     expect(p, MODULE);
     p->name = expect_text(p, IDENT);
@@ -684,7 +684,7 @@ RULE(module)
         error(p, "expected end of file");
     }
 
-    symbol_closescope(p);
+    symbol_closescope(p, scope);
 }
 
 static inline char* file_load(char* path)
index 97a021aa58132e0f66a15afc9bebdd9b3242ec33..2f83d71437014186b5d4433da2c984c9d60c2434 100644 (file)
@@ -1,9 +1,9 @@
 #include "cerise.h"
 
+#define NIL_SYMBOL ((size_t)-1)
+
 static int sym_matches(Parser* p, int class, char* name, Symbol* sym)
 {
-//    printf("  %s == %s\n", name, sym->name);
-
     if (name && sym->name && !strcmp(sym->name, name))
     {
         if (class >= 0 && (int)sym->class != class)
@@ -36,68 +36,74 @@ static int sym_matches(Parser* p, int class, char* name, Symbol* sym)
     return 0;
 }
 
-static Symbol* lookup(Parser* p, int class, char* name)
+static size_t lookup(Parser* p, size_t scope, char* name, int class)
 {
-    for (Symbol* scope = p->scope; scope; scope = scope->next)
+    size_t ret = NIL_SYMBOL;
+    size_t count = p->nsyms - scope;
+    size_t curr = p->nsyms - 1u;
+
+    for (size_t i = 0; i < count; i++, curr--)
     {
-//       printf("SCOPE(n: %p):\n", scope->next);
-        if (sym_matches(p, class, name, scope))
+        if (sym_matches(p, class, name, &p->syms[curr]))
         {
-            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))
-            {
-                return sym;
-            }
+            ret = curr;
+            break;
         }
     }
-    return NULL;
-}
 
+    return ret;
+}
 
-Symbol* symbol_new(Parser* p, char* name, int class, bool export)
+Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export)
 {
-    Symbol* prev = NULL;
-    Symbol* curr = p->scope->desc;
+    if (p->nsyms == p->msyms)
+    {
+        p->msyms = (p->msyms ? (p->msyms << 1) : 512u);
+        p->syms = realloc(p->syms, p->msyms * sizeof(Symbol));
+    }
 
-//    printf("\nsymbol_new(%s)\n", name);
-    while (curr)
+    /* verify we're not redefining it in the current scope */
+    if (NIL_SYMBOL != lookup(p, scope, name, class))
     {
-//        printf("  %s <- %s\n", curr->name, name);
-        if (curr->name && !strcmp(curr->name, name))
-        {
-            error(p, "multiple definitions of '%s' in scope", name);
-        }
-        prev = curr;
-        curr = curr->next;
+        error(p, "symbol '%s' is multiply defined in the current scope", name);
     }
 
-//    Symbol* existing = lookup(p, SYM_VAR, name);
-//    printf("%s : %p\n", name, existing);
-//    if ((class == SYM_VAR) && existing && !existing->global)
-//    {
-//        error(p, "local definition '%s' makes procedure argument inaccessible", name);
-//    }
+    /* insert */
+    p->syms[p->nsyms].name = name;
+    p->syms[p->nsyms].class = class;
+    p->syms[p->nsyms].export = export;
+    p->nsyms++;
 
-    Symbol* sym = calloc(1, sizeof(Symbol));
-    sym->name = name;
-    sym->class = class;
-    sym->export = export;
-    if (prev)
+    return &(p->syms[p->nsyms-1]);
+}
+
+Symbol* symbol_get(Parser* p, char* name, int class)
+{
+    Symbol* sym = NULL;
+    size_t index = lookup(p, 0, name, class);
+
+    if (NIL_SYMBOL != index)
     {
-        prev->next = sym;
+        error(p, "unknown symbol '%s'", name);
     }
     else
     {
-        p->scope->desc = sym;
+        sym = &(p->syms[index]);
     }
+
     return sym;
 }
 
+size_t symbol_openscope(Parser* p)
+{
+    return p->nsyms;
+}
+
+void symbol_closescope(Parser* p, size_t scope)
+{
+    p->nsyms = scope;
+}
+
 Symbol* symbol_addfield(Parser* p, Symbol* parent, char* name, int class, bool export)
 {
     Symbol* prev = NULL;
@@ -130,32 +136,6 @@ Symbol* symbol_addfield(Parser* p, Symbol* parent, char* name, int class, bool e
     return sym;
 }
 
-Symbol* symbol_get(Parser* p, int class, char* name)
-{
-    Symbol* sym = lookup(p, class, name);
-    if (!sym)
-    {
-        error(p, "unknown identifier '%s'", name);
-    }
-    return sym;
-}
-
-void symbol_openscope(Parser* p)
-{
-    Symbol* scope = calloc(1, sizeof(Symbol));
-    scope->class  = SYM_SCOPE;
-    scope->desc   = NULL;
-    scope->next   = p->scope;
-    p->scope      = scope;
-    p->level++;
-}
-
-void symbol_closescope(Parser* p)
-{
-    p->scope = p->scope->next;
-    p->level--;
-}
-
 /* Symbol Table Unit Tests
  *****************************************************************************/
 #ifdef CERISE_TESTS