G

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

AuthorJakob Wakeling <[email protected]>
Date2022-01-09 12:40:29
Commitff1f4bab6b966d384db5d53709f361c7d46f38c9
Parent31d2568f6eb86477718518881956bd23aaee217c

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