diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/AppliedContext.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/AppliedContext.kt new file mode 100644 index 0000000..ac829c9 --- /dev/null +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/AppliedContext.kt @@ -0,0 +1,17 @@ +package net.sergeych.lyng + +/** + * Special version of the [Context] used to `apply` new this object to + * _parent context property. + * + * @param _parent context to apply to + * @param args arguments for the new context + * @param appliedContext the new context to apply, it will have lower priority except for `this` which + * will be reset by appliedContext's `this`. + */ +class AppliedContext(_parent: Context, args: Arguments, val appliedContext: Context) + : Context(_parent, args, appliedContext.pos, appliedContext.thisObj) { + override fun get(name: String): ObjRecord? = + if (name == "this") thisObj.asReadonly + else super.get(name) ?: appliedContext[name] +} \ No newline at end of file diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt index 9c212c5..bd71577 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Compiler.kt @@ -387,14 +387,14 @@ class Compiler( val argsDeclaration = parseArgsDeclaration(cc) if (argsDeclaration != null && argsDeclaration.endTokenType != Token.Type.ARROW) throw ScriptError(startPos, "lambda must have either valid arguments declaration with '->' or no arguments") - val pos = cc.currentPos() + val body = parseBlock(cc, skipLeadingBrace = true) var closure: Context? = null val callStatement = statement { // and the source closure of the lambda which might have other thisObj. - val context = closure!!.copy(pos, args).applyContext(this) + val context = AppliedContext(closure!!,args,this) if (argsDeclaration == null) { // no args: automatic var 'it' val l = args.list diff --git a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Context.kt b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Context.kt index 5a0eeba..ec67348 100644 --- a/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Context.kt +++ b/lynglib/src/commonMain/kotlin/net/sergeych/lyng/Context.kt @@ -1,6 +1,6 @@ package net.sergeych.lyng -class Context( +open class Context( val parent: Context?, val args: Arguments = Arguments.EMPTY, var pos: Pos = Pos.builtIn, @@ -13,15 +13,6 @@ class Context( ) : this(Script.defaultContext, args, pos) - /** - * Making this context priority one - */ - fun applyContext(other: Context): Context { - if (other.thisObj != ObjVoid) thisObj = other.thisObj - appliedContext = other - return this - } - fun raiseNotImplemented(what: String = "operation"): Nothing = raiseError("$what is not implemented") @Suppress("unused") @@ -74,15 +65,13 @@ class Context( inline fun thisAs(): T = (thisObj as? T) ?: raiseClassCastError("Cannot cast ${thisObj.objClass.className} to ${T::class.simpleName}") - internal var appliedContext: Context? = null internal val objects = mutableMapOf() - operator fun get(name: String): ObjRecord? = + open operator fun get(name: String): ObjRecord? = if (name == "this") thisObj.asReadonly else { objects[name] ?: parent?.get(name) - ?: appliedContext?.get(name) } fun copy(pos: Pos, args: Arguments = Arguments.EMPTY, newThisObj: Obj? = null): Context = @@ -137,5 +126,4 @@ class Context( fun containsLocal(name: String): Boolean = name in objects - } diff --git a/lynglib/src/commonTest/kotlin/ScriptTest.kt b/lynglib/src/commonTest/kotlin/ScriptTest.kt index 74a31cf..02d334b 100644 --- a/lynglib/src/commonTest/kotlin/ScriptTest.kt +++ b/lynglib/src/commonTest/kotlin/ScriptTest.kt @@ -1,4 +1,3 @@ -package io.github.kotlin.fibonacci import kotlinx.coroutines.test.runTest import net.sergeych.lyng.* diff --git a/lynglib/src/commonTest/kotlin/TypesTest.kt b/lynglib/src/commonTest/kotlin/TypesTest.kt new file mode 100644 index 0000000..f0140bc --- /dev/null +++ b/lynglib/src/commonTest/kotlin/TypesTest.kt @@ -0,0 +1,10 @@ +import kotlinx.coroutines.test.runTest +import kotlin.test.Test + +class TypesTest { + + @Test + fun testTypeCollection1() = runTest { + + } +} \ No newline at end of file