G

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

AuthorJakob Wakeling <[email protected]>
Date2022-03-29 00:53:47
Commit30b1fa8700e75102ebe5aa17d1d41b0a95fb40af
Parent6d07b21638d06401c3fd9d67f8e868958cb9443e

llvm: Implement variables with a temporary hack

Diffstat

M README.md | 2 +-
A examples/dual.g | 2 ++
M src/llvm.c | 14 ++++++++++++--
M src/main.c | 2 +-
M src/parse.c | 23 ++++++++++++++++++-----
M src/parse.h | 2 +-
M src/symbol.c | 4 +++-

7 files changed, 38 insertions, 11 deletions

diff --git a/README.md b/README.md
index b2d1210..ade1857 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ command. The second command will output an executable file, *a.out* by default.
 > Not all todo items will necesarilly be implemented
 
 - [ ] Implement main entrypoint
-- [ ] Implement procedure definitions
+- [ ] Implement procedure declarations
 - [ ] Implement procedure calls
 - [ ] Implement variable assignments
 - [x] Implement integers
diff --git a/examples/dual.g b/examples/dual.g
new file mode 100644
index 0000000..81a3d6b
--- /dev/null
+++ b/examples/dual.g
@@ -0,0 +1,2 @@
+main :: proc() -> s64 { var := 42; return var; }
+test :: proc() -> s64 { return 2; }
diff --git a/src/llvm.c b/src/llvm.c
index 7174a44..e4aa6d4 100644
--- a/src/llvm.c
+++ b/src/llvm.c
@@ -5,6 +5,7 @@
 
 #include "llvm.h"
 #include "parse.h"
+#include "symbol.h"
 #include "type.h"
 #include "util/error.h"
 #include "util/util.h"
@@ -97,6 +98,7 @@ static LLVMValueRef llvm_stmt_compound(ast *a) {
 	return NULL;
 }
 
+static LLVMValueRef ref = NULL; /* TODO fix hack */
 /* Generate IR for a declaration statement. */
 static LLVMValueRef llvm_stmt_decl(ast *a) {
 	if (a->k != AK_DECL) { error(2, "_stmt_decl != AK_DECL"); } /* DEBUG */
@@ -112,8 +114,14 @@ static LLVMValueRef llvm_stmt_decl(ast *a) {
 		llvm_expr_proc(C[0]);
 	}
 	else {
-		LLVMValueRef v = LLVMAddGlobal(llvm_module, llvm_type(C[0]->t), a->s);
-		LLVMSetInitializer(v, llvm_int(C[0]));
+		if (a->p->k == AK_PROG) {
+			LLVMValueRef v = LLVMAddGlobal(llvm_module, llvm_type(C[0]->t), a->s);
+			LLVMSetInitializer(v, llvm_int(C[0])); ref = v;
+		}
+		else {
+			LLVMValueRef v = LLVMBuildAlloca(llvm_builder, llvm_type(C[0]->t), a->s);
+			LLVMBuildStore(llvm_builder, llvm_int(C[0]), v); ref = v;
+		}
 	}
 
 	return NULL;
@@ -143,7 +151,8 @@ static LLVMValueRef llvm_stmt_for(ast *a) {
 static LLVMValueRef llvm_expr(ast *a) {
 	if (a->k == AK_PROC) { return llvm_expr_proc(a); }
 	if (a->k == AK_INT) { return llvm_int(a); }
-	else { error(2, "_expr unknown kind"); }
+	if (a->k == AK_VAR) { return LLVMBuildLoad2(llvm_builder, LLVMIntType(64), ref, "var"); }
+	else { error(2, "_expr unknown kind %s", ast_ks[a->k]); }
 }
 
 /* Generate IR for a procedure. */
diff --git a/src/main.c b/src/main.c
index 480721d..73e325f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -22,7 +22,7 @@ static struct lop lops[] = {
 };
 
 static char *aw[] = {
-	"g", "--debug-parse", "/home/deus/Workspace/G/examples/main.g", NULL
+	"g", "--debug-parse", "/home/deus/Workspace/G/examples/dual.g", NULL
 };
 
 static void hlp(void);
diff --git a/src/parse.c b/src/parse.c
index 3555ea4..c79afa4 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -22,7 +22,7 @@ char *ast_ks[] = {
 
 	"AK_EXPR", "AK_PROC",
 
-	"AK_INT",
+	"AK_VAR", "AK_INT",
 };
 
 static ast *parse_stmt(lex *l, syt *st);
@@ -36,7 +36,7 @@ static ast *parse_stmt_for(lex *l, syt *st);
 static ast *parse_expr(lex *l, syt *st);
 static ast *parse_expr_proc(lex *l, syt *st);
 
-static ast *parse_int(lex *l);
+static ast *parse_int(lex *l, syt *st);
 
 /* Initialise an AST node. */
 ast *ast_init(void) {
@@ -85,7 +85,7 @@ static ast *parse_stmt_compound(lex *l, syt *st) {
 	lex_kind(l, TK_LBRACE);
 
 	ast *a = ast_init(); a->k = AK_COMP;
-	for (; T.k != TK_EOF && T.k != TK_RBRACE;) { ast_push(a, parse_stmt(l, st)); }
+	for (; T.k != TK_EOF && T.k != TK_RBRACE;) { ast_push(a, parse_stmt(l, &a->st)); }
 
 	lex_kind(l, TK_RBRACE); return a;
 }
@@ -176,7 +176,17 @@ static ast *parse_stmt_for(lex *l, syt *st) {
 /* Parse an expression. */
 static ast *parse_expr(lex *l, syt *st) {
 	if (T.k == TK_PROC) { return parse_expr_proc(l, st); }
-	if (T.k == TK_INT) { return parse_int(l); }
+	if (T.k == TK_INT) { return parse_int(l, st); }
+	if (T.k == TK_ID) {
+		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;
+		
+		if (!(a->s = strdup(t.s))) { error(1, "%s", SERR); }
+		
+		return a;
+	}
 	else { error(1, "PARSE_EXPR %s", tok_ks[T.k]); }
 }
 
@@ -210,10 +220,12 @@ static ast *parse_expr_proc(lex *l, syt *st) {
 }
 
 /* Parse an interger. */
-static ast *parse_int(lex *l) {
+static ast *parse_int(lex *l, syt *st) {
 	ast *a = ast_init(); tok t = lex_kind(l, TK_INT);
 	a->k = AK_INT; a->ln = t.ln; a->cl = t.cl;
 
+	a->t = &types[TY_U64]; /* TODO properly determine type */
+	
 	if (!(a->s = strdup(t.s))) { error(1, "%s", SERR); }
 	if (!(a->v = val_parse_int(t.s)).k) { error(1, "%s: %s", t.s, SERR); }
 
diff --git a/src/parse.h b/src/parse.h
index 67eaab7..3900784 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -19,7 +19,7 @@ typedef enum {
 
 	AK_EXPR, AK_PROC,
 
-	AK_INT,
+	AK_VAR, AK_INT,
 } ast_k;
 
 /* k: kind, ln: line, cl: column */
diff --git a/src/symbol.c b/src/symbol.c
index 43ef8e1..e4ff063 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -10,6 +10,7 @@
 	'typeof' operator will become standard in C23.
 */
 
+#include "parse.h"
 #include "symbol.h"
 #include "util/util.h"
 
@@ -159,7 +160,7 @@ sym syt_search_h(syt *st, u64 h, char *k) {
 /* 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) {
-		printf("%s -> %s\n", st->a[i].k, "TODO");
+		printf("%s -> %s\n", st->a[i].k, st->a[i].v.a->c.a[0]->t->s);
 	}
 }