working ons tring compilation

This commit is contained in:
SpookyDervish
2025-10-15 07:58:30 +11:00
parent 39a5151d97
commit e0dd9ee541
2 changed files with 31 additions and 3 deletions

View File

@@ -3,7 +3,7 @@ from llvmlite import ir
from AST import Node, NodeType, Program, Expression from AST import Node, NodeType, Program, Expression
from AST import ExpressionStatement, AssignmentStatement, BlockStatement, ReturnStatement, FunctionStatement, ReassignStatement, IfStatement from AST import ExpressionStatement, AssignmentStatement, BlockStatement, ReturnStatement, FunctionStatement, ReassignStatement, IfStatement
from AST import InfixExpression, CallExpression from AST import InfixExpression, CallExpression
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral, StringLiteral
from AST import FunctionParameter from AST import FunctionParameter
from environment import Environment from environment import Environment
@@ -18,7 +18,9 @@ class Compiler:
"Int": ir.IntType(32), "Int": ir.IntType(32),
"Long": ir.IntType(64), "Long": ir.IntType(64),
"Float": ir.FloatType(), "Float": ir.FloatType(),
"Double": ir.DoubleType() "Double": ir.DoubleType(),
"String": ir.PointerType(ir.IntType(8)),
"Nil": ir.VoidType()
} }
self.module: ir.Module = ir.Module("main") self.module: ir.Module = ir.Module("main")
@@ -29,6 +31,14 @@ class Compiler:
self.__initialize_builtins() self.__initialize_builtins()
def __initialize_builtins(self) -> None: def __initialize_builtins(self) -> None:
def __init_print() -> ir.Function:
fnty: ir.FunctionType = ir.FunctionType(
self.type_map["Int"],
[ir.IntType(8).as_pointer()],
var_arg=True
)
return ir.Function(self.module, fnty, "printf")
def __init_booleans() -> tuple[ir.GlobalVariable, ir.GlobalVariable]: def __init_booleans() -> tuple[ir.GlobalVariable, ir.GlobalVariable]:
bool_type: ir.Type = self.type_map["Bool"] bool_type: ir.Type = self.type_map["Bool"]
@@ -42,6 +52,8 @@ class Compiler:
return true_var, false_var return true_var, false_var
self.environment.define("print", __init_print(), ir.IntType(32))
true_var, false_var = __init_booleans() true_var, false_var = __init_booleans()
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)
@@ -315,10 +327,20 @@ class Compiler:
case NodeType.BooleanLiteral: case NodeType.BooleanLiteral:
node: BooleanLiteral = node node: BooleanLiteral = node
return ir.Constant(ir.IntType(1), 1 if node.value else 0), ir.IntType(1) return ir.Constant(ir.IntType(1), 1 if node.value else 0), ir.IntType(1)
case NodeType.StringLiteral:
node: StringLiteral = node
string, Type = self.__convert_string(node.value)
return string, Type
# expression value # expression value
case NodeType.InfixExpression: case NodeType.InfixExpression:
return self.__visit_infix_expression(node) return self.__visit_infix_expression(node)
case NodeType.CallExpression: case NodeType.CallExpression:
return self.__visit_call_expression(node) return self.__visit_call_expression(node)
def __convert_string(self, string: str) -> tuple[ir.Constant, ir.ArrayType]:
string = string.replace("\\n", "\n\0")
fmt: str = f"{string}\0"
c_fmt: ir.Constant = ir.Constant(ir.ArrayType(ir.IntType(8), len(fmt)), bytearray(fmt.encode("utf-8")))
# endregion # endregion

View File

@@ -6,7 +6,7 @@ from enum import Enum, auto
from AST import Statement, Expression, Program from AST import Statement, Expression, Program
from AST import ExpressionStatement, AssignmentStatement, FunctionStatement, ReturnStatement, BlockStatement, ReassignStatement, IfStatement from AST import ExpressionStatement, AssignmentStatement, FunctionStatement, ReturnStatement, BlockStatement, ReassignStatement, IfStatement
from AST import InfixExpression, CallExpression from AST import InfixExpression, CallExpression
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral, StringLiteral
from AST import FunctionParameter from AST import FunctionParameter
class PrecedenceType(Enum): class PrecedenceType(Enum):
@@ -50,9 +50,12 @@ class Parser:
TokenType.INT: self.__parse_int_literal, TokenType.INT: self.__parse_int_literal,
TokenType.FLOAT: self.__parse_float_literal, TokenType.FLOAT: self.__parse_float_literal,
TokenType.LPAREN: self.__parse_grouped_expression, TokenType.LPAREN: self.__parse_grouped_expression,
TokenType.IF: self.__parse_if_statement, TokenType.IF: self.__parse_if_statement,
TokenType.TRUE: self.__parse_boolean, TokenType.TRUE: self.__parse_boolean,
TokenType.FALSE: self.__parse_boolean, TokenType.FALSE: self.__parse_boolean,
TokenType.STRING: self.__parse_string_literal,
} }
self.infix_parse_functions: dict[Token, Callable] = { # 5 + 5 self.infix_parse_functions: dict[Token, Callable] = { # 5 + 5
TokenType.PLUS: self.__parse_infix_expression, TokenType.PLUS: self.__parse_infix_expression,
@@ -398,4 +401,7 @@ class Parser:
def __parse_boolean(self) -> BooleanLiteral: def __parse_boolean(self) -> BooleanLiteral:
return BooleanLiteral(value=self.__current_token_is(TokenType.TRUE)) return BooleanLiteral(value=self.__current_token_is(TokenType.TRUE))
def __parse_string_literal(self) -> StringLiteral:
return StringLiteral(value=self.current_token.literal)
# endregion # endregion