G

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

AuthorJakob Wakeling <[email protected]>
Date2021-12-05 12:40:22
Commit9fb3371fae9e536c6d56b2379fdf0f378641bcdd
Parentdade93a16a046d5b99d111c95526b17a49364aaf

util: Standardise util/stack

Diffstat

M src/llvm/gen.c | 4 ++--
M src/parse.c | 8 ++++----
M src/parse.h | 2 +-
M src/util/ast.h | 6 +++---
M src/util/stack.c | 37 ++++++++++++++++++++++++++++---------
M src/util/stack.h | 22 ++++++++++++++--------

6 files changed, 52 insertions, 27 deletions

diff --git a/src/llvm/gen.c b/src/llvm/gen.c
index 6cecb9d..120d2a2 100644
--- a/src/llvm/gen.c
+++ b/src/llvm/gen.c
@@ -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 ((((ast *)a->cs.a)[0])->k == AK_RETURN) {
+		return gen_int((((ast *)a->cs.a)[0])->c);
 	}
 	else { error(1, "gen_compound else!"); }
 
diff --git a/src/parse.c b/src/parse.c
index 1ecfe0b..f27ee55 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -35,7 +35,7 @@ static ast parse_proc(lex *l);
 static ast parse_int(lex *l);
 
 ast  ast_init(void) { return calloc(1, sizeof (struct ast_s)); }
-void ast_free(ast a) { stack_free(a->cs); free(a); return; }
+void ast_free(ast a) { stack_free(&a->cs); free(a); return; }
 
 /* Parse a program. */
 ast parse(lex *l) {
@@ -85,11 +85,11 @@ static ast parse_stmt_compound(lex *l) {
 	lex_kind(l, LK_LBRACE);
 	ast a = ast_init(); a->k = AK_COMPOUND;
 
-	a->cs = stack_init();
+	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));
+		stack_push(&a->cs, parse_stmt(l));
 	}
 
 	lex_kind(l, LK_RBRACE); return a;
@@ -116,7 +116,7 @@ static ast parse_proc(lex *l) {
 	lex_kind(l, LK_PROC); lex_kind(l, LK_LPAREN);
 	ast a = ast_init(); a->k = AK_PROC;
 
-	a->cs = stack_init();
+	a->cs = stack_init(sizeof (ast), (void (*)(void *))&ast_free);
 
 	/* Parse optional procedure parameter(s) */
 	/* TODO parse parameters(s) */
diff --git a/src/parse.h b/src/parse.h
index dd182b4..bbd0030 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -25,7 +25,7 @@ typedef struct ast_s *ast;
 struct ast_s {
 	ast_k k; UINT ln, cl;
 	type *t; val v; char *s;
-	ast c, lc, rc; stack *cs;
+	ast c, lc, rc; stack cs;
 
 	union {};
 };
diff --git a/src/util/ast.h b/src/util/ast.h
index 806ea75..cfeeba4 100644
--- a/src/util/ast.h
+++ b/src/util/ast.h
@@ -17,11 +17,11 @@ static 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->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) for (UINT ci = 0; ci != a->cs->al; ++ci) {
-		ast_print(a->cs->a[ci], 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);
 	}
 
 	return;
diff --git a/src/util/stack.c b/src/util/stack.c
index f6ab99e..e9d1f29 100644
--- a/src/util/stack.c
+++ b/src/util/stack.c
@@ -1,24 +1,40 @@
-// stack.c
-// Stack source file for G
+// 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>
 
-stack *stack_init(void) { return calloc(1, sizeof (void *)); }
-void stack_free(stack *a) { free(a->a); free(a); }
+/* 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 the stack. */
-void stack_push(stack *a, void *p) {
-	if (a->al == a->ac) { a->a = realloc(a->a, a->al * sizeof (*a->a)); }
-	a->a[a->al] = p; a->al += 1; return;
+/* 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 the stack. */
-void *stack_pop(stack *a) {
-	return a->a[--a->al];
+/* 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
index 4d376dd..b16b8d1 100644
--- a/src/util/stack.h
+++ b/src/util/stack.h
@@ -1,21 +1,23 @@
-// stack.h
-// Stack header file for G
+// util/stack.h
+// Stack utility header file for G
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 

 
-#ifndef OMKOV_G_STACK_H_0R2AT1B5
-#define OMKOV_G_STACK_H_0R2AT1B5
+#ifndef UTIL_STACK_H_5W2ABS0S
+#define UTIL_STACK_H_5W2ABS0S
 
-#include "../util/util.h"
+#include "util.h"
 
-typedef struct { void **a; UINT al, ac; } stack;
+#define STACK_PUSH(s, e) stack_push(s, (void *)(UINT)(e));
 
-extern stack *stack_init(void);
-extern void stack_free(stack *a);
+typedef struct { void *a; UINT al, ac, el; void (*free)(void *); } stack;
 
-extern void stack_push(stack *a, void *p);
-extern void *stack_pop(stack *a);
+extern stack stack_init(UINT el, void (*free)(void *));
+extern void  stack_free(stack *s);
 
-#endif // OMKOV_G_STACK_H_0R2AT1B5
+extern void  stack_push(stack *s, void *e);
+extern void *stack_pop(stack *s);
+
+#endif // UTIL_STACK_H_5W2ABS0S