Author | Jakob Wakeling <[email protected]> |
Date | 2022-04-12 11:27:15 |
Commit | 895c21f5f5943231651252c3093f5f4aebc78753 |
Parent | 8dbbe4a51fe9415c9224e43c1688141bbfdaad95 |
Use AST nodes in symbol table directly
Diffstat
A | doc/ast.md | | | 6 | ++++++ |
M | src/init.c | | | 53 | ++++++++++++++++++++++++++++------------------------- |
M | src/parse.c | | | 37 | +++++++++++++++++++------------------ |
M | src/parse.h | | | 2 | +- |
M | src/symbol.c | | | 32 | ++++++++++++++++---------------- |
M | src/symbol.h | | | 28 | ++++++++-------------------- |
6 files changed, 78 insertions, 80 deletions
diff --git a/doc/ast.md b/doc/ast.md new file mode 100644 index 0000000..3e65c48 --- /dev/null +++ b/doc/ast.md @@ -0,0 +1,6 @@ +# AST Structures + +## AK_DECL + +If an AST node of kind AK_DECL has a child, it shall be an expression representing the +initialisation value. diff --git a/src/init.c b/src/init.c index 6305081..949124d 100644 --- a/src/init.c +++ b/src/init.c @@ -4,51 +4,52 @@ // All rights reserved. #include "init.h" +#include "parse.h" #include "symbol.h" #include "type.h" #include <string.h> -static sym kwds[] = { +static ast kwds[] = { /* Boolean Types */ - { SK_TYPE, 0, 0, 0, "b8", &types[TY_B8], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "b16", &types[TY_B16], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "b32", &types[TY_B32], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "b64", &types[TY_B64], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "bool", &types[TY_B8], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "b8", &types[TY_B8], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "b16", &types[TY_B16], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "b32", &types[TY_B32], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "b64", &types[TY_B64], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "bool", &types[TY_B8], { 0 }, NULL }, /* Integer Types */ - { SK_TYPE, 0, 0, 0, "u8", &types[TY_U8], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "u16", &types[TY_U16], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "u32", &types[TY_U32], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "u64", &types[TY_U64], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "u128", &types[TY_U128], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "uint", &types[TY_UINT], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "u8", &types[TY_U8], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "u16", &types[TY_U16], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "u32", &types[TY_U32], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "u64", &types[TY_U64], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "u128", &types[TY_U128], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "uint", &types[TY_UINT], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "s8", &types[TY_S8], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "s16", &types[TY_S16], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "s32", &types[TY_S32], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "s64", &types[TY_S64], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "s128", &types[TY_S128], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "sint", &types[TY_SINT], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "s8", &types[TY_S8], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "s16", &types[TY_S16], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "s32", &types[TY_S32], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "s64", &types[TY_S64], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "s128", &types[TY_S128], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "sint", &types[TY_SINT], { 0 }, NULL }, /* Floating Point Types */ - { SK_TYPE, 0, 0, 0, "f16", &types[TY_F32], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "f32", &types[TY_F32], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "f64", &types[TY_F64], { 0 }, NULL }, - { SK_TYPE, 0, 0, 0, "f128", &types[TY_F128], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "f16", &types[TY_F32], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "f32", &types[TY_F32], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "f64", &types[TY_F64], { 0 }, NULL }, + { AK_TYPE, 0, 0, 0, "f128", &types[TY_F128], { 0 }, NULL }, // { SK_NULL, 0, 0, 0, "proc", NULL, { 0 }, NULL }, // { SK_NULL, 0, 0, 0, "return", NULL, { 0 }, NULL }, - { SK_NULL, 0, 0, 0, NULL, NULL, { 0 }, NULL } + { AK_NULL, 0, 0, 0, NULL, NULL, { 0 }, NULL } }; void initialise(void) { /* Populate the keyword symbol table */ for (UINT i = 0; kwds[i].s != NULL; i += 1) { kwds[i].h = syt_hash(kwds[i].s, strlen(kwds[i].s)); - syt_insert_h(&kwt, kwds[i].h, kwds[i].s, kwds[i]); + syt_insert_h(&kwt, kwds[i].h, kwds[i].s, &kwds[i]); } } diff --git a/src/parse.c b/src/parse.c index 6ca074e..5ffb6cd 100644 --- a/src/parse.c +++ b/src/parse.c @@ -16,7 +16,7 @@ #include <string.h> char *ast_ks[] = { - "AK_NULL", "AK_PROG", "AK_PROC", + "AK_NULL", "AK_PROG", "AK_PROC", "AK_TYPE", "AK_STMT", "AK_COMP", "AK_DECL", "AK_RETURN", "AK_IF", "AK_FOR", @@ -103,27 +103,26 @@ static ast *parse_stmt_compound(lex *l, syt *st) { /* Parse a declaration statement. */ static ast *parse_stmt_decl(lex *l, syt *st) { - sym sm = { SK_NULL, T.ln, T.cl, T.h, T.s }; - lex_kind(l, TK_ID); lex_kind(l, TK_COLON); + ast *sm = ast_init(); sm->k = AK_DECL; + sm->ln = T.ln; sm->cl = T.cl; sm->h = T.h; sm->s = T.s; - sm.a = ast_init(); sm.a->k = AK_DECL; - if (!(sm.a->s = strdup(sm.s))) { error(1, SERR); } + lex_kind(l, TK_ID); lex_kind(l, TK_COLON); /* Store the declaration's type if one is specified */ /* TODO store type when one is specified */ if (T.k == TK_ID) { - sym s = syt_search_h(st, T.h, T.s); + ast *s = syt_search_h(st, T.h, T.s); - if (s.k == SK_NULL) { error( /* ERROR */ + if (s == NULL) { error( /* ERROR */ 1, "%s:%zu:%zu: error: use of undeclared identifier \"%s\"", l->n, T.ln + 1, T.cl + 1, T.s ); } - if (s.k != SK_TYPE) { error( /* ERROR */ + if (s->k != AK_TYPE) { error( /* ERROR */ 1, "%s:%zu:%zu: error: expected type identifier", l->n, T.ln + 1, T.cl + 1 ); } - sm.t = s.t; lex_next(l); + sm->t = s->t; lex_next(l); if (T.k == TK_SCOLON) { lex_next(l); goto end; } } else if (T.k == TK_SCOLON) { error( @@ -132,14 +131,14 @@ static ast *parse_stmt_decl(lex *l, syt *st) { ); } /* Assign a constant or variable value */ - if (T.k == TK_COLON || T.k == TK_ASSIGN) { lex_next(l); ast_push(sm.a, parse_expr(l, st)); } + if (T.k == TK_COLON || T.k == TK_ASSIGN) { lex_next(l); ast_push(sm, parse_expr(l, st)); } else { error(1, "%s:%zu:%zu: error: expected ':' or '='", l->n, T.ln + 1, T.cl + 1); } /* Parse a semicolon if one is required */ - if (sm.a->c.a[0]->k != AK_PROC) { lex_kind(l, TK_SCOLON); } + if (sm->c.a[0]->k != AK_PROC) { lex_kind(l, TK_SCOLON); } /* Insert the new symbol and return */ - end:; syt_insert_h(st, sm.h, sm.s, sm); return sm.a; + end:; syt_insert_h(st, sm->h, sm->s, sm); return sm; } /* Parse an expression statement. */ @@ -219,7 +218,8 @@ static ast *parse_expr(lex *l, syt *st) { ast *a = ast_init(); tok t = lex_kind(l, TK_ID); a->k = AK_VAR; a->ln = t.ln; a->cl = t.cl; - a->t = syt_search_h(st, t.h, t.s).t; + ast *s = syt_search_h(st, t.h, t.s); + a->t = s ? s->t : NULL; if (!(a->s = strdup(t.s))) { error(1, "%s", SERR); } @@ -275,18 +275,18 @@ static ast *parse_expr_proc(lex *l, syt *st) { /* TODO parse more than one return type */ if (T.k == TK_RARROW) { lex_next(l); tok t = lex_kind(l, TK_ID); - sym s = syt_search_h(st, t.h, t.s); + ast *s = syt_search_h(st, t.h, t.s); - if (s.k == SK_NULL) { error( /* ERROR */ + if (s == NULL) { error( /* ERROR */ 1, "%s:%zu:%zu: error: use of undefined identifier \"%s\"", l->n, T.ln + 1, T.cl + 1, t.s ); } - if (s.k != SK_TYPE) { error( /* ERROR */ + if (s->k != AK_TYPE) { error( /* ERROR */ 1, "%s:%zu:%zu: error: expected type identifier", l->n, T.ln + 1, T.cl + 1 ); } - a->t = s.t; + a->t = s->t; } ast_push(a, parse_stmt_compound(l, st)); return a; diff --git a/src/parse.h b/src/parse.h index f26036a..e702883 100644 --- a/src/parse.h +++ b/src/parse.h @@ -13,7 +13,7 @@ #include "value.h" typedef enum { - AK_NULL, AK_PROG, AK_PROC, + AK_NULL, AK_PROG, AK_PROC, AK_TYPE, AK_STMT, AK_COMP, AK_DECL, AK_RETURN, AK_IF, AK_FOR, diff --git a/src/symbol.c b/src/symbol.c index f90c977..dfbc25b 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -55,12 +55,12 @@ u64 syt_hash(const char *s, UINT l) { #define DIB(i) ((i + st->ac - (st->a[i].h % st->ac)) % st->ac) /* Insert a key-value pair into a map. The key is duplicated. */ -void syt_insert(syt *st, char *k, sym v) { +void syt_insert(syt *st, char *k, ast *v) { return syt_insert_h(st, syt_hash(k, strlen(k)), k, v); } /* Lookup the value associated with a key from a map. */ -sym syt_lookup(syt *st, char *k) { +ast *syt_lookup(syt *st, char *k) { return syt_lookup_h(st, syt_hash(k, strlen(k)), k); } @@ -70,12 +70,12 @@ void syt_remove(syt *st, char *k) { } /* Search for a symbol in a symbol table and its parents. */ -sym syt_search(syt *st, char *k) { +ast *syt_search(syt *st, char *k) { return syt_search_h(st, syt_hash(k, strlen(k)), k); } /* Insert a key-value pair into a map using a precalculated hash. */ -void syt_insert_h(syt *st, u64 h, char *k, sym v) { +void syt_insert_h(syt *st, u64 h, char *k, ast *v) { if (st->ac == 0 || st->al >= ((f64)st->ac * LOAD_FACTOR)) { syt_resize(st); } UINT i = h % st->ac; k = strdup(k); @@ -100,15 +100,15 @@ void syt_insert_h(syt *st, u64 h, char *k, sym v) { } /* Lookup a key-value pair from a map using a precalculated hash. */ -sym syt_lookup_h(syt *st, u64 h, char *k) { - if (st->a == NULL) { return (sym){ 0 }; } +ast *syt_lookup_h(syt *st, u64 h, char *k) { + if (st->a == NULL) { return NULL; } UINT i = h % st->ac; for (UINT dist = 0;; i = (i + 1) % st->ac, dist += 1) { - if (st->a[i].h == 0) { return (sym){ 0 }; } + if (st->a[i].h == 0) { return NULL; } - if (dist > DIB(i)) { return (sym){}; } + if (dist > DIB(i)) { return NULL; /* ? */ } if ((st->a[i].h == h) && (strcmp(st->a[i].k, k) == 0)) { return st->a[i].v; } @@ -128,7 +128,7 @@ void syt_remove_h(syt *st, u64 h, char *k) { if ((st->a[i].h == h) && (strcmp(st->a[i].k, k) == 0)) { /* If the element to be removed is found, then deallocate it */ free(st->a[i].k); - st->a[i] = (typeof (*st->a)){ 0, NULL, {} }; st->al -= 1; + st->a[i] = (typeof (*st->a)){ 0, NULL, NULL }; st->al -= 1; /* */ for (UINT j = (i + 1) % st->ac;; i = j, j = (j + 1) % st->ac) { @@ -145,23 +145,23 @@ void syt_remove_h(syt *st, u64 h, char *k) { } /* Search for a symbol in the symbol tree using a precaclculated hash. */ -sym syt_search_h(syt *st, u64 h, char *k) { - sym sm = syt_lookup_h(&kwt, h, k); - if (sm.h != 0) { return sm; } +ast *syt_search_h(syt *st, u64 h, char *k) { + ast *sm = syt_lookup_h(&kwt, h, k); + if (sm != NULL) { return sm; } for (; st->pt != NULL; st = st->pt) { sm = syt_lookup_h(st, h, k); - if (sm.h != 0) { return sm; } + if (sm->h != 0) { return sm; } } - return (sym){ 0 }; + return NULL; } /* Print a basic representation of a map to stdout. */ void syt_print(syt *st) { for (UINT i = 0; i < st->ac; i += 1) if (st->a[i].h != 0) { - if (st->a[i].v.a->c.a[0]->t) { - printf("%s -> %s\n", st->a[i].k, st->a[i].v.a->c.a[0]->t->s); + if (st->a[i].v->c.a[0]->t) { + printf("%s -> %s\n", st->a[i].k, st->a[i].v->c.a[0]->t->s); } else { printf("%s -> unknown type\n", st->a[i].k); } } diff --git a/src/symbol.h b/src/symbol.h index b42ae7a..af3554f 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -10,21 +10,10 @@ #include "util/util.h" #include "value.h" -typedef enum { - SK_NULL, SK_TYPE, SK_PROC, - - SK_NASS, /* TODO replace SK_NASS with proper kind(s) */ -} sym_k; - typedef struct ast_s ast; -typedef struct { - sym_k k; UINT ln, cl; u64 h; char *s; - type *t; val v; ast *a; -} sym; - typedef struct syt_s { - struct { u64 h; char *k; sym v; } *a; + struct { u64 h; char *k; ast *v; } *a; UINT al, ac; struct syt_s *pt; } syt; @@ -35,15 +24,15 @@ extern syt kwt; extern void syt_free(syt *st); extern u64 syt_hash(const char *s, UINT l); -extern void syt_insert(syt *st, char *k, sym v); -extern sym syt_lookup(syt *st, char *k); +extern void syt_insert(syt *st, char *k, ast *v); +extern ast *syt_lookup(syt *st, char *k); extern void syt_remove(syt *st, char *k); -extern sym syt_search(syt *st, char *k); +extern ast *syt_search(syt *st, char *k); -extern void syt_insert_h(syt *st, u64 h, char *k, sym v); -extern sym syt_lookup_h(syt *st, u64 h, char *k); +extern void syt_insert_h(syt *st, u64 h, char *k, ast *v); +extern ast *syt_lookup_h(syt *st, u64 h, char *k); extern void syt_remove_h(syt *st, u64 h, char *k); -extern sym syt_search_h(syt *st, u64 h, char *k); +extern ast *syt_search_h(syt *st, u64 h, char *k); extern void syt_print(syt *st); extern void syt_debug(syt *st);