diff --git a/src/main/fr/celticinfo/lox/AstPrinter.kt b/src/main/fr/celticinfo/lox/AstPrinter.kt index 203f173..99464f4 100644 --- a/src/main/fr/celticinfo/lox/AstPrinter.kt +++ b/src/main/fr/celticinfo/lox/AstPrinter.kt @@ -5,6 +5,10 @@ class AstPrinter : ExprVisitor { return expr.accept(this) } + override fun visitCall(expr: Call): String { + return parenthesize("call", expr.callee, *expr.arguments.toTypedArray()) + } + override fun visitAssign(expr: Assign): String { return parenthesize("=", expr) } diff --git a/src/main/fr/celticinfo/lox/Interpreter.kt b/src/main/fr/celticinfo/lox/Interpreter.kt index c85efc7..0c81f1f 100644 --- a/src/main/fr/celticinfo/lox/Interpreter.kt +++ b/src/main/fr/celticinfo/lox/Interpreter.kt @@ -3,7 +3,24 @@ package fr.celticinfo.lox import fr.celticinfo.lox.TokenType.* class Interpreter: ExprVisitor, StmtVisitor{ - 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? { + return System.currentTimeMillis().toDouble() / 1000.0 + } + + override fun toString(): String { + return "" + } + }) + } fun interpret(statements: List) { try { diff --git a/src/main/fr/celticinfo/loxext/RpnPrinter.kt b/src/main/fr/celticinfo/loxext/RpnPrinter.kt index 76040c6..533b523 100644 --- a/src/main/fr/celticinfo/loxext/RpnPrinter.kt +++ b/src/main/fr/celticinfo/loxext/RpnPrinter.kt @@ -7,6 +7,10 @@ class RpnPrinter : ExprVisitor { return expr.accept(this) } + override fun visitCall(expr: Call): String { + return stack("call", expr.callee, *expr.arguments.toTypedArray()) + } + override fun visitAssign(expr: Assign): String { return stack("=", expr) } diff --git a/src/test/fr/celticinfo/lox/InterpreterTest.kt b/src/test/fr/celticinfo/lox/InterpreterTest.kt index 2924e83..d945373 100644 --- a/src/test/fr/celticinfo/lox/InterpreterTest.kt +++ b/src/test/fr/celticinfo/lox/InterpreterTest.kt @@ -1,6 +1,7 @@ package fr.celticinfo.lox import fr.celticinfo.loxext.RpnPrinter +import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.assertDoesNotThrow import java.io.ByteArrayOutputStream import java.io.PrintStream @@ -358,4 +359,32 @@ for (var b = 1; a < 10000; b = temp + b) { 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) + } + } + } \ No newline at end of file