feat: add if statements

This commit is contained in:
2026-02-06 01:12:12 +01:00
parent bbe216bdda
commit 330486fb81
5 changed files with 34 additions and 4 deletions

View File

@@ -3,7 +3,7 @@ let age = 14
if age >= 18 { if age >= 18 {
print("You are an adult") print("You are an adult")
} else { } else {
print("You are a child) print("You are a child")
} }
let guess = 12 let guess = 12

View File

@@ -13,7 +13,7 @@ def main():
123 123
"This is "This is
another string" """ another string" """
path: str = "examples/08_scopes.peb" path: str = "examples/04_if_else.peb"
with open(path, "r") as f: with open(path, "r") as f:
source = f.read() source = f.read()
lexer: Lexer = Lexer() lexer: Lexer = Lexer()

View File

@@ -25,6 +25,10 @@ class Stmt(ABC):
def visit_expression_stmt(self, stmt: ExpressionStmt) -> T: def visit_expression_stmt(self, stmt: ExpressionStmt) -> T:
... ...
@abstractmethod
def visit_if_stmt(self, stmt: IfStmt) -> T:
...
@abstractmethod @abstractmethod
def visit_print_stmt(self, stmt: PrintStmt) -> T: def visit_print_stmt(self, stmt: PrintStmt) -> T:
... ...
@@ -50,6 +54,16 @@ class ExpressionStmt(Stmt):
return visitor.visit_expression_stmt(self) return visitor.visit_expression_stmt(self)
@dataclass(frozen=True)
class IfStmt(Stmt):
condition: Expr
then_branch: Stmt
else_branch: Optional[Stmt]
def accept(self, visitor: Stmt.Visitor[T]) -> T:
return visitor.visit_if_stmt(self)
@dataclass(frozen=True) @dataclass(frozen=True)
class PrintStmt(Stmt): class PrintStmt(Stmt):
expression: Expr expression: Expr

View File

@@ -1,7 +1,7 @@
from typing import Any from typing import Any
from src.ast.expr import LiteralExpr, GroupingExpr, UnaryExpr, BinaryExpr, Expr, VariableExpr, AssignExpr from src.ast.expr import LiteralExpr, GroupingExpr, UnaryExpr, BinaryExpr, Expr, VariableExpr, AssignExpr
from src.ast.stmt import Stmt, PrintStmt, ExpressionStmt, LetStmt, BlockStmt from src.ast.stmt import Stmt, PrintStmt, ExpressionStmt, LetStmt, BlockStmt, IfStmt
from src.interpreter.environment import Environment from src.interpreter.environment import Environment
from src.interpreter.error import PebbleRuntimeError from src.interpreter.error import PebbleRuntimeError
from src.pebble import Pebble from src.pebble import Pebble
@@ -108,6 +108,12 @@ class Interpreter(Expr.Visitor[Any], Stmt.Visitor[None]):
def visit_expression_stmt(self, stmt: ExpressionStmt) -> None: def visit_expression_stmt(self, stmt: ExpressionStmt) -> None:
self.evaluate(stmt.expression) self.evaluate(stmt.expression)
def visit_if_stmt(self, stmt: IfStmt) -> None:
if self.is_truthy(self.evaluate(stmt.condition)):
self.execute(stmt.then_branch)
elif stmt.else_branch is not None:
self.execute(stmt.else_branch)
def visit_print_stmt(self, stmt: PrintStmt) -> None: def visit_print_stmt(self, stmt: PrintStmt) -> None:
value: Any = self.evaluate(stmt.expression) value: Any = self.evaluate(stmt.expression)
print(value) print(value)

View File

@@ -1,7 +1,7 @@
from typing import Optional from typing import Optional
from src.ast.expr import Expr, BinaryExpr, UnaryExpr, LiteralExpr, GroupingExpr, VariableExpr, AssignExpr from src.ast.expr import Expr, BinaryExpr, UnaryExpr, LiteralExpr, GroupingExpr, VariableExpr, AssignExpr
from src.ast.stmt import Stmt, PrintStmt, ExpressionStmt, LetStmt, BlockStmt from src.ast.stmt import Stmt, PrintStmt, ExpressionStmt, LetStmt, BlockStmt, IfStmt
from src.parser.error import ParsingError from src.parser.error import ParsingError
from src.pebble import Pebble from src.pebble import Pebble
from src.token import Token, TokenType from src.token import Token, TokenType
@@ -107,12 +107,22 @@ class Parser:
return LetStmt(name, initializer) return LetStmt(name, initializer)
def statement(self) -> Stmt: def statement(self) -> Stmt:
if self.match(TokenType.IF):
return self.if_stmt()
if self.match(TokenType.PRINT): if self.match(TokenType.PRINT):
return self.print_stmt() return self.print_stmt()
if self.match(TokenType.LEFT_BRACE): if self.match(TokenType.LEFT_BRACE):
return self.block_stmt() return self.block_stmt()
return self.expression_stmt() return self.expression_stmt()
def if_stmt(self) -> Stmt:
condition: Expr = self.expression()
then_branch: Stmt = self.statement()
else_branch: Optional[Stmt] = None
if self.match(TokenType.ELSE):
else_branch = self.statement()
return IfStmt(condition, then_branch, else_branch)
def print_stmt(self) -> Stmt: def print_stmt(self) -> Stmt:
self.consume(TokenType.LEFT_PAREN, "Missing parentheses") self.consume(TokenType.LEFT_PAREN, "Missing parentheses")
value: Expr = self.expression() value: Expr = self.expression()