From fd21c650c238e1846ed48920ba332bf77aad456f Mon Sep 17 00:00:00 2001 From: Olivier Abrivard Date: Sat, 17 Aug 2024 08:33:52 -0400 Subject: [PATCH] Add Logical Operators handling for control flow --- .idea/scala_compiler.xml | 6 ++++++ src/main/ExprGenerator.ws.kts | 1 + src/main/fr/celticinfo/lox/Expr.kt | 11 ++++++++++ src/main/fr/celticinfo/lox/Interpreter.kt | 12 +++++++++++ src/main/fr/celticinfo/lox/Parser.kt | 26 ++++++++++++++++++++++- 5 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 .idea/scala_compiler.xml diff --git a/.idea/scala_compiler.xml b/.idea/scala_compiler.xml new file mode 100644 index 0000000..3c0e0f6 --- /dev/null +++ b/.idea/scala_compiler.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/src/main/ExprGenerator.ws.kts b/src/main/ExprGenerator.ws.kts index a2ea20b..08352a8 100644 --- a/src/main/ExprGenerator.ws.kts +++ b/src/main/ExprGenerator.ws.kts @@ -44,6 +44,7 @@ val exprTypes = listOf( "Binary : Expr left, Token operator, Expr right", "Grouping : Expr expression", "Literal : Any? value", + "Logical : Expr left, Token operator, Expr right", "Unary : Token operator, Expr right", "Variable : Token name" ) diff --git a/src/main/fr/celticinfo/lox/Expr.kt b/src/main/fr/celticinfo/lox/Expr.kt index a213d3f..3f75a65 100644 --- a/src/main/fr/celticinfo/lox/Expr.kt +++ b/src/main/fr/celticinfo/lox/Expr.kt @@ -8,6 +8,7 @@ interface ExprVisitor { fun visitBinary(expr: Binary): R fun visitGrouping(expr: Grouping): R fun visitLiteral(expr: Literal): R + fun visitLogical(expr: Logical): R fun visitUnary(expr: Unary): R fun visitVariable(expr: Variable): R } @@ -52,6 +53,16 @@ data class Literal( } } +data class Logical( + val left: Expr, + val operator: Token, + val right: Expr +) : Expr() { + override fun accept(visitor: ExprVisitor): R { + return visitor.visitLogical(this) + } +} + data class Unary( val operator: Token, val right: Expr ) : Expr() { diff --git a/src/main/fr/celticinfo/lox/Interpreter.kt b/src/main/fr/celticinfo/lox/Interpreter.kt index 8809f9a..99cadc5 100644 --- a/src/main/fr/celticinfo/lox/Interpreter.kt +++ b/src/main/fr/celticinfo/lox/Interpreter.kt @@ -127,6 +127,18 @@ class Interpreter: ExprVisitor, StmtVisitor{ return expr.value } + override fun visitLogical(expr: Logical): Any? { + val left = evaluate(expr.left) + + if (expr.operator.type == OR) { + if (isTruthy(left)) return left + } else { + if (!isTruthy(left)) return left + } + + return evaluate(expr.right) + } + override fun visitUnary(expr: Unary): Any? { val right = evaluate(expr.right) diff --git a/src/main/fr/celticinfo/lox/Parser.kt b/src/main/fr/celticinfo/lox/Parser.kt index 2b7407a..7ea68c0 100644 --- a/src/main/fr/celticinfo/lox/Parser.kt +++ b/src/main/fr/celticinfo/lox/Parser.kt @@ -96,7 +96,7 @@ class Parser(private val tokens: List) { } private fun assignment(): Expr { - val expr = equality() + val expr = or() if (match(EQUAL)) { val equals = previous() @@ -113,6 +113,30 @@ class Parser(private val tokens: List) { return expr } + private fun or(): Expr { + var expr = and() + + while (match(OR)) { + val operator = previous() + val right = and() + expr = Logical(expr, operator, right) + } + + return expr + } + + private fun and(): Expr { + var expr = equality() + + while (match(AND)) { + val operator = previous() + val right = equality() + expr = Logical(expr, operator, right) + } + + return expr + } + private fun equality(): Expr { var expr = comparison()