Author | Jakob Wakeling <[email protected]> |
Date | 2022-04-20 00:44:26 |
Commit | 644f1986fa45910cf3ff590145bbbb40fd8f193c |
Parent | 38468186153fa035ab9a2fcafaa533175e3f9a33 |
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;