Scope.copy renamed to createChild for clarity; fixed error with Exception self serializing.
This commit is contained in:
parent
c854b06683
commit
7e289382ed
@ -21,7 +21,7 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
group = "net.sergeych"
|
group = "net.sergeych"
|
||||||
version = "0.9.2-SNAPSHOT"
|
version = "0.9.3-SNAPSHOT"
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@ -796,7 +796,7 @@ class Compiler(
|
|||||||
val v = left.getter(context)
|
val v = left.getter(context)
|
||||||
if (v.value == ObjNull && isOptional) return@Accessor v.value.asReadonly
|
if (v.value == ObjNull && isOptional) return@Accessor v.value.asReadonly
|
||||||
v.value.callOn(
|
v.value.callOn(
|
||||||
context.copy(
|
context.createChildScope(
|
||||||
context.pos,
|
context.pos,
|
||||||
args.toArguments(context, detectedBlockArgument)
|
args.toArguments(context, detectedBlockArgument)
|
||||||
// Arguments(
|
// Arguments(
|
||||||
@ -902,7 +902,7 @@ class Compiler(
|
|||||||
val args = extras?.let { required + it } ?: required
|
val args = extras?.let { required + it } ?: required
|
||||||
val fn = scope.get(t.value)?.value ?: scope.raiseSymbolNotFound("annotation not found: ${t.value}")
|
val fn = scope.get(t.value)?.value ?: scope.raiseSymbolNotFound("annotation not found: ${t.value}")
|
||||||
if (fn !is Statement) scope.raiseIllegalArgument("annotation must be callable, got ${fn.objClass}")
|
if (fn !is Statement) scope.raiseIllegalArgument("annotation must be callable, got ${fn.objClass}")
|
||||||
(fn.execute(scope.copy(Arguments(args))) as? Statement)
|
(fn.execute(scope.createChildScope(Arguments(args))) as? Statement)
|
||||||
?: scope.raiseClassCastError("function annotation must return callable")
|
?: scope.raiseClassCastError("function annotation must return callable")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1197,7 +1197,7 @@ class Compiler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (exceptionObject != null) {
|
if (exceptionObject != null) {
|
||||||
val catchContext = this.copy(pos = cdata.catchVar.pos)
|
val catchContext = this.createChildScope(pos = cdata.catchVar.pos)
|
||||||
catchContext.addItem(cdata.catchVar.value, false, objException)
|
catchContext.addItem(cdata.catchVar.value, false, objException)
|
||||||
result = cdata.block.execute(catchContext)
|
result = cdata.block.execute(catchContext)
|
||||||
isCaught = true
|
isCaught = true
|
||||||
@ -1313,7 +1313,7 @@ class Compiler(
|
|||||||
// accessors, constructor registration, etc.
|
// accessors, constructor registration, etc.
|
||||||
addItem(className, false, newClass)
|
addItem(className, false, newClass)
|
||||||
if (initScope.isNotEmpty()) {
|
if (initScope.isNotEmpty()) {
|
||||||
val classScope = copy(newThisObj = newClass)
|
val classScope = createChildScope(newThisObj = newClass)
|
||||||
newClass.classScope = classScope
|
newClass.classScope = classScope
|
||||||
for (s in initScope)
|
for (s in initScope)
|
||||||
s.execute(classScope)
|
s.execute(classScope)
|
||||||
@ -1367,7 +1367,7 @@ class Compiler(
|
|||||||
|
|
||||||
|
|
||||||
return statement(body.pos) { cxt ->
|
return statement(body.pos) { cxt ->
|
||||||
val forContext = cxt.copy(start)
|
val forContext = cxt.createChildScope(start)
|
||||||
|
|
||||||
// loop var: StoredObject
|
// loop var: StoredObject
|
||||||
val loopSO = forContext.addItem(tVar.value, true, ObjNull)
|
val loopSO = forContext.addItem(tVar.value, true, ObjNull)
|
||||||
@ -1536,7 +1536,7 @@ class Compiler(
|
|||||||
var result: Obj = ObjVoid
|
var result: Obj = ObjVoid
|
||||||
lateinit var doScope: Scope
|
lateinit var doScope: Scope
|
||||||
do {
|
do {
|
||||||
doScope = it.copy().apply { skipScopeCreation = true }
|
doScope = it.createChildScope().apply { skipScopeCreation = true }
|
||||||
try {
|
try {
|
||||||
result = body.execute(doScope)
|
result = body.execute(doScope)
|
||||||
} catch (e: LoopBreakContinueException) {
|
} catch (e: LoopBreakContinueException) {
|
||||||
@ -1816,7 +1816,7 @@ class Compiler(
|
|||||||
val block = parseScript()
|
val block = parseScript()
|
||||||
return statement(startPos) {
|
return statement(startPos) {
|
||||||
// block run on inner context:
|
// block run on inner context:
|
||||||
block.execute(if (it.skipScopeCreation) it else it.copy(startPos))
|
block.execute(if (it.skipScopeCreation) it else it.createChildScope(startPos))
|
||||||
}.also {
|
}.also {
|
||||||
val t1 = cc.next()
|
val t1 = cc.next()
|
||||||
if (t1.type != Token.Type.RBRACE)
|
if (t1.type != Token.Type.RBRACE)
|
||||||
|
|||||||
@ -138,13 +138,27 @@ open class Scope(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun copy(pos: Pos, args: Arguments = Arguments.EMPTY, newThisObj: Obj? = null): Scope =
|
/**
|
||||||
|
* Creates a new child scope using the provided arguments and optional `thisObj`.
|
||||||
|
*/
|
||||||
|
fun createChildScope(pos: Pos, args: Arguments = Arguments.EMPTY, newThisObj: Obj? = null): Scope =
|
||||||
Scope(this, args, pos, newThisObj ?: thisObj)
|
Scope(this, args, pos, newThisObj ?: thisObj)
|
||||||
|
|
||||||
fun copy(args: Arguments = Arguments.EMPTY, newThisObj: Obj? = null): Scope =
|
/**
|
||||||
|
* Creates a new child scope using the provided arguments and optional `thisObj`.
|
||||||
|
* The child scope inherits the current scope's properties such as position and the existing `thisObj` if no new `thisObj` is provided.
|
||||||
|
*
|
||||||
|
* @param args The arguments to associate with the child scope. Defaults to [Arguments.EMPTY].
|
||||||
|
* @param newThisObj The new `thisObj` to associate with the child scope. Defaults to the current scope's `thisObj` if not provided.
|
||||||
|
* @return A new instance of [Scope] initialized with the specified arguments and `thisObj`.
|
||||||
|
*/
|
||||||
|
fun createChildScope(args: Arguments = Arguments.EMPTY, newThisObj: Obj? = null): Scope =
|
||||||
Scope(this, args, pos, newThisObj ?: thisObj)
|
Scope(this, args, pos, newThisObj ?: thisObj)
|
||||||
|
|
||||||
fun copy() = Scope(this, args, pos, thisObj)
|
/**
|
||||||
|
* @return A child scope with the same arguments, position and [thisObj]
|
||||||
|
*/
|
||||||
|
fun createChildScope() = Scope(this, args, pos, thisObj)
|
||||||
|
|
||||||
fun addItem(
|
fun addItem(
|
||||||
name: String,
|
name: String,
|
||||||
@ -240,8 +254,6 @@ open class Scope(
|
|||||||
p = p.parent
|
p = p.parent
|
||||||
}
|
}
|
||||||
println("--------------------")
|
println("--------------------")
|
||||||
ObjVoid
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun applyClosure(closure: Scope): Scope = ClosureScope(this, closure)
|
open fun applyClosure(closure: Scope): Scope = ClosureScope(this, closure)
|
||||||
|
|||||||
@ -17,15 +17,12 @@
|
|||||||
|
|
||||||
package net.sergeych.lyng.obj
|
package net.sergeych.lyng.obj
|
||||||
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import net.sergeych.lyng.*
|
import net.sergeych.lyng.*
|
||||||
import net.sergeych.lynon.LynonDecoder
|
import net.sergeych.lynon.LynonDecoder
|
||||||
import net.sergeych.lynon.LynonEncoder
|
import net.sergeych.lynon.LynonEncoder
|
||||||
import net.sergeych.lynon.LynonType
|
import net.sergeych.lynon.LynonType
|
||||||
import net.sergeych.synctools.ProtectedOp
|
|
||||||
|
|
||||||
open class Obj {
|
open class Obj {
|
||||||
|
|
||||||
@ -39,12 +36,12 @@ open class Obj {
|
|||||||
|
|
||||||
var isFrozen: Boolean = false
|
var isFrozen: Boolean = false
|
||||||
|
|
||||||
private val monitor = Mutex()
|
// private val monitor = Mutex()
|
||||||
|
|
||||||
// private val memberMutex = Mutex()
|
// private val memberMutex = Mutex()
|
||||||
internal var parentInstances: MutableList<Obj> = mutableListOf()
|
// internal var parentInstances: MutableList<Obj> = mutableListOf()
|
||||||
|
|
||||||
private val opInstances = ProtectedOp()
|
// private val opInstances = ProtectedOp()
|
||||||
|
|
||||||
open suspend fun inspect(scope: Scope): String = toString(scope).value
|
open suspend fun inspect(scope: Scope): String = toString(scope).value
|
||||||
|
|
||||||
@ -100,7 +97,7 @@ open class Obj {
|
|||||||
// note that getInstanceMember traverses the hierarchy
|
// note that getInstanceMember traverses the hierarchy
|
||||||
objClass.getInstanceMember(scope.pos, name).value
|
objClass.getInstanceMember(scope.pos, name).value
|
||||||
|
|
||||||
fun getMemberOrNull(name: String): Obj? = objClass.getInstanceMemberOrNull(name)?.value
|
// fun getMemberOrNull(name: String): Obj? = objClass.getInstanceMemberOrNull(name)?.value
|
||||||
|
|
||||||
// methods that to override
|
// methods that to override
|
||||||
|
|
||||||
@ -232,14 +229,14 @@ open class Obj {
|
|||||||
if (isFrozen) scope.raiseError("attempt to mutate frozen object")
|
if (isFrozen) scope.raiseError("attempt to mutate frozen object")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun <T> sync(block: () -> T): T = monitor.withLock { block() }
|
// suspend fun <T> sync(block: () -> T): T = monitor.withLock { block() }
|
||||||
|
|
||||||
open suspend fun readField(scope: Scope, name: String): ObjRecord {
|
open suspend fun readField(scope: Scope, name: String): ObjRecord {
|
||||||
// could be property or class field:
|
// could be property or class field:
|
||||||
val obj = objClass.getInstanceMemberOrNull(name) ?: scope.raiseError("no such field: $name")
|
val obj = objClass.getInstanceMemberOrNull(name) ?: scope.raiseError("no such field: $name")
|
||||||
return when (val value = obj.value) {
|
return when (val value = obj.value) {
|
||||||
is Statement -> {
|
is Statement -> {
|
||||||
ObjRecord(value.execute(scope.copy(scope.pos, newThisObj = this)), obj.isMutable)
|
ObjRecord(value.execute(scope.createChildScope(scope.pos, newThisObj = this)), obj.isMutable)
|
||||||
}
|
}
|
||||||
// could be writable property naturally
|
// could be writable property naturally
|
||||||
// null -> ObjNull.asReadonly
|
// null -> ObjNull.asReadonly
|
||||||
@ -268,11 +265,11 @@ open class Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun invoke(scope: Scope, thisObj: Obj, args: Arguments): Obj =
|
suspend fun invoke(scope: Scope, thisObj: Obj, args: Arguments): Obj =
|
||||||
callOn(scope.copy(scope.pos, args = args, newThisObj = thisObj))
|
callOn(scope.createChildScope(scope.pos, args = args, newThisObj = thisObj))
|
||||||
|
|
||||||
suspend fun invoke(scope: Scope, thisObj: Obj, vararg args: Obj): Obj =
|
suspend fun invoke(scope: Scope, thisObj: Obj, vararg args: Obj): Obj =
|
||||||
callOn(
|
callOn(
|
||||||
scope.copy(
|
scope.createChildScope(
|
||||||
scope.pos,
|
scope.pos,
|
||||||
args = Arguments(args.toList()),
|
args = Arguments(args.toList()),
|
||||||
newThisObj = thisObj
|
newThisObj = thisObj
|
||||||
@ -281,7 +278,7 @@ open class Obj {
|
|||||||
|
|
||||||
suspend fun invoke(scope: Scope, thisObj: Obj): Obj =
|
suspend fun invoke(scope: Scope, thisObj: Obj): Obj =
|
||||||
callOn(
|
callOn(
|
||||||
scope.copy(
|
scope.createChildScope(
|
||||||
scope.pos,
|
scope.pos,
|
||||||
args = Arguments.EMPTY,
|
args = Arguments.EMPTY,
|
||||||
newThisObj = thisObj
|
newThisObj = thisObj
|
||||||
@ -289,7 +286,7 @@ open class Obj {
|
|||||||
)
|
)
|
||||||
|
|
||||||
suspend fun invoke(scope: Scope, atPos: Pos, thisObj: Obj, args: Arguments): Obj =
|
suspend fun invoke(scope: Scope, atPos: Pos, thisObj: Obj, args: Arguments): Obj =
|
||||||
callOn(scope.copy(atPos, args = args, newThisObj = thisObj))
|
callOn(scope.createChildScope(atPos, args = args, newThisObj = thisObj))
|
||||||
|
|
||||||
|
|
||||||
val asReadonly: ObjRecord by lazy { ObjRecord(this, false) }
|
val asReadonly: ObjRecord by lazy { ObjRecord(this, false) }
|
||||||
@ -302,7 +299,7 @@ open class Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun autoInstanceScope(parent: Scope): Scope {
|
fun autoInstanceScope(parent: Scope): Scope {
|
||||||
val scope = parent.copy(newThisObj = this, args = parent.args)
|
val scope = parent.createChildScope(newThisObj = this, args = parent.args)
|
||||||
for (m in objClass.members) {
|
for (m in objClass.members) {
|
||||||
scope.objects[m.key] = m.value
|
scope.objects[m.key] = m.value
|
||||||
}
|
}
|
||||||
@ -335,7 +332,7 @@ open class Obj {
|
|||||||
}
|
}
|
||||||
// utilities
|
// utilities
|
||||||
addFn("let") {
|
addFn("let") {
|
||||||
args.firstAndOnly().callOn(copy(Arguments(thisObj)))
|
args.firstAndOnly().callOn(createChildScope(Arguments(thisObj)))
|
||||||
}
|
}
|
||||||
addFn("apply") {
|
addFn("apply") {
|
||||||
val body = args.firstAndOnly()
|
val body = args.firstAndOnly()
|
||||||
@ -347,7 +344,7 @@ open class Obj {
|
|||||||
thisObj
|
thisObj
|
||||||
}
|
}
|
||||||
addFn("also") {
|
addFn("also") {
|
||||||
args.firstAndOnly().callOn(copy(Arguments(thisObj)))
|
args.firstAndOnly().callOn(createChildScope(Arguments(thisObj)))
|
||||||
thisObj
|
thisObj
|
||||||
}
|
}
|
||||||
addFn("run") {
|
addFn("run") {
|
||||||
|
|||||||
@ -61,7 +61,7 @@ open class ObjClass(
|
|||||||
|
|
||||||
override suspend fun callOn(scope: Scope): Obj {
|
override suspend fun callOn(scope: Scope): Obj {
|
||||||
val instance = ObjInstance(this)
|
val instance = ObjInstance(this)
|
||||||
instance.instanceScope = scope.copy(newThisObj = instance, args = scope.args)
|
instance.instanceScope = scope.createChildScope(newThisObj = instance, args = scope.args)
|
||||||
if (instanceConstructor != null) {
|
if (instanceConstructor != null) {
|
||||||
instanceConstructor!!.execute(instance.instanceScope)
|
instanceConstructor!!.execute(instance.instanceScope)
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ open class ObjClass(
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun callWithArgs(scope: Scope, vararg plainArgs: Obj): Obj {
|
suspend fun callWithArgs(scope: Scope, vararg plainArgs: Obj): Obj {
|
||||||
return callOn(scope.copy(Arguments(*plainArgs)))
|
return callOn(scope.createChildScope(Arguments(*plainArgs)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -53,7 +53,7 @@ class ObjDynamic : Obj() {
|
|||||||
internal var writeCallback: Statement? = null
|
internal var writeCallback: Statement? = null
|
||||||
|
|
||||||
override suspend fun readField(scope: Scope, name: String): ObjRecord {
|
override suspend fun readField(scope: Scope, name: String): ObjRecord {
|
||||||
return readCallback?.execute(scope.copy(Arguments(ObjString(name))))?.let {
|
return readCallback?.execute(scope.createChildScope(Arguments(ObjString(name))))?.let {
|
||||||
if (writeCallback != null)
|
if (writeCallback != null)
|
||||||
it.asMutable
|
it.asMutable
|
||||||
else
|
else
|
||||||
@ -63,17 +63,17 @@ class ObjDynamic : Obj() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun writeField(scope: Scope, name: String, newValue: Obj) {
|
override suspend fun writeField(scope: Scope, name: String, newValue: Obj) {
|
||||||
writeCallback?.execute(scope.copy(Arguments(ObjString(name), newValue)))
|
writeCallback?.execute(scope.createChildScope(Arguments(ObjString(name), newValue)))
|
||||||
?: super.writeField(scope, name, newValue)
|
?: super.writeField(scope, name, newValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getAt(scope: Scope, index: Obj): Obj {
|
override suspend fun getAt(scope: Scope, index: Obj): Obj {
|
||||||
return readCallback?.execute( scope.copy(Arguments(index)))
|
return readCallback?.execute( scope.createChildScope(Arguments(index)))
|
||||||
?: super.getAt(scope, index)
|
?: super.getAt(scope, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun putAt(scope: Scope, index: Obj, newValue: Obj) {
|
override suspend fun putAt(scope: Scope, index: Obj, newValue: Obj) {
|
||||||
writeCallback?.execute(scope.copy(Arguments(index, newValue)))
|
writeCallback?.execute(scope.createChildScope(Arguments(index, newValue)))
|
||||||
?: super.putAt(scope, index, newValue)
|
?: super.putAt(scope, index, newValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ class ObjDynamic : Obj() {
|
|||||||
suspend fun create(scope: Scope, builder: Statement): ObjDynamic {
|
suspend fun create(scope: Scope, builder: Statement): ObjDynamic {
|
||||||
val delegate = ObjDynamic()
|
val delegate = ObjDynamic()
|
||||||
val context = ObjDynamicContext(delegate)
|
val context = ObjDynamicContext(delegate)
|
||||||
builder.execute(scope.copy(newThisObj = context))
|
builder.execute(scope.createChildScope(newThisObj = context))
|
||||||
return delegate
|
return delegate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,9 +28,9 @@ import net.sergeych.synctools.withLock
|
|||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* note on [getStackTrace]. If [useStackTrace] is not null, it is used instead. Otherwise, it is calculated
|
* Note on [getStackTrace]. If [useStackTrace] is not null, it is used instead. Otherwise, it is calculated
|
||||||
* from the current scope which is treated as exception scope. It is used to restore serialized
|
* from the current scope, which is treated as an exception scope. It is used to restore a serialized
|
||||||
* exception with stack trace; the scope of the de-serialized exception is not valid
|
* exception with stack trace; the scope of the deserialized exception is not valid
|
||||||
* for stack unwinding.
|
* for stack unwinding.
|
||||||
*/
|
*/
|
||||||
open class ObjException(
|
open class ObjException(
|
||||||
@ -127,7 +127,7 @@ open class ObjException(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val Root = ExceptionClass("Throwable").apply {
|
val Root = ExceptionClass("Exception").apply {
|
||||||
addConst("message", statement {
|
addConst("message", statement {
|
||||||
(thisObj as ObjException).message.toObj()
|
(thisObj as ObjException).message.toObj()
|
||||||
})
|
})
|
||||||
|
|||||||
@ -58,7 +58,7 @@ class ObjFlowBuilder(val output: SendChannel<Obj>) : Obj() {
|
|||||||
private fun createLyngFlowInput(scope: Scope, producer: Statement): ReceiveChannel<Obj> {
|
private fun createLyngFlowInput(scope: Scope, producer: Statement): ReceiveChannel<Obj> {
|
||||||
val channel = Channel<Obj>(Channel.RENDEZVOUS)
|
val channel = Channel<Obj>(Channel.RENDEZVOUS)
|
||||||
val builder = ObjFlowBuilder(channel)
|
val builder = ObjFlowBuilder(channel)
|
||||||
val builderScope = scope.copy(newThisObj = builder)
|
val builderScope = scope.createChildScope(newThisObj = builder)
|
||||||
globalLaunch {
|
globalLaunch {
|
||||||
try {
|
try {
|
||||||
producer.execute(builderScope)
|
producer.execute(builderScope)
|
||||||
|
|||||||
@ -32,7 +32,7 @@ class ObjInstanceClass(val name: String) : ObjClass(name) {
|
|||||||
val actualSize = constructorMeta?.params?.size ?: 0
|
val actualSize = constructorMeta?.params?.size ?: 0
|
||||||
if (args.size > actualSize)
|
if (args.size > actualSize)
|
||||||
scope.raiseIllegalArgument("constructor $name has only $actualSize but serialized version has ${args.size}")
|
scope.raiseIllegalArgument("constructor $name has only $actualSize but serialized version has ${args.size}")
|
||||||
val newScope = scope.copy(args = Arguments(args))
|
val newScope = scope.createChildScope(args = Arguments(args))
|
||||||
return (callOn(newScope) as ObjInstance).apply {
|
return (callOn(newScope) as ObjInstance).apply {
|
||||||
deserializeStateVars(scope, decoder)
|
deserializeStateVars(scope, decoder)
|
||||||
invokeInstanceMethod(scope, "onDeserialized") { ObjVoid }
|
invokeInstanceMethod(scope, "onDeserialized") { ObjVoid }
|
||||||
|
|||||||
@ -93,7 +93,7 @@ val ObjIterable by lazy {
|
|||||||
val fn = requiredArg<Statement>(0)
|
val fn = requiredArg<Statement>(0)
|
||||||
while (it.invokeInstanceMethod(this, "hasNext").toBool()) {
|
while (it.invokeInstanceMethod(this, "hasNext").toBool()) {
|
||||||
val x = it.invokeInstanceMethod(this, "next")
|
val x = it.invokeInstanceMethod(this, "next")
|
||||||
fn.execute(this.copy(Arguments(listOf(x))))
|
fn.execute(this.createChildScope(Arguments(listOf(x))))
|
||||||
}
|
}
|
||||||
ObjVoid
|
ObjVoid
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,7 +71,7 @@ abstract class ImportProvider(
|
|||||||
newModuleAt(pos).also {
|
newModuleAt(pos).also {
|
||||||
it.eval("import lyng.stdlib\n")
|
it.eval("import lyng.stdlib\n")
|
||||||
}
|
}
|
||||||
}.copy()
|
}.createChildScope()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -60,7 +60,7 @@ abstract class Statement(
|
|||||||
val type = ObjClass("Callable")
|
val type = ObjClass("Callable")
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun call(scope: Scope, vararg args: Obj) = execute(scope.copy(args = Arguments(*args)))
|
suspend fun call(scope: Scope, vararg args: Obj) = execute(scope.createChildScope(args = Arguments(*args)))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3170,6 +3170,34 @@ class ScriptTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testExceptionSerializationPlain() = runTest {
|
||||||
|
eval(
|
||||||
|
"""
|
||||||
|
import lyng.serialization
|
||||||
|
val x = [1,2,3]
|
||||||
|
assertEquals( "[1,2,3]", x.toString() )
|
||||||
|
try {
|
||||||
|
throw "test"
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
println(e.stackTrace)
|
||||||
|
e.printStackTrace()
|
||||||
|
val coded = Lynon.encode(e)
|
||||||
|
val decoded = Lynon.decode(coded)
|
||||||
|
assertEquals( e::class, decoded::class )
|
||||||
|
assertEquals( e.stackTrace, decoded.stackTrace )
|
||||||
|
assertEquals( e.message, decoded.message )
|
||||||
|
println("-------------------- e")
|
||||||
|
println(e.toString())
|
||||||
|
println("-------------------- dee")
|
||||||
|
println(decoded.toString())
|
||||||
|
assertEquals( e.toString(), decoded.toString() )
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testThisInClosure() = runTest {
|
fun testThisInClosure() = runTest {
|
||||||
eval(
|
eval(
|
||||||
@ -3287,25 +3315,25 @@ class ScriptTest {
|
|||||||
|
|
||||||
|
|
||||||
// @Test
|
// @Test
|
||||||
fun testMinimumOptimization() = runTest {
|
// fun testMinimumOptimization() = runTest {
|
||||||
val x = Scope().eval(
|
// val x = Scope().eval(
|
||||||
"""
|
// """
|
||||||
fun naiveCountHappyNumbers() {
|
// fun naiveCountHappyNumbers() {
|
||||||
var count = 0
|
// var count = 0
|
||||||
for( n1 in 0..9 )
|
// for( n1 in 0..9 )
|
||||||
for( n2 in 0..9 )
|
// for( n2 in 0..9 )
|
||||||
for( n3 in 0..9 )
|
// for( n3 in 0..9 )
|
||||||
for( n4 in 0..9 )
|
// for( n4 in 0..9 )
|
||||||
for( n5 in 0..9 )
|
// for( n5 in 0..9 )
|
||||||
for( n6 in 0..9 )
|
// for( n6 in 0..9 )
|
||||||
if( n1 + n2 + n3 == n4 + n5 + n6 ) count++
|
// if( n1 + n2 + n3 == n4 + n5 + n6 ) count++
|
||||||
count
|
// count
|
||||||
}
|
// }
|
||||||
naiveCountHappyNumbers()
|
// naiveCountHappyNumbers()
|
||||||
""".trimIndent()
|
// """.trimIndent()
|
||||||
).toInt()
|
// ).toInt()
|
||||||
assertEquals(55252, x)
|
// assertEquals(55252, x)
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testRegex1() = runTest {
|
fun testRegex1() = runTest {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user