G

G Programming Language
git clone http://git.omkov.net/G
Log | Tree | Refs | README | Download

AuthorJakob Wakeling <[email protected]>
Date2022-04-12 11:27:15
Commit895c21f5f5943231651252c3093f5f4aebc78753
Parent8dbbe4a51fe9415c9224e43c1688141bbfdaad95

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