feat: add while loops
This commit is contained in:
13
examples/10_while.peb
Normal file
13
examples/10_while.peb
Normal file
@@ -0,0 +1,13 @@
|
||||
let i = 0
|
||||
let a = 1
|
||||
let b = 1
|
||||
|
||||
print("Fibonacci")
|
||||
|
||||
while i < 10 {
|
||||
print(a)
|
||||
let c = a + b
|
||||
a = b
|
||||
b = c
|
||||
i += 1
|
||||
}
|
||||
2
main.py
2
main.py
@@ -13,7 +13,7 @@ def main():
|
||||
123
|
||||
"This is
|
||||
another string" """
|
||||
path: str = "examples/09_logical.peb"
|
||||
path: str = "examples/10_while.peb"
|
||||
with open(path, "r") as f:
|
||||
source = f.read()
|
||||
lexer: Lexer = Lexer()
|
||||
|
||||
@@ -37,6 +37,10 @@ class Stmt(ABC):
|
||||
def visit_let_stmt(self, stmt: LetStmt) -> T:
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def visit_while_stmt(self, stmt: WhileStmt) -> T:
|
||||
...
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BlockStmt(Stmt):
|
||||
@@ -79,3 +83,13 @@ class LetStmt(Stmt):
|
||||
|
||||
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
||||
return visitor.visit_let_stmt(self)
|
||||
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class WhileStmt(Stmt):
|
||||
condition: Expr
|
||||
body: Stmt
|
||||
|
||||
def accept(self, visitor: Stmt.Visitor[T]) -> T:
|
||||
return visitor.visit_while_stmt(self)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Any
|
||||
|
||||
from src.ast.expr import LiteralExpr, GroupingExpr, UnaryExpr, BinaryExpr, Expr, VariableExpr, AssignExpr, LogicalExpr
|
||||
from src.ast.stmt import Stmt, PrintStmt, ExpressionStmt, LetStmt, BlockStmt, IfStmt
|
||||
from src.ast.stmt import Stmt, PrintStmt, ExpressionStmt, LetStmt, BlockStmt, IfStmt, WhileStmt
|
||||
from src.interpreter.environment import Environment
|
||||
from src.interpreter.error import PebbleRuntimeError
|
||||
from src.pebble import Pebble
|
||||
@@ -133,6 +133,10 @@ class Interpreter(Expr.Visitor[Any], Stmt.Visitor[None]):
|
||||
value: Any = self.evaluate(stmt.expression)
|
||||
print(value)
|
||||
|
||||
def visit_while_stmt(self, stmt: WhileStmt) -> None:
|
||||
while self.is_truthy(self.evaluate(stmt.condition)):
|
||||
self.execute(stmt.body)
|
||||
|
||||
def visit_let_stmt(self, stmt: LetStmt) -> None:
|
||||
value: Any = None
|
||||
if stmt.initializer is not None:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Optional
|
||||
|
||||
from src.ast.expr import Expr, BinaryExpr, UnaryExpr, LiteralExpr, GroupingExpr, VariableExpr, AssignExpr, LogicalExpr
|
||||
from src.ast.stmt import Stmt, PrintStmt, ExpressionStmt, LetStmt, BlockStmt, IfStmt
|
||||
from src.ast.stmt import Stmt, PrintStmt, ExpressionStmt, LetStmt, BlockStmt, IfStmt, WhileStmt
|
||||
from src.parser.error import ParsingError
|
||||
from src.pebble import Pebble
|
||||
from src.token import Token, TokenType
|
||||
@@ -111,6 +111,8 @@ class Parser:
|
||||
return self.if_stmt()
|
||||
if self.match(TokenType.PRINT):
|
||||
return self.print_stmt()
|
||||
if self.match(TokenType.WHILE):
|
||||
return self.while_stmt()
|
||||
if self.match(TokenType.LEFT_BRACE):
|
||||
return self.block_stmt()
|
||||
return self.expression_stmt()
|
||||
@@ -130,6 +132,11 @@ class Parser:
|
||||
self.expect_eol("Expected end of line after statement")
|
||||
return PrintStmt(value)
|
||||
|
||||
def while_stmt(self) -> Stmt:
|
||||
condition: Expr = self.expression()
|
||||
body: Stmt = self.statement()
|
||||
return WhileStmt(condition, body)
|
||||
|
||||
def block_stmt(self) -> Stmt:
|
||||
statements: list[Stmt] = []
|
||||
self.skip_newlines()
|
||||
|
||||
Reference in New Issue
Block a user