function calls not working entirely >:(

This commit is contained in:
2025-10-15 15:32:40 +11:00
parent e0dd9ee541
commit a75dcb933e
7 changed files with 52 additions and 27 deletions

View File

@@ -28,6 +28,8 @@ class Compiler:
self.environment: Environment = Environment() self.environment: Environment = Environment()
self.errors: list[str] = [] self.errors: list[str] = []
self.counter = 0
self.__initialize_builtins() self.__initialize_builtins()
def __initialize_builtins(self) -> None: def __initialize_builtins(self) -> None:
@@ -58,6 +60,10 @@ class Compiler:
self.environment.define("true", true_var, true_var.type) self.environment.define("true", true_var, true_var.type)
self.environment.define("false", false_var, false_var.type) self.environment.define("false", false_var, false_var.type)
def __increment_counter(self) -> int:
self.counter += 1
return self.counter
def compile(self, node: Node) -> None: def compile(self, node: Node) -> None:
match node.type(): match node.type():
case NodeType.Program: case NodeType.Program:
@@ -300,6 +306,9 @@ class Compiler:
types.append(p_type) types.append(p_type)
match name: match name:
case "print":
ret = self.builtin_print(params=args, return_type=types[0])
ret_type = self.type_map["Int"]
case _: case _:
func, ret_type = self.environment.lookup(name) func, ret_type = self.environment.lookup(name)
ret = self.builder.call(func, args) ret = self.builder.call(func, args)
@@ -343,4 +352,31 @@ class Compiler:
fmt: str = f"{string}\0" fmt: str = f"{string}\0"
c_fmt: ir.Constant = ir.Constant(ir.ArrayType(ir.IntType(8), len(fmt)), bytearray(fmt.encode("utf-8"))) c_fmt: ir.Constant = ir.Constant(ir.ArrayType(ir.IntType(8), len(fmt)), bytearray(fmt.encode("utf-8")))
global_fmt = ir.GlobalVariable(self.module, c_fmt.type, name=f"__str_{self.__increment_counter()}")
global_fmt.linkage = "internal"
global_fmt.global_constant = True
global_fmt.initializer = c_fmt
return global_fmt, global_fmt.type
def builtin_print(self, params: list[ir.Instruction], return_type: ir.Type) -> None:
func, _ = self.environment.lookup("print")
c_str = self.builder.alloca(return_type)
self.builder.store(params[0], c_str)
rest_params = params[1:]
if isinstance(params[0], ir.LoadInstr):
# printing from a variable load instruction
c_fmt: ir.LoadInstr = params[0]
g_var_ptr = c_fmt.operands[0]
string_val = self.builder.load(g_var_ptr)
fmt_arg = self.builder.bitcast(string_val, ir.IntType(8).as_pointer())
return self.builder.call(func, [fmt_arg, *rest_params])
else:
# printing from a normal string
fmt_arg = self.builder.bitcast(self.module.get_global(f"__str_{self.counter}"), ir.IntType(8).as_pointer())
return self.builder.call(func, [fmt_arg, *rest_params])
# endregion # endregion

View File

@@ -66,11 +66,11 @@
"arguments": [ "arguments": [
{ {
"type": "IntegerLiteral", "type": "IntegerLiteral",
"value": 2 "value": 1
}, },
{ {
"type": "IntegerLiteral", "type": "IntegerLiteral",
"value": 3 "value": 2
} }
] ]
} }

View File

@@ -1,7 +1,9 @@
; ModuleID = "main" ; ModuleID = "main"
target triple = "x86_64-pc-windows-msvc" target triple = "arm64-apple-darwin24.5.0"
target datalayout = "" target datalayout = ""
declare i32 @"printf"(i8* %".1", ...)
@"true" = constant i1 1 @"true" = constant i1 1
@"false" = constant i1 0 @"false" = constant i1 0
define i32 @"add"(i32 %".1", i32 %".2") define i32 @"add"(i32 %".1", i32 %".2")
@@ -17,23 +19,12 @@ add_entry:
ret i32 %".10" ret i32 %".10"
} }
define i32 @"sub"(i32 %".1", i32 %".2")
{
sub_entry:
%".4" = alloca i32
store i32 %".1", i32* %".4"
%".6" = alloca i32
store i32 %".2", i32* %".6"
%".8" = load i32, i32* %".4"
%".9" = load i32, i32* %".6"
%".10" = sub i32 %".8", %".9"
ret i32 %".10"
}
define i32 @"main"() define i32 @"main"()
{ {
main_entry: main_entry:
%".2" = call i32 @"add"(i32 50, i32 50) %".2" = call i32 @"add"(i32 1, i32 2)
%".3" = call i32 @"sub"(i32 %".2", i32 125) %".3" = alloca i32
ret i32 %".3" store i32 %".2", i32* %".3"
%".5" = load i32, i32* %".3"
ret i32 %".5"
} }

View File

@@ -172,5 +172,5 @@ class Lexer:
self.__read_char() self.__read_char()
if self.current_char == '"' or self.current_char is None: if self.current_char == '"' or self.current_char is None:
break break
return self.source[position:self.position]

View File

@@ -10,9 +10,9 @@ import llvmlite.binding as llvm
from ctypes import CFUNCTYPE, c_int, c_float from ctypes import CFUNCTYPE, c_int, c_float
LEXER_DEBUG: bool = False LEXER_DEBUG: bool = False
PARSER_DEBUG: bool = False PARSER_DEBUG: bool = True
COMPILER_DEBUG: bool = True COMPILER_DEBUG: bool = False
RUN_CODE: bool = True RUN_CODE: bool = False
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -170,8 +170,6 @@ class Parser:
func_stmt.parameters = self.__parse_function_parameters() func_stmt.parameters = self.__parse_function_parameters()
if not self.__expect_peek(TokenType.COLON): if not self.__expect_peek(TokenType.COLON):
return None return None

View File

@@ -3,6 +3,6 @@ add = Func(a: Int, b: Int): Int {
} }
main = Func(): Int { main = Func(): Int {
print("apples %i", add(2, 3)); add(1,2);
return 0; return x;
} }