diff --git a/src/main/ExprGenerator.ws.kts b/src/main/ExprGenerator.ws.kts index 08352a8..44a92f7 100644 --- a/src/main/ExprGenerator.ws.kts +++ b/src/main/ExprGenerator.ws.kts @@ -55,6 +55,7 @@ val stmtTypes = listOf( "Expression : Expr expression", "If : Expr condition, Stmt thenBranch, Stmt? elseBranch", "Print : Expr expression", - "Var : Token name, Expr? initializer" + "Var : Token name, Expr? initializer", + "While : Expr condition, Stmt body" ) defineAst("Stmt", stmtTypes) diff --git a/src/main/fr/celticinfo/lox/Interpreter.kt b/src/main/fr/celticinfo/lox/Interpreter.kt index 99cadc5..5fbb400 100644 --- a/src/main/fr/celticinfo/lox/Interpreter.kt +++ b/src/main/fr/celticinfo/lox/Interpreter.kt @@ -52,6 +52,12 @@ class Interpreter: ExprVisitor, StmtVisitor{ } } + override fun visitWhile(stmt: While) { + while (isTruthy(evaluate(stmt.condition))) { + execute(stmt.body) + } + } + override fun visitPrint(stmt: Print) { val value = evaluate(stmt.expression) println(stringify(value)) diff --git a/src/main/fr/celticinfo/lox/Parser.kt b/src/main/fr/celticinfo/lox/Parser.kt index 7ea68c0..d67567a 100644 --- a/src/main/fr/celticinfo/lox/Parser.kt +++ b/src/main/fr/celticinfo/lox/Parser.kt @@ -43,11 +43,20 @@ class Parser(private val tokens: List) { return Var(name, initializer) } + private fun whileStatement(): Stmt { + consume(LEFT_PAREN, "Expect '(' after 'while'.") + val condition = expression() + consume(RIGHT_PAREN, "Expect ')' after condition.") + val body = statement() + + return While(condition, body) + } private fun statement(): Stmt { return when { match(IF) -> ifStatement() match(PRINT) -> printStatement() + match(WHILE) -> whileStatement() match(LEFT_BRACE) -> Block(blockStatement()) else -> expressionStatement() } diff --git a/src/main/fr/celticinfo/lox/Stmt.kt b/src/main/fr/celticinfo/lox/Stmt.kt index 43c097c..ca40b5c 100644 --- a/src/main/fr/celticinfo/lox/Stmt.kt +++ b/src/main/fr/celticinfo/lox/Stmt.kt @@ -8,7 +8,8 @@ interface StmtVisitor { fun visitExpression(stmt: Expression): R fun visitIf(stmt: If): R fun visitPrint(stmt: Print): R - fun visitVar(stmt: Var): R + fun visitVar(stmt: Var): R + fun visitWhile(stmt: While): R } /** @@ -58,4 +59,13 @@ data class Var( override fun accept(visitor: StmtVisitor): R { return visitor.visitVar(this) } +} + +data class While( + val condition: Expr, + val body: Stmt +) : Stmt() { + override fun accept(visitor: StmtVisitor): R { + return visitor.visitWhile(this) + } } \ No newline at end of file