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 {
|
open suspend fun getAt(scope: Scope, index: Obj): Obj {
|
||||||
|
if (hasNonRootIndexerMember("getAt")) {
|
||||||
|
return invokeInstanceMethod(scope, "getAt", Arguments(index))
|
||||||
|
}
|
||||||
if (index is ObjString) {
|
if (index is ObjString) {
|
||||||
return readField(scope, index.value).value
|
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()))
|
suspend fun getAt(scope: Scope, index: Int): Obj = getAt(scope, ObjInt(index.toLong()))
|
||||||
|
|
||||||
open suspend fun putAt(scope: Scope, index: Obj, newValue: Obj) {
|
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) {
|
if (index is ObjString) {
|
||||||
writeField(scope, index.value, newValue)
|
writeField(scope, index.value, newValue)
|
||||||
return
|
return
|
||||||
@ -662,6 +675,17 @@ open class Obj {
|
|||||||
scope.raiseNotImplemented("indexing")
|
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 {
|
open suspend fun callOn(scope: Scope): Obj {
|
||||||
scope.raiseNotImplemented()
|
scope.raiseNotImplemented()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,6 @@ import net.sergeych.lyng.Script
|
|||||||
import net.sergeych.lyng.ScriptError
|
import net.sergeych.lyng.ScriptError
|
||||||
import net.sergeych.lyng.eval
|
import net.sergeych.lyng.eval
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
@ -536,6 +535,24 @@ class TypesTest {
|
|||||||
""".trimIndent())
|
""".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 {
|
// @Test fun nonTrivialOperatorsTest() = runTest {
|
||||||
// val s = Script.newScope()
|
// val s = Script.newScope()
|
||||||
// s.eval("""
|
// s.eval("""
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user