G

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

AuthorJakob Wakeling <[email protected]>
Date2022-04-20 00:44:26
Commit644f1986fa45910cf3ff590145bbbb40fd8f193c
Parent38468186153fa035ab9a2fcafaa533175e3f9a33

Handle local and argument-less procedure calls

Diffstat

M src/llvm.c | 12 ++++++++++--
M src/parse.c | 15 ++++++++++++---
M src/parse.h | 4 ++--

3 files changed, 24 insertions, 7 deletions

diff --git a/src/llvm.c b/src/llvm.c
index 9517968..6dfd355 100644
--- a/src/llvm.c
+++ b/src/llvm.c
@@ -113,7 +113,7 @@ static LLVMValueRef llvm_stmt_decl(ast *a, syt *st) {
 		LLVMBasicBlockRef bb = LLVMAppendBasicBlock(f, "entry");
 		LLVMPositionBuilderAtEnd(llvm_builder, bb);
 
-		llvm_expr_proc(C[0], st);
+		llvm_expr_proc(C[0], st); a->llvm_t = ft; a->llvm_v = f;
 	}
 	else {
 		if (a->p->k == AK_PROG) {
@@ -154,12 +154,20 @@ static LLVMValueRef llvm_expr(ast *a, syt *st) {
 	switch (A.k) {
 	case AK_PROC: { return llvm_expr_proc(a, st); } break;
 	case AK_INT: { return llvm_int(a); } break;
-	case AK_VAR: {
+	case AK_ID_VAR: {
 		ast *v = syt_search(st, a->s);
 		if (v == NULL) { error(2, "llvm_expr: Undefined variable %s", a->s); }
 
 		return LLVMBuildLoad2(llvm_builder, llvm_type(v->t), v->llvm_v, v->s);
 	} break;
+	case AK_ID_PROC: {
+		ast *v = syt_search(st, a->s);
+		if (v == NULL) { error(2, "llvm_expr: Undefined procedure %s", a->s); }
+		
+		if (!v->llvm_v) { error(2, "llvm_expr: Procedure follows"); }
+		
+		return LLVMBuildCall2(llvm_builder, v->llvm_t, v->llvm_v, NULL, 0, v->s);
+	} break;
 	case AK_OP_ADD: {
 		return LLVMBuildAdd(llvm_builder, llvm_expr(A.c.a[0], st), llvm_expr(A.c.a[1], st), "add");
 	} break;
diff --git a/src/parse.c b/src/parse.c
index 383844b..eb60ea9 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -25,7 +25,7 @@ char *ast_ks[] = {
 	"AK_OP_POS", "AK_OP_NEG",
 	"AK_OP_ADD", "AK_OP_SUB", "AK_OP_MUL", "AK_OP_DIV", "AK_OP_MOD",
 
-	"AK_VAR", "AK_INT",
+	"AK_ID_VAR", "AK_ID_PROC", "AK_INT",
 };
 
 static ast *parse_stmt(lex *l, syt *st);
@@ -203,9 +203,17 @@ static ast *parse_expr(lex *l, syt *st) {
 
 	/* Parse expressions with a shunting-yard algorithm */
 	for (;;) switch (T.k) {
-	case TK_ID: { /* TODO handle procedure calls */
+	case 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->ln = t.ln; a->cl = t.cl;
+		
+		if (T.k == TK_LPAREN) {
+			a->k = AK_ID_PROC; lex_kind(l, TK_LPAREN);
+			
+			/* TODO handle procedure arguments */
+			lex_kind(l, TK_RPAREN);
+		}
+		else { a->k = AK_ID_VAR; }
 
 		ast *s = syt_search_h(st, t.h, t.s);
 		a->t = s ? s->t : NULL;
diff --git a/src/parse.h b/src/parse.h
index 9174273..81be9df 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -22,7 +22,7 @@ typedef enum {
 	AK_OP_POS, AK_OP_NEG,
 	AK_OP_ADD, AK_OP_SUB, AK_OP_MUL, AK_OP_DIV, AK_OP_MOD,
 
-	AK_VAR, AK_INT,
+	AK_ID_VAR, AK_ID_PROC, AK_INT,
 } ast_k;
 
 /* k: kind, ln: line, cl: column */
@@ -31,7 +31,7 @@ typedef struct ast_s {
 	ast_k k; UINT ln, cl; u64 h; char *s; type *t; val v; syt st;
 	struct ast_s *p; struct { struct ast_s **a; UINT al; } c;
 
-	LLVMValueRef llvm_v;
+	LLVMTypeRef llvm_t; LLVMValueRef llvm_v;
 } ast;
 
 typedef struct { ast **a; UINT al; } ast_a;