working ons tring compilation
This commit is contained in:
26
compiler.py
26
compiler.py
@@ -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
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user