refs #35 Buffer is not mutable, MutableBuffer added (to cache in serialized form)
This commit is contained in:
1 parent
f3d766d1b1
commit
7aee25ffef
6 files changed
+120
-44
No files matched your search
@@ -82,6 +82,11 @@ open class Scope(
|
||||
}
|
||||
}
|
||||
|
||||
fun requireNoArgs() {
|
||||
if( args.list.isNotEmpty())
|
||||
raiseError("This function does not accept any arguments")
|
||||
}
|
||||
|
||||
inline fun <reified T : Obj> thisAs(): T = (thisObj as? T)
|
||||
?: raiseClassCastError("Cannot cast ${thisObj.objClass.className} to ${T::class.simpleName}")
|
||||
|
||||
|
||||
@@ -179,6 +179,7 @@ class Script(
|
||||
ImportManager(rootScope, SecurityManager.allowAll).apply {
|
||||
addPackage("lyng.buffer") {
|
||||
it.addConst("Buffer", ObjBuffer.type)
|
||||
it.addConst("MutableBuffer", ObjMutableBuffer.type)
|
||||
}
|
||||
addPackage("lyng.time") {
|
||||
it.addConst("Instant", ObjInstant.type)
|
||||
|
||||
@@ -6,7 +6,7 @@ import net.sergeych.lyng.Scope
|
||||
import net.sergeych.lyng.statement
|
||||
import kotlin.math.min
|
||||
|
||||
class ObjBuffer(val byteArray: UByteArray) : Obj() {
|
||||
open class ObjBuffer(val byteArray: UByteArray) : Obj() {
|
||||
|
||||
override val objClass: ObjClass = type
|
||||
|
||||
@@ -30,16 +30,6 @@ class ObjBuffer(val byteArray: UByteArray) : Obj() {
|
||||
} else ObjInt(byteArray[checkIndex(scope, index)].toLong(), true)
|
||||
}
|
||||
|
||||
override suspend fun putAt(scope: Scope, index: Obj, newValue: Obj) {
|
||||
byteArray[checkIndex(scope, index.toObj())] = when (newValue) {
|
||||
is ObjInt -> newValue.value.toUByte()
|
||||
is ObjChar -> newValue.value.code.toUByte()
|
||||
else -> scope.raiseIllegalArgument(
|
||||
"invalid byte value for buffer at index ${index.inspect()}: ${newValue.inspect()}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val size by byteArray::size
|
||||
|
||||
override fun hashCode(): Int {
|
||||
@@ -144,18 +134,10 @@ class ObjBuffer(val byteArray: UByteArray) : Obj() {
|
||||
thisAs<ObjBuffer>().byteArray.toByteArray().decodeToString()
|
||||
)
|
||||
}
|
||||
// )
|
||||
// addFn("getAt") {
|
||||
// requireExactCount(1)
|
||||
// thisAs<ObjList>().getAt(this, requiredArg<Obj>(0))
|
||||
// }
|
||||
// addFn("putAt") {
|
||||
// requireExactCount(2)
|
||||
// val newValue = args[1]
|
||||
// thisAs<ObjList>().putAt(this, requiredArg<ObjInt>(0).value.toInt(), newValue)
|
||||
// newValue
|
||||
// }
|
||||
|
||||
addFn("toMutable") {
|
||||
requireNoArgs()
|
||||
ObjMutableBuffer(thisAs<ObjBuffer>().byteArray.copyOf())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package net.sergeych.lyng.obj
|
||||
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import net.sergeych.lyng.Scope
|
||||
|
||||
class ObjMutableBuffer(byteArray: UByteArray) : ObjBuffer(byteArray) {
|
||||
|
||||
override suspend fun putAt(scope: Scope, index: Obj, newValue: Obj) {
|
||||
byteArray[checkIndex(scope, index.toObj())] = when (newValue) {
|
||||
is ObjInt -> newValue.value.toUByte()
|
||||
is ObjChar -> newValue.value.code.toUByte()
|
||||
else -> scope.raiseIllegalArgument(
|
||||
"invalid byte value for buffer at index ${index.inspect()}: ${newValue.inspect()}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private suspend fun createBufferFrom(scope: Scope, obj: Obj): ObjBuffer =
|
||||
when (obj) {
|
||||
is ObjBuffer -> ObjMutableBuffer(obj.byteArray.copyOf())
|
||||
is ObjInt -> {
|
||||
if (obj.value < 0)
|
||||
scope.raiseIllegalArgument("buffer size must be positive")
|
||||
val data = UByteArray(obj.value.toInt())
|
||||
ObjMutableBuffer(data)
|
||||
}
|
||||
|
||||
is ObjString -> ObjMutableBuffer(obj.value.encodeToByteArray().asUByteArray())
|
||||
else -> {
|
||||
if (obj.isInstanceOf(ObjIterable)) {
|
||||
ObjMutableBuffer(
|
||||
obj.toFlow(scope).map { it.toLong().toUByte() }.toList().toTypedArray()
|
||||
.toUByteArray()
|
||||
)
|
||||
} else
|
||||
scope.raiseIllegalArgument(
|
||||
"can't construct buffer from ${obj.inspect()}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val type = object : ObjClass("MutableBuffer", ObjBuffer.type) {
|
||||
override suspend fun callOn(scope: Scope): Obj {
|
||||
val args = scope.args.list
|
||||
return when (args.size) {
|
||||
// empty buffer
|
||||
0 -> ObjMutableBuffer(ubyteArrayOf())
|
||||
1 -> createBufferFrom(scope, args[0])
|
||||
else -> {
|
||||
// create buffer from array, each argument should be a byte then:
|
||||
val data = UByteArray(args.size)
|
||||
for ((i, b) in args.withIndex()) {
|
||||
val code = when (b) {
|
||||
is ObjChar -> b.value.code.toUByte()
|
||||
is ObjInt -> b.value.toUByte()
|
||||
else -> scope.raiseIllegalArgument(
|
||||
"invalid byte value for buffer constructor at index $i: ${b.inspect()}"
|
||||
)
|
||||
}
|
||||
data[i] = code
|
||||
}
|
||||
ObjMutableBuffer(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user