about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-07-12 20:51:19 +0200
committerBaitinq <[email protected]>2025-07-12 20:51:19 +0200
commitd157bcfbd23e3dcb95c397f351fad4ddcc25349c (patch)
tree73e7845387f5a5cdce51849f25bcefcd85d21e6f
parentBoostrap: Clean (diff)
downloadpry-lang-d157bcfbd23e3dcb95c397f351fad4ddcc25349c.tar.gz
pry-lang-d157bcfbd23e3dcb95c397f351fad4ddcc25349c.tar.bz2
pry-lang-d157bcfbd23e3dcb95c397f351fad4ddcc25349c.zip
Boostrap: Support calling function ptr
-rw-r--r--src/bootstrap/codegen.pry28
-rw-r--r--src/bootstrap/llvm.pry5
2 files changed, 30 insertions, 3 deletions
diff --git a/src/bootstrap/codegen.pry b/src/bootstrap/codegen.pry
index 0bc11f3..2846378 100644
--- a/src/bootstrap/codegen.pry
+++ b/src/bootstrap/codegen.pry
@@ -225,7 +225,23 @@ let codegen_get_llvm_type = (c: *codegen, node: *Node) => *LLVMTypeRef {
 };
 
 let codegen_generate_literal = (c: *codegen, literal_val: LLVMValueRef, name: *i8, node: *Node, node_type: *Node) => *Variable {
-	/* TODO: Global */
+	if name != cast(*i8, null) {
+		let e = (*c).environment;
+		if (*e).scope_stack_len == 1 {
+			let lt = codegen_get_llvm_type(c, node_type);
+			assert(lt != cast(*LLVMTypeRef, null));
+			let v = Variable{};
+			v.value = LLVMAddGlobal((*c).llvm_module, *lt, name);
+			v.type = cast(LLVMTypeRef, null);
+			v.stack_level = cast(*i64, null);
+			v.node = node;
+			v.node_type = node_type;
+			LLVMSetInitializer(v.value, literal_val);
+			return codegen_create_variable(c, v);
+		};
+	};
+
+
 	let v = Variable{};
 	v.value = literal_val;
 	v.type = cast(LLVMTypeRef, null);
@@ -760,7 +776,13 @@ let codegen_generate_function_call_statement = (c: *codegen, statement: *Node) =
 		printf("NO variable: %s\n", ident.name);
 		assert(false);
 	};
-	/* TODO: Support function ptr */
+	let node = statement;
+	if LLVMGetValueKind((*function).value) != LLVMFunctionValueKind {
+		let lt = codegen_get_llvm_type(c, (*function).node_type);
+		assert(lt != cast(*LLVMTypeRef, null));
+		(*function).value = LLVMBuildLoad2((*c).builder, LLVMPointerType(*lt, 0), (*function).value, "");
+		node = (*function).node;
+	};
 
 	let arguments = cast(*LLVMValueRef, arena_alloc((*c).arena, sizeof(LLVMValueRef) * (*stmt).arguments_len));
 
@@ -790,7 +812,7 @@ let codegen_generate_function_call_statement = (c: *codegen, statement: *Node) =
 	v.value = res;
 	v.type = cast(LLVMTypeRef, null);
 	v.stack_level = cast(*i64, null);
-	v.node = statement;
+	v.node = node;
 	v.node_type = function_return_type;
 
 	return codegen_create_variable(c, v);
diff --git a/src/bootstrap/llvm.pry b/src/bootstrap/llvm.pry
index c4f7612..2ddcd2c 100644
--- a/src/bootstrap/llvm.pry
+++ b/src/bootstrap/llvm.pry
@@ -258,6 +258,7 @@ let LLVMTargetRef = newtype *void;
 let LLVMIntPredicate = newtype i64;
 
 let LLVMValueRef = newtype *void;
+let LLVMValueKind = newtype i64;
 let LLVMTypeRef = newtype *void;
 let LLVMBasicBlockRef = newtype *void;
 
@@ -321,6 +322,10 @@ extern LLVMBuildNeg = (LLVMBuilderRef, LLVMValueRef, *i8) => LLVMValueRef;
 extern LLVMBuildSub = (LLVMBuilderRef, LLVMValueRef, LLVMValueRef, *i8) => LLVMValueRef;
 extern LLVMBuildAdd = (LLVMBuilderRef, LLVMValueRef, LLVMValueRef, *i8) => LLVMValueRef;
 extern LLVMBuildGEP2 = (LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, *LLVMValueRef, i64, *i8) => LLVMValueRef;
+extern LLVMAddGlobal = (LLVMModuleRef, LLVMTypeRef, *i8) => LLVMValueRef;
+extern LLVMSetInitializer = (LLVMValueRef, LLVMValueRef) => void;
+extern LLVMGetValueKind = (LLVMValueRef) => LLVMValueKind;
+let LLVMFunctionValueKind = cast(LLVMValueKind, 5);
 
 let LLVMIntEQ = 32;
 let LLVMIntNE = 33;