Added Stmt class
parent
cc4aa58bff
commit
72f48b75bb
@ -0,0 +1,32 @@
|
||||
package fr.celticinfo.lox
|
||||
|
||||
/**
|
||||
* The StmtVisitor interface is used to visit the different types of statements that can be parsed by the Parser.
|
||||
*/
|
||||
interface StmtVisitor<R> {
|
||||
fun visitExpression(stmt: Expression): R
|
||||
fun visitPrint(stmt: Print): R
|
||||
}
|
||||
|
||||
/**
|
||||
* The Stmt class represents the different types of statements that can be parsed by the Parser.
|
||||
*/
|
||||
sealed class Stmt {
|
||||
abstract fun <R> accept(visitor: StmtVisitor<R>): R
|
||||
}
|
||||
|
||||
data class Expression(
|
||||
val expression: Expr
|
||||
) : Stmt() {
|
||||
override fun <R> accept(visitor: StmtVisitor<R>): R {
|
||||
return visitor.visitExpression(this)
|
||||
}
|
||||
}
|
||||
|
||||
data class Print(
|
||||
val expression: Expr
|
||||
) : Stmt() {
|
||||
override fun <R> accept(visitor: StmtVisitor<R>): R {
|
||||
return visitor.visitPrint(this)
|
||||
}
|
||||
}
|
||||
@ -1,46 +1,60 @@
|
||||
package fr.celticinfo.lox
|
||||
|
||||
import fr.celticinfo.loxext.RpnPrinter
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import kotlin.test.*
|
||||
|
||||
class InterpreterTest {
|
||||
|
||||
@Test
|
||||
fun `validate interpreter`() {
|
||||
val code = """
|
||||
(1 + 2 * 3 - 5) / 2
|
||||
1 + 2 * 3 - 4 / 5;
|
||||
""".trimIndent()
|
||||
val scanner = Scanner(code)
|
||||
val tokens = scanner.scanTokens()
|
||||
val parser = Parser(tokens)
|
||||
val expr = parser.parse()
|
||||
val value = Interpreter().interpret(expr!!)
|
||||
assertEquals(1.0, value)
|
||||
val statements = parser.parse()
|
||||
assertEquals(1, statements.size)
|
||||
val stmt = statements.first()
|
||||
assertTrue(stmt is Expression)
|
||||
val expr = stmt.expression
|
||||
assertEquals("1.0 2.0 3.0 * + 4.0 5.0 / -", RpnPrinter().print(expr))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Division by zero should raise error`() {
|
||||
val code = """
|
||||
1 / 0
|
||||
1 / 0;
|
||||
""".trimIndent()
|
||||
val scanner = Scanner(code)
|
||||
val tokens = scanner.scanTokens()
|
||||
val parser = Parser(tokens)
|
||||
val expr = parser.parse()
|
||||
val value = Interpreter().interpret(expr!!)
|
||||
assertNull(value)
|
||||
val statements = parser.parse()
|
||||
assertEquals(1, statements.size)
|
||||
|
||||
assertFailsWith<RuntimeError>(
|
||||
block = {
|
||||
Interpreter().interpret(statements)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Invalid type raise error`() {
|
||||
val code = """
|
||||
1 + false
|
||||
1 + false;
|
||||
""".trimIndent()
|
||||
val scanner = Scanner(code)
|
||||
val tokens = scanner.scanTokens()
|
||||
val parser = Parser(tokens)
|
||||
val expr = parser.parse()
|
||||
val value = Interpreter().interpret(expr!!)
|
||||
assertNull(value)
|
||||
val statements = parser.parse()
|
||||
assertEquals(1, statements.size)
|
||||
|
||||
assertFailsWith<RuntimeError>(
|
||||
block = {
|
||||
Interpreter().interpret(statements)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue