fixed reassignment, starting work on if statements
This commit is contained in:
16
compiler.py
16
compiler.py
@@ -1,7 +1,7 @@
|
|||||||
from llvmlite import ir
|
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
|
from AST import ExpressionStatement, AssignmentStatement, BlockStatement, ReturnStatement, FunctionStatement, ReassignStatement
|
||||||
from AST import InfixExpression
|
from AST import InfixExpression
|
||||||
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral
|
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral
|
||||||
|
|
||||||
@@ -23,6 +23,7 @@ class Compiler:
|
|||||||
self.module: ir.Module = ir.Module("main")
|
self.module: ir.Module = ir.Module("main")
|
||||||
self.builder: ir.IRBuilder = ir.IRBuilder()
|
self.builder: ir.IRBuilder = ir.IRBuilder()
|
||||||
self.environment: Environment = Environment()
|
self.environment: Environment = Environment()
|
||||||
|
self.errors: list[str] = []
|
||||||
|
|
||||||
def compile(self, node: Node) -> None:
|
def compile(self, node: Node) -> None:
|
||||||
match node.type():
|
match node.type():
|
||||||
@@ -40,6 +41,8 @@ class Compiler:
|
|||||||
self.__visit_block_statement(node)
|
self.__visit_block_statement(node)
|
||||||
case NodeType.ReturnStatement:
|
case NodeType.ReturnStatement:
|
||||||
self.__visit_return_statement(node)
|
self.__visit_return_statement(node)
|
||||||
|
case NodeType.ReassignStatement:
|
||||||
|
self.__visit_reassign_statement(node)
|
||||||
|
|
||||||
# Expressions
|
# Expressions
|
||||||
case NodeType.InfixExpression:
|
case NodeType.InfixExpression:
|
||||||
@@ -115,6 +118,17 @@ class Compiler:
|
|||||||
|
|
||||||
self.builder = previous_builder
|
self.builder = previous_builder
|
||||||
|
|
||||||
|
def __visit_reassign_statement(self, node: ReassignStatement) -> None:
|
||||||
|
name: str = node.ident.value
|
||||||
|
value: Expression = node.right_value
|
||||||
|
|
||||||
|
value, Type = self.__resolve_value(value)
|
||||||
|
|
||||||
|
if self.environment.lookup(name) is None:
|
||||||
|
self.errors.append(f"Identifier {name} has not been declared before it was re-assigned.")
|
||||||
|
else:
|
||||||
|
ptr, _ = self.environment.lookup(name)
|
||||||
|
self.builder.store(value, ptr)
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Expressions
|
# region Expressions
|
||||||
|
|||||||
15
debug/ir.ll
15
debug/ir.ll
@@ -2,17 +2,14 @@
|
|||||||
target triple = "x86_64-pc-windows-msvc"
|
target triple = "x86_64-pc-windows-msvc"
|
||||||
target datalayout = ""
|
target datalayout = ""
|
||||||
|
|
||||||
define i32 @"main"()
|
|
||||||
{
|
|
||||||
main_entry:
|
|
||||||
%".2" = alloca i32
|
|
||||||
store i32 0, i32* %".2"
|
|
||||||
%".4" = load i32, i32* %".2"
|
|
||||||
ret i32 %".4"
|
|
||||||
}
|
|
||||||
|
|
||||||
define i32 @"test"()
|
define i32 @"test"()
|
||||||
{
|
{
|
||||||
test_entry:
|
test_entry:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @"main"()
|
||||||
|
{
|
||||||
|
main_entry:
|
||||||
ret i32 123
|
ret i32 123
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ class TokenType(Enum):
|
|||||||
# Assignment symbols
|
# Assignment symbols
|
||||||
EQ = "EQ"
|
EQ = "EQ"
|
||||||
|
|
||||||
|
# Comparison symbols
|
||||||
|
LT = "<"
|
||||||
|
GT = ">"
|
||||||
|
EQ_EQ = "=="
|
||||||
|
LT_EQ = "<="
|
||||||
|
GT_EQ = ">="
|
||||||
|
|
||||||
# Symbols
|
# Symbols
|
||||||
LPAREN = "LPAREN"
|
LPAREN = "LPAREN"
|
||||||
RPAREN = "RPAREN"
|
RPAREN = "RPAREN"
|
||||||
@@ -35,6 +42,10 @@ class TokenType(Enum):
|
|||||||
|
|
||||||
# Keywords
|
# Keywords
|
||||||
RETURN = "RETURN"
|
RETURN = "RETURN"
|
||||||
|
IF = "IF"
|
||||||
|
UNLESS = "UNLESS"
|
||||||
|
TRUE = "TRUE"
|
||||||
|
FALSE = "FALSE"
|
||||||
|
|
||||||
# Typing
|
# Typing
|
||||||
TYPE = "TYPE"
|
TYPE = "TYPE"
|
||||||
@@ -54,7 +65,11 @@ class Token:
|
|||||||
|
|
||||||
|
|
||||||
KEYWORDS: dict[str, TokenType] = {
|
KEYWORDS: dict[str, TokenType] = {
|
||||||
"return": TokenType.RETURN
|
"return": TokenType.RETURN,
|
||||||
|
"if": TokenType.IF,
|
||||||
|
"unless": TokenType.UNLESS,
|
||||||
|
"true": TokenType.TRUE,
|
||||||
|
"false": TokenType.FALSE
|
||||||
}
|
}
|
||||||
|
|
||||||
ALT_KEYWORDS: dict[str, TokenType] = {
|
ALT_KEYWORDS: dict[str, TokenType] = {
|
||||||
|
|||||||
2
main.py
2
main.py
@@ -12,7 +12,7 @@ from ctypes import CFUNCTYPE, c_int, c_float
|
|||||||
LEXER_DEBUG: bool = False
|
LEXER_DEBUG: bool = False
|
||||||
PARSER_DEBUG: bool = False
|
PARSER_DEBUG: bool = False
|
||||||
COMPILER_DEBUG: bool = True
|
COMPILER_DEBUG: bool = True
|
||||||
RUN_CODE: bool = False
|
RUN_CODE: bool = True
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
depend "io.pla"
|
depend "io.pla"
|
||||||
|
|
||||||
if (1 + 2 == 3) {
|
if 1 + 2 == 3 {
|
||||||
print("The universe is functional!");
|
print("The universe is functional!");
|
||||||
}
|
}
|
||||||
unless
|
unless
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
main = Func(): Int {
|
main = Func(): Int {
|
||||||
x: Int = 0;
|
x: Int = 123;
|
||||||
|
|
||||||
x = x * 2;
|
if x == 123 {
|
||||||
|
x = 0;
|
||||||
|
} unless {
|
||||||
|
x = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user