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
|
||||
@@ -66,11 +66,11 @@
|
||||
"arguments": [
|
||||
{
|
||||
"type": "IntegerLiteral",
|
||||
"value": 2
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"type": "IntegerLiteral",
|
||||
"value": 3
|
||||
"value": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
25
debug/ir.ll
25
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"
|
||||
}
|
||||
|
||||
2
lexer.py
2
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]
|
||||
|
||||
6
main.py
6
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__":
|
||||
|
||||
@@ -170,8 +170,6 @@ class Parser:
|
||||
|
||||
func_stmt.parameters = self.__parse_function_parameters()
|
||||
|
||||
|
||||
|
||||
if not self.__expect_peek(TokenType.COLON):
|
||||
return None
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user