fix #37 AppliedContext optimization
This commit is contained in:
		
							parent
							
								
									2d4c4d345d
								
							
						
					
					
						commit
						d969d6d572
					
				@ -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]
 | 
			
		||||
}
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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 <reified T : Obj> thisAs(): T = (thisObj as? T)
 | 
			
		||||
        ?: raiseClassCastError("Cannot cast ${thisObj.objClass.className} to ${T::class.simpleName}")
 | 
			
		||||
 | 
			
		||||
    internal var appliedContext: Context? = null
 | 
			
		||||
    internal val objects = mutableMapOf<String, ObjRecord>()
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,3 @@
 | 
			
		||||
package io.github.kotlin.fibonacci
 | 
			
		||||
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import net.sergeych.lyng.*
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								lynglib/src/commonTest/kotlin/TypesTest.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lynglib/src/commonTest/kotlin/TypesTest.kt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
import kotlinx.coroutines.test.runTest
 | 
			
		||||
import kotlin.test.Test
 | 
			
		||||
 | 
			
		||||
class TypesTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testTypeCollection1() = runTest {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user