Support extensions on singleton objects

This commit is contained in:
sergeych committed 2026-04-06 19:24:28 +03:00
1 parent 671583638b
commit 35628c8453
5 files changed
+56 -9

No files matched your search

@@ -85,8 +85,7 @@ internal suspend fun executeFunctionDecl(
}
if (spec.extTypeName != null) {
val type = scope[spec.extTypeName]?.value ?: scope.raiseSymbolNotFound("class ${spec.extTypeName} not found")
if (type !is ObjClass) scope.raiseClassCastError("${spec.extTypeName} is not the class instance")
val type = scope.resolveExtensionReceiverClass(spec.extTypeName)
scope.addExtension(
type,
spec.name,
@@ -167,8 +166,7 @@ internal suspend fun executeFunctionDecl(
val compiledFnBody = annotatedFnBody
spec.extTypeName?.let { typeName ->
val type = scope[typeName]?.value ?: scope.raiseSymbolNotFound("class $typeName not found")
if (type !is ObjClass) scope.raiseClassCastError("$typeName is not the class instance")
val type = scope.resolveExtensionReceiverClass(typeName)
if (spec.isStatic) {
type.createClassField(
spec.name,
@@ -1004,4 +1004,13 @@ open class Scope(
return rec.value as? net.sergeych.lyng.obj.ObjClass
?: raiseClassCastError("Expected class $name, got ${rec.value.objClass.className}")
}
internal fun resolveExtensionReceiverClass(name: String): net.sergeych.lyng.obj.ObjClass {
val value = get(name)?.value ?: raiseSymbolNotFound("class $name not found")
return when (value) {
is net.sergeych.lyng.obj.ObjClass -> value
is net.sergeych.lyng.obj.ObjInstance -> value.objClass
else -> raiseClassCastError("$name is not the class instance")
}
}
}
@@ -3094,11 +3094,7 @@ class CmdDeclExtProperty(internal val constId: Int, internal val slot: Int) : Cm
override suspend fun perform(frame: CmdFrame) {
val decl = frame.fn.constants[constId] as? BytecodeConst.ExtensionPropertyDecl
?: error("DECL_EXT_PROPERTY expects ExtensionPropertyDecl at $constId")
val type = frame.ensureScope()[decl.extTypeName]?.value
?: frame.ensureScope().raiseSymbolNotFound("class ${decl.extTypeName} not found")
if (type !is ObjClass) {
frame.ensureScope().raiseClassCastError("${decl.extTypeName} is not the class instance")
}
val type = frame.ensureScope().resolveExtensionReceiverClass(decl.extTypeName)
frame.ensureScope().addExtension(
type,
decl.property.name,