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 ExpressionStatement, AssignmentStatement, BlockStatement, ReturnStatement, FunctionStatement, ReassignStatement, IfStatement
|
||||
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 environment import Environment
|
||||
@@ -18,7 +18,9 @@ class Compiler:
|
||||
"Int": ir.IntType(32),
|
||||
"Long": ir.IntType(64),
|
||||
"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")
|
||||
@@ -29,6 +31,14 @@ class Compiler:
|
||||
self.__initialize_builtins()
|
||||
|
||||
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]:
|
||||
bool_type: ir.Type = self.type_map["Bool"]
|
||||
|
||||
@@ -42,6 +52,8 @@ class Compiler:
|
||||
|
||||
return true_var, false_var
|
||||
|
||||
self.environment.define("print", __init_print(), ir.IntType(32))
|
||||
|
||||
true_var, false_var = __init_booleans()
|
||||
self.environment.define("true", true_var, true_var.type)
|
||||
self.environment.define("false", false_var, false_var.type)
|
||||
@@ -315,10 +327,20 @@ class Compiler:
|
||||
case NodeType.BooleanLiteral:
|
||||
node: BooleanLiteral = node
|
||||
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
|
||||
case NodeType.InfixExpression:
|
||||
return self.__visit_infix_expression(node)
|
||||
case NodeType.CallExpression:
|
||||
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
|
||||
@@ -6,7 +6,7 @@ from enum import Enum, auto
|
||||
from AST import Statement, Expression, Program
|
||||
from AST import ExpressionStatement, AssignmentStatement, FunctionStatement, ReturnStatement, BlockStatement, ReassignStatement, IfStatement
|
||||
from AST import InfixExpression, CallExpression
|
||||
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral
|
||||
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral, StringLiteral
|
||||
from AST import FunctionParameter
|
||||
|
||||
class PrecedenceType(Enum):
|
||||
@@ -50,9 +50,12 @@ class Parser:
|
||||
TokenType.INT: self.__parse_int_literal,
|
||||
TokenType.FLOAT: self.__parse_float_literal,
|
||||
TokenType.LPAREN: self.__parse_grouped_expression,
|
||||
|
||||
TokenType.IF: self.__parse_if_statement,
|
||||
TokenType.TRUE: self.__parse_boolean,
|
||||
TokenType.FALSE: self.__parse_boolean,
|
||||
|
||||
TokenType.STRING: self.__parse_string_literal,
|
||||
}
|
||||
self.infix_parse_functions: dict[Token, Callable] = { # 5 + 5
|
||||
TokenType.PLUS: self.__parse_infix_expression,
|
||||
@@ -398,4 +401,7 @@ class Parser:
|
||||
|
||||
def __parse_boolean(self) -> BooleanLiteral:
|
||||
return BooleanLiteral(value=self.__current_token_is(TokenType.TRUE))
|
||||
|
||||
def __parse_string_literal(self) -> StringLiteral:
|
||||
return StringLiteral(value=self.current_token.literal)
|
||||
# endregion
|
||||
Reference in New Issue
Block a user