From 42c9858fbd16a85a53c3a9391d1717bc43c4a377 Mon Sep 17 00:00:00 2001 From: Baitinq Date: Wed, 9 Jul 2025 22:30:04 +0200 Subject: Bootstrap: Support unary expressions --- src/bootstrap/codegen.pry | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/bootstrap/llvm.pry | 1 + 2 files changed, 50 insertions(+) diff --git a/src/bootstrap/codegen.pry b/src/bootstrap/codegen.pry index c115da9..9062ba1 100644 --- a/src/bootstrap/codegen.pry +++ b/src/bootstrap/codegen.pry @@ -523,6 +523,55 @@ let codegen_generate_expression_value = (c: *codegen, expression: *Node, name: * return codegen_generate_literal(c, cmp, name, expression, create_node(c, node_type)); }; + if ((*expression).type == NODE_UNARY_EXPRESSION) { + let exp = (*(cast(*NODE_UNARY_EXPRESSION_DATA, (*expression).data))); + let k = codegen_generate_expression_value(c, exp.expression, cast(*i8, null)); + if k == cast(*Variable, null) { + return cast(*Variable, null); + }; + + let r = cast(LLVMValueRef, null); + let typ = (*k).node_type; + + if exp.typ == UNARY_EXPRESSION_TYPE_NOT { + /* TODO: assert bool */ + r = LLVMBuildICmp((*c).builder, cast(LLVMIntPredicate, LLVMIntEQ), (*k).value, LLVMConstInt(LLVMInt1Type(), 0, 0), ""); + let node_type = Node{}; + node_type.type = NODE_TYPE_SIMPLE_TYPE; + + let d = cast(*NODE_TYPE_SIMPLE_TYPE_DATA, arena_alloc((*c).arena, sizeof(NODE_TYPE_SIMPLE_TYPE_DATA))); + (*d).name = "bool"; + (*d).underlying_type = cast(*Node, null); + node_type.data = cast(*void, d); + typ = create_node(c, node_type); + }; + + if exp.typ == UNARY_EXPRESSION_TYPE_MINUS { + r = LLVMBuildNeg((*c).builder, (*k).value, ""); + let node_type = Node{}; + node_type.type = NODE_TYPE_SIMPLE_TYPE; + + let d = cast(*NODE_TYPE_SIMPLE_TYPE_DATA, arena_alloc((*c).arena, sizeof(NODE_TYPE_SIMPLE_TYPE_DATA))); + (*d).name = "i64"; + (*d).underlying_type = cast(*Node, null); + node_type.data = cast(*void, d); + typ = create_node(c, node_type); + }; + + if exp.typ == UNARY_EXPRESSION_TYPE_STAR { + /* TODO: assert ptr */ + let n = (*k).node_type; + typ = (*cast(*NODE_TYPE_POINTER_TYPE_DATA, (*n).data)).type; + let ptr_type = codegen_get_llvm_type(c, typ); + if ptr_type == cast(*LLVMTypeRef, null) { + return cast(*Variable, null); + }; + r = LLVMBuildLoad2((*c).builder, *ptr_type, (*k).value, ""); + }; + + return codegen_generate_literal(c, r, name, expression, typ); + }; + if ((*expression).type == NODE_TYPE_FUNCTION_TYPE) { let e = *((*c).environment); printf("LLEL\n"); diff --git a/src/bootstrap/llvm.pry b/src/bootstrap/llvm.pry index bc68d86..0530299 100644 --- a/src/bootstrap/llvm.pry +++ b/src/bootstrap/llvm.pry @@ -317,6 +317,7 @@ extern LLVMBuildBr = (LLVMBuilderRef, LLVMBasicBlockRef) => LLVMValueRef; extern LLVMIsATerminatorInst = (LLVMValueRef) => LLVMValueRef; extern LLVMBuildCondBr = (LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, LLVMBasicBlockRef) => LLVMValueRef; extern LLVMBuildICmp = (LLVMBuilderRef, LLVMIntPredicate, LLVMValueRef, LLVMValueRef, *i8) => LLVMValueRef; +extern LLVMBuildNeg = (LLVMBuilderRef, LLVMValueRef, *i8) => LLVMValueRef; let LLVMIntEQ = 32; let LLVMIntNE = 33; -- cgit 1.4.1