From a75dcb933ee954dc80b2b629f7a81f89c95066ec Mon Sep 17 00:00:00 2001 From: SpookyDervish Date: Wed, 15 Oct 2025 15:32:40 +1100 Subject: [PATCH] function calls not working entirely >:( --- compiler.py | 36 ++++++++++++++++++++++++++++++++++++ debug/ast.json | 4 ++-- debug/ir.ll | 25 ++++++++----------------- lexer.py | 2 +- main.py | 6 +++--- plasma_parser.py | 2 -- tests/test.pla | 4 ++-- 7 files changed, 52 insertions(+), 27 deletions(-) diff --git a/compiler.py b/compiler.py index 051a4d3..aeda6cb 100644 --- a/compiler.py +++ b/compiler.py @@ -28,6 +28,8 @@ class Compiler: self.environment: Environment = Environment() self.errors: list[str] = [] + self.counter = 0 + self.__initialize_builtins() def __initialize_builtins(self) -> None: @@ -58,6 +60,10 @@ class Compiler: self.environment.define("true", true_var, true_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: match node.type(): case NodeType.Program: @@ -300,6 +306,9 @@ class Compiler: types.append(p_type) match name: + case "print": + ret = self.builtin_print(params=args, return_type=types[0]) + ret_type = self.type_map["Int"] case _: func, ret_type = self.environment.lookup(name) ret = self.builder.call(func, args) @@ -343,4 +352,31 @@ class Compiler: fmt: str = f"{string}\0" 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 \ No newline at end of file diff --git a/debug/ast.json b/debug/ast.json index 2dc73bc..501dde3 100644 --- a/debug/ast.json +++ b/debug/ast.json @@ -66,11 +66,11 @@ "arguments": [ { "type": "IntegerLiteral", - "value": 2 + "value": 1 }, { "type": "IntegerLiteral", - "value": 3 + "value": 2 } ] } diff --git a/debug/ir.ll b/debug/ir.ll index 1238b18..0bd30e3 100644 --- a/debug/ir.ll +++ b/debug/ir.ll @@ -1,7 +1,9 @@ ; ModuleID = "main" -target triple = "x86_64-pc-windows-msvc" +target triple = "arm64-apple-darwin24.5.0" target datalayout = "" +declare i32 @"printf"(i8* %".1", ...) + @"true" = constant i1 1 @"false" = constant i1 0 define i32 @"add"(i32 %".1", i32 %".2") @@ -17,23 +19,12 @@ add_entry: 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"() { main_entry: - %".2" = call i32 @"add"(i32 50, i32 50) - %".3" = call i32 @"sub"(i32 %".2", i32 125) - ret i32 %".3" + %".2" = call i32 @"add"(i32 1, i32 2) + %".3" = alloca i32 + store i32 %".2", i32* %".3" + %".5" = load i32, i32* %".3" + ret i32 %".5" } diff --git a/lexer.py b/lexer.py index 6148f11..0043cf2 100644 --- a/lexer.py +++ b/lexer.py @@ -172,5 +172,5 @@ class Lexer: self.__read_char() if self.current_char == '"' or self.current_char is None: break - + return self.source[position:self.position] \ No newline at end of file diff --git a/main.py b/main.py index ad60a43..b287b44 100644 --- a/main.py +++ b/main.py @@ -10,9 +10,9 @@ import llvmlite.binding as llvm from ctypes import CFUNCTYPE, c_int, c_float LEXER_DEBUG: bool = False -PARSER_DEBUG: bool = False -COMPILER_DEBUG: bool = True -RUN_CODE: bool = True +PARSER_DEBUG: bool = True +COMPILER_DEBUG: bool = False +RUN_CODE: bool = False if __name__ == "__main__": diff --git a/plasma_parser.py b/plasma_parser.py index b4178ea..7e548e5 100644 --- a/plasma_parser.py +++ b/plasma_parser.py @@ -169,8 +169,6 @@ class Parser: return None func_stmt.parameters = self.__parse_function_parameters() - - if not self.__expect_peek(TokenType.COLON): return None diff --git a/tests/test.pla b/tests/test.pla index ac19427..ded45d4 100644 --- a/tests/test.pla +++ b/tests/test.pla @@ -3,6 +3,6 @@ add = Func(a: Int, b: Int): Int { } main = Func(): Int { - print("apples %i", add(2, 3)); - return 0; + add(1,2); + return x; } \ No newline at end of file