From: mike lowis Date: Wed, 5 May 2021 02:26:51 +0000 (-0400) Subject: partial overhaul of symbol table... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=8c41dd016c653f42d93fd77aeb796dca60b6838d;p=proto%2Fobnc.git partial overhaul of symbol table... --- diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 21a83e7..37feb3e 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -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); diff --git a/cerise/oberon0/OSP.Mod b/cerise/oberon0/OSP.Mod index 5afc26c..dd90229 100644 --- a/cerise/oberon0/OSP.Mod +++ b/cerise/oberon0/OSP.Mod @@ -8,46 +8,83 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017 OSPX*) W: Texts.Writer; PROCEDURE NewObj(VAR obj: OSG.Object; class: INTEGER); - VAR new, x: OSG.Object; - BEGIN x := topScope; - WHILE (x.next # NIL) & (x.next.name # OSS.id) DO x := x.next END ; + VAR + new, x: OSG.Object; + BEGIN + x := topScope; + WHILE (x.next # NIL) & (x.next.name # OSS.id) DO + x := x.next + END ; + IF x.next = NIL THEN - NEW(new); new.name := OSS.id; new.class := class; new.next := NIL; - x.next := new; obj := new - ELSE obj := x.next; OSS.Mark("mult def") + NEW(new); + new.name := OSS.id; + new.class := class; + new.next := NIL; + x.next := new; + obj := new + ELSE + obj := x.next; + OSS.Mark("mult def") END END NewObj; PROCEDURE find(VAR obj: OSG.Object); - VAR s, x: OSG.Object; - BEGIN s := topScope; - REPEAT x := s.next; - WHILE (x # NIL) & (x.name # OSS.id) DO x := x.next END ; - s := s.dsc + VAR + s, x: OSG.Object; + BEGIN + s := topScope; + REPEAT + x := s.next; + WHILE (x # NIL) & (x.name # OSS.id) DO + x := x.next + END ; + s := s.dsc UNTIL (x # NIL) OR (s = NIL); - IF x = NIL THEN x := dummy; OSS.Mark("undef") END ; + + IF x = NIL THEN + x := dummy; + OSS.Mark("undef") + END ; + obj := x END find; PROCEDURE FindField(VAR obj: OSG.Object; list: OSG.Object); BEGIN - WHILE (list # NIL) & (list.name # OSS.id) DO list := list.next END ; - IF list # NIL THEN obj := list ELSE OSS.Mark("undef"); obj := dummy END + WHILE (list # NIL) & (list.name # OSS.id) DO + list := list.next + END ; + + IF list # NIL THEN + obj := list + ELSE + OSS.Mark("undef"); + obj := dummy + END END FindField; PROCEDURE Check(s: INTEGER; msg: ARRAY OF CHAR); BEGIN - IF sym = s THEN OSS.Get(sym) ELSE OSS.Mark(msg) END + IF sym = s THEN + OSS.Get(sym) + ELSE + OSS.Mark(msg) + END END Check; PROCEDURE CheckInt(VAR x: OSG.Item); BEGIN - IF x.type.form # OSG.Integer THEN OSS.Mark("not integer") END + IF x.type.form # OSG.Integer THEN + OSS.Mark("not integer") + END END CheckInt; PROCEDURE CheckBool(VAR x: OSG.Item); BEGIN - IF x.type.form # OSG.Boolean THEN OSS.Mark("not Boolean") END + IF x.type.form # OSG.Boolean THEN + OSS.Mark("not Boolean") + END END CheckBool; PROCEDURE OpenScope; @@ -458,11 +495,15 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017 OSPX*) VAR obj: OSG.Object; BEGIN IF sym = OSS.ident THEN - NewObj(first, class); OSS.Get(sym); + NewObj(first, class); + OSS.Get(sym); WHILE sym = OSS.comma DO OSS.Get(sym); - IF sym = OSS.ident THEN NewObj(obj, class); OSS.Get(sym) - ELSE OSS.Mark("ident?") + IF sym = OSS.ident THEN + NewObj(obj, class); + OSS.Get(sym) + ELSE + OSS.Mark("ident?") END END; Check(OSS.colon, "no :") @@ -550,13 +591,18 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017 OSPX*) IF sym = OSS.const THEN OSS.Get(sym); WHILE sym = OSS.ident DO - NewObj(obj, OSG.Const); OSS.Get(sym); - IF sym = OSS.eql THEN OSS.Get(sym) ELSE OSS.Mark("=?") END; + NewObj(obj, OSG.Const); + OSS.Get(sym); + IF sym = OSS.eql THEN + OSS.Get(sym) + ELSE + OSS.Mark("=?") + END; expression(x); IF x.mode = OSG.Const THEN - obj.val := x.a; obj.type := x.type + obj.val := x.a; obj.type := x.type ELSE - OSS.Mark("expression not constant") + OSS.Mark("expression not constant") END ; Check(OSS.semicolon, "; expected") END @@ -726,7 +772,10 @@ MODULE OSP; (* NW 23.9.93 / 9,5.2017 OSPX*) END ; Check(OSS.semicolon, "; expected"); Declarations(dc); - WHILE sym = OSS.procedure DO ProcedureDecl; Check(OSS.semicolon, "; expected") END ; + WHILE sym = OSS.procedure DO + ProcedureDecl; + Check(OSS.semicolon, "; expected") + END ; OSG.Header(dc); IF sym = OSS.begin THEN OSS.Get(sym); StatSequence END ; diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 6076527..7ff70b7 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -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); diff --git a/cerise/src/sym.c b/cerise/src/sym.c index bc5f6fa..2797ccc 100644 --- a/cerise/src/sym.c +++ b/cerise/src/sym.c @@ -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; +}