From 61249d6eaf4b29a7caa6da63ed1b6ccb584760a8 Mon Sep 17 00:00:00 2001 From: servostar Date: Wed, 29 May 2024 13:03:39 +0200 Subject: [PATCH] feature: implemented while statement --- src/llvm/func.c | 19 ++++++++++++- src/llvm/func.h | 4 +++ src/llvm/stmt.c | 71 +++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 85 insertions(+), 9 deletions(-) diff --git a/src/llvm/func.c b/src/llvm/func.c index 5c6024d..dc6c8da 100644 --- a/src/llvm/func.c +++ b/src/llvm/func.c @@ -9,6 +9,21 @@ #include #include +LLVMLocalScope* new_local_scope(LLVMLocalScope* parent) { + LLVMLocalScope* scope = malloc(sizeof(LLVMLocalScope)); + + scope->func_scope = parent->func_scope; + scope->vars = g_hash_table_new(g_str_hash, g_str_equal); + scope->parent_scope = parent; + + return scope; +} + +void delete_local_scope(LLVMLocalScope* scope) { + g_hash_table_destroy(scope->vars); + free(scope); +} + static LLVMValueRef get_parameter(const LLVMFuncScope* scope, const char* name) { if (g_hash_table_contains(scope->params, name)) { return g_hash_table_lookup(scope->params, name); @@ -124,7 +139,9 @@ BackendError impl_func(LLVMBackendCompileUnit* unit, LLVMGlobalScope* global_sco g_hash_table_insert(func_scope->params, (gpointer) param->name, LLVMGetParam(llvm_func, i)); } - // parse function body + // TODO: parse function body + + LLVMDisposeBuilder(builder); // delete function scope GLib structs g_hash_table_destroy(func_scope->params); diff --git a/src/llvm/func.h b/src/llvm/func.h index ac27a83..e93eca4 100644 --- a/src/llvm/func.h +++ b/src/llvm/func.h @@ -22,6 +22,10 @@ typedef struct LLVMLocalScope_t { LLVMLocalScope* parent_scope; } LLVMLocalScope; +LLVMLocalScope* new_local_scope(LLVMLocalScope* parent); + +void delete_local_scope(LLVMLocalScope*); + LLVMValueRef get_variable(const LLVMLocalScope* scope, const char* name); #endif // LLVM_BACKEND_FUNC_H_ diff --git a/src/llvm/stmt.c b/src/llvm/stmt.c index 471360c..a77ffed 100644 --- a/src/llvm/stmt.c +++ b/src/llvm/stmt.c @@ -6,11 +6,12 @@ #include #include #include +#include #include -BackendError impl_assign_stmt(LLVMBackendCompileUnit* unit, - const LLVMBuilderRef builder, const LLVMLocalScope* scope, - const Assignment* assignment) { +BackendError impl_assign_stmt(LLVMBackendCompileUnit *unit, + const LLVMBuilderRef builder, const LLVMLocalScope *scope, + const Assignment *assignment) { BackendError err = SUCCESS; DEBUG("implementing assignment for variabel: %s", assignment->variable->name); @@ -21,15 +22,69 @@ BackendError impl_assign_stmt(LLVMBackendCompileUnit* unit, case VariableKindDeclaration: case VariableKindDefinition: const LLVMValueRef llvm_ptr = - get_variable(scope, assignment->variable->name); - LLVMBuildStore(builder, llvm_value, llvm_ptr); - break; + get_variable(scope, assignment->variable->name); + LLVMBuildStore(builder, llvm_value, llvm_ptr); + break; case VariableKindBoxMember: // TODO: resolve LLVMValueRef from BoxAccess - break; + break; } return err; } -BackendError impl_stmt(LLVMBackendCompileUnit* unit, Statement* stmt) {} +BackendError impl_basic_block(LLVMBackendCompileUnit *unit, + LLVMBuilderRef builder, LLVMLocalScope *scope, + const Block *block, LLVMBasicBlockRef *llvm_block) { + BackendError err = SUCCESS; + + LLVMLocalScope *block_scope = new_local_scope(scope); + // append a new LLVM basic block + *llvm_block = LLVMAppendBasicBlockInContext(unit->context, scope->func_scope->llvm_func, + "basic block"); + LLVMPositionBuilderAtEnd(builder, *llvm_block); + + for (size_t i = 0; i < block->statemnts->len; i++) { + Statement *stmt = ((Statement *) block->statemnts->data) + i; + + // TODO: implement statement + } + + delete_local_scope(block_scope); + + return err; +} + +BackendError impl_while(LLVMBackendCompileUnit *unit, + LLVMBuilderRef builder, LLVMLocalScope *scope, + const While *while_stmt) { + BackendError err; + + // Create condition block + LLVMBasicBlockRef while_cond_block = LLVMAppendBasicBlockInContext(unit->context, scope->func_scope->llvm_func, + "loop.while.cond"); + LLVMPositionBuilderAtEnd(builder, while_cond_block); + // Resolve condition in block to a variable + LLVMValueRef cond_result = NULL; + impl_expr(unit, scope, builder, &while_stmt->conditon, &cond_result); + + // build body of loop + LLVMBasicBlockRef while_body_block = NULL; + err = impl_basic_block(unit, builder, scope, &while_stmt->block, &while_body_block); + LLVMPositionBuilderAtEnd(builder, while_body_block); + // jump back to condition after body end + LLVMBuildBr(builder, while_cond_block); + + // builder will continue after the loop + LLVMBasicBlockRef while_after_block = LLVMAppendBasicBlockInContext(unit->context, scope->func_scope->llvm_func, + "loop.while.after"); + // build conditional branch at end of condition block + LLVMPositionBuilderAtEnd(builder, while_cond_block); + LLVMBuildCondBr(builder, cond_result, while_body_block, while_after_block); + + LLVMPositionBuilderAtEnd(builder, while_after_block); + + return err; +} + +BackendError impl_stmt(LLVMBackendCompileUnit *unit, Statement *stmt) {}