Author | Jakob Wakeling <[email protected]> |
Date | 2022-04-13 13:41:59 |
Commit | a019f098d23d9dfeeb80e1d0f814e9bcd517e9a4 |
Parent | a47f6532e4d1c1d6af1d4c443e4e0d28f2bbd5d9 |
Remove LLVM variable hack
Diffstat
M | src/llvm.c | | | 73 | +++++++++++++++++++++++++++++++++++++++++++------------------------------ |
M | src/parse.h | | | 4 | ++++ |
M | src/symbol.c | | | 3 | ++- |
3 files changed, 49 insertions, 31 deletions
diff --git a/src/llvm.c b/src/llvm.c index e4aa6d4..61ded72 100644 --- a/src/llvm.c +++ b/src/llvm.c @@ -23,16 +23,16 @@ static LLVMContextRef llvm_context = NULL; static LLVMModuleRef llvm_module = NULL; static LLVMBuilderRef llvm_builder = NULL; -static LLVMValueRef llvm_stmt(ast *a); -static LLVMValueRef llvm_stmt_compound(ast *a); -static LLVMValueRef llvm_stmt_decl(ast *a); -static LLVMValueRef llvm_stmt_expr(ast *a); -static LLVMValueRef llvm_stmt_return(ast *a); -static LLVMValueRef llvm_stmt_if(ast *a); -static LLVMValueRef llvm_stmt_for(ast *a); +static LLVMValueRef llvm_stmt(ast *a, syt *st); +static LLVMValueRef llvm_stmt_compound(ast *a, syt *st); +static LLVMValueRef llvm_stmt_decl(ast *a, syt *st); +static LLVMValueRef llvm_stmt_expr(ast *a, syt *st); +static LLVMValueRef llvm_stmt_return(ast *a, syt *st); +static LLVMValueRef llvm_stmt_if(ast *a, syt *st); +static LLVMValueRef llvm_stmt_for(ast *a, syt *st); -static LLVMValueRef llvm_expr(ast *a); -static LLVMValueRef llvm_expr_proc(ast *a); +static LLVMValueRef llvm_expr(ast *a, syt *st); +static LLVMValueRef llvm_expr_proc(ast *a, syt *st); static LLVMValueRef llvm_int(ast *a); @@ -40,6 +40,7 @@ static inline void llvm_init(void); static inline void llvm_free(void); static LLVMTypeRef llvm_type(type *t); +#define A (*a) #define C (a->c.a) /* AST child shorthand "C[i]" */ /* Generate IR from an AST with LLVM. */ @@ -47,7 +48,7 @@ void llvm(ast *a) { llvm_init(); /* Generate IR for all child nodes */ - for (UINT i = 0; i < a->c.al; i += 1) { llvm_stmt_decl(a->c.a[i]); } + for (UINT i = 0; i < a->c.al; i += 1) { llvm_stmt_decl(a->c.a[i], &a->st); } if (LLVMWriteBitcodeToFile(llvm_module, "llvm.bc")) { error(2, "LLVMWriteBitcodeToFile failure"); @@ -80,28 +81,29 @@ void llvm(ast *a) { } /* Generate IR for a statement. */ -static LLVMValueRef llvm_stmt(ast *a) { +static LLVMValueRef llvm_stmt(ast *a, syt *st) { switch (a->k) { - case AK_COMP: { return llvm_stmt_compound(a); } break; - case AK_DECL: { return llvm_stmt_decl(a); } break; - case AK_RETURN: { return llvm_stmt_return(a); } break; - case AK_IF: { return llvm_stmt_if(a); } break; - case AK_FOR: { return llvm_stmt_for(a); } break; + case AK_COMP: { return llvm_stmt_compound(a, st); } break; + case AK_DECL: { return llvm_stmt_decl(a, st); } break; + case AK_RETURN: { return llvm_stmt_return(a, st); } break; + case AK_IF: { return llvm_stmt_if(a, st); } break; + case AK_FOR: { return llvm_stmt_for(a, st); } break; default: { error(2, "llvm_stmt: Unhandled AST kind %s", ast_ks[a->k]); } break; } } /* Generate IR for a compound statement. */ -static LLVMValueRef llvm_stmt_compound(ast *a) { - for (UINT i = 0; i < a->c.al; i += 1) { llvm_stmt(C[i]); } +static LLVMValueRef llvm_stmt_compound(ast *a, syt *st) { + assert(A.k == AK_COMP); + + for (UINT i = 0; i < a->c.al; i += 1) { llvm_stmt(C[i], &A.st); } 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 */ +static LLVMValueRef llvm_stmt_decl(ast *a, syt *st) { + assert(a->k == AK_DECL); if (C[0]->k == AK_PROC) { /* TODO handle procedure arguments if present */ @@ -111,16 +113,16 @@ static LLVMValueRef llvm_stmt_decl(ast *a) { LLVMBasicBlockRef bb = LLVMAppendBasicBlock(f, "entry"); LLVMPositionBuilderAtEnd(llvm_builder, bb); - llvm_expr_proc(C[0]); + llvm_expr_proc(C[0], st); } else { 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; + LLVMSetInitializer(v, llvm_int(C[0])); a->llvm_v = v; } else { LLVMValueRef v = LLVMBuildAlloca(llvm_builder, llvm_type(C[0]->t), a->s); - LLVMBuildStore(llvm_builder, llvm_int(C[0]), v); ref = v; + LLVMBuildStore(llvm_builder, llvm_int(C[0]), v); a->llvm_v = v; } } @@ -128,36 +130,41 @@ static LLVMValueRef llvm_stmt_decl(ast *a) { } /* Generate IR for an expression statement. */ -static LLVMValueRef llvm_stmt_expr(ast *a) { +static LLVMValueRef llvm_stmt_expr(ast *a, syt *st) { } /* Generate IR for a return statement. */ -static LLVMValueRef llvm_stmt_return(ast *a) { - return LLVMBuildRet(llvm_builder, llvm_expr(C[0])); +static LLVMValueRef llvm_stmt_return(ast *a, syt *st) { + return LLVMBuildRet(llvm_builder, llvm_expr(C[0], st)); } /* Generate IR for an if statement. */ -static LLVMValueRef llvm_stmt_if(ast *a) { +static LLVMValueRef llvm_stmt_if(ast *a, syt *st) { } /* Generate IR for a for statement. */ -static LLVMValueRef llvm_stmt_for(ast *a) { +static LLVMValueRef llvm_stmt_for(ast *a, syt *st) { } /* Generate IR for an expression. */ -static LLVMValueRef llvm_expr(ast *a) { - if (a->k == AK_PROC) { return llvm_expr_proc(a); } +static LLVMValueRef llvm_expr(ast *a, syt *st) { + if (a->k == AK_PROC) { return llvm_expr_proc(a, st); } if (a->k == AK_INT) { return llvm_int(a); } - if (a->k == AK_VAR) { return LLVMBuildLoad2(llvm_builder, LLVMIntType(64), ref, "var"); } + if (a->k == AK_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); + } else { error(2, "_expr unknown kind %s", ast_ks[a->k]); } } /* Generate IR for a procedure. */ -static LLVMValueRef llvm_expr_proc(ast *a) { - return llvm_stmt_compound(C[0]); +static LLVMValueRef llvm_expr_proc(ast *a, syt *st) { + return llvm_stmt_compound(C[0], st); } /* Generate IR for an integer. */ diff --git a/src/parse.h b/src/parse.h index e702883..f051e2c 100644 --- a/src/parse.h +++ b/src/parse.h @@ -12,6 +12,8 @@ #include "util/util.h" #include "value.h" +#include <llvm-c/Types.h> + typedef enum { AK_NULL, AK_PROG, AK_PROC, AK_TYPE, @@ -27,6 +29,8 @@ 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 *p; struct { struct ast_s **a; UINT al; } c; + + LLVMValueRef llvm_v; } ast; typedef struct { ast **a; UINT al; } ast_a; diff --git a/src/symbol.c b/src/symbol.c index e3bb6bd..4ff4d92 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -149,9 +149,9 @@ ast *syt_search_h(syt *st, u64 h, char *k) { ast *sm = syt_lookup_h(&kwt, h, k); if (sm != NULL) { return sm; } - for (; st->pt != NULL; st = st->pt) { + for (; st != NULL; st = st->pt) { sm = syt_lookup_h(st, h, k); - if (sm->h != 0) { return sm; } + if (sm != NULL) { return sm; } } return NULL;