diff --git a/library/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt b/library/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt index 163987d..0cca6d9 100644 --- a/library/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt +++ b/library/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt @@ -402,7 +402,9 @@ class Compiler( } enum class AccessType(val isMutable: Boolean) { - Val(false), Var(true), Initialization(false) + Val(false), Var(true), + @Suppress("unused") + Initialization(false) } enum class Visibility { @@ -728,8 +730,8 @@ class Compiler( val className = nameToken.value lateinit var classContext: Context - val defaultAccess = if (isStruct) AccessType.Var else AccessType.Initialization - val defaultVisibility = Visibility.Public + @Suppress("UNUSED_VARIABLE") val defaultAccess = if (isStruct) AccessType.Var else AccessType.Initialization + @Suppress("UNUSED_VARIABLE") val defaultVisibility = Visibility.Public // create instance constructor // create custom objClass with all fields and instance constructor @@ -741,14 +743,11 @@ class Compiler( // the context now is a "class creation context", we must use its args to initialize // fields. Note that 'this' is already set by class - constructorArgsDeclaration?.let { cad -> - cad.assignToContext(this) - // note that accessors are created in ObjClass instance, not during instance - // initialization (not here) - } + constructorArgsDeclaration?.assignToContext(this) bodyInit?.execute(this) // export public for( (name,record) in objects ) { + println("-- $name $record") when(record.visibility) { Visibility.Public -> { thisObj.publicFields += name diff --git a/library/src/commonMain/kotlin/net/sergeych/lyng/Obj.kt b/library/src/commonMain/kotlin/net/sergeych/lyng/Obj.kt index 08a3851..a32a02b 100644 --- a/library/src/commonMain/kotlin/net/sergeych/lyng/Obj.kt +++ b/library/src/commonMain/kotlin/net/sergeych/lyng/Obj.kt @@ -69,7 +69,7 @@ open class Obj { args: Arguments = Arguments.EMPTY ): T = invokeInstanceMethod(context, name, args) as T - suspend fun invokeInstanceMethod( + open suspend fun invokeInstanceMethod( context: Context, name: String, args: Arguments = Arguments.EMPTY diff --git a/library/src/commonMain/kotlin/net/sergeych/lyng/ObjClass.kt b/library/src/commonMain/kotlin/net/sergeych/lyng/ObjClass.kt index 311c172..f079535 100644 --- a/library/src/commonMain/kotlin/net/sergeych/lyng/ObjClass.kt +++ b/library/src/commonMain/kotlin/net/sergeych/lyng/ObjClass.kt @@ -151,25 +151,3 @@ val ObjArray by lazy { } } -class ObjInstance(override val objClass: ObjClass) : Obj() { - - internal val publicFields = mutableSetOf() - internal val protectedFields = mutableSetOf() - - internal lateinit var instanceContext: Context - - override suspend fun readField(context: Context, name: String): ObjRecord { - return if( name in publicFields ) instanceContext[name]!! - else super.readField(context, name) - } - - override suspend fun writeField(context: Context, name: String, newValue: Obj) { - if( name in publicFields ) { - val f = instanceContext[name]!! - if( !f.isMutable ) ObjIllegalAssignmentError(context, "can't reassign val $name").raise() - if( f.value.assign(context, newValue) == null) - f.value = newValue - } - else super.writeField(context, name, newValue) - } -} diff --git a/library/src/commonMain/kotlin/net/sergeych/lyng/ObjInstance.kt b/library/src/commonMain/kotlin/net/sergeych/lyng/ObjInstance.kt new file mode 100644 index 0000000..6b59711 --- /dev/null +++ b/library/src/commonMain/kotlin/net/sergeych/lyng/ObjInstance.kt @@ -0,0 +1,29 @@ +package net.sergeych.lyng + +class ObjInstance(override val objClass: ObjClass) : Obj() { + + internal val publicFields = mutableSetOf() + internal val protectedFields = mutableSetOf() + + internal lateinit var instanceContext: Context + + override suspend fun readField(context: Context, name: String): ObjRecord { + return if( name in publicFields ) instanceContext[name]!! + else super.readField(context, name) + } + + override suspend fun writeField(context: Context, name: String, newValue: Obj) { + if( name in publicFields ) { + val f = instanceContext[name]!! + if( !f.isMutable ) ObjIllegalAssignmentError(context, "can't reassign val $name").raise() + if( f.value.assign(context, newValue) == null) + f.value = newValue + } + else super.writeField(context, name, newValue) + } + + override suspend fun invokeInstanceMethod(context: Context, name: String, args: Arguments): Obj { + if( name in publicFields ) return instanceContext[name]!!.value.invoke(context, this, args) + return super.invokeInstanceMethod(context, name, args) + } +} \ No newline at end of file diff --git a/library/src/commonTest/kotlin/ScriptTest.kt b/library/src/commonTest/kotlin/ScriptTest.kt index 24ca0d8..689a3ac 100644 --- a/library/src/commonTest/kotlin/ScriptTest.kt +++ b/library/src/commonTest/kotlin/ScriptTest.kt @@ -1435,4 +1435,22 @@ class ScriptTest { assert( p.length == 5 ) """.trimIndent()) } + + @Test + fun testStructBodyFun() = runTest { + val c = Context() + c.eval(""" + struct Point(x,y) { + fun length() { + sqrt(x*x+y*y) + } + var foo = "zero" + } + val p = Point(3,4) + assertEquals(5, p.length()) + p.y = 10 + println(p.length()) + assertEquals(sqrt(109), p.length()) + """.trimIndent()) + } } \ No newline at end of file