about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-07-11 00:30:28 +0200
committerBaitinq <[email protected]>2025-07-11 00:32:50 +0200
commit055fbcfb9db4087cde5f102c0753999f569b2f35 (patch)
tree5f2189b3dfc89d725f6f372c9ca3cb05424c9ae1
parentBootstrap: Support variable assignment (diff)
downloadpry-lang-055fbcfb9db4087cde5f102c0753999f569b2f35.tar.gz
pry-lang-055fbcfb9db4087cde5f102c0753999f569b2f35.tar.bz2
pry-lang-055fbcfb9db4087cde5f102c0753999f569b2f35.zip
Bootstrap: Support addition
-rw-r--r--examples/0.pry72
-rw-r--r--src/bootstrap/codegen.pry47
-rw-r--r--src/bootstrap/llvm.pry3
3 files changed, 122 insertions, 0 deletions
diff --git a/examples/0.pry b/examples/0.pry
index d0054f2..eb9f990 100644
--- a/examples/0.pry
+++ b/examples/0.pry
@@ -1,7 +1,79 @@
 /* HELLO! Welcome to the unnamed language */
 
+extern printf = (*i8, varargs) => void;
+extern exit = (i64) => void;
+
+let strcmp = (stra: *i8, strb: *i8) => bool {
+	let i = 0;
+	while i < 10 {
+		printf("I: %d\n", i); /* CONTINUE */
+		i = i + 1;
+	};
+
+	return true;
+};
+
+let isdigit = (c: i8) => bool {
+	if c >= '0' {
+		if c <= '9' {
+			return true;
+		};
+	};
+	return false;
+};
+
+let isalpha = (c: i8) => bool {
+	if c >= 'a' {
+		if c <= 'z' {
+			return true;
+		};
+	};
+	if c >= 'A' {
+		if c <= 'Z' {
+			return true;
+		};
+	};
+	return false;
+};
+
+let isalphanum = (c: i8) => bool {
+	if isalpha(c) {
+		return true;
+	};
+	if isdigit(c) {
+		return true;
+	};
+
+	return false;
+};
+
+let iswhitespace = (c: i8) => bool {
+	if c == ' ' {
+		return true;
+	};
+
+	if c >= '\t' {
+		if c <= '\r' {
+			return true;
+		};
+	};
+
+	return false;
+};
+
+let assert = (cond: bool) => void {
+	if !cond {
+		printf("ASSERTION FAILED\n");
+		exit(1);
+	};
+
+	return;
+};
+
 let main = (argc: i64, argv: *i64) => i64 {
 	printf("%d\n", argc);
+	isdigit('a');
+	strcmp("a", "b");
 	
 	return 2;
 };
diff --git a/src/bootstrap/codegen.pry b/src/bootstrap/codegen.pry
index 53453f1..1a81c42 100644
--- a/src/bootstrap/codegen.pry
+++ b/src/bootstrap/codegen.pry
@@ -525,6 +525,53 @@ 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_ADDITIVE_EXPRESSION) {
+		let exp = (*(cast(*NODE_ADDITIVE_EXPRESSION_DATA, (*expression).data)));
+		let lhs_value = codegen_generate_expression_value(c, exp.lhs, cast(*i8, null));
+		if lhs_value == cast(*Variable, null) {
+			return cast(*Variable, null);
+		};
+		let rhs_value = codegen_generate_expression_value(c, exp.rhs, cast(*i8, null));
+		if rhs_value == cast(*Variable, null) {
+			return cast(*Variable, null);
+		};
+
+		/* TODO: Compare types */
+
+		let result = cast(LLVMValueRef, null);
+		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);
+
+		let pnode_type = create_node(c, node_type);
+
+		if exp.addition {
+			let nt = (*lhs_value).node_type;
+			if (*nt).type == NODE_TYPE_POINTER_TYPE {
+				let ipt = cast(*NODE_TYPE_POINTER_TYPE_DATA, (*nt).data);
+				let llvmipt = codegen_get_llvm_type(c, (*ipt).type);
+				assert(llvmipt != cast(*LLVMTypeRef, null));
+				let arr = cast(*LLVMValueRef, arena_alloc((*c).arena, sizeof(LLVMValueRef) * 1));
+				(*(arr + cast(*LLVMValueRef, 0))) = (*rhs_value).value;
+				result = LLVMBuildGEP2((*c).builder, *llvmipt, (*lhs_value).value, arr, 1, "");
+				pnode_type = (*lhs_value).node_type;
+			};
+			if (*nt).type != NODE_TYPE_POINTER_TYPE {
+                        	result = LLVMBuildAdd((*c).builder, (*lhs_value).value, (*rhs_value).value, "");
+			};
+
+		};
+		if !exp.addition {
+			result = LLVMBuildSub((*c).builder, (*lhs_value).value, (*rhs_value).value, "");
+		};
+
+		return codegen_generate_literal(c, result, name, expression, pnode_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));
diff --git a/src/bootstrap/llvm.pry b/src/bootstrap/llvm.pry
index 0530299..c4f7612 100644
--- a/src/bootstrap/llvm.pry
+++ b/src/bootstrap/llvm.pry
@@ -318,6 +318,9 @@ 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;
+extern LLVMBuildSub = (LLVMBuilderRef, LLVMValueRef, LLVMValueRef, *i8) => LLVMValueRef;
+extern LLVMBuildAdd = (LLVMBuilderRef, LLVMValueRef, LLVMValueRef, *i8) => LLVMValueRef;
+extern LLVMBuildGEP2 = (LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, *LLVMValueRef, i64, *i8) => LLVMValueRef;
 
 let LLVMIntEQ = 32;
 let LLVMIntNE = 33;