From 3e9fca65935cb358b0ec4730e1d1fa0ae5ae69ee Mon Sep 17 00:00:00 2001 From: Olivier Abrivard Date: Tue, 17 Sep 2024 11:11:00 +0200 Subject: [PATCH] Add instances creation --- src/main/fr/celticinfo/lox/LoxClass.kt | 9 +++++- src/main/fr/celticinfo/lox/LoxInstance.kt | 5 +++ src/test/fr/celticinfo/lox/InterpreterTest.kt | 32 +++++++++++++++++++ src/test/fr/celticinfo/lox/ParserTest.kt | 16 ++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/main/fr/celticinfo/lox/LoxInstance.kt diff --git a/src/main/fr/celticinfo/lox/LoxClass.kt b/src/main/fr/celticinfo/lox/LoxClass.kt index 35fb8c7..ea44ad2 100644 --- a/src/main/fr/celticinfo/lox/LoxClass.kt +++ b/src/main/fr/celticinfo/lox/LoxClass.kt @@ -1,5 +1,12 @@ package fr.celticinfo.lox -class LoxClass(val name: String) { +class LoxClass(private val name: String) : LoxCallable { + override fun call(interpreter: Interpreter, arguments: List): Any? { + val instance = LoxInstance(this) + return instance + } + + override fun arity() = 0 + override fun toString() = name } \ No newline at end of file diff --git a/src/main/fr/celticinfo/lox/LoxInstance.kt b/src/main/fr/celticinfo/lox/LoxInstance.kt new file mode 100644 index 0000000..bf94d47 --- /dev/null +++ b/src/main/fr/celticinfo/lox/LoxInstance.kt @@ -0,0 +1,5 @@ +package fr.celticinfo.lox + +class LoxInstance(private val klass: LoxClass) { + override fun toString() = "$klass instance" +} \ No newline at end of file diff --git a/src/test/fr/celticinfo/lox/InterpreterTest.kt b/src/test/fr/celticinfo/lox/InterpreterTest.kt index 33bccf3..cddb1ad 100644 --- a/src/test/fr/celticinfo/lox/InterpreterTest.kt +++ b/src/test/fr/celticinfo/lox/InterpreterTest.kt @@ -805,4 +805,36 @@ var a = "global"; System.setOut(standardOut) } } + + @Test + fun `valid code with class declaration and instantiation`() { + val standardOut = System.out + val outputStreamCaptor = ByteArrayOutputStream() + + System.setOut(PrintStream(outputStreamCaptor)) + + try { + val code = """ + class DevonshireCream {} + var cream = DevonshireCream(); + print cream; + """.trimIndent() + val scanner = Scanner(code) + val tokens = scanner.scanTokens() + val parser = Parser(tokens) + val statements = parser.parse() + assertEquals(3, statements.size) + + val interpreter = Interpreter() + + val resolver = Resolver(interpreter) + resolver.resolve(statements) + + interpreter.interpret(statements) + val output = outputStreamCaptor.toString().trim() + assertEquals("DevonshireCream instance", output) + } finally { + System.setOut(standardOut) + } + } } diff --git a/src/test/fr/celticinfo/lox/ParserTest.kt b/src/test/fr/celticinfo/lox/ParserTest.kt index 756597a..3b0dcd1 100644 --- a/src/test/fr/celticinfo/lox/ParserTest.kt +++ b/src/test/fr/celticinfo/lox/ParserTest.kt @@ -254,4 +254,20 @@ class ParserTest { val stmt = statements[0] assertTrue(stmt is ClassStmt) } + + @Test + fun `valid code with class instantiation`() { + val code = """ + class DevonshireCream {} + var cream = DevonshireCream(); + print cream; + """.trimIndent() + val scanner = Scanner(code) + val tokens = scanner.scanTokens() + val parser = Parser(tokens) + val statements = parser.parse() + assertEquals(3,statements.size) + val stmt = statements[1] + assertTrue(stmt is Var) + } } \ No newline at end of file