0.8.4: stadlib in Lyng! added universal Iterable functions
This commit is contained in:
1 parent
f9198fe583
commit
3948283481
15 files changed
+338
-15
No files matched your search
@@ -163,13 +163,14 @@ open class Scope(
|
||||
fun addConst(name: String, value: Obj) = addItem(name, false, value)
|
||||
|
||||
suspend fun eval(code: String): Obj =
|
||||
Compiler.compile(code.toSource(), currentImportProvider).execute(this)
|
||||
eval(code.toSource())
|
||||
|
||||
suspend fun eval(source: Source): Obj =
|
||||
Compiler.compile(
|
||||
suspend fun eval(source: Source): Obj {
|
||||
return Compiler.compile(
|
||||
source,
|
||||
currentImportProvider
|
||||
).execute(this)
|
||||
}
|
||||
|
||||
fun containsLocal(name: String): Boolean = name in objects
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.yield
|
||||
import net.sergeych.lyng.obj.*
|
||||
import net.sergeych.lyng.pacman.ImportManager
|
||||
import net.sergeych.lyng.stdlib_included.rootLyng
|
||||
import net.sergeych.lynon.ObjLynonClass
|
||||
import net.sergeych.mp_tools.globalDefer
|
||||
import kotlin.math.*
|
||||
@@ -22,10 +23,14 @@ class Script(
|
||||
return lastResult
|
||||
}
|
||||
|
||||
suspend fun execute() = execute(defaultImportManager.newModule())
|
||||
suspend fun execute() = execute(
|
||||
defaultImportManager.newStdScope()
|
||||
)
|
||||
|
||||
companion object {
|
||||
|
||||
suspend fun newScope(pos: Pos = Pos.builtIn) = defaultImportManager.newStdScope(pos)
|
||||
|
||||
internal val rootScope: Scope = Scope(null).apply {
|
||||
ObjException.addExceptionsToContext(this)
|
||||
addFn("print") {
|
||||
@@ -202,6 +207,7 @@ class Script(
|
||||
addConst("Iterable", ObjIterable)
|
||||
addConst("Collection", ObjCollection)
|
||||
addConst("Array", ObjArray)
|
||||
addConst("RingBuffer", ObjRingBuffer.type)
|
||||
addConst("Class", ObjClassType)
|
||||
|
||||
addConst("Deferred", ObjDeferred.type)
|
||||
@@ -235,6 +241,9 @@ class Script(
|
||||
|
||||
val defaultImportManager: ImportManager by lazy {
|
||||
ImportManager(rootScope, SecurityManager.allowAll).apply {
|
||||
addTextPackages(
|
||||
rootLyng
|
||||
)
|
||||
addPackage("lyng.buffer") {
|
||||
it.addConst("Buffer", ObjBuffer.type)
|
||||
it.addConst("MutableBuffer", ObjMutableBuffer.type)
|
||||
|
||||
@@ -36,7 +36,9 @@ class ObjKotlinObjIterator(val iterator: Iterator<Obj>) : Obj() {
|
||||
addFn("next") {
|
||||
thisAs<ObjKotlinObjIterator>().iterator.next()
|
||||
}
|
||||
addFn("hasNext") { thisAs<ObjKotlinIterator>().iterator.hasNext().toObj() }
|
||||
addFn("hasNext") {
|
||||
thisAs<ObjKotlinObjIterator>().iterator.hasNext().toObj()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,4 +68,4 @@ class ObjMutableBuffer(byteArray: UByteArray) : ObjBuffer(byteArray) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import net.sergeych.lyng.Scope
|
||||
|
||||
class RingBuffer<T>(val maxSize: Int) : Iterable<T> {
|
||||
private val data = arrayOfNulls<Any>(maxSize)
|
||||
|
||||
var size = 0
|
||||
private set
|
||||
|
||||
private var start = 0
|
||||
|
||||
init {
|
||||
check(maxSize > 0) { "Max size should be a positive number: $maxSize" }
|
||||
}
|
||||
|
||||
fun add(item: T) {
|
||||
if (size < maxSize)
|
||||
size++
|
||||
else
|
||||
start = (start + 1) % maxSize
|
||||
data[(start + size - 1) % maxSize] = item
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun addAll(vararg items: T) {
|
||||
for (i in items) add(i)
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun addAll(elements: Iterable<T>) {
|
||||
elements.forEach { add(it) }
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
fun clear() {
|
||||
start = 0
|
||||
size = 0
|
||||
for (i in data.indices) {
|
||||
data[i] = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<T> =
|
||||
object : Iterator<T> {
|
||||
private var i = 0
|
||||
|
||||
override fun hasNext(): Boolean = i < size
|
||||
|
||||
override fun next(): T {
|
||||
if (!hasNext()) throw NoSuchElementException()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return data[(start + i++) % maxSize] as T
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ObjRingBuffer(val capacity: Int) : Obj() {
|
||||
val buffer = RingBuffer<Obj>(capacity)
|
||||
|
||||
override val objClass: ObjClass = type
|
||||
|
||||
override suspend fun plusAssign(scope: Scope, other: Obj): Obj {
|
||||
buffer.add(other.byValueCopy())
|
||||
return this
|
||||
}
|
||||
|
||||
companion object {
|
||||
val type = object : ObjClass("RingBuffer", ObjIterable) {
|
||||
override suspend fun callOn(scope: Scope): Obj {
|
||||
return ObjRingBuffer(scope.requireOnlyArg<ObjInt>().toInt())
|
||||
}
|
||||
}.apply {
|
||||
addFn("capacity") {
|
||||
thisAs<ObjRingBuffer>().capacity.toObj()
|
||||
}
|
||||
addFn("size") {
|
||||
thisAs<ObjRingBuffer>().buffer.size.toObj()
|
||||
}
|
||||
addFn("iterator") {
|
||||
val buffer = thisAs<ObjRingBuffer>().buffer
|
||||
ObjKotlinObjIterator(buffer.iterator())
|
||||
}
|
||||
addFn("add") {
|
||||
thisAs<ObjRingBuffer>().apply { buffer.add(requireOnlyArg<Obj>()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.sergeych.lyng.pacman
|
||||
|
||||
import net.sergeych.lyng.*
|
||||
import net.sergeych.mptools.CachedExpression
|
||||
|
||||
/**
|
||||
* Package manager INTERFACE (abstract class). Performs import routines
|
||||
@@ -45,6 +46,15 @@ abstract class ImportProvider(
|
||||
|
||||
fun newModuleAt(pos: Pos): ModuleScope =
|
||||
ModuleScope(this, pos, "unknown")
|
||||
|
||||
private var cachedStdScope = CachedExpression<Scope>()
|
||||
|
||||
suspend fun newStdScope(pos: Pos = Pos.builtIn): Scope =
|
||||
cachedStdScope.get {
|
||||
newModuleAt(pos).also {
|
||||
it.eval("import lyng.stdlib\n")
|
||||
}
|
||||
}.copy()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,58 @@
|
||||
package net.sergeych.lyng.stdlib_included
|
||||
|
||||
internal val rootLyng = """
|
||||
package lyng.stdlib
|
||||
|
||||
""".trimIndent()
|
||||
fun Iterable.filter(predicate) {
|
||||
val list = this
|
||||
flow {
|
||||
for( item in list ) {
|
||||
if( predicate(item) ) {
|
||||
emit(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Iterable.drop(n) {
|
||||
var cnt = 0
|
||||
filter { cnt++ >= n }
|
||||
}
|
||||
|
||||
fun Iterable.first() {
|
||||
val i = iterator()
|
||||
if( !i.hasNext() ) throw NoSuchElementException()
|
||||
i.next()
|
||||
}
|
||||
|
||||
fun Iterable.last() {
|
||||
var found = false
|
||||
var element = null
|
||||
for( i in this ) {
|
||||
element = i
|
||||
found = true
|
||||
}
|
||||
if( !found ) throw NoSuchElementException()
|
||||
element
|
||||
}
|
||||
|
||||
fun Iterable.dropLast(n) {
|
||||
val list = this
|
||||
val buffer = RingBuffer(n)
|
||||
flow {
|
||||
for( item in list ) {
|
||||
if( buffer.size == n )
|
||||
emit( buffer.first() )
|
||||
buffer += item
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Iterable.takeLast(n) {
|
||||
val list = this
|
||||
val buffer = RingBuffer(n)
|
||||
for( item in list ) buffer += item
|
||||
buffer
|
||||
}
|
||||
|
||||
""".trimIndent()
|
||||
|
||||
Reference in new issue
Block a user