Compare commits
No commits in common. "master" and "fix/scope-parent-cycle" have entirely different histories.
master
...
fix/scope-
@ -1,28 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="Tests in 'lyng.lynglib.jvmTest'" type="GradleRunConfiguration" factoryName="Gradle">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value=":lynglib:cleanJvmTest" />
|
|
||||||
<option value=":lynglib:jvmTest" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<ExternalSystemDebugDisabled>false</ExternalSystemDebugDisabled>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>true</RunAsTest>
|
|
||||||
<GradleProfilingDisabled>false</GradleProfilingDisabled>
|
|
||||||
<GradleCoverageDisabled>false</GradleCoverageDisabled>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
@ -1,20 +1,3 @@
|
|||||||
<!--
|
|
||||||
~ Copyright 2025 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.
|
|
||||||
~ You may obtain a copy of the License at
|
|
||||||
~
|
|
||||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
~
|
|
||||||
~ Unless required by applicable law or agreed to in writing, software
|
|
||||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
~ See the License for the specific language governing permissions and
|
|
||||||
~ limitations under the License.
|
|
||||||
~
|
|
||||||
-->
|
|
||||||
|
|
||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="lyng:site [jsBrowserDevelopmentRun]" type="GradleRunConfiguration" factoryName="Gradle">
|
<configuration default="false" name="lyng:site [jsBrowserDevelopmentRun]" type="GradleRunConfiguration" factoryName="Gradle">
|
||||||
<ExternalSystemSettings>
|
<ExternalSystemSettings>
|
||||||
@ -34,11 +17,8 @@
|
|||||||
</ExternalSystemSettings>
|
</ExternalSystemSettings>
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
<ExternalSystemDebugDisabled>false</ExternalSystemDebugDisabled>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
<RunAsTest>false</RunAsTest>
|
<RunAsTest>false</RunAsTest>
|
||||||
<GradleProfilingDisabled>true</GradleProfilingDisabled>
|
|
||||||
<GradleCoverageDisabled>true</GradleCoverageDisabled>
|
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
||||||
@ -101,7 +101,7 @@ die() { echo "ERROR: $*" 1>&2 ; exit 1; }
|
|||||||
# Update the IDEA plugin download link in docs (temporarily), then build, then restore the doc
|
# Update the IDEA plugin download link in docs (temporarily), then build, then restore the doc
|
||||||
updateIdeaPluginDownloadLink || echo "WARN: proceeding without updating IDEA plugin download link"
|
updateIdeaPluginDownloadLink || echo "WARN: proceeding without updating IDEA plugin download link"
|
||||||
|
|
||||||
./gradlew site:jsBrowserDistribution
|
./gradlew site:clean site:jsBrowserDistribution
|
||||||
BUILD_RC=$?
|
BUILD_RC=$?
|
||||||
|
|
||||||
# Always restore original doc if backup exists
|
# Always restore original doc if backup exists
|
||||||
|
|||||||
@ -68,20 +68,6 @@ These, again, does the thing:
|
|||||||
|
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
## map and mapNotNull
|
|
||||||
|
|
||||||
Used to transform either the whole iterable stream or also skipping som elements from it:
|
|
||||||
|
|
||||||
val source = [1,2,3,4]
|
|
||||||
// transform every element to string or null:
|
|
||||||
assertEquals(["n1", "n2", null, "n4"], source.map { if( it == 3 ) null else "n"+it } )
|
|
||||||
|
|
||||||
// transform every element to stirng, skipping 3:
|
|
||||||
assertEquals(["n1", "n2", "n4"], source.mapNotNull { if( it == 3 ) null else "n"+it } )
|
|
||||||
|
|
||||||
>>> void
|
|
||||||
|
|
||||||
|
|
||||||
## Instance methods:
|
## Instance methods:
|
||||||
|
|
||||||
| fun/method | description |
|
| fun/method | description |
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
# Migration of Instant and Clock
|
|
||||||
|
|
||||||
## History
|
|
||||||
|
|
||||||
Before kotlin 2.0, there was an excellent library, kotlinx.datetime, which was widely used everywhere, also in Lyng and its dependencies.
|
|
||||||
|
|
||||||
When kotlin 2.0 was released, or soon after, JetBrains made an exptic decision to remove `Instant` and `Clock` from kotlinx.datetime and replace it with _yet experimental_ analogs in `kotlin.time`.
|
|
||||||
|
|
||||||
The problem is, these were not quite the same (these weren't `@Serializable`!), so people didn't migrate with ease. Okay, then JetBrains decided to not only deprecate it but also make them unusable on Apple targets. It sort of split auditories of many published libraries to those who hate JetBrains and Apple and continue to use 1.9-2.0 compatible versions that no longer work with Kotlin 2.2 on Apple targets (but work pretty well with earlier Kotlin or on other platforms).
|
|
||||||
|
|
||||||
Later JetBrains added serializers for their new `Instant` and `Clock` types, but strangely not in the stdlib, but in newer versions of `kotlinx.serialization`. This means that plain upgrade of dependencies to 2.2 is not enough to make them work.
|
|
||||||
|
|
||||||
## Solution
|
|
||||||
|
|
||||||
We hereby publish a new version of Lyng, 1.0.8-SNAPSHOT, which uses `ktlin.time.Instant` and `kotlin.time.Clock` instead of `kotlinx.datetime.Instant` and `kotlinx.datetime.Clock; it is in other aspects compatible also with Lynon encoded binaries. Still you might need to migrate your code to use `kotlinx.datetime` types.
|
|
||||||
|
|
||||||
So, if you are getting errors with new version, plase do:
|
|
||||||
|
|
||||||
- upgrade to Kotlin 2.2
|
|
||||||
- upgrade to Lyng 1.0.8-SNAPSHOT
|
|
||||||
- replace in your code imports (or other uses) of`kotlinx.datetime.Clock` to `kotlin.time.Clock` and `kotlinx.datetime.Instant` to `kotlin.time.Instant`.
|
|
||||||
|
|
||||||
This should solve the problem and hopefully we'll see no more suh a brillant ideas from IDEA ideologspersons.
|
|
||||||
|
|
||||||
Sorry for inconvenicence and send a ray of hate to JetBrains ;)
|
|
||||||
@ -1379,9 +1379,9 @@ Part match:
|
|||||||
Typical set of String functions includes:
|
Typical set of String functions includes:
|
||||||
|
|
||||||
| fun/prop | description / notes |
|
| fun/prop | description / notes |
|
||||||
|----------------------|------------------------------------------------------------|
|
|--------------------|------------------------------------------------------------|
|
||||||
| lower(), lowercase() | change case to unicode upper |
|
| lower() | change case to unicode upper |
|
||||||
| upper(), uppercase() | change case to unicode lower |
|
| upper() | change case to unicode lower |
|
||||||
| trim() | trim space chars from both ends |
|
| trim() | trim space chars from both ends |
|
||||||
| startsWith(prefix) | true if starts with a prefix |
|
| startsWith(prefix) | true if starts with a prefix |
|
||||||
| endsWith(prefix) | true if ends with a prefix |
|
| endsWith(prefix) | true if ends with a prefix |
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.5.2"
|
agp = "8.5.2"
|
||||||
clikt = "5.0.3"
|
clikt = "5.0.3"
|
||||||
kotlin = "2.3.0"
|
kotlin = "2.2.21"
|
||||||
android-minSdk = "24"
|
android-minSdk = "24"
|
||||||
android-compileSdk = "34"
|
android-compileSdk = "34"
|
||||||
kotlinx-coroutines = "1.10.2"
|
kotlinx-coroutines = "1.10.2"
|
||||||
mp_bintools = "0.3.2"
|
mp_bintools = "0.1.12"
|
||||||
firebaseCrashlyticsBuildtools = "3.0.3"
|
firebaseCrashlyticsBuildtools = "3.0.3"
|
||||||
okioVersion = "3.10.2"
|
okioVersion = "3.10.2"
|
||||||
compiler = "3.2.0-alpha11"
|
compiler = "3.2.0-alpha11"
|
||||||
|
|||||||
@ -38,7 +38,7 @@ kotlin {
|
|||||||
publishLibraryVariants("release")
|
publishLibraryVariants("release")
|
||||||
@OptIn(ExperimentalKotlinGradlePluginApi::class)
|
@OptIn(ExperimentalKotlinGradlePluginApi::class)
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
jvmTarget.set(JvmTarget.JVM_17)
|
jvmTarget.set(JvmTarget.JVM_11)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iosX64()
|
iosX64()
|
||||||
@ -71,7 +71,11 @@ kotlin {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
all {
|
all {
|
||||||
languageSettings.optIn("kotlin.ExperimentalUnsignedTypes")
|
languageSettings.optIn("kotlin.ExperimentalUnsignedTypes")
|
||||||
languageSettings.optIn("kotlin.time.ExperimentalTime")
|
// languageSettings.optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
|
||||||
|
// Correct opt-in markers for coroutines
|
||||||
|
// languageSettings.optIn("kotlinx.coroutines.DelicateCoroutinesApi")
|
||||||
|
// languageSettings.optIn("kotlin.contracts.ExperimentalContracts")
|
||||||
|
// languageSettings.optIn("kotlinx.coroutines.FlowPreview")
|
||||||
}
|
}
|
||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -111,8 +115,8 @@ android {
|
|||||||
minSdk = libs.versions.android.minSdk.get().toInt()
|
minSdk = libs.versions.android.minSdk.get().toInt()
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
lint {
|
lint {
|
||||||
// Prevent Android Lint from failing the build due to Kotlin toolchain
|
// Prevent Android Lint from failing the build due to Kotlin toolchain
|
||||||
|
|||||||
@ -163,7 +163,7 @@ private suspend fun buildFsModule(module: ModuleScope, policy: FsAccessPolicy) {
|
|||||||
fsGuard {
|
fsGuard {
|
||||||
val self = this.thisObj as ObjPath
|
val self = this.thisObj as ObjPath
|
||||||
val m = self.ensureMetadata()
|
val m = self.ensureMetadata()
|
||||||
m.createdAtMillis?.let { ObjInstant(kotlin.time.Instant.fromEpochMilliseconds(it)) } ?: ObjNull
|
m.createdAtMillis?.let { ObjInstant(kotlinx.datetime.Instant.fromEpochMilliseconds(it)) } ?: ObjNull
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// createdAtMillis(): Int? — milliseconds since epoch or null
|
// createdAtMillis(): Int? — milliseconds since epoch or null
|
||||||
|
|||||||
@ -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 = "1.0.8-SNAPSHOT"
|
version = "1.0.7-SNAPSHOT"
|
||||||
|
|
||||||
// Removed legacy buildscript classpath declarations; plugins are applied via the plugins DSL below
|
// Removed legacy buildscript classpath declarations; plugins are applied via the plugins DSL below
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ kotlin {
|
|||||||
publishLibraryVariants("release")
|
publishLibraryVariants("release")
|
||||||
@OptIn(ExperimentalKotlinGradlePluginApi::class)
|
@OptIn(ExperimentalKotlinGradlePluginApi::class)
|
||||||
compilerOptions {
|
compilerOptions {
|
||||||
jvmTarget.set(JvmTarget.JVM_17)
|
jvmTarget.set(JvmTarget.JVM_11)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iosX64()
|
iosX64()
|
||||||
@ -89,16 +89,16 @@ kotlin {
|
|||||||
languageSettings.optIn("kotlinx.coroutines.DelicateCoroutinesApi")
|
languageSettings.optIn("kotlinx.coroutines.DelicateCoroutinesApi")
|
||||||
languageSettings.optIn("kotlin.contracts.ExperimentalContracts")
|
languageSettings.optIn("kotlin.contracts.ExperimentalContracts")
|
||||||
languageSettings.optIn("kotlinx.coroutines.FlowPreview")
|
languageSettings.optIn("kotlinx.coroutines.FlowPreview")
|
||||||
languageSettings.optIn("kotlin.time.ExperimentalTime")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
kotlin.srcDir("$buildDir/generated/buildConfig/commonMain/kotlin")
|
kotlin.srcDir("$buildDir/generated/buildConfig/commonMain/kotlin")
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1")
|
||||||
//put your multiplatform dependencies here
|
//put your multiplatform dependencies here
|
||||||
api(libs.kotlinx.coroutines.core)
|
api(libs.kotlinx.coroutines.core)
|
||||||
api(libs.mp.bintools)
|
api(libs.mp.bintools)
|
||||||
|
api("net.sergeych:mp_stools:1.5.2")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val commonTest by getting {
|
val commonTest by getting {
|
||||||
@ -116,18 +116,6 @@ kotlin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
|
||||||
namespace = "net.sergeych.lynglib"
|
|
||||||
compileSdk = libs.versions.android.compileSdk.get().toInt()
|
|
||||||
defaultConfig {
|
|
||||||
minSdk = libs.versions.android.minSdk.get().toInt()
|
|
||||||
}
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Build-time generation of stdlib text from .lyng files into a Kotlin constant ----
|
// ---- Build-time generation of stdlib text from .lyng files into a Kotlin constant ----
|
||||||
// Implemented as a proper task type compatible with Gradle Configuration Cache
|
// Implemented as a proper task type compatible with Gradle Configuration Cache
|
||||||
|
|
||||||
|
|||||||
@ -428,13 +428,13 @@ open class Scope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline fun addVoidFn(vararg names: String, crossinline fn: suspend Scope.() -> Unit) {
|
inline fun addVoidFn(vararg names: String, crossinline fn: suspend Scope.() -> Unit) {
|
||||||
addFn(*names) {
|
addFn<ObjVoid>(*names) {
|
||||||
fn(this)
|
fn(this)
|
||||||
ObjVoid
|
ObjVoid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addFn(vararg names: String, fn: suspend Scope.() -> Obj) {
|
inline fun <reified T : Obj> addFn(vararg names: String, crossinline fn: suspend Scope.() -> T) {
|
||||||
val newFn = object : Statement() {
|
val newFn = object : Statement() {
|
||||||
override val pos: Pos = Pos.builtIn
|
override val pos: Pos = Pos.builtIn
|
||||||
|
|
||||||
@ -516,23 +516,6 @@ open class Scope(
|
|||||||
|
|
||||||
open fun applyClosure(closure: Scope): Scope = ClosureScope(this, closure)
|
open fun applyClosure(closure: Scope): Scope = ClosureScope(this, closure)
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve and evaluate a qualified identifier exactly as compiled code would.
|
|
||||||
* For input like `A.B.C`, it builds the same ObjRef chain the compiler emits:
|
|
||||||
* `LocalVarRef("A", Pos.builtIn)` followed by `FieldRef` for each segment, then evaluates it.
|
|
||||||
* This mirrors `eval("A.B.C")` resolution semantics without invoking the compiler.
|
|
||||||
*/
|
|
||||||
suspend fun resolveQualifiedIdentifier(qualifiedName: String): Obj {
|
|
||||||
val trimmed = qualifiedName.trim()
|
|
||||||
if (trimmed.isEmpty()) raiseSymbolNotFound("empty identifier")
|
|
||||||
val parts = trimmed.split('.')
|
|
||||||
var ref: ObjRef = LocalVarRef(parts[0], Pos.builtIn)
|
|
||||||
for (i in 1 until parts.size) {
|
|
||||||
ref = FieldRef(ref, parts[i], false)
|
|
||||||
}
|
|
||||||
return ref.evalValue(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun new(): Scope =
|
fun new(): Scope =
|
||||||
|
|||||||
@ -173,44 +173,31 @@ class Script(
|
|||||||
val a = requiredArg<Obj>(0)
|
val a = requiredArg<Obj>(0)
|
||||||
val b = requiredArg<Obj>(1)
|
val b = requiredArg<Obj>(1)
|
||||||
if( a.compareTo(this, b) != 0 )
|
if( a.compareTo(this, b) != 0 )
|
||||||
raiseError(
|
raiseError(ObjAssertionFailedException(this,"Assertion failed: ${a.inspect(this)} == ${b.inspect(this)}"))
|
||||||
ObjAssertionFailedException(
|
|
||||||
this,
|
|
||||||
"Assertion failed: ${a.inspect(this)} == ${b.inspect(this)}"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
// alias used in tests
|
// alias used in tests
|
||||||
addVoidFn("assertEqual") {
|
addVoidFn("assertEqual") {
|
||||||
val a = requiredArg<Obj>(0)
|
val a = requiredArg<Obj>(0)
|
||||||
val b = requiredArg<Obj>(1)
|
val b = requiredArg<Obj>(1)
|
||||||
if( a.compareTo(this, b) != 0 )
|
if( a.compareTo(this, b) != 0 )
|
||||||
raiseError(
|
raiseError(ObjAssertionFailedException(this,"Assertion failed: ${a.inspect(this)} == ${b.inspect(this)}"))
|
||||||
ObjAssertionFailedException(
|
|
||||||
this,
|
|
||||||
"Assertion failed: ${a.inspect(this)} == ${b.inspect(this)}"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
addVoidFn("assertNotEquals") {
|
addVoidFn("assertNotEquals") {
|
||||||
val a = requiredArg<Obj>(0)
|
val a = requiredArg<Obj>(0)
|
||||||
val b = requiredArg<Obj>(1)
|
val b = requiredArg<Obj>(1)
|
||||||
if( a.compareTo(this, b) == 0 )
|
if( a.compareTo(this, b) == 0 )
|
||||||
raiseError(
|
raiseError(ObjAssertionFailedException(this,"Assertion failed: ${a.inspect(this)} != ${b.inspect(this)}"))
|
||||||
ObjAssertionFailedException(
|
|
||||||
this,
|
|
||||||
"Assertion failed: ${a.inspect(this)} != ${b.inspect(this)}"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
addFn("assertThrows") {
|
addFn("assertThrows") {
|
||||||
val code = requireOnlyArg<Statement>()
|
val code = requireOnlyArg<Statement>()
|
||||||
val result =try {
|
val result =try {
|
||||||
code.execute(this)
|
code.execute(this)
|
||||||
null
|
null
|
||||||
} catch (e: ExecutionError) {
|
}
|
||||||
|
catch( e: ExecutionError ) {
|
||||||
e.errorObject
|
e.errorObject
|
||||||
} catch (_: ScriptError) {
|
}
|
||||||
|
catch (_: ScriptError) {
|
||||||
ObjNull
|
ObjNull
|
||||||
}
|
}
|
||||||
result ?: raiseError(ObjAssertionFailedException(this,"Expected exception but nothing was thrown"))
|
result ?: raiseError(ObjAssertionFailedException(this,"Expected exception but nothing was thrown"))
|
||||||
|
|||||||
@ -131,7 +131,7 @@ object CompletionEngineLight {
|
|||||||
}
|
}
|
||||||
is MiniClassDecl -> add(CompletionItem(d.name, Kind.Class_))
|
is MiniClassDecl -> add(CompletionItem(d.name, Kind.Class_))
|
||||||
is MiniValDecl -> add(CompletionItem(d.name, Kind.Value, typeText = typeOf(d.type)))
|
is MiniValDecl -> add(CompletionItem(d.name, Kind.Value, typeText = typeOf(d.type)))
|
||||||
// else -> add(CompletionItem(d.name, Kind.Value))
|
else -> add(CompletionItem(d.name, Kind.Value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -197,20 +197,9 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
|
|||||||
!it.key.contains("::") && it.value.visibility.isPublic && it.value.type.serializable
|
!it.key.contains("::") && it.value.visibility.isPublic && it.value.type.serializable
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toString(scope: Scope, calledFromLyng: Boolean): ObjString {
|
override fun toString(): String {
|
||||||
return ObjString(buildString {
|
val fields = publicFields.map { "${it.key}=${it.value.value}" }.joinToString(",")
|
||||||
append("${objClass.className}(")
|
return "${objClass.className}($fields)"
|
||||||
var first = true
|
|
||||||
for ((name, value) in publicFields) {
|
|
||||||
if (first) first = false else append(",")
|
|
||||||
append("$name=${value.value.toString(scope)}")
|
|
||||||
}
|
|
||||||
append(")")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun inspect(scope: Scope): String {
|
|
||||||
return toString(scope).value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun serialize(scope: Scope, encoder: LynonEncoder, lynonType: LynonType?) {
|
override suspend fun serialize(scope: Scope, encoder: LynonEncoder, lynonType: LynonType?) {
|
||||||
|
|||||||
@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
package net.sergeych.lyng.obj
|
package net.sergeych.lyng.obj
|
||||||
|
|
||||||
|
import kotlinx.datetime.Clock
|
||||||
|
import kotlinx.datetime.Instant
|
||||||
|
import kotlinx.datetime.isDistantFuture
|
||||||
|
import kotlinx.datetime.isDistantPast
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
import net.sergeych.lyng.Scope
|
import net.sergeych.lyng.Scope
|
||||||
@ -24,10 +28,6 @@ import net.sergeych.lynon.LynonDecoder
|
|||||||
import net.sergeych.lynon.LynonEncoder
|
import net.sergeych.lynon.LynonEncoder
|
||||||
import net.sergeych.lynon.LynonSettings
|
import net.sergeych.lynon.LynonSettings
|
||||||
import net.sergeych.lynon.LynonType
|
import net.sergeych.lynon.LynonType
|
||||||
import kotlin.time.Clock
|
|
||||||
import kotlin.time.Instant
|
|
||||||
import kotlin.time.isDistantFuture
|
|
||||||
import kotlin.time.isDistantPast
|
|
||||||
|
|
||||||
class ObjInstant(val instant: Instant,val truncateMode: LynonSettings.InstantTruncateMode=LynonSettings.InstantTruncateMode.Microsecond) : Obj() {
|
class ObjInstant(val instant: Instant,val truncateMode: LynonSettings.InstantTruncateMode=LynonSettings.InstantTruncateMode.Microsecond) : Obj() {
|
||||||
override val objClass: ObjClass get() = type
|
override val objClass: ObjClass get() = type
|
||||||
|
|||||||
@ -158,23 +158,6 @@ val ObjIterable by lazy {
|
|||||||
ObjList(result)
|
ObjList(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
addFnDoc(
|
|
||||||
name = "mapNotNull",
|
|
||||||
doc = "Transform elements by applying the given lambda unless it returns null.",
|
|
||||||
params = listOf(ParamDoc("transform")),
|
|
||||||
returns = type("lyng.List"),
|
|
||||||
isOpen = true,
|
|
||||||
moduleName = "lyng.stdlib"
|
|
||||||
) {
|
|
||||||
val fn = requiredArg<Statement>(0)
|
|
||||||
val result = mutableListOf<Obj>()
|
|
||||||
thisObj.toFlow(this).collect {
|
|
||||||
val transformed = fn.call(this, it)
|
|
||||||
if( transformed != ObjNull) result += transformed
|
|
||||||
}
|
|
||||||
ObjList(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
addFnDoc(
|
addFnDoc(
|
||||||
name = "take",
|
name = "take",
|
||||||
doc = "Take the first N elements and return them as a list.",
|
doc = "Take the first N elements and return them as a list.",
|
||||||
|
|||||||
@ -198,18 +198,6 @@ class ObjList(val list: MutableList<Obj> = mutableListOf()) : Obj() {
|
|||||||
return JsonArray(list.map { it.toJson(scope) })
|
return JsonArray(list.map { it.toJson(scope) })
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toString(scope: Scope, calledFromLyng: Boolean): ObjString {
|
|
||||||
return ObjString(buildString {
|
|
||||||
append("[")
|
|
||||||
var first = true
|
|
||||||
for (v in list) {
|
|
||||||
if (first) first = false else append(",")
|
|
||||||
append(v.toString(scope).value)
|
|
||||||
}
|
|
||||||
append("]")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val type = object : ObjClass("List", ObjArray) {
|
val type = object : ObjClass("List", ObjArray) {
|
||||||
override suspend fun deserialize(scope: Scope, decoder: LynonDecoder, lynonType: LynonType?): Obj {
|
override suspend fun deserialize(scope: Scope, decoder: LynonDecoder, lynonType: LynonType?): Obj {
|
||||||
|
|||||||
@ -52,8 +52,8 @@ class ObjMapEntry(val key: Obj, val value: Obj) : Obj() {
|
|||||||
else -> scope.raiseIndexOutOfBounds()
|
else -> scope.raiseIndexOutOfBounds()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toString(scope: Scope, calledFromLyng: Boolean): ObjString {
|
override fun toString(): String {
|
||||||
return ObjString("(${key.toString(scope).value} => ${value.toString(scope).value})")
|
return "$key=>$value"
|
||||||
}
|
}
|
||||||
|
|
||||||
override val objClass = type
|
override val objClass = type
|
||||||
|
|||||||
@ -1625,7 +1625,7 @@ class ListLiteralRef(private val entries: List<ListEntry>) : ObjRef {
|
|||||||
when (elements) {
|
when (elements) {
|
||||||
is ObjList -> {
|
is ObjList -> {
|
||||||
// Grow underlying array once when possible
|
// Grow underlying array once when possible
|
||||||
list.ensureCapacity(list.size + elements.list.size)
|
if (list is ArrayList) list.ensureCapacity(list.size + elements.list.size)
|
||||||
list.addAll(elements.list)
|
list.addAll(elements.list)
|
||||||
}
|
}
|
||||||
else -> scope.raiseError("Spread element must be list")
|
else -> scope.raiseError("Spread element must be list")
|
||||||
|
|||||||
@ -216,14 +216,6 @@ data class ObjString(val value: String) : Obj() {
|
|||||||
) {
|
) {
|
||||||
thisAs<ObjString>().value.lowercase().let(::ObjString)
|
thisAs<ObjString>().value.lowercase().let(::ObjString)
|
||||||
}
|
}
|
||||||
addFnDoc(
|
|
||||||
name = "lowercase",
|
|
||||||
doc = "Lowercase version of this string (default locale).",
|
|
||||||
returns = type("lyng.String"),
|
|
||||||
moduleName = "lyng.stdlib"
|
|
||||||
) {
|
|
||||||
thisAs<ObjString>().value.lowercase().let(::ObjString)
|
|
||||||
}
|
|
||||||
addFnDoc(
|
addFnDoc(
|
||||||
name = "upper",
|
name = "upper",
|
||||||
doc = "Uppercase version of this string (default locale).",
|
doc = "Uppercase version of this string (default locale).",
|
||||||
@ -232,14 +224,6 @@ data class ObjString(val value: String) : Obj() {
|
|||||||
) {
|
) {
|
||||||
thisAs<ObjString>().value.uppercase().let(::ObjString)
|
thisAs<ObjString>().value.uppercase().let(::ObjString)
|
||||||
}
|
}
|
||||||
addFnDoc(
|
|
||||||
name = "uppercase",
|
|
||||||
doc = "Uppercase version of this string (default locale).",
|
|
||||||
returns = type("lyng.String"),
|
|
||||||
moduleName = "lyng.stdlib"
|
|
||||||
) {
|
|
||||||
thisAs<ObjString>().value.uppercase().let(::ObjString)
|
|
||||||
}
|
|
||||||
addFnDoc(
|
addFnDoc(
|
||||||
name = "characters",
|
name = "characters",
|
||||||
doc = "List of characters of this string.",
|
doc = "List of characters of this string.",
|
||||||
|
|||||||
@ -82,16 +82,8 @@ open class LynonDecoder(val bin: BitInput, val settings: LynonSettings = LynonSe
|
|||||||
if (it !is ObjClass)
|
if (it !is ObjClass)
|
||||||
scope.raiseClassCastError("Expected obj class but got ${it::class.simpleName}")
|
scope.raiseClassCastError("Expected obj class but got ${it::class.simpleName}")
|
||||||
it
|
it
|
||||||
} ?: run {
|
} ?: scope.raiseSymbolNotFound("can't deserialize: not found type $className")
|
||||||
// Use Scope API that mirrors compiler-emitted ObjRef chain for qualified identifiers
|
|
||||||
val evaluated = scope.resolveQualifiedIdentifier(className.value)
|
|
||||||
if (evaluated !is ObjClass)
|
|
||||||
scope.raiseClassCastError("Expected obj class but got ${evaluated::class.simpleName}")
|
|
||||||
evaluated
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// helper moved to Scope as resolveQualifiedIdentifier
|
|
||||||
|
|
||||||
suspend fun decodeAnyList(scope: Scope, fixedSize: Int? = null): MutableList<Obj> {
|
suspend fun decodeAnyList(scope: Scope, fixedSize: Int? = null): MutableList<Obj> {
|
||||||
return if (bin.getBit() == 1) {
|
return if (bin.getBit() == 1) {
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
package net.sergeych.tools
|
package net.sergeych.tools
|
||||||
|
|
||||||
import kotlin.time.Clock
|
import kotlinx.datetime.Clock
|
||||||
|
|
||||||
inline fun bm(text: String="", f: ()->Unit) {
|
inline fun bm(text: String="", f: ()->Unit) {
|
||||||
val start = Clock.System.now()
|
val start = Clock.System.now()
|
||||||
|
|||||||
@ -23,6 +23,8 @@ import kotlinx.coroutines.flow.toList
|
|||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.withTimeout
|
import kotlinx.coroutines.withTimeout
|
||||||
|
import kotlinx.datetime.Clock
|
||||||
|
import kotlinx.datetime.Instant
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
@ -34,9 +36,7 @@ import net.sergeych.lyng.pacman.InlineSourcesImportProvider
|
|||||||
import net.sergeych.mp_tools.globalDefer
|
import net.sergeych.mp_tools.globalDefer
|
||||||
import net.sergeych.tools.bm
|
import net.sergeych.tools.bm
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
import kotlin.time.Clock
|
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
import kotlin.time.Instant
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2025 Sergey S. Chernov real.sergeych@gmail.com
|
* Copyright 2025 Sergey S. Chernov real.sergeych@gmail.com
|
||||||
|
|||||||
@ -18,12 +18,12 @@
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import kotlinx.datetime.Clock
|
||||||
import net.sergeych.lyng.Scope
|
import net.sergeych.lyng.Scope
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import kotlin.io.path.extension
|
import kotlin.io.path.extension
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.time.Clock
|
|
||||||
|
|
||||||
suspend fun executeSampleTests(fileName: String) {
|
suspend fun executeSampleTests(fileName: String) {
|
||||||
val sample = withContext(Dispatchers.IO) {
|
val sample = withContext(Dispatchers.IO) {
|
||||||
|
|||||||
@ -36,7 +36,7 @@ fun HomePage() {
|
|||||||
// Benefits pills
|
// Benefits pills
|
||||||
listOf(
|
listOf(
|
||||||
"Clean, familiar syntax",
|
"Clean, familiar syntax",
|
||||||
"both FP and OOP",
|
"Immutable-first collections",
|
||||||
"Batteries-included standard library",
|
"Batteries-included standard library",
|
||||||
"Embeddable and testable"
|
"Embeddable and testable"
|
||||||
).forEach { b ->
|
).forEach { b ->
|
||||||
|
|||||||
@ -329,7 +329,7 @@
|
|||||||
<!-- Top-left version ribbon -->
|
<!-- Top-left version ribbon -->
|
||||||
<div class="corner-ribbon bg-danger text-white">
|
<div class="corner-ribbon bg-danger text-white">
|
||||||
<span style="margin-left: -5em">
|
<span style="margin-left: -5em">
|
||||||
v1.0.8-SNAPSHOT
|
v1.0.6-SNAPSHOT
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- Fixed top navbar for the whole site -->
|
<!-- Fixed top navbar for the whole site -->
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user