Move qualified identifier resolution to Scope as resolveQualifiedIdentifier, replace inline logic in LynonDecoder.

This commit is contained in:
sergeych committed 2025-12-14 00:20:43 +01:00
1 parent 5a8881bfd5
commit 5d8fdce637
2 files changed
+23 -18

No files matched your search

@@ -17,9 +17,10 @@
package net.sergeych.lynon
import net.sergeych.lyng.Pos
import net.sergeych.lyng.Scope
import net.sergeych.lyng.obj.*
import net.sergeych.lyng.obj.Obj
import net.sergeych.lyng.obj.ObjClass
import net.sergeych.lyng.obj.ObjString
open class LynonDecoder(val bin: BitInput, val settings: LynonSettings = LynonSettings.default) {
@@ -82,28 +83,15 @@ open class LynonDecoder(val bin: BitInput, val settings: LynonSettings = LynonSe
scope.raiseClassCastError("Expected obj class but got ${it::class.simpleName}")
it
} ?: run {
// Precisely mimic what `scope.eval(className.value)` would compile and execute for
// a simple qualified name: LocalVarRef(head) followed by chained FieldRef segments.
val evaluated = evaluateQualifiedNameAsCompiled(scope, className.value)
// Use Scope API that mirrors compiler-emitted ObjRef chain for qualified identifiers
val evaluated = scope.resolveQualifiedIdentifier(className.value)
if (evaluated !is ObjClass)
scope.raiseClassCastError("Expected obj class but got ${evaluated::class.simpleName}")
evaluated
}
}
// Build and execute the exact ObjRef chain that the compiler would emit for an identifier
// with optional dotted selectors, e.g., "A.B.C" -> LocalVarRef("A") -> FieldRef(..., "B") -> FieldRef(..., "C")
private suspend fun evaluateQualifiedNameAsCompiled(scope: Scope, name: String): Obj {
val trimmed = name.trim()
if (trimmed.isEmpty()) scope.raiseSymbolNotFound("empty identifier")
val parts = trimmed.split('.')
// Use built-in position; eval() would carry a Source position, which does not affect resolution semantics here
var ref: ObjRef = LocalVarRef(parts[0], Pos.builtIn)
for (i in 1 until parts.size) {
ref = FieldRef(ref, parts[i], false)
}
return ref.evalValue(scope)
}
// helper moved to Scope as resolveQualifiedIdentifier
suspend fun decodeAnyList(scope: Scope, fixedSize: Int? = null): MutableList<Obj> {
return if (bin.getBit() == 1) {