about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-07-09 22:30:04 +0200
committerBaitinq <[email protected]>2025-07-09 22:30:04 +0200
commit42c9858fbd16a85a53c3a9391d1717bc43c4a377 (patch)
tree936898791edea22c5ae3c65a1b3a73185fdeb84c /src
parentBootstrap: Support equality expressions (diff)
downloadpry-lang-42c9858fbd16a85a53c3a9391d1717bc43c4a377.tar.gz
pry-lang-42c9858fbd16a85a53c3a9391d1717bc43c4a377.tar.bz2
pry-lang-42c9858fbd16a85a53c3a9391d1717bc43c4a377.zip
Bootstrap: Support unary expressions
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/codegen.pry49
-rw-r--r--src/bootstrap/llvm.pry1
2 files changed, 50 insertions, 0 deletions
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;