Browse Source

Use AST nodes in symbol table directly

master
Jake Wakeling 4 months ago
parent
commit
2b392ce691
  1. 6
      doc/ast.md
  2. 49
      src/init.c
  3. 34
      src/parse.c
  4. 2
      src/parse.h
  5. 32
      src/symbol.c
  6. 25
      src/symbol.h

6
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.

49
src/init.c

@ -4,51 +4,52 @@
// MIT Licence
#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]);
}
}

34
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;

2
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,

32
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); }
}

25
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);

Loading…
Cancel
Save