indexer fix
This commit is contained in:
parent
8a32ffe655
commit
c54d947f1c
@ -646,6 +646,9 @@ open class Obj {
|
||||
}
|
||||
|
||||
open suspend fun getAt(scope: Scope, index: Obj): Obj {
|
||||
if (hasNonRootIndexerMember("getAt")) {
|
||||
return invokeInstanceMethod(scope, "getAt", Arguments(index))
|
||||
}
|
||||
if (index is ObjString) {
|
||||
return readField(scope, index.value).value
|
||||
}
|
||||
@ -655,6 +658,16 @@ open class Obj {
|
||||
suspend fun getAt(scope: Scope, index: Int): Obj = getAt(scope, ObjInt(index.toLong()))
|
||||
|
||||
open suspend fun putAt(scope: Scope, index: Obj, newValue: Obj) {
|
||||
when {
|
||||
hasNonRootIndexerMember("putAt") -> {
|
||||
invokeInstanceMethod(scope, "putAt", Arguments(index, newValue))
|
||||
return
|
||||
}
|
||||
hasNonRootIndexerMember("setAt") -> {
|
||||
invokeInstanceMethod(scope, "setAt", Arguments(index, newValue))
|
||||
return
|
||||
}
|
||||
}
|
||||
if (index is ObjString) {
|
||||
writeField(scope, index.value, newValue)
|
||||
return
|
||||
@ -662,6 +675,17 @@ open class Obj {
|
||||
scope.raiseNotImplemented("indexing")
|
||||
}
|
||||
|
||||
private fun hasNonRootIndexerMember(name: String): Boolean {
|
||||
for (cls in objClass.mro) {
|
||||
if (cls.className == "Obj") break
|
||||
val rec = cls.members[name] ?: cls.classScope?.objects?.get(name)
|
||||
if (rec != null && !rec.isAbstract && rec.type != ObjRecord.Type.Delegated) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
open suspend fun callOn(scope: Scope): Obj {
|
||||
scope.raiseNotImplemented()
|
||||
}
|
||||
|
||||
@ -20,7 +20,6 @@ import net.sergeych.lyng.Script
|
||||
import net.sergeych.lyng.ScriptError
|
||||
import net.sergeych.lyng.eval
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@ -536,6 +535,24 @@ class TypesTest {
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
@Test fun testIndexer() = runTest {
|
||||
eval("""
|
||||
class Greeter {
|
||||
override fun getAt(name) = "Hello, %s!"(name)
|
||||
}
|
||||
assertEquals("Hello, Bob!",Greeter()["Bob"])
|
||||
val g = Greeter()
|
||||
assertEquals("Hello, Bob!",g["Bob"])
|
||||
|
||||
// it should work with objects too:
|
||||
object Polite {
|
||||
override fun getAt(name) = "How do you do, %s?"(name)
|
||||
}
|
||||
|
||||
assertEquals("How do you do, Bob?",Polite["Bob"])
|
||||
|
||||
""".trimIndent())
|
||||
}
|
||||
// @Test fun nonTrivialOperatorsTest() = runTest {
|
||||
// val s = Script.newScope()
|
||||
// s.eval("""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user