Author | Jakob Wakeling <[email protected]> |
Date | 2022-01-09 12:40:29 |
Commit | ff1f4bab6b966d384db5d53709f361c7d46f38c9 |
Parent | 31d2568f6eb86477718518881956bd23aaee217c |
parse: Integrate the AST child stack
Diffstat
M | src/llvm/gen.c | | | 12 | ++++++------ |
M | src/parse.c | | | 41 | +++++++++++++++++++++++++++-------------- |
M | src/parse.h | | | 6 | +++--- |
D | src/util/stack.c | | | 40 | ---------------------------------------- |
D | src/util/stack.h | | | 23 | ----------------------- |
5 files changed, 36 insertions, 86 deletions
diff --git a/src/llvm/gen.c b/src/llvm/gen.c index 42a18aa..b317dd7 100644 --- a/src/llvm/gen.c +++ b/src/llvm/gen.c @@ -46,7 +46,7 @@ void llvm_free(void) { } void llvm_test(ast *a) { - llvm_init(); gen_decl(a); + llvm_init(); gen_decl(a->c.a[0]); if (LLVMWriteBitcodeToFile(llvm_module, "llvm.bc")) { error(11, "LLVMWriteBitcodeToFile failure!"); @@ -83,8 +83,8 @@ void llvm_test(ast *a) { /* Generate IR for a declaration. */ static LLVMValueRef gen_decl(ast *a) { /* TODO actually implement this properly. */ - if (a->k == AK_DECL && a->c->k == AK_PROC) { - return gen_proc(a->c); + if (a->k == AK_DECL && a->c.a[0]->k == AK_PROC) { + return gen_proc(a->c.a[0]); } else { error(1, "gen_decl else!"); } @@ -94,8 +94,8 @@ static LLVMValueRef gen_decl(ast *a) { /* Generate IR for a compound statement. */ static LLVMValueRef gen_compound(ast *a) { /* TODO actually implement this properly. */ - if ((((ast **)a->cs.a)[0])->k == AK_RETURN) { - return gen_int((((ast **)a->cs.a)[0])->c); + if ((a->c.a[0])->k == AK_RETURN) { + return gen_int(a->c.a[0]->c.a[0]); } else { error(1, "gen_compound else!"); } @@ -110,7 +110,7 @@ static LLVMValueRef gen_proc(ast *a) { LLVMBasicBlockRef bb = LLVMAppendBasicBlock(f, "entry"); LLVMPositionBuilderAtEnd(llvm_builder, bb); - LLVMValueRef r = gen_compound(a->c); if (!r) { return NULL; } + LLVMValueRef r = gen_compound(a->c.a[0]); if (!r) { return NULL; } LLVMBuildRet(llvm_builder, r); return f; } diff --git a/src/parse.c b/src/parse.c index beccac3..ed8dd43 100644 --- a/src/parse.c +++ b/src/parse.c @@ -12,7 +12,6 @@ #include "type.h" #include "util/alloc.h" #include "util/error.h" -#include "util/stack.h" #include "util/util.h" #include "value.h" @@ -45,7 +44,17 @@ ast *ast_aloc(void) { return xcalloc(1, sizeof (ast)); } void ast_init(ast *a) { *a = (ast){ 0 }; } /* Uninitialise an AST node. */ -void ast_free(ast *a) { stack_free(&a->cs); free(a); return; } +void ast_free(ast *a) { + if (a == NULL) { return; } + for (UINT i = 0; i < a->c.ac; i += 1) { ast_free(a->c.a[i]); } + free(a->c.a); free(a); *a = (ast){ 0 }; return; +} + +/* Push a child AST node to an AST node. */ +void ast_push(ast *a, ast *c) { + a->c.a = xrealloc(a->c.a, (a->c.ac += 1) * sizeof (ast *)); + a->c.a[a->c.al] = c; a->c.al += 1; +} #define T (l->t) /* lex_peek equivalent */ @@ -53,8 +62,13 @@ void ast_free(ast *a) { stack_free(&a->cs); free(a); return; } ast *parse(lex *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; + for (ast *c; T.k != LK_EOF;) { + /* Parse and append all child nodes */ + if ((c = parse_decl(l, &a->st)) != NULL) { ast_push(a, c); } + else { /* TODO */ error(1, "NULL AST (parse_decl)"); } + } + + return a; } /* Parse a declaration. */ @@ -71,7 +85,7 @@ static ast *parse_decl(lex *l, syt *st) { 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); + ast_push(sm.a, parse_expr(l)); } break; default: { error( 1, "%s:%zu:%zu: error: Unexpected: \"%s\" (parse_decl)", @@ -79,7 +93,7 @@ static ast *parse_decl(lex *l, syt *st) { ); } break; } - if (sm.a->c->k == AK_PROC) { sm.a->c->s = sm.a->s; } + if (sm.a->c.a[0]->k == AK_PROC) { sm.a->c.a[0]->s = sm.a->s; } assert(sm.h != 0); @@ -110,7 +124,9 @@ static ast *parse_stmt(lex *l) { 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; + case LK_RETURN: { + lex_kind(l, LK_RETURN); a->k = AK_RETURN; ast_push(a, parse_expr(l)); + } break; default: { error( 1, "%zu:%zu: Unexpected: \"%s\" (parse_stmt)", lex_peek(l).ln + 1, lex_peek(l).cl + 1, tok_ks[lex_peek(l).k] @@ -125,11 +141,10 @@ static ast *parse_stmt_compound(lex *l) { lex_kind(l, LK_LBRACE); 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 */ for (; lex_peek(l).k != LK_EOF && lex_peek(l).k != LK_RBRACE;) { - stack_push(&a->cs, parse_stmt(l)); + ast_push(a, parse_stmt(l)); } lex_kind(l, LK_RBRACE); return a; @@ -156,8 +171,6 @@ static ast *parse_proc(lex *l) { lex_kind(l, LK_PROC); lex_kind(l, LK_LPAREN); ast *a = ast_aloc(); a->k = AK_PROC; - a->cs = stack_init(sizeof (ast *), (void (*)(void *))&ast_free); - /* Parse optional procedure parameter(s) */ /* TODO parse parameters(s) */ if (lex_peek(l).k != LK_RPAREN) { @@ -175,7 +188,7 @@ static ast *parse_proc(lex *l) { lex_kind(l, LK_ID); a->t = t_s64; } - a->c = parse_stmt_compound(l); return a; + ast_push(a, parse_stmt_compound(l)); return a; } static ast *parse_int(lex *l) { @@ -188,11 +201,8 @@ void ast_print(ast *a, UINT i) { for (UINT j = 0; j != i; ++j) { printf(" "); } printf("%zu:%zu: %s: %s\n", a->ln, a->cl, ast_ks[a->k], a->s); - if (a->c) { ast_print(a->c, i + 1); } - if (a->lc) { ast_print(a->lc, i + 1); } - if (a->rc) { ast_print(a->rc, i + 1); } - if (a->cs.a) for (UINT ci = 0; ci != a->cs.al; ci += 1) { - ast_print(((ast **)a->cs.a)[ci], i + 1); + if (a->c.a != NULL) for (UINT ci = 0; ci != a->c.al; ci += 1) { + ast_print(a->c.a[ci], i + 1); } if (a->st.a != NULL) { diff --git a/src/parse.h b/src/parse.h index f5b64a2..eed8a09 100644 --- a/src/parse.h +++ b/src/parse.h @@ -11,7 +11,6 @@ #include "lex.h" #include "symbol.h" #include "type.h" -#include "util/stack.h" #include "util/util.h" #include "value.h" @@ -25,7 +24,7 @@ typedef enum { typedef struct ast_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; + struct { struct ast_s **a; UINT al, ac; } c; } ast; extern char *ast_ks[]; @@ -34,6 +33,8 @@ extern ast *ast_aloc(void); extern void ast_init(ast *a); extern void ast_free(ast *a); +extern void ast_push(ast *a, ast *c); + extern ast *parse(lex *l); extern void ast_print(ast *a, UINT i); diff --git a/src/util/stack.c b/src/util/stack.c deleted file mode 100644 index e9d1f29..0000000 --- a/src/util/stack.c +++ /dev/null @@ -1,40 +0,0 @@ -// util/stack.c -// Stack utility source file for G -// Copyright (C) 2021, Jakob Wakeling -// All rights reserved. - - - -#include "alloc.h" -#include "stack.h" -#include "util.h" - -#include <stdlib.h> -#include <string.h> - -/* Initialise a stack. */ -stack stack_init(UINT el, void (*free)(void *)) { - return (stack){ NULL, 0, 0, el, free }; -} - -/* Uninitialise a stack. */ -void stack_free(stack *s) { - if (s) { - if (s->free) for (UINT i = 0; i != s->al; i += 1) { - void *e; memcpy(&e, s->a + i * s->el, s->el); s->free(e); - } - - free(s->a); - } -} - -/* Push a pointer to the top of a stack. */ -void stack_push(stack *s, void *e) { - s->a = xrealloc(s->a, (s->ac += 1) * s->el); - memcpy(s->a + (s->al * s->el), &e, s->el); s->al += 1; -} - -/* Pop a pointer from the top of a stack. */ -void *stack_pop(stack *s) { - void *e; memcpy(&e, s->a + ((s->al -= 1) * s->el), s->el); return e; -} diff --git a/src/util/stack.h b/src/util/stack.h deleted file mode 100644 index 914d80b..0000000 --- a/src/util/stack.h +++ /dev/null @@ -1,23 +0,0 @@ -// util/stack.h -// Stack utility header file for G -// Copyright (C) 2021, Jakob Wakeling -// All rights reserved. - - - -#ifndef UTIL_STACK_H_5W2ABS0S -#define UTIL_STACK_H_5W2ABS0S - -#include "util.h" - -#define STACK_PUSH(s, e) stack_push(s, (void *)(UINT)(e)) - -typedef struct { void *a; UINT al, ac, el; void (*free)(void *); } stack; - -extern stack stack_init(UINT el, void (*free)(void *)); -extern void stack_free(stack *s); - -extern void stack_push(stack *s, void *e); -extern void *stack_pop(stack *s); - -#endif // UTIL_STACK_H_5W2ABS0S