Add native functions

main
Olivier Abrivard 2 years ago
parent 5ee14af59a
commit 0dcf8dd26c

@ -5,6 +5,10 @@ class AstPrinter : ExprVisitor<String> {
return expr.accept(this) return expr.accept(this)
} }
override fun visitCall(expr: Call): String {
return parenthesize("call", expr.callee, *expr.arguments.toTypedArray())
}
override fun visitAssign(expr: Assign): String { override fun visitAssign(expr: Assign): String {
return parenthesize("=", expr) return parenthesize("=", expr)
} }

@ -3,7 +3,24 @@ package fr.celticinfo.lox
import fr.celticinfo.lox.TokenType.* import fr.celticinfo.lox.TokenType.*
class Interpreter: ExprVisitor<Any?>, StmtVisitor<Unit>{ class Interpreter: ExprVisitor<Any?>, StmtVisitor<Unit>{
private var environment = Environment() private var globals = Environment()
private var environment = globals
constructor() {
globals.define("clock", object : LoxCallable {
override fun arity(): Int {
return 0
}
override fun call(interpreter: Interpreter, arguments: List<Any?>): Any? {
return System.currentTimeMillis().toDouble() / 1000.0
}
override fun toString(): String {
return "<native fn>"
}
})
}
fun interpret(statements: List<Stmt?>) { fun interpret(statements: List<Stmt?>) {
try { try {

@ -7,6 +7,10 @@ class RpnPrinter : ExprVisitor<String> {
return expr.accept(this) return expr.accept(this)
} }
override fun visitCall(expr: Call): String {
return stack("call", expr.callee, *expr.arguments.toTypedArray())
}
override fun visitAssign(expr: Assign): String { override fun visitAssign(expr: Assign): String {
return stack("=", expr) return stack("=", expr)
} }

@ -1,6 +1,7 @@
package fr.celticinfo.lox package fr.celticinfo.lox
import fr.celticinfo.loxext.RpnPrinter import fr.celticinfo.loxext.RpnPrinter
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.assertDoesNotThrow import org.junit.jupiter.api.assertDoesNotThrow
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.PrintStream import java.io.PrintStream
@ -358,4 +359,32 @@ for (var b = 1; a < 10000; b = temp + b) {
System.setOut(standardOut) System.setOut(standardOut)
} }
} }
@Test
fun `Clock native function should return a valid timestamp`() {
val standardOut = System.out
val outputStreamCaptor = ByteArrayOutputStream()
System.setOut(PrintStream(outputStreamCaptor))
try {
val code = """
print clock();
""".trimIndent()
val scanner = Scanner(code)
val tokens = scanner.scanTokens()
val parser = Parser(tokens)
val statements = parser.parse()
Assertions.assertEquals(1, statements.size)
Interpreter().interpret(statements)
val output = outputStreamCaptor.toString().trim()
val timestamp = output.toDoubleOrNull()
Assertions.assertNotNull(timestamp)
Assertions.assertTrue(timestamp!! >= 0)
} finally {
System.setOut(standardOut)
}
}
} }
Loading…
Cancel
Save