Add Logical Operators handling for control flow

main
Olivier Abrivard 1 year ago
parent 066c613c50
commit fd21c650c2

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ScalaCompilerConfiguration">
<option name="separateProdTestSources" value="false" />
</component>
</project>

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

@ -8,6 +8,7 @@ interface ExprVisitor<R> {
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 <R> accept(visitor: ExprVisitor<R>): R {
return visitor.visitLogical(this)
}
}
data class Unary(
val operator: Token, val right: Expr
) : Expr() {

@ -127,6 +127,18 @@ class Interpreter: ExprVisitor<Any?>, StmtVisitor<Unit>{
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)

@ -96,7 +96,7 @@ class Parser(private val tokens: List<Token>) {
}
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<Token>) {
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()

Loading…
Cancel
Save