feature: implemented while statement
This commit is contained in:
parent
1ac9664c4d
commit
61249d6eaf
|
@ -9,6 +9,21 @@
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
#include <llvm/func.h>
|
#include <llvm/func.h>
|
||||||
|
|
||||||
|
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) {
|
static LLVMValueRef get_parameter(const LLVMFuncScope* scope, const char* name) {
|
||||||
if (g_hash_table_contains(scope->params, name)) {
|
if (g_hash_table_contains(scope->params, name)) {
|
||||||
return g_hash_table_lookup(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));
|
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
|
// delete function scope GLib structs
|
||||||
g_hash_table_destroy(func_scope->params);
|
g_hash_table_destroy(func_scope->params);
|
||||||
|
|
|
@ -22,6 +22,10 @@ typedef struct LLVMLocalScope_t {
|
||||||
LLVMLocalScope* parent_scope;
|
LLVMLocalScope* parent_scope;
|
||||||
} LLVMLocalScope;
|
} LLVMLocalScope;
|
||||||
|
|
||||||
|
LLVMLocalScope* new_local_scope(LLVMLocalScope* parent);
|
||||||
|
|
||||||
|
void delete_local_scope(LLVMLocalScope*);
|
||||||
|
|
||||||
LLVMValueRef get_variable(const LLVMLocalScope* scope, const char* name);
|
LLVMValueRef get_variable(const LLVMLocalScope* scope, const char* name);
|
||||||
|
|
||||||
#endif // LLVM_BACKEND_FUNC_H_
|
#endif // LLVM_BACKEND_FUNC_H_
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <llvm/func.h>
|
#include <llvm/func.h>
|
||||||
#include <llvm/parser.h>
|
#include <llvm/parser.h>
|
||||||
#include <llvm/stmt.h>
|
#include <llvm/stmt.h>
|
||||||
|
#include <llvm/expr.h>
|
||||||
#include <sys/log.h>
|
#include <sys/log.h>
|
||||||
|
|
||||||
BackendError impl_assign_stmt(LLVMBackendCompileUnit *unit,
|
BackendError impl_assign_stmt(LLVMBackendCompileUnit *unit,
|
||||||
|
@ -32,4 +33,58 @@ BackendError impl_assign_stmt(LLVMBackendCompileUnit* unit,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {}
|
BackendError impl_stmt(LLVMBackendCompileUnit *unit, Statement *stmt) {}
|
||||||
|
|
Loading…
Reference in New Issue