Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
23737f9b5c | |||
fb6e2aa49e | |||
95c1da60ed | |||
835333dfad | |||
eefecae7b4 | |||
2ac92a1d09 | |||
464a6dcb99 | |||
eca746b189 | |||
b07452e66e | |||
202e70a99a | |||
f45310f7d9 | |||
48a7f0839c | |||
2adb0ff512 | |||
6735499959 | |||
b5e89c7e78 | |||
84e345b04e | |||
9bd7aa368e | |||
9704f18284 |
@ -1,3 +1,20 @@
|
||||
<!--
|
||||
~ 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">
|
||||
<configuration default="false" name="Tests in 'lyng.lynglib.jvmTest'" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
|
3
NOTICE
Normal file
3
NOTICE
Normal file
@ -0,0 +1,3 @@
|
||||
The Lyng programming language.
|
||||
Copyright (c) 2024-2025 Sergey Chernov real.sergeych@gmail.com
|
||||
|
@ -157,6 +157,7 @@ Ready features:
|
||||
- [x] typesafe bit-effective serialization
|
||||
- [x] compression/decompression (integrated in serialization)
|
||||
- [x] dynamic fields
|
||||
- [x] function annotations
|
||||
|
||||
### Under way:
|
||||
|
||||
|
@ -1,5 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
root=./lyng/build/install/lyng-jvm/
|
||||
|
@ -1,5 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
file=./lyng/build/bin/linuxX64/releaseExecutable/lyng.kexe
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.androidLibrary) apply false
|
||||
alias(libs.plugins.kotlinMultiplatform) apply false
|
||||
|
@ -102,20 +102,50 @@ As with [List], it is possible to use ranges as indexes to slice a Buffer:
|
||||
|
||||
>>> void
|
||||
|
||||
## Encoding
|
||||
|
||||
You can encode `String` to buffer using buffer constructor, as was shown. Also, buffer supports out of the box base64 (
|
||||
which is used in `toString`) and hex encoding:
|
||||
|
||||
import lyng.buffer
|
||||
|
||||
// to UTF8 and back:
|
||||
val b = Buffer("hello")
|
||||
assertEquals( "hello", b.decodeUtf8() )
|
||||
|
||||
// to base64 and back:
|
||||
assertEquals( b, Buffer.decodeBase64(b.base64) )
|
||||
assertEquals( b, Buffer.decodeHex(b.hex) )
|
||||
>>> void
|
||||
|
||||
## Members
|
||||
|
||||
| name | meaning | type |
|
||||
|---------------|------------------------------------|---------------|
|
||||
|----------------------------|-----------------------------------------|---------------|
|
||||
| `size` | size | Int |
|
||||
| `decodeUtf8` | decodee to String using UTF8 rules | Any |
|
||||
| `decodeUtf8` | decode to String using UTF8 rules | Any |
|
||||
| `+` | buffer concatenation | Any |
|
||||
| `toMutable()` | create a mutable copy | MutableBuffer |
|
||||
| `hex` | encode to hex strign | String |
|
||||
| `Buffer.decodeHex(hexStr) | decode hex string | Buffer |
|
||||
| `base64` | encode to base64 (url flavor) (2) | String |
|
||||
| `Buffer.decodeBase64(str)` | decode base64 to new Buffer (2) | Buffer |
|
||||
| `toBitInput()` | create bit input from a byte buffer (3) | |
|
||||
|
||||
(1)
|
||||
: optimized implementation that override `Iterable` one
|
||||
|
||||
(2)
|
||||
: base64url alphabet is used without trailing '=', which allows string to be used in URI without escaping. Note that
|
||||
decoding supports both traditional and URL alphabets automatically, and ignores filling `=` characters. Base64URL is
|
||||
well known and mentioned in the internet, for example, [here](https://base64.guru/standards/base64url).
|
||||
|
||||
(3)
|
||||
: `BitInput` is a bit buffer that is used, for example, in [Lynon.decode](serialization.md)
|
||||
|
||||
Also, it inherits methods from [Iterable] and [Array].
|
||||
|
||||
|
||||
[Range]: Range.md
|
||||
|
||||
[Iterable]: Iterable.md
|
@ -26,16 +26,34 @@ Just remember at this stage typed declarations are not yet supported.
|
||||
Having `Iterable` in base classes allows to use it in for loop. Also, each `Iterable` has some utility functions available, for example
|
||||
|
||||
val r = 1..10 // Range is Iterable!
|
||||
assertEquals( [9,10] r.takeLast(2) )
|
||||
assertEquals( [1,2,3] r.take(3) )
|
||||
assertEquals( [9,10] r.drop(8) )
|
||||
assertEquals( [1,2] r.dropLast(8) )
|
||||
assertEquals( [9,10], r.takeLast(2).toList() )
|
||||
assertEquals( [1,2,3], r.take(3).toList() )
|
||||
assertEquals( [9,10], r.drop(8).toList() )
|
||||
assertEquals( [1,2], r.dropLast(8).toList() )
|
||||
>>> void
|
||||
|
||||
## joinToString
|
||||
|
||||
This methods convert any iterable to a string joining string representation of each element, optionally transforming it and joining using specified suffix.
|
||||
|
||||
Iterable.joinToString(suffux=' ', transform=null)
|
||||
|
||||
- if `Iterable` `isEmpty`, the empty string `""` is returned.
|
||||
- `suffix` is inserted between items when there are more than one.
|
||||
- `transform` of specified is applied to each element, otherwise its `toString()` method is used.
|
||||
|
||||
Here is the sample:
|
||||
|
||||
assertEquals( (1..3).joinToString(), "1 2 3")
|
||||
assertEquals( (1..3).joinToString(":"), "1:2:3")
|
||||
assertEquals( (1..3).joinToString { it * 10 }, "10 20 30")
|
||||
>>> void
|
||||
|
||||
## Instance methods:
|
||||
|
||||
|
||||
| fun/method | description |
|
||||
|-----------------|---------------------------------------------------------------------------------|
|
||||
|-------------------|---------------------------------------------------------------------------|
|
||||
| toList() | create a list from iterable |
|
||||
| toSet() | create a set from iterable |
|
||||
| contains(i) | check that iterable contains `i` |
|
||||
@ -52,10 +70,14 @@ Having `Iterable` in base classes allows to use it in for loop. Also, each `Iter
|
||||
| taleLast(n) | return [Iterable] of up to n last elements |
|
||||
| drop(n) | return new [Iterable] without first n elements |
|
||||
| dropLast(n) | return new [Iterable] without last n elements |
|
||||
| joinToString(s,t) | convert iterable to string, see (2) |
|
||||
|
||||
(1)
|
||||
: throws `NoSuchElementException` if there is no such element
|
||||
|
||||
(2)
|
||||
: `joinToString(suffix=" ",transform=null)`: suffix is inserted between items if there are more than one, trasnfom is optional function applied to each item that must return result string for an item, otherwise `item.toString()` is used.
|
||||
|
||||
fun Iterable.toList(): List
|
||||
fun Iterable.toSet(): Set
|
||||
fun Iterable.indexOf(element): Int
|
||||
|
@ -112,6 +112,49 @@ arguments list in almost arbitrary ways. For example:
|
||||
)
|
||||
>>> void
|
||||
|
||||
,
|
||||
# Annotations
|
||||
|
||||
Annotation in Lyng resembles these proposed for Javascript. Annotation is just regular functions that, if used as annotation, are called when defining a function, var, val or class.
|
||||
|
||||
## Function annotation
|
||||
|
||||
When used without params, annotation calls a function with two arguments: actual function name and callable function body. Function annotation __must return callable for the function__, either what it received as a second argument (most often), or something else. Annotation name convention is upper scaled:
|
||||
|
||||
var annotated = false
|
||||
|
||||
// this is annotation function:
|
||||
fun Special(name, body) {
|
||||
assertEquals("foo", name)
|
||||
annotated = true
|
||||
{ body(it) + 100 }
|
||||
}
|
||||
|
||||
@Special
|
||||
fun foo(value) { value + 1 }
|
||||
|
||||
assert(annotated)
|
||||
assertEquals(111, foo( 10 ))
|
||||
>>> void
|
||||
|
||||
Function annotation can have more args specified at call time. There arguments must follow two mandatory ones (name and body). Use default values in order to allow parameterless annotation to be used simultaneously.
|
||||
|
||||
val registered = Map()
|
||||
|
||||
// it is recommended to provide defaults for extra parameters:
|
||||
fun Registered(name, body, overrideName = null) {
|
||||
registered[ overrideName ?: name ] = body
|
||||
body
|
||||
}
|
||||
|
||||
// witout parameters is Ok as we provided default value
|
||||
@Registered
|
||||
fun foo() { "called foo" }
|
||||
|
||||
@Registered("bar")
|
||||
fun foo2() { "called foo2" }
|
||||
|
||||
assertEquals(registered["foo"](), "called foo")
|
||||
assertEquals(registered["bar"](), "called foo2")
|
||||
>>> void
|
||||
|
||||
[parallelism]: parallelism.md
|
||||
|
14
docs/development/scope_resolution.md
Normal file
14
docs/development/scope_resolution.md
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
|
||||
Provide:
|
||||
|
||||
|
||||
fun outer(a1)
|
||||
// a1 is caller.a1:arg
|
||||
val a1_local = a1 + 1
|
||||
// we return lambda:
|
||||
{ it ->
|
||||
// a1_local
|
||||
a1_lcoal + it
|
||||
}
|
||||
}
|
46
docs/serialization.md
Normal file
46
docs/serialization.md
Normal file
@ -0,0 +1,46 @@
|
||||
# Lyng serialization
|
||||
|
||||
Lyng has builting binary bit-effective serialization format, called Lynon for LYng Object Notation. It is typed, binary, implements caching, automatic compression, variable-length ints, one-bit Booleans an many nice features.
|
||||
|
||||
It is as simple as:
|
||||
|
||||
import lyng.serialization
|
||||
|
||||
val text = "
|
||||
We hold these truths to be self-evident, that all men are created equal,
|
||||
that they are endowed by their Creator with certain unalienable Rights,
|
||||
that among these are Life, Liberty and the pursuit of Happiness.
|
||||
"
|
||||
val encodedBits = Lynon.encode(text)
|
||||
|
||||
// decode bits source:
|
||||
assertEquals( text, Lynon.decode(encodedBits) )
|
||||
|
||||
// compression was used automatically
|
||||
assert( text.length > encodedBits.toBuffer().size )
|
||||
>>> void
|
||||
|
||||
Any class you create is serializable by default; lynon serializes first constructor fields, then any `var` member fields:
|
||||
|
||||
import lyng.serialization
|
||||
|
||||
class Point(x,y)
|
||||
|
||||
val p = Lynon.decode( Lynon.encode( Point(5,6) ) )
|
||||
|
||||
assertEquals( 5, p.x )
|
||||
assertEquals( 6, p.y )
|
||||
>>> void
|
||||
|
||||
|
||||
just as expected.
|
||||
|
||||
Important is to understand that normally `Lynon.decode` wants [BitBuffer], as `Lynon.encode` produces. If you have the regular [Buffer], be sure to convert it:
|
||||
|
||||
buffer.toBitInput()
|
||||
|
||||
this possibly creates extra zero bits at the end, as bit content could be shorter than byte-grained but for the Lynon format it does not make sense. Note that when you serialize [BitBuffer], exact number of bits is written. To convert bit buffer to bytes:
|
||||
|
||||
Lynon.encode("hello").toBuffer()
|
||||
|
||||
(topic is incomplete and under construction)
|
@ -225,6 +225,19 @@ It works much like `also`, but is executed in the context of the source object:
|
||||
assertEquals(p, Point(2,3))
|
||||
>>> void
|
||||
|
||||
## run
|
||||
|
||||
Executes a block after it returning the value passed by the block. for example, can be used with elvis operator:
|
||||
|
||||
var someVar = null
|
||||
val result = someVar ?: run {
|
||||
someVar = 121
|
||||
"reset"
|
||||
}
|
||||
assertEquals("reset", result)
|
||||
assertEquals(121, someVar)
|
||||
>>> void
|
||||
|
||||
## Math
|
||||
|
||||
It is rather simple, like everywhere else:
|
||||
@ -475,7 +488,7 @@ Lyng has built-in mutable array class `List` with simple literals:
|
||||
[1, "two", 3.33].size
|
||||
>>> 3
|
||||
|
||||
[List] is an implementation of the type `Array`, and through it `Collection` and [Iterable].
|
||||
[List] is an implementation of the type `Array`, and through it `Collection` and [Iterable]. Please read [Iterable], many collection based methods are implemented there.
|
||||
|
||||
Lists can contain any type of objects, lists too:
|
||||
|
||||
@ -747,7 +760,7 @@ You can thest that _when expression_ is _contained_, or not contained, in some o
|
||||
`!in container`. The container is any object that provides `contains` method, otherwise the runtime exception will be
|
||||
thrown.
|
||||
|
||||
Typical builtin types that are containers (e.g. support `conain`):
|
||||
Typical builtin types that are containers (e.g. support `contains`):
|
||||
|
||||
| class | notes |
|
||||
|------------|------------------------------------------------|
|
||||
@ -756,6 +769,8 @@ Typical builtin types that are containers (e.g. support `conain`):
|
||||
| List | faster than Array's |
|
||||
| String | character in string or substring in string (3) |
|
||||
| Range | object is included in the range (2) |
|
||||
| Buffer | byte is in buffer |
|
||||
| RingBuffer | object is in buffer |
|
||||
|
||||
(1)
|
||||
: Iterable is not the container as it can be infinite
|
||||
@ -1120,6 +1135,25 @@ These should be imported from [lyng.time](time.md). For example:
|
||||
|
||||
See [more docs on time manipulation](time.md)
|
||||
|
||||
# Enums
|
||||
|
||||
For the moment, only simple enums are implemented. Enum is a list of constants, represented also by their _ordinal_ - [Int] value.
|
||||
|
||||
enum Color {
|
||||
RED, GREEN, BLUE
|
||||
}
|
||||
|
||||
assert( Color.RED is Color )
|
||||
|
||||
assertEquals( 2, Color.BLUE.ordinal )
|
||||
assertEquals( "BLUE", Color.BLUE.name )
|
||||
|
||||
assertEquals( [Color.RED,Color.GREEN,Color.BLUE], Color.entries)
|
||||
assertEquals( Color.valueOf("GREEN"), Color.GREEN )
|
||||
>>> void
|
||||
|
||||
Enums are serialized as ordinals. Please note that due to caching, serialized string arrays could be even more compact than enum arrays, until `Lynon.encodeTyped` will be implemented.
|
||||
|
||||
# Comments
|
||||
|
||||
// single line comment
|
||||
@ -1278,7 +1312,7 @@ if blank, will be removed too, for example:
|
||||
See [math functions](math.md). Other general purpose functions are:
|
||||
|
||||
| name | description |
|
||||
|--------------------------------------------|-----------------------------------------------------------|
|
||||
|----------------------------------------------|------------------------------------------------------------|
|
||||
| assert(condition,message="assertion failed") | runtime code check. There will be an option to skip them |
|
||||
| assertEquals(a,b) | |
|
||||
| assertNotEquals(a,b) | |
|
||||
@ -1289,6 +1323,9 @@ See [math functions](math.md). Other general purpose functions are:
|
||||
| print(args...) | Open for overriding, it prints to stdout without newline. |
|
||||
| flow {} | create flow sequence, see [parallelism] |
|
||||
| delay, launch, yield | see [parallelism] |
|
||||
| cached(builder) | remembers builder() on first invocation and return it then |
|
||||
| let, also, apply, run | see above, flow controls |
|
||||
|
||||
|
||||
# Built-in constants
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
|
||||
#Gradle
|
||||
org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M"
|
||||
org.gradle.caching=true
|
||||
|
17
gradle/wrapper/gradle-wrapper.properties
vendored
17
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,3 +1,20 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
|
5
gradlew
vendored
5
gradlew
vendored
@ -1,13 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# 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
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
# 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,
|
||||
@ -15,6 +15,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform") version "2.1.21"
|
||||
}
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych
|
||||
|
||||
import com.github.ajalt.clikt.core.CliktCommand
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych
|
||||
|
||||
import kotlin.system.exitProcess
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@file:Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
|
||||
|
||||
package net.sergeych
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng_cli
|
||||
|
||||
import net.sergeych.runMain
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
import net.sergeych.runMain
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
@ -1,4 +1,23 @@
|
||||
@file:OptIn(ExperimentalForeignApi::class, ExperimentalForeignApi::class, ExperimentalForeignApi::class)
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalForeignApi::class, ExperimentalForeignApi::class, ExperimentalForeignApi::class,
|
||||
ExperimentalForeignApi::class
|
||||
)
|
||||
|
||||
package net.sergeych
|
||||
|
||||
|
@ -1,10 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING
|
||||
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
|
||||
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
group = "net.sergeych"
|
||||
version = "0.8.6-SNAPSHOT"
|
||||
version = "0.8.14-SNAPSHOT"
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
enum class AccessType(val isMutable: Boolean) {
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import net.sergeych.lyng.obj.Obj
|
||||
@ -31,13 +48,12 @@ data class ArgsDeclaration(val params: List<Item>, val endTokenType: Token.Type)
|
||||
arguments: Arguments = scope.args,
|
||||
defaultAccessType: AccessType = AccessType.Var,
|
||||
defaultVisibility: Visibility = Visibility.Public,
|
||||
defaultRecordType: ObjRecord.Type = ObjRecord.Type.ConstructorField
|
||||
) {
|
||||
fun assign(a: Item, value: Obj) {
|
||||
scope.addItem(a.name, (a.accessType ?: defaultAccessType).isMutable,
|
||||
value.byValueCopy(),
|
||||
a.visibility ?: defaultVisibility,
|
||||
recordType = defaultRecordType)
|
||||
recordType = ObjRecord.Type.Argument)
|
||||
}
|
||||
|
||||
// will be used with last lambda arg fix
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import net.sergeych.lyng.obj.Obj
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
//fun buildDoubleFromParts(
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import net.sergeych.lyng.obj.ObjRecord
|
||||
@ -7,10 +24,33 @@ import net.sergeych.lyng.obj.ObjRecord
|
||||
* Inherits [Scope.args] and [Scope.thisObj] from [callScope] and adds lookup for symbols
|
||||
* from [closureScope] with proper precedence
|
||||
*/
|
||||
class ClosureScope(val callScope: Scope,val closureScope: Scope) : Scope(callScope, callScope.args, thisObj = callScope.thisObj) {
|
||||
class ClosureScope(val callScope: Scope, val closureScope: Scope) :
|
||||
Scope(callScope, callScope.args, thisObj = callScope.thisObj) {
|
||||
|
||||
override fun get(name: String): ObjRecord? {
|
||||
// closure should be treated below callScope
|
||||
return super.get(name) ?: closureScope.get(name)
|
||||
// we take arguments from the callerScope, the rest
|
||||
// from the closure.
|
||||
|
||||
// note using super, not callScope, as arguments are assigned by the constructor
|
||||
// and are not assigned yet to vars in callScope self:
|
||||
super.objects[name]?.let {
|
||||
// if( name == "predicate" ) {
|
||||
// println("predicate: ${it.type.isArgument}: ${it.value}")
|
||||
// }
|
||||
if( it.type.isArgument ) return it
|
||||
}
|
||||
return closureScope.get(name)
|
||||
}
|
||||
}
|
||||
|
||||
class ApplyScope(_parent: Scope,val applied: Scope) : Scope(_parent, thisObj = applied.thisObj) {
|
||||
|
||||
override fun get(name: String): ObjRecord? {
|
||||
return applied.get(name) ?: super.get(name)
|
||||
}
|
||||
|
||||
override fun applyClosure(closure: Scope): Scope {
|
||||
return this
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
sealed class CodeContext {
|
||||
class Module(@Suppress("unused") val packageName: String?): CodeContext()
|
||||
class Function(val name: String): CodeContext()
|
||||
class ClassBody(val name: String): CodeContext()
|
||||
}
|
@ -1,5 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import ObjEnumClass
|
||||
import net.sergeych.lyng.obj.*
|
||||
import net.sergeych.lyng.pacman.ImportProvider
|
||||
|
||||
@ -27,6 +45,17 @@ class Compiler(
|
||||
|
||||
private fun popInitScope(): MutableList<Statement> = initStack.removeLast()
|
||||
|
||||
private val codeContexts = mutableListOf<CodeContext>(CodeContext.Module(null))
|
||||
|
||||
private suspend fun <T> inCodeContext(context: CodeContext, f: suspend () -> T): T {
|
||||
return try {
|
||||
codeContexts.add(context)
|
||||
f()
|
||||
} finally {
|
||||
codeContexts.removeLast()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun parseScript(): Script {
|
||||
val statements = mutableListOf<Statement>()
|
||||
val start = cc.currentPos()
|
||||
@ -69,7 +98,7 @@ class Compiler(
|
||||
statements += it
|
||||
}
|
||||
if (s == null) {
|
||||
when( t.type ) {
|
||||
when (t.type) {
|
||||
Token.Type.RBRACE, Token.Type.EOF, Token.Type.SEMICOLON -> {}
|
||||
else ->
|
||||
throw ScriptError(t.pos, "unexpeced `${t.value}` here")
|
||||
@ -96,7 +125,10 @@ class Compiler(
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
private var lastAnnotation: (suspend (Scope, ObjString, Statement) -> Statement)? = null
|
||||
|
||||
private suspend fun parseStatement(braceMeansLambda: Boolean = false): Statement? {
|
||||
lastAnnotation = null
|
||||
while (true) {
|
||||
val t = cc.next()
|
||||
return when (t.type) {
|
||||
@ -113,6 +145,11 @@ class Compiler(
|
||||
parseExpression()
|
||||
}
|
||||
|
||||
Token.Type.ATLABEL -> {
|
||||
lastAnnotation = parseAnnotation(t)
|
||||
continue
|
||||
}
|
||||
|
||||
Token.Type.LABEL -> continue
|
||||
Token.Type.SINLGE_LINE_COMMENT, Token.Type.MULTILINE_COMMENT -> continue
|
||||
|
||||
@ -339,6 +376,13 @@ class Compiler(
|
||||
|
||||
}
|
||||
|
||||
"throw" -> {
|
||||
val s = parseThrowStatement()
|
||||
operand = Accessor {
|
||||
s.execute(it).asReadonly
|
||||
}
|
||||
}
|
||||
|
||||
else -> operand?.let { left ->
|
||||
// selector: <lvalue>, '.' , <id>
|
||||
// we replace operand with selector code, that
|
||||
@ -478,7 +522,7 @@ class Compiler(
|
||||
|
||||
val callStatement = statement {
|
||||
// and the source closure of the lambda which might have other thisObj.
|
||||
val context = ClosureScope(this, closure!!) //AppliedScope(closure!!, args, this)
|
||||
val context = this.applyClosure(closure!!)
|
||||
if (argsDeclaration == null) {
|
||||
// no args: automatic var 'it'
|
||||
val l = args.list
|
||||
@ -490,7 +534,7 @@ class Compiler(
|
||||
// more args: it is a list of args
|
||||
else -> ObjList(l.toMutableList())
|
||||
}
|
||||
context.addItem("it", false, itValue)
|
||||
context.addItem("it", false, itValue, recordType = ObjRecord.Type.Argument)
|
||||
} else {
|
||||
// assign vars as declared the standard way
|
||||
argsDeclaration.assignToContext(context, defaultAccessType = AccessType.Val)
|
||||
@ -499,7 +543,7 @@ class Compiler(
|
||||
}
|
||||
|
||||
return Accessor { x ->
|
||||
if (closure == null) closure = x
|
||||
closure = x
|
||||
callStatement.asReadonly
|
||||
}
|
||||
}
|
||||
@ -818,6 +862,26 @@ class Compiler(
|
||||
return parseNumberOrNull(isPlus) ?: throw ScriptError(cc.currentPos(), "Expecting number")
|
||||
}
|
||||
|
||||
suspend fun parseAnnotation(t: Token): (suspend (Scope, ObjString, Statement) -> Statement) {
|
||||
val extraArgs = parseArgsOrNull()
|
||||
println("annotation ${t.value}: args: $extraArgs")
|
||||
return { scope, name, body ->
|
||||
val extras = extraArgs?.first?.toArguments(scope, extraArgs.second)?.list
|
||||
val required = listOf(name, body)
|
||||
val args = extras?.let { required + it } ?: required
|
||||
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}")
|
||||
(fn.execute(scope.copy(Arguments(args))) as? Statement)
|
||||
?: scope.raiseClassCastError("function annotation must return callable")
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun parseArgsOrNull(): Pair<List<ParsedArgument>, Boolean>? =
|
||||
if (cc.skipNextIf(Token.Type.LPAREN))
|
||||
parseArgs()
|
||||
else
|
||||
null
|
||||
|
||||
/**
|
||||
* Parse keyword-starting statement.
|
||||
* @return parsed statement or null if, for example. [id] is not among keywords
|
||||
@ -831,7 +895,8 @@ class Compiler(
|
||||
"break" -> parseBreakStatement(id.pos)
|
||||
"continue" -> parseContinueStatement(id.pos)
|
||||
"if" -> parseIfStatement()
|
||||
"class" -> parseClassDeclaration(false)
|
||||
"class" -> parseClassDeclaration()
|
||||
"enum" -> parseEnumDeclaration()
|
||||
"try" -> parseTryStatement()
|
||||
"throw" -> parseThrowStatement()
|
||||
"when" -> parseWhenStatement()
|
||||
@ -1118,8 +1183,44 @@ class Compiler(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun parseClassDeclaration(isStruct: Boolean): Statement {
|
||||
private fun parseEnumDeclaration(): Statement {
|
||||
val nameToken = cc.requireToken(Token.Type.ID)
|
||||
// so far only simplest enums:
|
||||
val names = mutableListOf<String>()
|
||||
// skip '{'
|
||||
cc.skipTokenOfType(Token.Type.LBRACE)
|
||||
|
||||
do {
|
||||
val t = cc.skipWsTokens()
|
||||
when (t.type) {
|
||||
Token.Type.ID -> {
|
||||
names += t.value
|
||||
val t1 = cc.skipWsTokens()
|
||||
when (t1.type) {
|
||||
Token.Type.COMMA ->
|
||||
continue
|
||||
|
||||
Token.Type.RBRACE -> break
|
||||
else -> {
|
||||
t1.raiseSyntax("unexpected token")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> t.raiseSyntax("expected enum entry name")
|
||||
}
|
||||
} while (true)
|
||||
|
||||
return statement {
|
||||
ObjEnumClass.createSimpleEnum(nameToken.value, names).also {
|
||||
addItem(nameToken.value, false, it, recordType = ObjRecord.Type.Enum)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun parseClassDeclaration(): Statement {
|
||||
val nameToken = cc.requireToken(Token.Type.ID)
|
||||
return inCodeContext(CodeContext.ClassBody(nameToken.value)) {
|
||||
val constructorArgsDeclaration =
|
||||
if (cc.skipTokenOfType(Token.Type.LPAREN, isOptional = true))
|
||||
parseArgsDeclaration(isClassDeclaration = true)
|
||||
@ -1151,8 +1252,8 @@ class Compiler(
|
||||
// create class
|
||||
val className = nameToken.value
|
||||
|
||||
@Suppress("UNUSED_VARIABLE") val defaultAccess = if (isStruct) AccessType.Var else AccessType.Initialization
|
||||
@Suppress("UNUSED_VARIABLE") val defaultVisibility = Visibility.Public
|
||||
// @Suppress("UNUSED_VARIABLE") val defaultAccess = if (isStruct) AccessType.Var else AccessType.Initialization
|
||||
// @Suppress("UNUSED_VARIABLE") val defaultVisibility = Visibility.Public
|
||||
|
||||
// create instance constructor
|
||||
// create custom objClass with all fields and instance constructor
|
||||
@ -1175,7 +1276,7 @@ class Compiler(
|
||||
constructorMeta = constructorArgsDeclaration
|
||||
}
|
||||
|
||||
return statement {
|
||||
statement {
|
||||
// the main statement should create custom ObjClass instance with field
|
||||
// accessors, constructor registration, etc.
|
||||
addItem(className, false, newClass)
|
||||
@ -1184,12 +1285,13 @@ class Compiler(
|
||||
newClass.classScope = classScope
|
||||
for (s in initScope)
|
||||
s.execute(classScope)
|
||||
.also { println("executed, ${classScope.objects}") }
|
||||
}
|
||||
newClass
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private fun getLabel(maxDepth: Int = 2): String? {
|
||||
var cnt = 0
|
||||
@ -1558,8 +1660,7 @@ class Compiler(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun
|
||||
parseFunctionDeclaration(
|
||||
private suspend fun parseFunctionDeclaration(
|
||||
visibility: Visibility = Visibility.Public,
|
||||
@Suppress("UNUSED_PARAMETER") isOpen: Boolean = false,
|
||||
isExtern: Boolean = false,
|
||||
@ -1572,6 +1673,9 @@ class Compiler(
|
||||
throw ScriptError(t.pos, "Expected identifier after 'fun'")
|
||||
else t.value
|
||||
|
||||
val annotation = lastAnnotation
|
||||
val parentContext = codeContexts.last()
|
||||
|
||||
t = cc.next()
|
||||
// Is extension?
|
||||
if (t.type == Token.Type.DOT) {
|
||||
@ -1595,6 +1699,8 @@ class Compiler(
|
||||
|
||||
if (cc.current().type == Token.Type.COLON) parseTypeDeclaration()
|
||||
|
||||
return inCodeContext(CodeContext.Function(name)) {
|
||||
|
||||
// Here we should be at open body
|
||||
val fnStatements = if (isExtern)
|
||||
statement { raiseError("extern function not provided: $name") }
|
||||
@ -1607,9 +1713,10 @@ class Compiler(
|
||||
callerContext.pos = start
|
||||
|
||||
// restore closure where the function was defined, and making a copy of it
|
||||
// for local space (otherwise it will write local stuff to closure!)
|
||||
// for local space. If there is no closure, we are in, say, class context where
|
||||
// the closure is in the class initialization and we needn't more:
|
||||
val context = closure?.let { ClosureScope(callerContext, it) }
|
||||
?: callerContext.raiseError("bug: closure not set")
|
||||
?: callerContext
|
||||
|
||||
// load params from caller context
|
||||
argsDeclaration.assignToContext(context, callerContext.args, defaultAccessType = AccessType.Val)
|
||||
@ -1620,8 +1727,13 @@ class Compiler(
|
||||
}
|
||||
val fnCreateStatement = statement(start) { context ->
|
||||
// we added fn in the context. now we must save closure
|
||||
// for the function
|
||||
// for the function, unless we're in the class scope:
|
||||
if (isStatic || parentContext !is CodeContext.ClassBody)
|
||||
closure = context
|
||||
|
||||
val annotatedFnBody = annotation?.invoke(context, ObjString(name), fnBody)
|
||||
?: fnBody
|
||||
|
||||
extTypeName?.let { typeName ->
|
||||
// class extension method
|
||||
val type = context[typeName]?.value ?: context.raiseSymbolNotFound("class $typeName not found")
|
||||
@ -1629,24 +1741,25 @@ class Compiler(
|
||||
type.addFn(name, isOpen = true) {
|
||||
// ObjInstance has a fixed instance scope, so we need to build a closure
|
||||
(thisObj as? ObjInstance)?.let { i ->
|
||||
fnBody.execute(ClosureScope(this, i.instanceScope))
|
||||
annotatedFnBody.execute(ClosureScope(this, i.instanceScope))
|
||||
}
|
||||
// other classes can create one-time scope for this rare case:
|
||||
?: fnBody.execute(thisObj.autoInstanceScope(this))
|
||||
?: annotatedFnBody.execute(thisObj.autoInstanceScope(this))
|
||||
}
|
||||
}
|
||||
// regular function/method
|
||||
?: context.addItem(name, false, fnBody, visibility)
|
||||
?: context.addItem(name, false, annotatedFnBody, visibility)
|
||||
// as the function can be called from anywhere, we have
|
||||
// saved the proper context in the closure
|
||||
fnBody
|
||||
annotatedFnBody
|
||||
}
|
||||
return if (isStatic) {
|
||||
if (isStatic) {
|
||||
currentInitScope += fnCreateStatement
|
||||
NopStatement
|
||||
} else
|
||||
fnCreateStatement
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun parseBlock(skipLeadingBrace: Boolean = false): Statement {
|
||||
val startPos = cc.currentPos()
|
||||
@ -1680,6 +1793,10 @@ class Compiler(
|
||||
|
||||
val eqToken = cc.next()
|
||||
var setNull = false
|
||||
|
||||
val isDelegate = if (eqToken.isId("by")) {
|
||||
true
|
||||
} else {
|
||||
if (eqToken.type != Token.Type.ASSIGN) {
|
||||
if (!isMutable)
|
||||
throw ScriptError(start, "val must be initialized")
|
||||
@ -1688,16 +1805,19 @@ class Compiler(
|
||||
setNull = true
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
val initialExpression = if (setNull) null else parseStatement(true)
|
||||
val initialExpression = if (setNull) null
|
||||
else parseStatement(true)
|
||||
?: throw ScriptError(eqToken.pos, "Expected initializer expression")
|
||||
|
||||
if (isStatic) {
|
||||
// find objclass instance: this is tricky: this code executes in object initializer,
|
||||
// when creating instance, but we need to execute it in the class initializer which
|
||||
// is missing as for now. Add it to the compiler context?
|
||||
// add there
|
||||
// return
|
||||
|
||||
// if (isDelegate) throw ScriptError(start, "static delegates are not yet implemented")
|
||||
currentInitScope += statement {
|
||||
val initValue = initialExpression?.execute(this)?.byValueCopy() ?: ObjNull
|
||||
(thisObj as ObjClass).createClassField(name, initValue, isMutable, visibility, pos)
|
||||
@ -1711,14 +1831,34 @@ class Compiler(
|
||||
if (context.containsLocal(name))
|
||||
throw ScriptError(nameToken.pos, "Variable $name is already defined")
|
||||
|
||||
if (isDelegate) {
|
||||
TODO()
|
||||
// println("initial expr = $initialExpression")
|
||||
// val initValue =
|
||||
// (initialExpression?.execute(context.copy(Arguments(ObjString(name)))) as? Statement)
|
||||
// ?.execute(context.copy(Arguments(ObjString(name))))
|
||||
// ?: context.raiseError("delegate initialization required")
|
||||
// println("delegate init: $initValue")
|
||||
// if (!initValue.isInstanceOf(ObjArray))
|
||||
// context.raiseIllegalArgument("delegate initialized must be an array")
|
||||
// val s = initValue.getAt(context, 1)
|
||||
// val setter = if (s == ObjNull) statement { raiseNotImplemented("setter is not provided") }
|
||||
// else (s as? Statement) ?: context.raiseClassCastError("setter must be a callable")
|
||||
// ObjDelegate(
|
||||
// (initValue.getAt(context, 0) as? Statement)
|
||||
// ?: context.raiseClassCastError("getter must be a callable"), setter
|
||||
// ).also {
|
||||
// context.addItem(name, isMutable, it, visibility, recordType = ObjRecord.Type.Field)
|
||||
// }
|
||||
} else {
|
||||
// init value could be a val; when we initialize by-value type var with it, we need to
|
||||
// create a separate copy:
|
||||
val initValue = initialExpression?.execute(context)?.byValueCopy() ?: ObjNull
|
||||
|
||||
context.addItem(name, isMutable, initValue, visibility, recordType = ObjRecord.Type.Field)
|
||||
initValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class Operator(
|
||||
val tokenType: Token.Type,
|
||||
@ -1835,7 +1975,15 @@ class Compiler(
|
||||
Operator.simple(Token.Type.IS, lastPriority) { _, a, b -> ObjBool(a.isInstanceOf(b)) },
|
||||
Operator.simple(Token.Type.NOTIS, lastPriority) { _, a, b -> ObjBool(!a.isInstanceOf(b)) },
|
||||
|
||||
Operator.simple(Token.Type.ELVIS, ++lastPriority) { _, a, b -> if (a == ObjNull) b else a },
|
||||
Operator(Token.Type.ELVIS, ++lastPriority, 2) { _: Pos, a: Accessor, b: Accessor ->
|
||||
Accessor {
|
||||
val aa = a.getter(it).value
|
||||
(
|
||||
if (aa != ObjNull) aa
|
||||
else b.getter(it).value
|
||||
).asReadonly
|
||||
}
|
||||
},
|
||||
|
||||
// shuttle <=> 6
|
||||
Operator.simple(Token.Type.SHUTTLE, ++lastPriority) { c, a, b ->
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
class CompilerContext(val tokens: List<Token>) {
|
||||
@ -20,7 +37,7 @@ class CompilerContext(val tokens: List<Token>) {
|
||||
fun hasNext() = currentIndex < tokens.size
|
||||
fun hasPrevious() = currentIndex > 0
|
||||
fun next() =
|
||||
if( currentIndex < tokens.size ) tokens[currentIndex++]
|
||||
if (currentIndex < tokens.size) tokens[currentIndex++]
|
||||
else Token("", tokens.last().pos, Token.Type.EOF)
|
||||
// throw IllegalStateException("No more tokens")
|
||||
|
||||
@ -61,7 +78,7 @@ class CompilerContext(val tokens: List<Token>) {
|
||||
*/
|
||||
fun skipId(name: String): Boolean {
|
||||
current().let { t ->
|
||||
if( t.type == Token.Type.ID && t.value == name ) {
|
||||
if (t.type == Token.Type.ID && t.value == name) {
|
||||
next()
|
||||
return true
|
||||
}
|
||||
@ -93,6 +110,20 @@ class CompilerContext(val tokens: List<Token>) {
|
||||
} else true
|
||||
}
|
||||
|
||||
/**
|
||||
* If next token is one of these types, skip it.
|
||||
* @return true if token was found and skipped
|
||||
*/
|
||||
fun skipNextIf(vararg types: Token.Type): Boolean {
|
||||
val t = next()
|
||||
return if (t.type in types)
|
||||
true
|
||||
else {
|
||||
previous()
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun skipTokens(vararg tokenTypes: Token.Type) {
|
||||
while (next().type in tokenTypes) { /**/
|
||||
@ -143,19 +174,24 @@ class CompilerContext(val tokens: List<Token>) {
|
||||
fun matchQualifiers(keyword: String, vararg qualifiers: String): Boolean {
|
||||
val pos = savePos()
|
||||
var count = 0
|
||||
while( count < qualifiers.size) {
|
||||
while (count < qualifiers.size) {
|
||||
val t = next()
|
||||
when(t.type) {
|
||||
when (t.type) {
|
||||
Token.Type.ID -> {
|
||||
if( t.value in qualifiers ) count++
|
||||
else { restorePos(pos); return false }
|
||||
if (t.value in qualifiers) count++
|
||||
else {
|
||||
restorePos(pos); return false
|
||||
}
|
||||
}
|
||||
|
||||
Token.Type.MULTILINE_COMMENT, Token.Type.SINLGE_LINE_COMMENT, Token.Type.NEWLINE -> {}
|
||||
else -> { restorePos(pos); return false }
|
||||
else -> {
|
||||
restorePos(pos); return false
|
||||
}
|
||||
}
|
||||
}
|
||||
val t = next()
|
||||
if( t.type == Token.Type.ID && t.value == keyword ) {
|
||||
if (t.type == Token.Type.ID && t.value == keyword) {
|
||||
return true
|
||||
} else {
|
||||
restorePos(pos)
|
||||
@ -168,7 +204,7 @@ class CompilerContext(val tokens: List<Token>) {
|
||||
* Note that [Token.Type.EOF] is not considered a whitespace token.
|
||||
*/
|
||||
fun skipWsTokens(): Token {
|
||||
while( current().type in wstokens ) {
|
||||
while (current().type in wstokens) {
|
||||
next()
|
||||
}
|
||||
return next()
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import net.sergeych.lyng.obj.Accessor
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import net.sergeych.lyng.obj.Obj
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import net.sergeych.lyng.obj.ObjRecord
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
val digitsSet = ('0'..'9').toSet()
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
data class Pos(val source: Source, val line: Int, val column: Int) {
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import net.sergeych.lyng.obj.*
|
||||
@ -71,6 +88,11 @@ open class Scope(
|
||||
throw ExecutionError(obj)
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun raiseNotFound(message: String="not found"): Nothing {
|
||||
throw ExecutionError(ObjNotFoundException(this,message))
|
||||
}
|
||||
|
||||
inline fun <reified T : Obj> requiredArg(index: Int): T {
|
||||
if (args.list.size <= index) raiseError("Expected at least ${index + 1} argument, got ${args.list.size}")
|
||||
return (args.list[index].byValueCopy() as? T)
|
||||
@ -109,9 +131,16 @@ open class Scope(
|
||||
open operator fun get(name: String): ObjRecord? =
|
||||
if (name == "this") thisObj.asReadonly
|
||||
else {
|
||||
objects[name]
|
||||
(objects[name]
|
||||
?: parent?.get(name)
|
||||
?: thisObj.objClass.getInstanceMemberOrNull(name)
|
||||
?: thisObj.objClass
|
||||
.getInstanceMemberOrNull(name)
|
||||
)
|
||||
// ?.also {
|
||||
// if( name == "predicate") {
|
||||
// println("got predicate $it")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fun copy(pos: Pos, args: Arguments = Arguments.EMPTY, newThisObj: Obj? = null): Scope =
|
||||
@ -220,6 +249,8 @@ open class Scope(
|
||||
|
||||
}
|
||||
|
||||
open fun applyClosure(closure: Scope): Scope = ClosureScope(this, closure)
|
||||
|
||||
companion object {
|
||||
|
||||
fun new(): Scope =
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
import kotlinx.coroutines.delay
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@file:Suppress("CanBeParameter")
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
interface SecurityManager {
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
class Source(val fileName: String, text: String) {
|
||||
|
@ -1,8 +1,33 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
data class Token(val value: String, val pos: Pos, val type: Type) {
|
||||
fun raiseSyntax(text: String): Nothing {
|
||||
throw ScriptError(pos, text)
|
||||
}
|
||||
|
||||
val isComment: Boolean by lazy { type == Type.SINLGE_LINE_COMMENT || type == Type.MULTILINE_COMMENT }
|
||||
|
||||
fun isId(text: String) =
|
||||
type == Type.ID && value == text
|
||||
|
||||
|
||||
@Suppress("unused")
|
||||
enum class Type {
|
||||
ID, INT, REAL, HEX, STRING, CHAR,
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
enum class Visibility {
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
@ -68,13 +85,15 @@ open class Obj {
|
||||
name: String,
|
||||
args: Arguments = Arguments.EMPTY,
|
||||
onNotFoundResult: Obj?=null
|
||||
): Obj =
|
||||
objClass.getInstanceMemberOrNull(name)?.value?.invoke(
|
||||
): Obj {
|
||||
return objClass.getInstanceMemberOrNull(name)?.value?.invoke(
|
||||
scope,
|
||||
this,
|
||||
args)
|
||||
args
|
||||
)
|
||||
?: onNotFoundResult
|
||||
?: scope.raiseSymbolNotFound(name)
|
||||
}
|
||||
|
||||
open suspend fun getInstanceMethod(
|
||||
scope: Scope,
|
||||
@ -144,6 +163,8 @@ open class Obj {
|
||||
|
||||
open suspend fun assign(scope: Scope, other: Obj): Obj? = null
|
||||
|
||||
open fun getValue(scope: Scope) = this
|
||||
|
||||
/**
|
||||
* a += b
|
||||
* if( the operation is not defined, it returns null and the compiler would try
|
||||
@ -269,6 +290,9 @@ open class Obj {
|
||||
addFn("toString") {
|
||||
thisObj.asStr
|
||||
}
|
||||
addFn("inspect", true) {
|
||||
thisObj.inspect().toObj()
|
||||
}
|
||||
addFn("contains") {
|
||||
ObjBool(thisObj.contains(this, args.firstAndOnly()))
|
||||
}
|
||||
@ -277,15 +301,23 @@ open class Obj {
|
||||
args.firstAndOnly().callOn(copy(Arguments(thisObj)))
|
||||
}
|
||||
addFn("apply") {
|
||||
val newContext = (thisObj as? ObjInstance)?.instanceScope ?: this
|
||||
args.firstAndOnly()
|
||||
.callOn(newContext)
|
||||
val body = args.firstAndOnly()
|
||||
(thisObj as? ObjInstance)?.let {
|
||||
println("apply in ${thisObj is ObjInstance}, ${it.instanceScope}")
|
||||
body.callOn(ApplyScope(this, it.instanceScope))
|
||||
} ?: run {
|
||||
println("apply on non-instance $thisObj")
|
||||
body.callOn(this)
|
||||
}
|
||||
thisObj
|
||||
}
|
||||
addFn("also") {
|
||||
args.firstAndOnly().callOn(copy(Arguments(thisObj)))
|
||||
thisObj
|
||||
}
|
||||
addFn("run") {
|
||||
args.firstAndOnly().callOn(this)
|
||||
}
|
||||
addFn("getAt") {
|
||||
requireExactCount(1)
|
||||
thisObj.getAt(this, requiredArg<Obj>(0))
|
||||
@ -513,6 +545,7 @@ open class ObjException(exceptionClass: ExceptionClass, val scope: Scope, val me
|
||||
"IterationEndException",
|
||||
"AccessException",
|
||||
"UnknownException",
|
||||
"NotFoundException"
|
||||
)) {
|
||||
scope.addConst(name, getOrCreateExceptionClass(name))
|
||||
}
|
||||
@ -556,3 +589,6 @@ class ObjUnknownException(scope: Scope, message: String = "access not allowed er
|
||||
|
||||
class ObjIllegalOperationException(scope: Scope, message: String = "Operation is illegal") :
|
||||
ObjException("IllegalOperationException", scope, message)
|
||||
|
||||
class ObjNotFoundException(scope: Scope, message: String = "not found") :
|
||||
ObjException("NotFoundException", scope, message)
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
val ObjArray by lazy {
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.bintools.toDump
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
|
@ -1,20 +1,44 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import net.sergeych.bintools.decodeHex
|
||||
import net.sergeych.bintools.encodeToHex
|
||||
import net.sergeych.bintools.toDump
|
||||
import net.sergeych.lyng.Scope
|
||||
import net.sergeych.lyng.statement
|
||||
import net.sergeych.lynon.BitArray
|
||||
import net.sergeych.lynon.LynonDecoder
|
||||
import net.sergeych.lynon.LynonEncoder
|
||||
import net.sergeych.lynon.LynonType
|
||||
import net.sergeych.mp_tools.decodeBase64Url
|
||||
import net.sergeych.mp_tools.encodeToBase64Url
|
||||
import kotlin.math.min
|
||||
|
||||
open class ObjBuffer(val byteArray: UByteArray) : Obj() {
|
||||
|
||||
override val objClass: ObjClass = type
|
||||
|
||||
val hex by lazy { byteArray.encodeToHex("")}
|
||||
val base64 by lazy { byteArray.toByteArray().encodeToBase64Url()}
|
||||
|
||||
fun checkIndex(scope: Scope, index: Obj): Int {
|
||||
if (index !is ObjInt)
|
||||
scope.raiseIllegalArgument("index must be Int")
|
||||
@ -66,9 +90,7 @@ open class ObjBuffer(val byteArray: UByteArray) : Obj() {
|
||||
} else scope.raiseIllegalArgument("can't concatenate buffer with ${other.inspect()}")
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "Buffer(${byteArray.encodeToHex()})"
|
||||
}
|
||||
override fun toString(): String = base64
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
@ -85,6 +107,8 @@ open class ObjBuffer(val byteArray: UByteArray) : Obj() {
|
||||
encoder.encodeCachedBytes(byteArray.asByteArray())
|
||||
}
|
||||
|
||||
override fun inspect(): String = "Buf($base64)"
|
||||
|
||||
companion object {
|
||||
private suspend fun createBufferFrom(scope: Scope, obj: Obj): ObjBuffer =
|
||||
when (obj) {
|
||||
@ -141,11 +165,27 @@ open class ObjBuffer(val byteArray: UByteArray) : Obj() {
|
||||
})
|
||||
|
||||
}.apply {
|
||||
addClassFn("decodeBase64") {
|
||||
ObjBuffer(requireOnlyArg<Obj>().toString().decodeBase64Url().asUByteArray())
|
||||
}
|
||||
addClassFn("decodeHex") {
|
||||
ObjBuffer(requireOnlyArg<Obj>().toString().decodeHex().asUByteArray())
|
||||
}
|
||||
createField("size",
|
||||
statement {
|
||||
(thisObj as ObjBuffer).byteArray.size.toObj()
|
||||
}
|
||||
)
|
||||
createField("hex",
|
||||
statement {
|
||||
thisAs<ObjBuffer>().hex.toObj()
|
||||
}
|
||||
)
|
||||
createField("base64",
|
||||
statement {
|
||||
thisAs<ObjBuffer>().base64.toObj()
|
||||
}
|
||||
)
|
||||
addFn("decodeUtf8") {
|
||||
ObjString(
|
||||
thisAs<ObjBuffer>().byteArray.toByteArray().decodeToString()
|
||||
@ -161,6 +201,9 @@ open class ObjBuffer(val byteArray: UByteArray) : Obj() {
|
||||
thisAs<ObjBuffer>().byteArray.toByteArray().toDump()
|
||||
)
|
||||
}
|
||||
addFn("toBitInput") {
|
||||
ObjBitBuffer(BitArray(thisAs<ObjBuffer>().byteArray, 8))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.*
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
/**
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import kotlinx.coroutines.Deferred
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
//class ObjDelegateContext()
|
||||
//
|
||||
//class ObjDelegate(
|
||||
// val getter: Statement,
|
||||
// val setter: Statement = statement { raiseNotImplemented("setter is not implemented") }
|
||||
//): Obj() {
|
||||
//
|
||||
// override suspend fun assign(scope: Scope, other: Obj): Obj? {
|
||||
// setter.execute(scope.copy(Arguments(other)))
|
||||
// return other
|
||||
// }
|
||||
//
|
||||
// companion object {
|
||||
// val type = object: ObjClass("Delegate") {
|
||||
// override suspend fun callOn(scope: Scope): Obj {
|
||||
// scope.raiseError("Delegate should not be constructed directly")
|
||||
// }
|
||||
// }.apply {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Arguments
|
||||
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
import net.sergeych.lyng.obj.*
|
||||
import net.sergeych.lynon.LynonDecoder
|
||||
import net.sergeych.lynon.LynonEncoder
|
||||
import net.sergeych.lynon.LynonType
|
||||
|
||||
open class ObjEnumEntry(enumClass: ObjEnumClass, val name: ObjString, val ordinal: ObjInt) : Obj() {
|
||||
override val objClass = enumClass
|
||||
|
||||
override fun toString(): String {
|
||||
return "$objClass.$name"
|
||||
}
|
||||
|
||||
override suspend fun serialize(scope: Scope, encoder: LynonEncoder, lynonType: LynonType?) {
|
||||
encoder.encodeUnsigned(ordinal.value.toULong())
|
||||
}
|
||||
|
||||
override suspend fun compareTo(scope: Scope, other: Obj): Int {
|
||||
if( other !is ObjEnumEntry) return -2
|
||||
if( other.objClass != objClass ) return -2
|
||||
return ordinal.compareTo(scope, other.ordinal)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object EnumBase : ObjClass("Enum") {
|
||||
|
||||
}
|
||||
|
||||
class ObjEnumClass(val name: String) : ObjClass(name, EnumBase) {
|
||||
val objEntries = ObjList()
|
||||
val byName by lazy { objEntries.list.associateBy { (it as ObjEnumEntry).name } }
|
||||
|
||||
init {
|
||||
addClassConst("entries", objEntries )
|
||||
addClassFn("valueOf") {
|
||||
val name = requireOnlyArg<ObjString>()
|
||||
byName[name] ?: raiseSymbolNotFound("does not exists: enum ${className}.$name")
|
||||
}
|
||||
addFn("name") { thisAs<ObjEnumEntry>().name }
|
||||
addFn("ordinal") { thisAs<ObjEnumEntry>().ordinal }
|
||||
|
||||
}
|
||||
|
||||
override suspend fun deserialize(scope: Scope, decoder: LynonDecoder, lynonType: LynonType?): Obj {
|
||||
val index = decoder.unpackUnsigned().toInt()
|
||||
return objEntries.list[index]
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun createSimpleEnum(enumName: String, names: List<String>): ObjEnumClass {
|
||||
val klass = ObjEnumClass(enumName)
|
||||
names.forEachIndexed { index, name ->
|
||||
val entry = ObjEnumEntry(klass, ObjString(name), ObjInt(index.toLong(), isConst = true))
|
||||
klass.objEntries.list += entry
|
||||
klass.addClassConst(name, entry)
|
||||
}
|
||||
return klass
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
@ -23,12 +40,12 @@ class ObjFlowBuilder(val output: SendChannel<Obj>) : Obj() {
|
||||
val data = requireOnlyArg<Obj>()
|
||||
try {
|
||||
val channel = thisAs<ObjFlowBuilder>().output
|
||||
if( !channel.isClosedForSend )
|
||||
if (!channel.isClosedForSend)
|
||||
channel.send(data)
|
||||
else
|
||||
throw ScriptFlowIsNoMoreCollected()
|
||||
} catch (x: Exception) {
|
||||
if( x !is CancellationException )
|
||||
if (x !is CancellationException)
|
||||
x.printStackTrace()
|
||||
throw ScriptFlowIsNoMoreCollected()
|
||||
}
|
||||
@ -45,12 +62,10 @@ private fun createLyngFlowInput(scope: Scope, producer: Statement): ReceiveChann
|
||||
globalLaunch {
|
||||
try {
|
||||
producer.execute(builderScope)
|
||||
}
|
||||
catch(x: ScriptFlowIsNoMoreCollected) {
|
||||
} catch (x: ScriptFlowIsNoMoreCollected) {
|
||||
x.printStackTrace()
|
||||
// premature flow closing, OK
|
||||
}
|
||||
catch(x: Exception) {
|
||||
} catch (x: Exception) {
|
||||
x.printStackTrace()
|
||||
}
|
||||
channel.close()
|
||||
@ -70,7 +85,11 @@ class ObjFlow(val producer: Statement, val scope: Scope) : Obj() {
|
||||
}.apply {
|
||||
addFn("iterator") {
|
||||
val objFlow = thisAs<ObjFlow>()
|
||||
ObjFlowIterator( statement { objFlow.producer.execute(ClosureScope(this,objFlow.scope)) } )
|
||||
ObjFlowIterator(statement {
|
||||
objFlow.producer.execute(
|
||||
ClosureScope(this, objFlow.scope)
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,9 +107,10 @@ class ObjFlowIterator(val producer: Statement) : Obj() {
|
||||
private var isCancelled = false
|
||||
|
||||
private fun checkNotCancelled(scope: Scope) {
|
||||
if( isCancelled )
|
||||
if (isCancelled)
|
||||
scope.raiseIllegalState("iteration is cancelled")
|
||||
}
|
||||
|
||||
suspend fun hasNext(scope: Scope): ObjBool {
|
||||
checkNotCancelled(scope)
|
||||
// cold start:
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Arguments
|
||||
@ -71,18 +88,15 @@ class ObjInstance(override val objClass: ObjClass) : Obj() {
|
||||
val vars = instanceVars.values.map { it.value }
|
||||
if( vars.isNotEmpty()) {
|
||||
encoder.encodeAnyList(scope, vars)
|
||||
println("serialized state vars $vars")
|
||||
}
|
||||
}
|
||||
|
||||
internal suspend fun deserializeStateVars(scope: Scope, decoder: LynonDecoder) {
|
||||
val localVars = instanceVars.values.toList()
|
||||
if( localVars.isNotEmpty() ) {
|
||||
println("gonna read vars")
|
||||
val vars = decoder.decodeAnyList(scope)
|
||||
if (vars.size > instanceVars.size)
|
||||
scope.raiseIllegalArgument("serialized vars has bigger size than instance vars")
|
||||
println("deser state vars $vars")
|
||||
for ((i, v) in vars.withIndex()) {
|
||||
localVars[i].value = v
|
||||
}
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Arguments
|
||||
@ -12,7 +29,6 @@ class ObjInstanceClass(val name: String) : ObjClass(name) {
|
||||
|
||||
override suspend fun deserialize(scope: Scope, decoder: LynonDecoder, lynonType: LynonType?): Obj {
|
||||
val args = decoder.decodeAnyList(scope)
|
||||
println("deserializing constructor $name, $args params")
|
||||
val actualSize = constructorMeta?.params?.size ?: 0
|
||||
if( args.size > actualSize )
|
||||
scope.raiseIllegalArgument("constructor $name has only $actualSize but serialized version has ${args.size}")
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import kotlinx.datetime.Clock
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
@ -45,7 +62,7 @@ class ObjInt(var value: Long, override val isConst: Boolean = false) : Obj(), Nu
|
||||
|
||||
override fun toString(): String = value.toString()
|
||||
|
||||
override val objClass: ObjClass = type
|
||||
override val objClass: ObjClass by lazy { type }
|
||||
|
||||
override suspend fun plus(scope: Scope, other: Obj): Obj =
|
||||
if (other is ObjInt)
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Arguments
|
||||
@ -42,6 +59,9 @@ val ObjIterable by lazy {
|
||||
}
|
||||
|
||||
addFn("toSet") {
|
||||
if( thisObj.isInstanceOf(ObjSet.type) )
|
||||
thisObj
|
||||
else {
|
||||
val result = mutableSetOf<Obj>()
|
||||
val it = thisObj.invokeInstanceMethod(this, "iterator")
|
||||
while (it.invokeInstanceMethod(this, "hasNext").toBool()) {
|
||||
@ -49,6 +69,7 @@ val ObjIterable by lazy {
|
||||
}
|
||||
ObjSet(result)
|
||||
}
|
||||
}
|
||||
|
||||
addFn("toMap") {
|
||||
val result = ObjMap()
|
||||
|
@ -1,4 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
val ObjIterator by lazy { ObjClass("Iterator") }
|
||||
/**
|
||||
* Iterator should provide lyng-level iterator functions:
|
||||
*
|
||||
* - hasNext()
|
||||
* - next()
|
||||
* - optional cancelIteration() that _may_ be called when iteration is performed
|
||||
* only on the part of the iterable entity. Implement it when there are resources
|
||||
* to be reclaimed on iteration interruption.
|
||||
*/
|
||||
val ObjIterator by lazy {
|
||||
ObjClass("Iterator").apply {
|
||||
addFn("cancelIteration", true) {
|
||||
ObjVoid
|
||||
}
|
||||
addFn("hasNext", true) {
|
||||
raiseNotImplemented("hasNext() is not implemented")
|
||||
}
|
||||
addFn("next", true) {
|
||||
raiseNotImplemented("next() is not implemented")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
@ -39,7 +56,7 @@ class ObjRangeIterator(val self: ObjRange) : Obj() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
val type = ObjClass("RangeIterator", ObjIterable).apply {
|
||||
val type = ObjClass("RangeIterator", ObjIterator).apply {
|
||||
addFn("hasNext") {
|
||||
thisAs<ObjRangeIterator>().hasNext().toObj()
|
||||
}
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Pos
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
@ -18,8 +35,15 @@ data class ObjRecord(
|
||||
Field(true, true),
|
||||
@Suppress("unused")
|
||||
Fun,
|
||||
@Suppress("unused")
|
||||
ConstructorField(true, true),
|
||||
Other
|
||||
Argument(true, true),
|
||||
@Suppress("unused")
|
||||
Class,
|
||||
Enum,
|
||||
Other;
|
||||
|
||||
val isArgument get() = this == Argument
|
||||
}
|
||||
@Suppress("unused")
|
||||
fun qualifiedName(name: String): String =
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
@ -92,7 +109,7 @@ class ObjSet(val set: MutableSet<Obj> = mutableSetOf()) : Obj() {
|
||||
companion object {
|
||||
|
||||
|
||||
val type = object : ObjClass("Set", ObjCollection) {
|
||||
val type: ObjClass = object : ObjClass("Set", ObjCollection) {
|
||||
override suspend fun callOn(scope: Scope): Obj {
|
||||
return ObjSet(scope.args.list.toMutableSet())
|
||||
}
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.pacman
|
||||
|
||||
import net.sergeych.lyng.*
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.pacman
|
||||
|
||||
import net.sergeych.lyng.*
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.pacman
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
|
@ -1,7 +1,25 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
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)
|
||||
@ -28,6 +46,7 @@ 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
|
||||
throw UnsupportedOperationException("not comparable")
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng.stdlib_included
|
||||
internal val rootLyng = """
|
||||
package lyng.stdlib
|
||||
|
||||
fun cached(builder) {
|
||||
var calculated = false
|
||||
var value = null
|
||||
{
|
||||
if( !calculated ) {
|
||||
value = builder()
|
||||
calculated = true
|
||||
}
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
fun Iterable.filter(predicate) {
|
||||
val list = this
|
||||
flow {
|
||||
for( item in list ) {
|
||||
if( predicate(item) ) {
|
||||
if( predicate(item) ) {ln
|
||||
emit(item)
|
||||
}
|
||||
}
|
||||
@ -21,7 +50,7 @@ fun Iterable.drop(n) {
|
||||
fun Iterable.first() {
|
||||
val i = iterator()
|
||||
if( !i.hasNext() ) throw NoSuchElementException()
|
||||
i.next()
|
||||
i.next().also { i.cancelIteration() }
|
||||
}
|
||||
|
||||
fun Iterable.last() {
|
||||
@ -54,5 +83,26 @@ fun Iterable.takeLast(n) {
|
||||
buffer
|
||||
}
|
||||
|
||||
fun Iterable.joinToString(prefix=" ", transformer=null) {
|
||||
var result = null
|
||||
for( part in this ) {
|
||||
val transformed = transformer?(part)?.toString() ?: part.toString()
|
||||
if( result == null ) result = transformed
|
||||
else result += prefix + transformed
|
||||
}
|
||||
result ?: ""
|
||||
}
|
||||
|
||||
fun Iterable.any(predicate): Bool {
|
||||
for( i in this ) {
|
||||
if( predicate(i) )
|
||||
break true
|
||||
} else false
|
||||
}
|
||||
|
||||
fun Iterable.all(predicate): Bool {
|
||||
!any { !predicate(it) }
|
||||
}
|
||||
|
||||
""".trimIndent()
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lyng
|
||||
|
||||
fun leftMargin(s: String): Int {
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
interface BitInput {
|
||||
@ -82,6 +99,8 @@ interface BitInput {
|
||||
fun decompressStringOrNull(): String? = decompressOrNull()?.decodeToString()
|
||||
|
||||
fun decompressString(): String = decompress().decodeToString()
|
||||
|
||||
@Suppress("unused")
|
||||
fun unpackDouble(): Double {
|
||||
val bits = getBits(64)
|
||||
return Double.fromBits(bits.toLong())
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
@Suppress("unused")
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
interface BitOutput {
|
||||
@ -84,7 +101,6 @@ interface BitOutput {
|
||||
val compressed = LZW.compress(source.asUByteArray())
|
||||
// check that compression is effective including header bits size:
|
||||
if( compressed.size + 2 < source.size * 8L) {
|
||||
println("write compressed")
|
||||
putBit(1)
|
||||
// LZW algorithm
|
||||
putBits(0, 2)
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
class DecompressionException(message: String) : IllegalArgumentException(message) {}
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
@ -48,7 +65,6 @@ open class LynonDecoder(val bin: BitInput, val settings: LynonSettings = LynonSe
|
||||
|
||||
private suspend fun decodeClassObj(scope: Scope): ObjClass {
|
||||
val className = decodeObject(scope, ObjString.type, null) as ObjString
|
||||
println("expected class name $className")
|
||||
return scope.get(className.value)?.value?.let {
|
||||
if (it !is ObjClass)
|
||||
scope.raiseClassCastError("Expected obj class but got ${it::class.simpleName}")
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
import net.sergeych.bintools.ByteChunk
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
import net.sergeych.lyng.obj.ObjBool
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
import kotlin.math.min
|
||||
@ -85,7 +102,7 @@ class BitArray(val bytes: UByteArray, val lastByteBits: Int) : BitList {
|
||||
* in the bit 0x02 of the first byte, etc.
|
||||
*
|
||||
* This allows automatic fill of the last byte with zeros. This is important when
|
||||
* using bytes stored from [asByteArray] or [asUbyteArray]. When converting to
|
||||
* using bytes stored from [asByteArray] or `asUbyteArray`. When converting to
|
||||
* bytes, automatic padding to byte size is applied. With such bit order, constructing
|
||||
* [BitInput] to read from [ByteArray.toUByteArray] result only provides 0 to 7 extra zeroes bits
|
||||
* at teh end which is often acceptable. To avoid this, use [toBitArray]; the [BitArray]
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
/**
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
import net.sergeych.collections.SortedList
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
import net.sergeych.bintools.ByteChunk
|
||||
|
@ -1,3 +1,20 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package net.sergeych.lynon
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
@ -9,28 +26,43 @@ import net.sergeych.lyng.obj.ObjString
|
||||
// Most often used types:
|
||||
|
||||
|
||||
val ObjLynonClass = object : ObjClass("Lynon") {
|
||||
object ObjLynonClass : ObjClass("Lynon") {
|
||||
|
||||
suspend fun Scope.encodeAny(obj: Obj): Obj {
|
||||
suspend fun encodeAny(scope: Scope, obj: Obj): ObjBitBuffer {
|
||||
val bout = MemoryBitOutput()
|
||||
val serializer = LynonEncoder(bout)
|
||||
serializer.encodeAny(this, obj)
|
||||
serializer.encodeAny(scope, obj)
|
||||
return ObjBitBuffer(bout.toBitArray())
|
||||
}
|
||||
|
||||
suspend fun Scope.decodeAny(source: Obj): Obj {
|
||||
if( source !is ObjBitBuffer) throw Exception("Invalid source: $source")
|
||||
suspend fun decodeAny(scope: Scope, source: Obj): Obj {
|
||||
if (source !is ObjBitBuffer) throw Exception("Invalid source: $source")
|
||||
val bin = source.bitArray.toInput()
|
||||
val deserializer = LynonDecoder(bin)
|
||||
return deserializer.decodeAny(this)
|
||||
return deserializer.decodeAny(scope)
|
||||
}
|
||||
|
||||
}.apply {
|
||||
init {
|
||||
addClassConst("test", ObjString("test_const"))
|
||||
addClassFn("encode") {
|
||||
encodeAny(requireOnlyArg<Obj>())
|
||||
encodeAny(this, requireOnlyArg<Obj>())
|
||||
}
|
||||
addClassFn("decode") {
|
||||
decodeAny(requireOnlyArg<Obj>())
|
||||
decodeAny(this, requireOnlyArg<Obj>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
suspend fun lynonEncodeAny(scope: Scope, value: Obj): UByteArray =
|
||||
(ObjLynonClass.encodeAny(scope, value))
|
||||
.bitArray.asUbyteArray()
|
||||
|
||||
@Suppress("unused")
|
||||
suspend fun lynonDecodeAny(scope: Scope, encoded: UByteArray): Obj =
|
||||
ObjLynonClass.decodeAny(
|
||||
scope,
|
||||
ObjBitBuffer(
|
||||
BitArray(encoded, 8)
|
||||
)
|
||||
)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user