From 4bd698e3303bae2d2b4de87362368e14ffcb2f5c Mon Sep 17 00:00:00 2001 From: SpookyDervish <78246495+SpookyDervish@users.noreply.github.com> Date: Sat, 18 Oct 2025 19:28:54 +1100 Subject: [PATCH] sqrt function works... finally... ;-; --- compiler.py | 50 +++++++++++++++++++++++++++++++++++++++++++++++- debug/ast.json | 47 --------------------------------------------- debug/ir.ll | 13 ------------- ir.ll | 27 ++++++++++++++++++++++++++ main.py | 7 ++++--- plasma_parser.py | 2 +- tests/math.pla | 3 --- tests/test.pla | 5 ++--- 8 files changed, 83 insertions(+), 71 deletions(-) delete mode 100644 debug/ast.json delete mode 100644 debug/ir.ll create mode 100644 ir.ll diff --git a/compiler.py b/compiler.py index 0b82cc2..7733604 100644 --- a/compiler.py +++ b/compiler.py @@ -22,11 +22,15 @@ class Compiler: "Short": ir.IntType(16), "Int": ir.IntType(32), "Long": ir.IntType(64), - "Float": ir.FloatType(), + "Float": ir.DoubleType(), "Double": ir.DoubleType(), "String": ir.PointerType(ir.IntType(8)), "Nil": ir.VoidType() } + self.py_type_map: dict[str, type] = { + "Int": int, + "Float": float + } self.module: ir.Module = ir.Module("main") self.builder: ir.IRBuilder = ir.IRBuilder() @@ -50,6 +54,14 @@ class Compiler: var_arg=True ) return ir.Function(self.module, fnty, "printf") + + def __init_sqrt() -> ir.Function: + fnty: ir.FunctionType = ir.FunctionType( + self.type_map["Float"], + [ir.DoubleType()], + var_arg=False + ) + return ir.Function(self.module, fnty, "sqrt") def __init_booleans() -> tuple[ir.GlobalVariable, ir.GlobalVariable]: bool_type: ir.Type = self.type_map["Bool"] @@ -65,6 +77,7 @@ class Compiler: return true_var, false_var self.environment.define("print", __init_print(), ir.IntType(32)) + self.environment.define("sqrt", __init_sqrt(), ir.IntType(32)) true_var, false_var = __init_booleans() self.environment.define("true", true_var, true_var.type) @@ -221,6 +234,8 @@ class Compiler: value = None Type = None + + match operator: case "=": value = right_value @@ -246,8 +261,10 @@ class Compiler: value = self.builder.fdiv(orig_value, right_value) case _: print("Unsupported assignment operator.") + return ptr, _ = self.environment.lookup(name) + self.builder.store(value, ptr) def __visit_if_statement(self, node: IfStatement) -> None: @@ -281,9 +298,14 @@ class Compiler: test, _ = self.__resolve_value(condition) + + while_loop_entry = self.builder.append_basic_block(f"while_loop_entry_{self.__increment_counter()}") while_loop_otherwise = self.builder.append_basic_block(f"while_loop_otherwise_{self.counter}") + self.breakpoints.append(while_loop_otherwise) + self.continues.append(while_loop_entry) + # Creating a condition branch # condition # / \ @@ -299,6 +321,9 @@ class Compiler: self.builder.cbranch(test, while_loop_entry, while_loop_otherwise) self.builder.position_at_start(while_loop_otherwise) + self.breakpoints.pop() + self.continues.pop() + def __visit_break_statement(self, node: BreakStatement) -> None: self.builder.branch(self.breakpoints[-1]) @@ -458,7 +483,14 @@ class Compiler: case "print": ret = self.builtin_print(params=args, return_type=types[0]) ret_type = self.type_map["Int"] + case "sqrt": + ret = self.builtin_sqrt(params=args) + ret_type = self.type_map["Float"] case _: + if not self.environment.lookup(name): + print(f"The function \"{name}\" is not defined.") + exit(1) + func, ret_type = self.environment.lookup(name) ret = self.builder.call(func, args) @@ -563,6 +595,7 @@ class Compiler: return global_fmt, global_fmt.type + # region Builtins def builtin_print(self, params: list[ir.Instruction], return_type: ir.Type) -> None: func, _ = self.environment.lookup("print") @@ -582,4 +615,19 @@ class Compiler: # 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]) + + def builtin_sqrt(self, params: list[ir.Instruction]) -> None: + func, _ = self.environment.lookup("sqrt") + + c_float = self.builder.alloca(self.type_map["Float"]) + self.builder.store(params[0], c_float) + + if isinstance(params[0], ir.LoadInstr): + c_fmt: ir.LoadInstr = params[0] + g_var_ptr = c_fmt.operands[0] + float_val = self.builder.load(g_var_ptr) + return self.builder.call(func, [float_val]) + else: + return self.builder.call(func, [params[0]]) + # endregion # endregion \ No newline at end of file diff --git a/debug/ast.json b/debug/ast.json deleted file mode 100644 index b86a162..0000000 --- a/debug/ast.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "DependStatement": { - "type": "DependStatement", - "file_path": "tests/math.pla" - } - }, - { - "FunctionStatement": { - "type": "FunctionStatement", - "name": { - "type": "IdentifierLiteral", - "value": "main" - }, - "return_type": "Int", - "parameters": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ReturnStatement", - "return_value": { - "type": "CallExpression", - "function": { - "type": "IdentifierLiteral", - "value": "add" - }, - "arguments": [ - { - "type": "IntegerLiteral", - "value": 1 - }, - { - "type": "IntegerLiteral", - "value": 2 - } - ] - } - } - ] - } - } - } - ] -} \ No newline at end of file diff --git a/debug/ir.ll b/debug/ir.ll deleted file mode 100644 index 6cc09e9..0000000 --- a/debug/ir.ll +++ /dev/null @@ -1,13 +0,0 @@ -; ModuleID = "main" -target triple = "x86_64-unknown-linux-gnu" -target datalayout = "" - -declare i32 @"printf"(i8* %".1", ...) - -@"true" = constant i1 1 -@"false" = constant i1 0 -define i32 @"main"() -{ -main_entry: - ret i32 0 -} diff --git a/ir.ll b/ir.ll new file mode 100644 index 0000000..7d7c042 --- /dev/null +++ b/ir.ll @@ -0,0 +1,27 @@ +; ModuleID = "main" +target triple = "x86_64-pc-windows-msvc" +target datalayout = "" + +declare i32 @"printf"(i8* %".1", ...) + +declare double @"sqrt"(double %".1") + +@"true" = constant i1 1 +@"false" = constant i1 0 +define i32 @"main"() +{ +main_entry: + %".2" = alloca double + store double 0x4010000000000000, double* %".2" + %".4" = call double @"sqrt"(double 0x4010000000000000) + %".5" = alloca double + store double %".4", double* %".5" + %".7" = load double, double* %".5" + %".8" = alloca [5 x i8]* + store [5 x i8]* @"__str_1", [5 x i8]** %".8" + %".10" = bitcast [5 x i8]* @"__str_1" to i8* + %".11" = call i32 (i8*, ...) @"printf"(i8* %".10", double %".7") + ret i32 0 +} + +@"__str_1" = internal constant [5 x i8] c"%f\0a\00\00" \ No newline at end of file diff --git a/main.py b/main.py index a2a4101..8c0f3bb 100644 --- a/main.py +++ b/main.py @@ -46,7 +46,7 @@ if __name__ == "__main__": parse_st: float = time.time() program: Program = p.parse_program() parse_et: float = time.time() - print(f"Parsed in {round((parse_et - parse_st) * 1000, 6)} ms.") + #print(f"Parsed in {round((parse_et - parse_st) * 1000, 6)} ms.") if len(p.errors) > 0: for err in p.errors: @@ -67,7 +67,7 @@ if __name__ == "__main__": compiler_st: float = time.time() c.compile(program) compiler_et: float = time.time() - print(f"Compiled in {round((compiler_et - compiler_st) * 1000, 6)} ms.") + #print(f"Compiled in {round((compiler_et - compiler_st) * 1000, 6)} ms.") module: ir.Module = c.module module.triple = llvm.get_default_triple() @@ -101,4 +101,5 @@ if __name__ == "__main__": et = time.time() - print(f"\n\nProgram returned: {result}\n=== Executed in {round((et - st) * 1000, 6)} ms. ===") \ No newline at end of file + #print(f"\n\nProgram returned: {result}\n=== Executed in {round((et - st) * 1000, 6)} ms. ===") + exit(result) \ No newline at end of file diff --git a/plasma_parser.py b/plasma_parser.py index 43ff7c2..d55bf2b 100644 --- a/plasma_parser.py +++ b/plasma_parser.py @@ -381,7 +381,7 @@ class Parser: self.__next_token() # skip ; - stmt.action = self.__parse_expression(PrecedenceType.P_LOWEST) + stmt.action = self.__parse_assignment_statement() self.__next_token() diff --git a/tests/math.pla b/tests/math.pla index 1f4ad01..e69de29 100644 --- a/tests/math.pla +++ b/tests/math.pla @@ -1,3 +0,0 @@ -add = Func(a: Int, b: Int): Int { - return a + b; -} \ No newline at end of file diff --git a/tests/test.pla b/tests/test.pla index 2d7aac9..f6ffb6f 100644 --- a/tests/test.pla +++ b/tests/test.pla @@ -1,5 +1,4 @@ -depend "tests/math.pla"; - main = Func(): Int { - return $add(1 ,2); + $print("%f\n", $sqrt(9.0)); + return 0; } \ No newline at end of file