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"
|
||||
IfStatement = "IfStatement"
|
||||
WhileStatement = "WhileStatement"
|
||||
BreakStatement = "BreakStatement"
|
||||
ContinueStatement = "ContinueStatement"
|
||||
ForStatement = "ForStatement"
|
||||
|
||||
# Expressions
|
||||
InfixExpression = "InfixExpression"
|
||||
@@ -263,6 +266,48 @@ class WhileStatement(Statement):
|
||||
"condition": self.condition.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
|
||||
|
||||
# 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 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 IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral, StringLiteral
|
||||
from AST import FunctionParameter
|
||||
@@ -33,6 +33,9 @@ class Compiler:
|
||||
|
||||
self.__initialize_builtins()
|
||||
|
||||
self.breakpoints: list[ir.Block] = []
|
||||
self.continues: list[ir.Block] = []
|
||||
|
||||
def __initialize_builtins(self) -> None:
|
||||
def __init_print() -> ir.Function:
|
||||
fnty: ir.FunctionType = ir.FunctionType(
|
||||
@@ -87,6 +90,12 @@ class Compiler:
|
||||
self.__visit_if_statement(node)
|
||||
case NodeType.WhileStatement:
|
||||
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
|
||||
case NodeType.InfixExpression:
|
||||
@@ -238,6 +247,44 @@ class Compiler:
|
||||
test, _ = self.__resolve_value(condition)
|
||||
self.builder.cbranch(test, while_loop_entry, 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
|
||||
|
||||
# region Expressions
|
||||
|
||||
@@ -51,6 +51,9 @@ class TokenType(Enum):
|
||||
TRUE = "TRUE"
|
||||
FALSE = "FALSE"
|
||||
WHILE = "WHILE"
|
||||
CONTINUE = "CONTINUE"
|
||||
BREAK = "BREAK"
|
||||
FOR = "FOR"
|
||||
|
||||
# Typing
|
||||
TYPE = "TYPE"
|
||||
@@ -75,7 +78,10 @@ KEYWORDS: dict[str, TokenType] = {
|
||||
"unless": TokenType.UNLESS,
|
||||
"true": TokenType.TRUE,
|
||||
"false": TokenType.FALSE,
|
||||
"while": TokenType.WHILE
|
||||
"while": TokenType.WHILE,
|
||||
"break": TokenType.BREAK,
|
||||
"continue": TokenType.CONTINUE,
|
||||
"for": TokenType.FOR
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
LEXER_DEBUG: bool = False
|
||||
PARSER_DEBUG: bool = False
|
||||
PARSER_DEBUG: bool = True
|
||||
COMPILER_DEBUG: bool = False
|
||||
RUN_CODE: bool = True
|
||||
RUN_CODE: bool = False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -5,7 +5,7 @@ from enum import Enum, auto
|
||||
|
||||
from AST import Statement, Expression, Program
|
||||
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 FunctionParameter
|
||||
|
||||
@@ -138,6 +138,12 @@ class Parser:
|
||||
return self.__parse_return_statement()
|
||||
case TokenType.WHILE:
|
||||
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 _:
|
||||
return self.__parse_expression_statement()
|
||||
|
||||
@@ -318,6 +324,47 @@ class Parser:
|
||||
body = self.__parse_block_statement()
|
||||
|
||||
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
|
||||
|
||||
# region Expression Methods
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
main = Func(): Int {
|
||||
a: Int = 0;
|
||||
|
||||
while a < 10 {
|
||||
$print("a = %i\n", a);
|
||||
a = a + 1;
|
||||
for (x: Int = 1; x <= 20; x = x + 1) {
|
||||
print("i = %i\n", x)
|
||||
}
|
||||
|
||||
return a;
|
||||
return x;
|
||||
}
|
||||
Reference in New Issue
Block a user