Author | Jakob Wakeling <[email protected]> |
Date | 2022-01-09 03:12:18 |
Commit | 31d2568f6eb86477718518881956bd23aaee217c |
Parent | d73e05f98c9a79592bdbb71aacb39a728a3fb03d |
init: Add keyword table initialisation
Diffstat
M | src/compile.c | | | 9 | ++++++--- |
M | src/compile.h | | | 1 | + |
A | src/init.c | | | 58 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/init.h | | | 15 | +++++++++++++++ |
M | src/lex.c | | | 17 | +++++++++-------- |
M | src/lex.h | | | 8 | ++++---- |
M | src/main.c | | | 6 | ++++++ |
M | src/parse.c | | | 96 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- |
M | src/parse.h | | | 19 | +++++++++---------- |
M | src/symbol.c | | | 178 | +++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------- |
M | src/symbol.h | | | 41 | +++++++++++++++++++++++++++++++---------- |
M | src/type.c | | | 2 | +- |
M | src/type.h | | | 6 | ++++-- |
13 files changed, 338 insertions, 118 deletions
diff --git a/src/compile.c b/src/compile.c index 5761d29..bb64d7f 100644 --- a/src/compile.c +++ b/src/compile.c @@ -6,6 +6,7 @@ #include "compile.h" +#include "init.h" #include "llvm/llvm.h" #include "parse.h" #include "util/error.h" @@ -18,8 +19,10 @@ bool lflag = false, pflag = false; -void compile(char *src, UINT len) { - lex l = lex_init(src, len); +void compile(const char * file, char *src, UINT len) { + initialise(); + + lex l = lex_init(file, src, len); if (lflag) { lex_debug(&l); goto ret; } ast *a = parse(&l); @@ -40,5 +43,5 @@ void compile_file(const char *file) { fb = malloc((fl + 1) * sizeof (*fb)); fread(fb, 1, fl, fi); fb[fl] = 0; fclose(fi); - compile(fb, fl); free(fb); return; + compile(file, fb, fl); free(fb); return; } diff --git a/src/compile.h b/src/compile.h index c5d5361..9ccb5ba 100644 --- a/src/compile.h +++ b/src/compile.h @@ -12,7 +12,7 @@ extern bool lflag, pflag; -extern void compile(char *src, UINT len); +extern void compile(const char *file, char *src, UINT len); extern void compile_file(const char *file); #endif // G_COMPILE_H_DSDZQ0ZM diff --git a/src/init.c b/src/init.c new file mode 100644 index 0000000..d5235ee --- /dev/null +++ b/src/init.c @@ -0,0 +1,58 @@ +// init.c +// Initialiser source file for G +// Copyright (C) 2021, Jakob Wakeling +// All rights reserved. + + + +#include "init.h" +#include "symbol.h" +#include "type.h" + +#include <string.h> + +static sym kwds[] = { + /* Boolean Types */ + { 0, 0, 0, 0, "b8", &types[TK_B8], { 0 }, NULL }, + { 0, 0, 0, 0, "b16", &types[TK_B16], { 0 }, NULL }, + { 0, 0, 0, 0, "b32", &types[TK_B32], { 0 }, NULL }, + { 0, 0, 0, 0, "b64", &types[TK_B64], { 0 }, NULL }, + { 0, 0, 0, 0, "bool", &types[TK_B8], { 0 }, NULL }, + + /* Integer Types */ + { 0, 0, 0, 0, "u8", &types[TK_U8], { 0 }, NULL }, + { 0, 0, 0, 0, "u16", &types[TK_U16], { 0 }, NULL }, + { 0, 0, 0, 0, "u32", &types[TK_U32], { 0 }, NULL }, + { 0, 0, 0, 0, "u64", &types[TK_U64], { 0 }, NULL }, + { 0, 0, 0, 0, "u128", &types[TK_U128], { 0 }, NULL }, + { 0, 0, 0, 0, "uint", &types[TK_UINT], { 0 }, NULL }, + + { 0, 0, 0, 0, "s8", &types[TK_S8], { 0 }, NULL }, + { 0, 0, 0, 0, "s16", &types[TK_S16], { 0 }, NULL }, + { 0, 0, 0, 0, "s32", &types[TK_S32], { 0 }, NULL }, + { 0, 0, 0, 0, "s64", &types[TK_S64], { 0 }, NULL }, + { 0, 0, 0, 0, "s128", &types[TK_S128], { 0 }, NULL }, + { 0, 0, 0, 0, "sint", &types[TK_SINT], { 0 }, NULL }, + + /* Floating Point Types */ + { 0, 0, 0, 0, "f16", &types[TK_F32], { 0 }, NULL }, + { 0, 0, 0, 0, "f32", &types[TK_F32], { 0 }, NULL }, + { 0, 0, 0, 0, "f64", &types[TK_F64], { 0 }, NULL }, + { 0, 0, 0, 0, "f128", &types[TK_F128], { 0 }, NULL }, + + /* Keywords */ + { 0, 0, 0, 0, "proc", NULL, { 0 }, NULL }, + { 0, 0, 0, 0, "return", NULL, { 0 }, NULL }, + + { SK_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]); + } +} + +void uninitialise(void) { syt_free(&kwt); } diff --git a/src/init.h b/src/init.h new file mode 100644 index 0000000..b2da599 --- /dev/null +++ b/src/init.h @@ -0,0 +1,15 @@ +// init.h +// Initialiser header file for G +// Copyright (C) 2021, Jakob Wakeling +// All rights reserved. + + + +#ifndef G_INIT_H_9Q2WGC4Z +#define G_INIT_H_9Q2WGC4Z + +#include "symbol.h" + +extern void initialise(void); + +#endif // G_INIT_H_9Q2WGC4Z diff --git a/src/lex.c b/src/lex.c index 0f6a644..5c31709 100644 --- a/src/lex.c +++ b/src/lex.c @@ -7,9 +7,9 @@ #include "keyword.h" #include "lex.h" +#include "symbol.h" #include "type.h" #include "util/error.h" -#include "util/fnv.h" #include "util/util.h" #include <ctype.h> @@ -37,8 +37,9 @@ char *tok_ks[] = { }; /* Initialise a lexer. */ -lex lex_init(char *src, UINT len) { - lex l = { src, src, src + len, 0, 0, 0 }; lex_next(&l); return l; +lex lex_init(const char *file, char *src, UINT len) { + lex l = { file, src, src, src + len, 0, 0, 0 }; + lex_next(&l); return l; } #define P (l->p) /* Pointer to the Current Character */ @@ -94,8 +95,8 @@ skip:; for (P += 1; isalpha(C) || isdigit(C) || C == '_'; P += 1); sl = P - s; CL += sl; - T.v_str = strndup(s, sl); - T.h = fnv1a64(s, sl); kwd *k = kwd_find(T.h); + T.s = strndup(s, sl); + T.h = syt_hash(s, sl); kwd *k = kwd_find(T.h); if (k) { T.k = k->k; } else { T.k = LK_ID; } } @@ -106,7 +107,7 @@ skip:; for (P += 1; isalnum(C); P += 1); sl = P - s; CL += sl; - T.v_str = strndup(s, sl); + T.s = strndup(s, sl); T.k = LK_INT; } @@ -204,7 +205,7 @@ tok lex_kind(lex *l, tok_k k) { /* Print lexer debug output and exit. */ void lex_debug(lex *l) { - for (tok t = lex_next(l); t.k != LK_EOF; free(t.v_str), t = lex_next(l)) { - printf("%zu:%zu: %s \"%s\"\n", t.ln + 1, t.cl + 1, tok_ks[t.k], t.v_str); + for (tok t = lex_next(l); t.k != LK_EOF; free(t.s), t = lex_next(l)) { + printf("%zu:%zu: %s \"%s\"\n", t.ln + 1, t.cl + 1, tok_ks[t.k], t.s); } } diff --git a/src/lex.h b/src/lex.h index 7e050a9..7e4336e 100644 --- a/src/lex.h +++ b/src/lex.h @@ -28,17 +28,17 @@ typedef enum { } tok_k; typedef struct { - tok_k k; UINT ln, cl; u64 h; - union { u64 v_u64; s64 v_s64; f64 v_f64; char *v_str; }; + tok_k k; UINT ln, cl; u64 h; char *s; + union { u64 v_u64; s64 v_s64; f64 v_f64; }; } tok; typedef struct { - char *s, *p, *q; UINT ln, cl; tok t; + const char *n; char *s, *p, *q; UINT ln, cl; tok t; } lex; extern char *tok_ks[]; -extern lex lex_init(char *src, UINT len); +extern lex lex_init(const char *file, char *src, UINT len); extern tok lex_peek(lex *l); extern tok lex_next(lex *l); extern tok lex_kind(lex *l, tok_k k); diff --git a/src/main.c b/src/main.c index f93599b..3541ca6 100644 --- a/src/main.c +++ b/src/main.c @@ -24,10 +24,16 @@ static struct lop lops[] = { { NULL, 0, 0 } }; +static char *aw[] = { + "g", "--debug-parse", "/home/deus/Workspace/G/examples/main.g", NULL +}; + static void hlp(void); static void ver(void); int main(int ac, char *av[]) { (void)(ac); A0 = av[0]; + if (ac == 1) { ac = 3; av = aw; } /* DEBUG */ + struct opt opt = OPTGET_INIT; opt.str = ""; opt.lops = lops; for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) { case 256: { hlp(); } return 0; diff --git a/src/parse.c b/src/parse.c index 1541bd9..beccac3 100644 --- a/src/parse.c +++ b/src/parse.c @@ -5,9 +5,12 @@ +#include "init.h" #include "lex.h" #include "parse.h" +#include "symbol.h" #include "type.h" +#include "util/alloc.h" #include "util/error.h" #include "util/stack.h" #include "util/util.h" @@ -18,12 +21,13 @@ #include <string.h> char *ast_ks[] = { - "AK_NULL", "AK_INT", "AK_FLT", + "AK_NULL", "AK_PROG", - "AK_DECL", "AK_COMPOUND", "AK_PROC", "AK_RETURN", + "AK_DECL", "AK_COMP", "AK_PROC", "AK_RETURN", + "AK_INT", "AK_FLT", }; -static ast *parse_decl(lex *l); +static ast *parse_decl(lex *l, syt *st); static ast *parse_stmt(lex *l); static ast *parse_stmt_compound(lex *l); @@ -34,40 +38,76 @@ static ast *parse_proc(lex *l); static ast *parse_int(lex *l); -ast *ast_init(void) { return calloc(1, sizeof (struct ast_s)); } +/* Allocate an AST node. */ +ast *ast_aloc(void) { return xcalloc(1, sizeof (ast)); } + +/* Initialise an AST node. */ +void ast_init(ast *a) { *a = (ast){ 0 }; } + +/* Uninitialise an AST node. */ void ast_free(ast *a) { stack_free(&a->cs); free(a); return; } +#define T (l->t) /* lex_peek equivalent */ + /* Parse a program. */ ast *parse(lex *l) { - return parse_decl(l); + ast *a = ast_aloc(); a->k = AK_PROG; syt_init(&a->st); + + /* TODO beyond this point */ + a->c = parse_decl(l, &a->st); return a; } /* Parse a declaration. */ -static ast *parse_decl(lex *l) { - ast *a = ast_init(); +static ast *parse_decl(lex *l, syt *st) { + sym sm = { SK_NULL, T.ln, T.cl, T.h, T.s }; + + lex_kind(l, LK_ID); lex_kind(l, LK_COLON); + + if (T.k == LK_ID) { /* TODO lookup and store type */ } + if (T.k == LK_SCOLON) { error(1, "LK_SCOLON (parse_decl)"); } + + switch (T.k) { + case LK_COLON: { lex_kind(l, LK_COLON); } goto decl_expr; + case LK_ASSIGN: { lex_kind(l, LK_ASSIGN); } goto decl_expr; + decl_expr: { + sm.a = ast_aloc(); sm.a->k = AK_DECL; sm.a->s = strdup(sm.s); + sm.a->c = parse_expr(l); + } break; + default: { error( + 1, "%s:%zu:%zu: error: Unexpected: \"%s\" (parse_decl)", + l->n, lex_peek(l).ln + 1, lex_peek(l).cl + 1, tok_ks[lex_peek(l).k] + ); } break; + } - a->s = lex_kind(l, LK_ID).v_str; lex_kind(l, LK_COLON); + if (sm.a->c->k == AK_PROC) { sm.a->c->s = sm.a->s; } - if (lex_peek(l).k == LK_ID) { /* TODO lookup and store type */ } + assert(sm.h != 0); - switch (lex_peek(l).k) { - case LK_COLON: { lex_kind(l, LK_COLON); a->k = AK_DECL; } goto decl_expr; - case LK_ASSIGN: { lex_kind(l, LK_ASSIGN); a->k = AK_DECL; } goto decl_expr; - decl_expr: { a->c = parse_expr(l); } break; - default: { error( - 1, "%zu:%zu: Unexpected: \"%s\" (parse_decl)", - lex_peek(l).ln + 1, lex_peek(l).cl + 1, tok_ks[lex_peek(l).k] - ); } break; + /* Confirm that the identifier is not a keyword */ + if (syt_lookup_h(&kwt, sm.h, sm.s).h != 0) { + error( + 1, "%s:%zu:%zu: error: keyword '%s' (parse_decl)", + l->n, sm.ln + 1, sm.cl + 1, sm.s + ); + } + + /* Confirm that the identifier is not being reused */ + if (syt_lookup_h(st, sm.h, sm.s).h != 0) { + error( + 1, "%s:%zu:%zu: error: redefinition of '%s' (parse_decl)", + l->n, sm.ln + 1, sm.cl + 1, sm.s + ); } - if (a->c->k == AK_PROC) { a->c->s = a->s; } return a; + /* Otherwise insert the new symbol and return */ + syt_insert_h(st, sm.h, sm.s, sm); return sm.a; } /* Parse a statement. */ static ast *parse_stmt(lex *l) { if (lex_peek(l).k == LK_LBRACE) { return parse_stmt_compound(l); } - ast *a = ast_init(); + ast *a = ast_aloc(); switch (lex_peek(l).k) { case LK_RETURN: { lex_kind(l, LK_RETURN); a->k = AK_RETURN; a->c = parse_expr(l); } break; @@ -83,8 +123,8 @@ static ast *parse_stmt(lex *l) { /* Parse a compound statement. */ static ast *parse_stmt_compound(lex *l) { lex_kind(l, LK_LBRACE); - ast *a = ast_init(); a->k = AK_COMPOUND; + ast *a = ast_aloc(); a->k = AK_COMP; syt_init(&a->st); a->cs = stack_init(sizeof (ast *), (void (*)(void *))&ast_free); /* Parse statements until EOF or closing brace */ @@ -97,7 +137,7 @@ static ast *parse_stmt_compound(lex *l) { /* Parse an expression. */ static ast *parse_expr(lex *l) { - ast *a = ast_init(); + ast *a = ast_aloc(); switch (lex_peek(l).k) { case LK_PROC: { return parse_proc(l); } break; @@ -114,7 +154,7 @@ static ast *parse_expr(lex *l) { /* Parse a procedure. */ static ast *parse_proc(lex *l) { lex_kind(l, LK_PROC); lex_kind(l, LK_LPAREN); - ast *a = ast_init(); a->k = AK_PROC; + ast *a = ast_aloc(); a->k = AK_PROC; a->cs = stack_init(sizeof (ast *), (void (*)(void *))&ast_free); @@ -131,7 +171,7 @@ static ast *parse_proc(lex *l) { if (lex_peek(l).k == LK_RARROW) { lex_kind(l, LK_RARROW); - /* TODO dont hardcode return type */ + /* TODO dont hardcode return type */ lex_kind(l, LK_ID); a->t = t_s64; } @@ -139,8 +179,8 @@ static ast *parse_proc(lex *l) { } static ast *parse_int(lex *l) { - val v = val_strint(lex_kind(l, LK_INT).v_str); - ast *a = ast_init(); a->k = AK_INT; a->v = v; + val v = val_strint(lex_kind(l, LK_INT).s); + ast *a = ast_aloc(); a->k = AK_INT; a->v = v; return a; } @@ -155,5 +195,11 @@ void ast_print(ast *a, UINT i) { ast_print(((ast **)a->cs.a)[ci], i + 1); } + if (a->st.a != NULL) { + printf("--- SYT for %s: %s ---\n", ast_ks[a->k], a->s); + syt_print(&a->st); + printf("--- SYT for %s: %s ---\n", ast_ks[a->k], a->s); + } + return; } diff --git a/src/parse.h b/src/parse.h index 90987fc..f5b64a2 100644 --- a/src/parse.h +++ b/src/parse.h @@ -9,30 +9,29 @@ #define G_PARSE_H_VB50JOSX #include "lex.h" +#include "symbol.h" #include "type.h" #include "util/stack.h" #include "util/util.h" #include "value.h" typedef enum { - AK_NULL, AK_INT, AK_FLT, + AK_NULL, AK_PROG, - AK_DECL, AK_COMPOUND, AK_PROC, AK_RETURN, + AK_DECL, AK_COMP, AK_PROC, AK_RETURN, + AK_INT, AK_FLT, } ast_k; typedef struct ast_s { - ast_k k; UINT ln, cl; - type *t; val v; char *s; + ast_k k; UINT ln, cl; u64 h; char *s; + type *t; val v; syt st; struct ast_s *c, *lc, *rc; stack cs; - - union { - - }; } ast; extern char *ast_ks[]; -extern ast *ast_init(void); +extern ast *ast_aloc(void); +extern void ast_init(ast *a); extern void ast_free(ast *a); extern ast *parse(lex *l); diff --git a/src/symbol.c b/src/symbol.c index 6b4b21a..461fe30 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -24,135 +24,175 @@ #define INITIAL_CAPACITY 64 #define LOAD_FACTOR 0.90 -static void map_resize(syt *m); +syt kwt = (syt){ NULL, 0, 0, NULL }; -/* Initialise a map. */ -syt syt_init(void (*free)(void *)) { - return (syt){ NULL, 0, 0 }; -} +static void syt_resize(syt *st); + +/* Allocate a symbol table. */ +syt *syt_aloc(void) { return xcalloc(1, sizeof (syt)); } + +/* Initialise a symbol table. */ +void syt_init(syt *st) { *st = (syt){ NULL, 0, 0, NULL }; } -/* Uninitialise a map. */ -void syt_free(syt *m) { - for (UINT i = 0; i < m->ac; i += 1) { - if (m->a[i].h == 0) { continue; } free(m->a[i].k); +/* Uninitialise a symbol table. */ +void syt_free(syt *st) { + if (st == NULL || st->a == NULL) { return; } + + for (UINT i = 0; i < st->ac; i += 1) { + if (st->a[i].h == 0) { continue; } + free(st->a[i].k); /*free(s->a[i].v)*/ } - free(m->a); *m = (syt){ NULL, 0, 0 }; + free(st->a); *st = (syt){ NULL, 0, 0 }; } /* Compute the hash of some data. Will not return 0. */ -u64 syt_hash(const char *dat, UINT len) { +u64 syt_hash(const char *s, UINT l) { register u64 fnv = 0xCBF29CE484222325; - for (; len; len -= 1, dat += 1) { fnv ^= *dat; fnv *= 0x00000100000001B3; } + for (; l; l -= 1, s += 1) { fnv ^= *s; fnv *= 0x00000100000001B3; } fnv |= fnv == 0; return fnv; } #define SWAP(a, b) { register typeof (a) t = a; a = b; b = t; } -#define DIB(i) ((i + m->ac - (m->a[i].h % m->ac)) % m->ac) +#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 *m, char *k, sym v) { - if (m->ac == 0 || m->al >= ((f64)m->ac * LOAD_FACTOR)) { map_resize(m); } - UINT h = syt_hash(k, strlen(k)), i = h % m->ac; k = strdup(k); +void syt_insert(syt *st, char *k, sym 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) { + return syt_lookup_h(st, syt_hash(k, strlen(k)), k); +} + +/* Remove a key-value pair from a map. */ +void syt_remove(syt *st, char *k) { + return syt_remove_h(st, syt_hash(k, strlen(k)), k); +} + +/* Search for a symbol in a symbol table and its parents. */ +sym 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) { + if (st->ac == 0 || st->al >= ((f64)st->ac * LOAD_FACTOR)) { syt_resize(st); } + UINT i = h % st->ac; k = strdup(k); - for (UINT dist = 0;; i = (i + 1) % m->ac, dist += 1) { - if (m->a[i].h == 0) { + for (UINT dist = 0;; i = (i + 1) % st->ac, dist += 1) { + if (st->a[i].h == 0) { /* If an empty bucket is found, insert here */ - m->a[i] = (typeof (*m->a)){ h, k, v }; - m->al += 1; return; + st->a[i] = (typeof (*st->a)){ h, k, v }; + st->al += 1; return; } /* Calculate tsid, the DIB of the item at the current index */ - UINT tsid = (i + m->ac - (m->a[i].h % m->ac)) % m->ac; + UINT tsid = (i + st->ac - (st->a[i].h % st->ac)) % st->ac; if (dist > tsid) { - SWAP(m->a[i].h, h); - SWAP(m->a[i].k, k); - SWAP(m->a[i].v, v); + SWAP(st->a[i].h, h); + SWAP(st->a[i].k, k); + SWAP(st->a[i].v, v); dist = tsid; } } } -/* Lookup the value associated with a key from a map. */ -sym syt_lookup(syt *m, char *k) { - UINT h = syt_hash(k, strlen(k)), i = h % m->ac; +/* 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 }; } - for (UINT dist = 0;; i = (i + 1) % m->ac, dist += 1) { - if (m->a[i].h == 0) { return (sym){}; } + 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 (dist > DIB(i)) { return (sym){}; } - if ((m->a[i].h == h) && (strcmp(m->a[i].k, k) == 0)) { - return m->a[i].v; + if ((st->a[i].h == h) && (strcmp(st->a[i].k, k) == 0)) { + return st->a[i].v; } } } -/* Remove a key-value pair from a map. */ -void syt_remove(syt *m, char *k) { - UINT h = syt_hash(k, strlen(k)), i = h % m->ac; +/* Remove a key-value pair from a map using a precalculated hash. */ +void syt_remove_h(syt *st, u64 h, char *k) { + if (st->a == NULL) { return; } + + UINT i = h % st->ac; - for (UINT dist = 0;; i = (i + 1) % m->ac, dist += 1) { - if (m->a[i].h == 0) { return; } + for (UINT dist = 0;; i = (i + 1) % st->ac, dist += 1) { + if (st->a[i].h == 0) { return; } if (dist > DIB(i)) { return; } - if ((m->a[i].h == h) && (strcmp(m->a[i].k, k) == 0)) { + 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(m->a[i].k); - m->a[i] = (typeof (*m->a)){ 0, NULL, {} }; m->al -= 1; + free(st->a[i].k); + st->a[i] = (typeof (*st->a)){ 0, NULL, {} }; st->al -= 1; /* */ - for (UINT j = (i + 1) % m->ac;; i = j, j = (j + 1) % m->ac) { - if (m->a[j].h == 0 || DIB(j) == 0) { break; } + for (UINT j = (i + 1) % st->ac;; i = j, j = (j + 1) % st->ac) { + if (st->a[j].h == 0 || DIB(j) == 0) { break; } - SWAP(m->a[i].h, m->a[j].h); - SWAP(m->a[i].k, m->a[j].k); - SWAP(m->a[i].v, m->a[j].v); + SWAP(st->a[i].h, st->a[j].h); + SWAP(st->a[i].k, st->a[j].k); + SWAP(st->a[i].v, st->a[j].v); } - /* - TODO I am unsure if I want to have this procedure return the - removed value or simply an acknowledgement of its removal - */ return; } } } +/* 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; } + + for (; st->pt != NULL; st = st->pt) { + sm = syt_lookup_h(st, h, k); + if (sm.h != 0) { return sm; } + } + + return (sym){ 0 }; +} + /* Print a basic representation of a map to stdout. */ -void syt_print(syt *m) { - for (UINT i = 0; i < m->ac; i += 1) if (m->a[i].h != 0) { - printf("%s -> %s\n", m->a[i].k, "TODO"); +void syt_print(syt *st) { + for (UINT i = 0; i < st->ac; i += 1) if (st->a[i].h != 0) { + printf("%s -> %s\n", st->a[i].k, "TODO"); } } /* Print a debug representation of a map to stdout. */ -void syt_debug(syt *m) { - for (UINT i = 0; i < m->ac; i += 1) { - if (m->a[i].h == 0) { printf("[%zu] %lu\n", i, m->a[i].h); } +void syt_debug(syt *st) { + for (UINT i = 0; i < st->ac; i += 1) { + if (st->a[i].h == 0) { printf("[%zu] %lu\n", i, st->a[i].h); } else printf( "[%zu] %lu, %s -> %s, DIB: %zu\n", - i, m->a[i].h, m->a[i].k, "TODO", DIB(i) + i, st->a[i].h, st->a[i].k, "TODO", DIB(i) ); } } /* Double the number of buckets in a map. */ -static void map_resize(syt *m) { +static void syt_resize(syt *st) { /* If the map is empty, simply allocate it without rehashing */ - if (m->ac == 0) { - m->ac = INITIAL_CAPACITY; - m->a = xcalloc(m->ac, sizeof (*m->a)); return; + if (st->ac == 0) { + st->ac = INITIAL_CAPACITY; + st->a = xcalloc(st->ac, sizeof (*st->a)); return; } /* Otherwise rehash every element into a new resized map */ - syt old = *m; m->ac *= 2; m->a = xcalloc(m->ac, sizeof (*m->a)); m->al = 0; + syt old = *st; st->ac *= 2; st->al = 0; + st->a = xcalloc(st->ac, sizeof (*st->a)); for (UINT i = 0; i < old.ac; i += 1) { if (old.a[i].h == 0) { continue; } - syt_insert(m, old.a[i].k, old.a[i].v); + syt_insert(st, old.a[i].k, old.a[i].v); free(old.a[i].k); } diff --git a/src/symbol.h b/src/symbol.h index 0b26eac..f6d3100 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -5,29 +5,47 @@ -#ifndef UTIL_SYMBOL_H_Q1VLFKFE -#define UTIL_SYMBOL_H_Q1VLFKFE +#ifndef G_SYMBOL_H_Q1VLFKFE +#define G_SYMBOL_H_Q1VLFKFE +#include "type.h" #include "util/util.h" +#include "value.h" + +typedef enum { + SK_NULL, SK_PROC, +} sym_k; + +typedef struct ast_s ast; typedef struct { - UINT a; + sym_k k; UINT ln, cl; u64 h; char *s; + type *t; val v; ast *a; } sym; -typedef struct { +typedef struct syt_s { struct { u64 h; char *k; sym v; } *a; - UINT al, ac; + UINT al, ac; struct syt_s *pt; } syt; -extern syt syt_init(void (*free)(void *)); -extern void syt_free(syt *m); +extern syt kwt; + +extern syt *syt_aloc(void); +extern void syt_init(syt *st); +extern void syt_free(syt *st); extern u64 syt_hash(const char *s, UINT l); -extern void syt_insert(syt *m, char *k, sym v); -extern sym syt_lookup(syt *m, char *k); -extern void syt_remove(syt *m, char *k); +extern void syt_insert(syt *st, char *k, sym v); +extern sym syt_lookup(syt *st, char *k); +extern void syt_remove(syt *st, char *k); +extern sym 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_remove_h(syt *st, u64 h, char *k); +extern sym syt_search_h(syt *st, u64 h, char *k); -extern void syt_print(syt *m); -extern void syt_debug(syt *m); +extern void syt_print(syt *st); +extern void syt_debug(syt *st); -#endif // UTIL_SYMBOL_H_Q1VLFKFE +#endif // G_SYMBOL_H_Q1VLFKFE diff --git a/src/type.c b/src/type.c index c15934b..90319a7 100644 --- a/src/type.c +++ b/src/type.c @@ -9,7 +9,7 @@ #include <stdlib.h> -static type types[] = { +type types[] = { { TK_VOID, 0, 0, "void" }, { TK_PTR, TF_PTR, -1, "ptr" }, { TK_TYPE, 0, -1, "type" }, diff --git a/src/type.h b/src/type.h index a15f8dd..10c2b23 100644 --- a/src/type.h +++ b/src/type.h @@ -45,11 +45,13 @@ typedef enum { TF_NUM = TF_INT | TF_FLT | TF_CLX, } type_f; -typedef struct type { +typedef struct type_s { type_k k; type_f f; sint l; - char *name; struct type *base; + char *s; struct type_s *base; } type; +extern type types[]; + extern type *t_void, *t_ptr, *t_type, *t_any; extern type *t_bool, *t_b8, *t_b16, *t_b32, *t_b64;