about summary refs log tree commit diff
path: root/src/bootstrap/codegen.pry
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/codegen.pry')
-rw-r--r--src/bootstrap/codegen.pry114
1 files changed, 107 insertions, 7 deletions
diff --git a/src/bootstrap/codegen.pry b/src/bootstrap/codegen.pry
index 7d83a3b..3a809fe 100644
--- a/src/bootstrap/codegen.pry
+++ b/src/bootstrap/codegen.pry
@@ -92,21 +92,93 @@ let codegen_create_variable = (c: *codegen, variable: Variable) => *Variable {
 };
 
 let codegen_get_llvm_type = (c: *codegen, node: *Node) => *LLVMTypeRef {
-	printf("LLVM TYPE: %d\n", (*node).type);
 	assert((*node).type >= NODE_TYPE_SIMPLE_TYPE);
 	assert((*node).type <= NODE_TYPE_STRUCT_TYPE);
 	
-	assert((*node).type == NODE_TYPE_SIMPLE_TYPE); /* TODO */
+	if (*node).type == NODE_TYPE_SIMPLE_TYPE {
+		let simple_type = *cast(*NODE_TYPE_SIMPLE_TYPE_DATA, (*node).data);
 
-	let simple_type = *cast(*NODE_TYPE_SIMPLE_TYPE_DATA, (*node).data);
+		if strcmp(simple_type.name, "i8") {
+			let r = cast(*LLVMTypeRef, arena_alloc((*c).arena, sizeof(LLVMTypeRef)));
+			*r = LLVMInt8Type();
+			return r;
+		};
+		
+		if strcmp(simple_type.name, "i64") {
+			let r = cast(*LLVMTypeRef, arena_alloc((*c).arena, sizeof(LLVMTypeRef)));
+			*r = LLVMInt64Type();
+			return r;
+		};
+		
+		if strcmp(simple_type.name, "void") {
+			let r = cast(*LLVMTypeRef, arena_alloc((*c).arena, sizeof(LLVMTypeRef)));
+			*r = LLVMVoidType();
+			return r;
+		};
+		
+		if strcmp(simple_type.name, "varargs") { /* Hack for varargs (only used for printf) */
+			let r = cast(*LLVMTypeRef, arena_alloc((*c).arena, sizeof(LLVMTypeRef)));
+			*r = LLVMPointerType(LLVMInt64Type(), 0);
+			return r;
+		};
+
+		printf("NO SIMPLE TYPE %s!\n", simple_type.name);
+		assert(false);
+	};
 	
-	if strcmp(simple_type.name, "i64") {
+	if (*node).type == NODE_TYPE_FUNCTION_TYPE {
+		let function_type = *cast(*NODE_TYPE_FUNCTION_TYPE_DATA, (*node).data);
+		let retur_type = codegen_get_llvm_type(c, function_type.retur_type);
+		if retur_type == cast(*LLVMTypeRef, null) {
+			return cast(*LLVMTypeRef, null);
+		};
+		let paramtypes = cast(*LLVMTypeRef, arena_alloc((*c).arena, sizeof(LLVMTypeRef) * 20));
+		let paramtypes_len = 0;
+		let is_varargs = 0;
+
+		let i = 0;
+		while i < function_type.parameters_len {
+			let param = *(function_type.parameters + cast(**Node, i));
+			if (*param).type == NODE_TYPE_SIMPLE_TYPE {
+				let simple_type = *cast(*NODE_TYPE_SIMPLE_TYPE_DATA, (*param).data);
+				if strcmp(simple_type.name, "varargs") {
+					is_varargs = 1;
+					i = i + 1;
+					continue;
+				};
+			};
+			let typ = codegen_get_llvm_type(c, param);
+			if typ == cast(*LLVMTypeRef, null) {
+				return cast(*LLVMTypeRef, null);
+			};
+			if (*param).type == NODE_TYPE_FUNCTION_TYPE {
+				*typ = LLVMPointerType(*typ, 0);
+			};
+
+			(*(paramtypes + cast(*LLVMTypeRef, paramtypes_len))) = *typ;
+			paramtypes_len = paramtypes_len + 1;
+
+			i = i + 1;
+		};
+		let function_type = LLVMFunctionType(*retur_type, paramtypes, paramtypes_len, is_varargs);
 		let r = cast(*LLVMTypeRef, arena_alloc((*c).arena, sizeof(LLVMTypeRef)));
-		*r = LLVMInt64Type();
+		*r = function_type;
+		printf("FUNCTION\n");
 		return r;
 	};
 
-	printf("NO TYPE!\n");
+	if (*node).type == NODE_TYPE_POINTER_TYPE {
+		let pointer_type = *cast(*NODE_TYPE_POINTER_TYPE_DATA, (*node).data);
+		let inner_type = codegen_get_llvm_type(c, pointer_type.type);
+		if inner_type == cast(*LLVMTypeRef, null) {
+			return cast(*LLVMTypeRef, null);
+		};
+		let r = cast(*LLVMTypeRef, arena_alloc((*c).arena, sizeof(LLVMTypeRef)));
+		*r = LLVMPointerType(*inner_type, 0);
+		return r;
+	};
+
+	printf("NO TYPEEE BOI %d\n", (*node).type);
 	assert(false);
 
 	return cast(*LLVMTypeRef, null);
@@ -126,7 +198,9 @@ let codegen_generate_literal = (c: *codegen, literal_val: LLVMValueRef, name: *i
 extern codegen_generate_statement = (*codegen, *Node) => i64;
 
 let codegen_generate_expression_value = (c: *codegen, expression: *Node, name: *i8) => *Variable {
+	printf("NAME: %s\n", name);
 	if ((*expression).type == NODE_PRIMARY_EXPRESSION_NUMBER) {
+		printf("THIS\n");
 		let n = (*cast(*NODE_PRIMARY_EXPRESSION_NUMBER_DATA, (*expression).data)).value;
 		
 		printf("X: %d\n", n);
@@ -143,6 +217,7 @@ let codegen_generate_expression_value = (c: *codegen, expression: *Node, name: *
 	};
 	
 	if ((*expression).type == NODE_FUNCTION_DEFINITION) {
+		printf("THIS2\n");
 	/* TODO: IMPLEMENT */
 		printf("ASS %d\n", (*expression).type);
 
@@ -163,7 +238,7 @@ let codegen_generate_expression_value = (c: *codegen, expression: *Node, name: *
 
 		let retur_type = codegen_get_llvm_type(c, function_definition.retur_type);
 		if retur_type == cast(*LLVMTypeRef, null) {
-			printf("LEL\n");
+			printf("LEL2\n");
 			return cast(*Variable, null);
 		};
 
@@ -208,6 +283,7 @@ let codegen_generate_expression_value = (c: *codegen, expression: *Node, name: *
 
 			let res = codegen_generate_statement(c, stmt);
 			if res != 0 {
+				printf("LEL\n");
 				return cast(*Variable, null);
 			};
 
@@ -224,6 +300,30 @@ let codegen_generate_expression_value = (c: *codegen, expression: *Node, name: *
 		v.node_type = node_type;
 		return codegen_create_variable(c, v);
 	};
+	
+	if ((*expression).type == NODE_TYPE_FUNCTION_TYPE) {
+		let e = *((*c).environment);
+		printf("LLEL\n");
+		assert(e.scope_stack_len == 1);
+		printf("THIS3\n");
+
+		/* TODO: Check if already exists */
+
+		let function_type = codegen_get_llvm_type(c, expression);
+		if function_type == cast(*LLVMTypeRef, null) {
+			printf("LOL\n");
+			return cast(*Variable, null);
+		};
+		let function = LLVMAddFunction((*c).llvm_module, name, *function_type);
+		let v = Variable{};
+		v.value = function;
+		v.type = cast(LLVMTypeRef, null);
+		v.stack_level = cast(*i64, null);
+		v.node = expression;
+		v.node_type = expression;
+		printf("RET\n");
+		return codegen_create_variable(c, v);
+	};
 
 	printf("ASSERT 1\n");
 	assert(false);