function calls not working entirely >:(
This commit is contained in:
36
compiler.py
36
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
|
||||
Reference in New Issue
Block a user