parser isnt liking for statements :(
This commit is contained in:
45
AST.py
45
AST.py
@@ -14,6 +14,9 @@ class NodeType(Enum):
|
|||||||
ReturnStatement = "ReturnStatement"
|
ReturnStatement = "ReturnStatement"
|
||||||
IfStatement = "IfStatement"
|
IfStatement = "IfStatement"
|
||||||
WhileStatement = "WhileStatement"
|
WhileStatement = "WhileStatement"
|
||||||
|
BreakStatement = "BreakStatement"
|
||||||
|
ContinueStatement = "ContinueStatement"
|
||||||
|
ForStatement = "ForStatement"
|
||||||
|
|
||||||
# Expressions
|
# Expressions
|
||||||
InfixExpression = "InfixExpression"
|
InfixExpression = "InfixExpression"
|
||||||
@@ -263,6 +266,48 @@ class WhileStatement(Statement):
|
|||||||
"condition": self.condition.json(),
|
"condition": self.condition.json(),
|
||||||
"body": self.body.json()
|
"body": self.body.json()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BreakStatement(Statement):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def type(self) -> NodeType:
|
||||||
|
return NodeType.BreakStatement
|
||||||
|
|
||||||
|
def json(self) -> dict:
|
||||||
|
return {
|
||||||
|
"type": self.type().value
|
||||||
|
}
|
||||||
|
|
||||||
|
class ContinueStatement(Statement):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def type(self) -> NodeType:
|
||||||
|
return NodeType.ContinueStatement
|
||||||
|
|
||||||
|
def json(self) -> dict:
|
||||||
|
return {
|
||||||
|
"type": self.type().value
|
||||||
|
}
|
||||||
|
|
||||||
|
class ForStatement(Statement):
|
||||||
|
def __init__(self, var_declaration: AssignmentStatement = None, condition: Expression = None, action: ReassignStatement = None, body: BlockStatement = None) -> None:
|
||||||
|
self.var_declaration = var_declaration
|
||||||
|
self.condition = condition
|
||||||
|
self.action = action
|
||||||
|
self.body = body
|
||||||
|
|
||||||
|
def type(self) -> NodeType:
|
||||||
|
return NodeType.ForStatement
|
||||||
|
|
||||||
|
def json(self) -> dict:
|
||||||
|
return {
|
||||||
|
"type": self.type().value,
|
||||||
|
"var_declaration": self.var_declaration.json(),
|
||||||
|
"condition": self.condition.json(),
|
||||||
|
"body": self.body.json()
|
||||||
|
}
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Expressions
|
# region Expressions
|
||||||
|
|||||||
49
compiler.py
49
compiler.py
@@ -2,7 +2,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 WhileStatement
|
from AST import WhileStatement, BreakStatement, ContinueStatement, ForStatement
|
||||||
from AST import InfixExpression, CallExpression
|
from AST import InfixExpression, CallExpression
|
||||||
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral, StringLiteral
|
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral, StringLiteral
|
||||||
from AST import FunctionParameter
|
from AST import FunctionParameter
|
||||||
@@ -33,6 +33,9 @@ class Compiler:
|
|||||||
|
|
||||||
self.__initialize_builtins()
|
self.__initialize_builtins()
|
||||||
|
|
||||||
|
self.breakpoints: list[ir.Block] = []
|
||||||
|
self.continues: list[ir.Block] = []
|
||||||
|
|
||||||
def __initialize_builtins(self) -> None:
|
def __initialize_builtins(self) -> None:
|
||||||
def __init_print() -> ir.Function:
|
def __init_print() -> ir.Function:
|
||||||
fnty: ir.FunctionType = ir.FunctionType(
|
fnty: ir.FunctionType = ir.FunctionType(
|
||||||
@@ -87,6 +90,12 @@ class Compiler:
|
|||||||
self.__visit_if_statement(node)
|
self.__visit_if_statement(node)
|
||||||
case NodeType.WhileStatement:
|
case NodeType.WhileStatement:
|
||||||
self.__visit_while_statement(node)
|
self.__visit_while_statement(node)
|
||||||
|
case NodeType.BreakStatement:
|
||||||
|
self.__visit_break_statement(node)
|
||||||
|
case NodeType.ContinueStatement:
|
||||||
|
self.__visit_continue_statement(node)
|
||||||
|
case NodeType.ForStatement:
|
||||||
|
self.__visit_for_statement(node)
|
||||||
|
|
||||||
# Expressions
|
# Expressions
|
||||||
case NodeType.InfixExpression:
|
case NodeType.InfixExpression:
|
||||||
@@ -238,6 +247,44 @@ class Compiler:
|
|||||||
test, _ = self.__resolve_value(condition)
|
test, _ = self.__resolve_value(condition)
|
||||||
self.builder.cbranch(test, while_loop_entry, while_loop_otherwise)
|
self.builder.cbranch(test, while_loop_entry, while_loop_otherwise)
|
||||||
self.builder.position_at_start(while_loop_otherwise)
|
self.builder.position_at_start(while_loop_otherwise)
|
||||||
|
|
||||||
|
def __visit_break_statement(self, node: BreakStatement) -> None:
|
||||||
|
self.builder.branch(self.breakpoints[-1])
|
||||||
|
|
||||||
|
def __visit_continue_statement(self, node: ContinueStatement) -> None:
|
||||||
|
self.builder.branch[self.continues[-1]]
|
||||||
|
|
||||||
|
def __visit_for_statement(self, node: ForStatement) -> None:
|
||||||
|
var_declaration: AssignmentStatement = node.var_declaration
|
||||||
|
condition: Expression = node.condition
|
||||||
|
action: ReassignStatement = node.action
|
||||||
|
body: BlockStatement = node.body
|
||||||
|
|
||||||
|
previous_env = self.environment
|
||||||
|
self.environment = Environment(parent=previous_env)
|
||||||
|
|
||||||
|
self.compile(var_declaration)
|
||||||
|
|
||||||
|
for_loop_entry = self.builder.append_basic_block(f"for_loop_entry_{self.__increment_counter()}")
|
||||||
|
for_loop_otherwise = self.builder.append_basic_block(f"for_loop_otherwise_{self.counter}")
|
||||||
|
|
||||||
|
self.breakpoints.append(for_loop_otherwise)
|
||||||
|
self.continues.append(for_loop_entry)
|
||||||
|
|
||||||
|
self.builder.branch(for_loop_entry)
|
||||||
|
self.builder.position_at_start(for_loop_entry)
|
||||||
|
|
||||||
|
self.compile(body)
|
||||||
|
|
||||||
|
self.compile(action)
|
||||||
|
|
||||||
|
test, _ = self.__resolve_value(condition)
|
||||||
|
self.builder.cbranch(test, for_loop_entry, for_loop_otherwise)
|
||||||
|
|
||||||
|
self.builder.position_at_start(for_loop_otherwise)
|
||||||
|
|
||||||
|
self.breakpoints.pop()
|
||||||
|
self.continues.pop()
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Expressions
|
# region Expressions
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ class TokenType(Enum):
|
|||||||
TRUE = "TRUE"
|
TRUE = "TRUE"
|
||||||
FALSE = "FALSE"
|
FALSE = "FALSE"
|
||||||
WHILE = "WHILE"
|
WHILE = "WHILE"
|
||||||
|
CONTINUE = "CONTINUE"
|
||||||
|
BREAK = "BREAK"
|
||||||
|
FOR = "FOR"
|
||||||
|
|
||||||
# Typing
|
# Typing
|
||||||
TYPE = "TYPE"
|
TYPE = "TYPE"
|
||||||
@@ -75,7 +78,10 @@ KEYWORDS: dict[str, TokenType] = {
|
|||||||
"unless": TokenType.UNLESS,
|
"unless": TokenType.UNLESS,
|
||||||
"true": TokenType.TRUE,
|
"true": TokenType.TRUE,
|
||||||
"false": TokenType.FALSE,
|
"false": TokenType.FALSE,
|
||||||
"while": TokenType.WHILE
|
"while": TokenType.WHILE,
|
||||||
|
"break": TokenType.BREAK,
|
||||||
|
"continue": TokenType.CONTINUE,
|
||||||
|
"for": TokenType.FOR
|
||||||
}
|
}
|
||||||
|
|
||||||
ALT_KEYWORDS: dict[str, TokenType] = {
|
ALT_KEYWORDS: dict[str, TokenType] = {
|
||||||
|
|||||||
4
main.py
4
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 = False
|
COMPILER_DEBUG: bool = False
|
||||||
RUN_CODE: bool = True
|
RUN_CODE: bool = False
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -5,7 +5,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, WhileStatement
|
from AST import ExpressionStatement, AssignmentStatement, FunctionStatement, ReturnStatement, BlockStatement, ReassignStatement, IfStatement, WhileStatement
|
||||||
from AST import InfixExpression, CallExpression
|
from AST import InfixExpression, CallExpression, BreakStatement, ContinueStatement, ForStatement
|
||||||
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral, StringLiteral
|
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral, StringLiteral
|
||||||
from AST import FunctionParameter
|
from AST import FunctionParameter
|
||||||
|
|
||||||
@@ -138,6 +138,12 @@ class Parser:
|
|||||||
return self.__parse_return_statement()
|
return self.__parse_return_statement()
|
||||||
case TokenType.WHILE:
|
case TokenType.WHILE:
|
||||||
return self.__parse_while_statement()
|
return self.__parse_while_statement()
|
||||||
|
case TokenType.BREAK:
|
||||||
|
return self.__parse_break_statement()
|
||||||
|
case TokenType.CONTINUE:
|
||||||
|
return self.__parse_continue_statement()
|
||||||
|
case TokenType.FOR:
|
||||||
|
return self.__parse_for_statement()
|
||||||
case _:
|
case _:
|
||||||
return self.__parse_expression_statement()
|
return self.__parse_expression_statement()
|
||||||
|
|
||||||
@@ -318,6 +324,47 @@ class Parser:
|
|||||||
body = self.__parse_block_statement()
|
body = self.__parse_block_statement()
|
||||||
|
|
||||||
return WhileStatement(condition, body)
|
return WhileStatement(condition, body)
|
||||||
|
|
||||||
|
def __parse_break_statement(self) -> BreakStatement:
|
||||||
|
self.__next_token()
|
||||||
|
return BreakStatement()
|
||||||
|
|
||||||
|
def __parse_continue_statement(self) -> ContinueStatement:
|
||||||
|
self.__next_token()
|
||||||
|
return ContinueStatement()
|
||||||
|
|
||||||
|
def __parse_for_statement(self) -> ForStatement:
|
||||||
|
stmt: ForStatement = ForStatement()
|
||||||
|
|
||||||
|
if not self.__expect_peek(TokenType.LPAREN):
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not self.__expect_peek(TokenType.IDENT):
|
||||||
|
return None
|
||||||
|
|
||||||
|
stmt.var_declaration = self.__parse_assignment_statement()
|
||||||
|
|
||||||
|
self.__next_token() # skip ;
|
||||||
|
|
||||||
|
stmt.condition = self.__parse_expression(PrecedenceType.P_LOWEST)
|
||||||
|
|
||||||
|
if not self.__expect_peek(TokenType.SEMICOLON):
|
||||||
|
return None
|
||||||
|
|
||||||
|
self.__next_token() # skip ;
|
||||||
|
|
||||||
|
stmt.action = self.__parse_assignment_statement()
|
||||||
|
|
||||||
|
print(stmt.action.json())
|
||||||
|
|
||||||
|
self.__next_token()
|
||||||
|
|
||||||
|
if not self.__expect_peek(TokenType.LBRACE):
|
||||||
|
return None
|
||||||
|
|
||||||
|
stmt.body = self.__parse_block_statement()
|
||||||
|
|
||||||
|
return stmt
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Expression Methods
|
# region Expression Methods
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
main = Func(): Int {
|
main = Func(): Int {
|
||||||
a: Int = 0;
|
for (x: Int = 1; x <= 20; x = x + 1) {
|
||||||
|
print("i = %i\n", x)
|
||||||
while a < 10 {
|
|
||||||
$print("a = %i\n", a);
|
|
||||||
a = a + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return a;
|
return x;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user