From: Michael D. Lowis Date: Fri, 14 May 2021 20:23:03 +0000 (-0400) Subject: initial record pass using symbols. Added a field type, should convert to using that... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=1ce188754504c33f09c145cdf0195c66c2d71493;p=proto%2Fobnc.git initial record pass using symbols. Added a field type, should convert to using that over the symbol type when specifying record fields --- diff --git a/cerise/backend/c99/codegen.c b/cerise/backend/c99/codegen.c index 9a1f738..1db17e9 100644 --- a/cerise/backend/c99/codegen.c +++ b/cerise/backend/c99/codegen.c @@ -23,7 +23,7 @@ Type StringType = { }; static char* TypeNames[FORM_COUNT] = { - [FORM_BOOL] = "bool", + [FORM_BOOL] = "_Bool", [FORM_INT] = "long", [FORM_REAL] = "double", [FORM_STRING] = "char*" diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 56891e7..f550ecb 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -79,6 +79,13 @@ typedef struct LexFile { struct Symbol; +typedef struct Field { + struct Field* next; + char* name; + Type* type; + long offset; +} Field; + typedef struct Type { enum { FORM_BOOL, FORM_INT, FORM_REAL, FORM_ARRAY, FORM_STRING, @@ -99,7 +106,7 @@ typedef union { typedef struct Symbol { struct Symbol* next; enum{ - SYM_SCOPE, SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC + SYM_SCOPE, SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC, SYM_FIELD } class; char* name; Type* type; diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 3372ae4..811b8d2 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -347,35 +347,33 @@ RULE(type) { item->type = calloc(1, sizeof(Type)); item->type->form = FORM_RECORD; -// Symbol **fields = &(item->type->fields); -// while (peek(p)->type != END) -// { -// do -// { -// char* name = expect_text(p, IDENT); -// bool export = accept(p, '*'); -// *prev = symbol_new(p, name, SYM_VAR, export); -// nsyms++; -// } -// while (accept(p, ',')); -// -// -//// int nsyms = 0; -//// Symbol head = {0}; -//// Symbol **prev = &(head.next); -//// -//// Item base_type = {0}; -//// expect(p, ':'); -//// type(p, &base_type); -// -//// /* apply the type to the newly created symbols */ -//// for (int i = 0; i < nsyms; i++) -//// { -//// first->type = base_type.type; -//// codegen_var(p, first); -//// sym = first->next; -//// } -// } + Symbol head = {0}; + int nfields = 0; + + while (peek(p)->type != END) + { + do + { + char* name = expect_text(p, IDENT); + bool export = accept(p, '*'); + (void)symbol_addfield(p, &head, name, SYM_FIELD, export); + nfields++; + } + while (accept(p, ',')); + + Item field_type = {0}; + expect(p, ':'); + type(p, &field_type); + + /* apply the type to the newly created symbols */ + Symbol* field = head.desc; + for (int i = 0; i < nfields; i++) + { + field->type = field_type.type; + field = field->next; + } + item->type->fields = head.desc; + } expect(p, END); } @@ -555,6 +553,7 @@ RULE(proc_decl) var_decl(p, item); } +// /* TODO: Support nested procedures */ // while (matches(p, PROCEDURE)) // { // proc_decl(p, item); diff --git a/cerise/src/sym.c b/cerise/src/sym.c index 6f1e15c..97a021a 100644 --- a/cerise/src/sym.c +++ b/cerise/src/sym.c @@ -36,6 +36,29 @@ static int sym_matches(Parser* p, int class, char* name, Symbol* sym) return 0; } +static Symbol* lookup(Parser* p, int class, char* name) +{ + for (Symbol* scope = p->scope; scope; scope = scope->next) + { +// printf("SCOPE(n: %p):\n", scope->next); + 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)) + { + return sym; + } + } + } + return NULL; +} + + Symbol* symbol_new(Parser* p, char* name, int class, bool export) { Symbol* prev = NULL; @@ -53,6 +76,13 @@ Symbol* symbol_new(Parser* p, char* name, int class, bool export) curr = curr->next; } +// 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); +// } + Symbol* sym = calloc(1, sizeof(Symbol)); sym->name = name; sym->class = class; @@ -102,25 +132,12 @@ Symbol* symbol_addfield(Parser* p, Symbol* parent, char* name, int class, bool e Symbol* symbol_get(Parser* p, int class, char* name) { - for (Symbol* scope = p->scope; scope; scope = scope->next) + Symbol* sym = lookup(p, class, name); + if (!sym) { -// printf("SCOPE(n: %p):\n", scope->next); - 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)) - { - return sym; - } - } + error(p, "unknown identifier '%s'", name); } - error(p, "unknown identifier '%s'", name); - return NULL; + return sym; } void symbol_openscope(Parser* p)