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.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
|
||||||
@@ -66,11 +66,11 @@
|
|||||||
"arguments": [
|
"arguments": [
|
||||||
{
|
{
|
||||||
"type": "IntegerLiteral",
|
"type": "IntegerLiteral",
|
||||||
"value": 2
|
"value": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "IntegerLiteral",
|
"type": "IntegerLiteral",
|
||||||
"value": 3
|
"value": 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
25
debug/ir.ll
25
debug/ir.ll
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
2
lexer.py
2
lexer.py
@@ -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]
|
||||||
|
|
||||||
6
main.py
6
main.py
@@ -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__":
|
||||||
|
|||||||
@@ -169,8 +169,6 @@ class Parser:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user