parser isnt liking for statements :(

This commit is contained in:
SpookyDervish
2025-10-16 07:24:40 +11:00
parent 9f6fff9977
commit 600bebb9b2
6 changed files with 153 additions and 11 deletions

45
AST.py
View File

@@ -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

View File

@@ -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

View File

@@ -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] = {

View File

@@ -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__":

View File

@@ -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

View File

@@ -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;
}