"cache" bug found and fixed, causing some improvemts in lambda processing.
This commit is contained in:
1 parent
ce021e85f4
commit
ce0fc3650d
7 files changed
+137
-36
No files matched your search
@@ -628,35 +628,30 @@ class Compiler(
|
||||
|
||||
val body = parseBlock(skipLeadingBrace = true)
|
||||
|
||||
var closure: Scope? = null
|
||||
|
||||
val callStatement = statement {
|
||||
// and the source closure of the lambda which might have other thisObj.
|
||||
val context = this.applyClosure(closure!!)
|
||||
// Execute lambda body in a closure-aware context. Blocks inside the lambda
|
||||
// will create child scopes as usual, so re-declarations inside loops work.
|
||||
if (argsDeclaration == null) {
|
||||
// no args: automatic var 'it'
|
||||
val l = args.list
|
||||
val itValue: Obj = when (l.size) {
|
||||
// no args: it == void
|
||||
0 -> ObjVoid
|
||||
// one args: it is this arg
|
||||
1 -> l[0]
|
||||
// more args: it is a list of args
|
||||
else -> ObjList(l.toMutableList())
|
||||
return ValueFnRef { closureScope ->
|
||||
statement {
|
||||
// and the source closure of the lambda which might have other thisObj.
|
||||
val context = this.applyClosure(closureScope)
|
||||
// Execute lambda body in a closure-aware context. Blocks inside the lambda
|
||||
// will create child scopes as usual, so re-declarations inside loops work.
|
||||
if (argsDeclaration == null) {
|
||||
// no args: automatic var 'it'
|
||||
val l = args.list
|
||||
val itValue: Obj = when (l.size) {
|
||||
// no args: it == void
|
||||
0 -> ObjVoid
|
||||
// one args: it is this arg
|
||||
1 -> l[0]
|
||||
// more args: it is a list of args
|
||||
else -> ObjList(l.toMutableList())
|
||||
}
|
||||
context.addItem("it", false, itValue, recordType = ObjRecord.Type.Argument)
|
||||
} else {
|
||||
// assign vars as declared the standard way
|
||||
argsDeclaration.assignToContext(context, defaultAccessType = AccessType.Val)
|
||||
}
|
||||
context.addItem("it", false, itValue, recordType = ObjRecord.Type.Argument)
|
||||
} else {
|
||||
// assign vars as declared the standard way
|
||||
argsDeclaration.assignToContext(context, defaultAccessType = AccessType.Val)
|
||||
}
|
||||
body.execute(context)
|
||||
}
|
||||
|
||||
return ValueFnRef { x ->
|
||||
closure = x
|
||||
callStatement.asReadonly
|
||||
body.execute(context)
|
||||
}.asReadonly
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2025 Sergey S. Chernov real.sergeych@gmail.com
|
||||
* Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -271,7 +271,7 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
|
||||
|
||||
protected val comparableVars: Map<String, ObjRecord> by lazy {
|
||||
instanceScope.objects.filter {
|
||||
it.value.type.comparable
|
||||
it.value.type.comparable && (it.value.type != ObjRecord.Type.Field || it.value.isMutable)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2025 Sergey S. Chernov real.sergeych@gmail.com
|
||||
* Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ package net.sergeych.lyng
|
||||
|
||||
import net.sergeych.lyng.obj.Obj
|
||||
import net.sergeych.lyng.obj.ObjClass
|
||||
import net.sergeych.lyng.obj.ObjNull
|
||||
import net.sergeych.lyng.obj.ObjVoid
|
||||
|
||||
fun String.toSource(name: String = "eval"): Source = Source(name, this)
|
||||
@@ -46,9 +45,8 @@ abstract class Statement(
|
||||
abstract suspend fun execute(scope: Scope): Obj
|
||||
|
||||
override suspend fun compareTo(scope: Scope, other: Obj): Int {
|
||||
if( other == ObjNull || other == ObjVoid ) return 1
|
||||
if( other === this ) return 0
|
||||
return -1
|
||||
return -3
|
||||
}
|
||||
|
||||
override suspend fun callOn(scope: Scope): Obj {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2025 Sergey S. Chernov real.sergeych@gmail.com
|
||||
* Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -396,4 +396,26 @@ class OOTest {
|
||||
assertThrows { "answer is 42".totalDigits }
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCacheInClass() = runTest {
|
||||
eval("""
|
||||
class T(salt) {
|
||||
private var c
|
||||
|
||||
init {
|
||||
println("create cached with "+salt)
|
||||
c = cached { salt + "." }
|
||||
}
|
||||
|
||||
fun getResult() = c()
|
||||
}
|
||||
|
||||
val t1 = T("foo")
|
||||
val t2 = T("bar")
|
||||
assertEquals("bar.", t2.getResult())
|
||||
assertEquals("foo.", t1.getResult())
|
||||
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user