+list + / += Iterable
+CLI app started
This commit is contained in:
1 parent
939e391a20
commit
6ef94fff65
14 files changed
+271
-82
No files matched your search
@@ -44,6 +44,12 @@ open class Obj {
|
||||
suspend fun invokeInstanceMethod(context: Context, name: String, vararg args: Obj): Obj =
|
||||
invokeInstanceMethod(context, name, Arguments(args.map { Arguments.Info(it, context.pos) }))
|
||||
|
||||
inline suspend fun <reified T : Obj> callMethod(
|
||||
context: Context,
|
||||
name: String,
|
||||
args: Arguments = Arguments.EMPTY
|
||||
): T = invokeInstanceMethod(context, name, args) as T
|
||||
|
||||
suspend fun invokeInstanceMethod(
|
||||
context: Context,
|
||||
name: String,
|
||||
|
||||
@@ -3,8 +3,8 @@ package net.sergeych.ling
|
||||
class ObjList(val list: MutableList<Obj>) : Obj() {
|
||||
|
||||
init {
|
||||
for( p in objClass.parents)
|
||||
parentInstances.add( p.defaultInstance())
|
||||
for (p in objClass.parents)
|
||||
parentInstances.add(p.defaultInstance())
|
||||
}
|
||||
|
||||
override fun toString(): String = "[${
|
||||
@@ -46,21 +46,32 @@ class ObjList(val list: MutableList<Obj>) : Obj() {
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun plus(context: Context, other: Obj): Obj {
|
||||
(other as? ObjList) ?: context.raiseError("'+': can't concatenate $this with $other")
|
||||
return ObjList((list + other.list).toMutableList())
|
||||
}
|
||||
override suspend fun plus(context: Context, other: Obj): Obj =
|
||||
when {
|
||||
other is ObjList ->
|
||||
ObjList((list + other.list).toMutableList())
|
||||
|
||||
other.isInstanceOf(ObjIterable) -> {
|
||||
val l = other.callMethod<ObjList>(context, "toList")
|
||||
ObjList((list + l.list).toMutableList())
|
||||
}
|
||||
|
||||
else ->
|
||||
context.raiseError("'+': can't concatenate $this with $other")
|
||||
}
|
||||
|
||||
|
||||
override suspend fun plusAssign(context: Context, other: Obj): Obj {
|
||||
// optimization
|
||||
if( other is ObjList) {
|
||||
if (other is ObjList) {
|
||||
list += other.list
|
||||
return this
|
||||
}
|
||||
if( other.isInstanceOf(ObjIterable)) {
|
||||
TODO("plusassign for iterable is not yet implemented")
|
||||
}
|
||||
list += other
|
||||
if (other.isInstanceOf(ObjIterable)) {
|
||||
val otherList = other.invokeInstanceMethod(context, "toList") as ObjList
|
||||
list += otherList.list
|
||||
} else
|
||||
list += other
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
@@ -56,24 +56,6 @@ class ObjRange(val start: Obj?, val end: Obj?, val isEndInclusive: Boolean) : Ob
|
||||
return true
|
||||
}
|
||||
|
||||
override suspend fun getAt(context: Context, index: Int): Obj {
|
||||
if (!isIntRange && !isCharRange) {
|
||||
return when (index) {
|
||||
0 -> start ?: ObjNull
|
||||
1 -> end ?: ObjNull
|
||||
else -> context.raiseIndexOutOfBounds("index out of range: $index for max of 2 for non-int ranges")
|
||||
}
|
||||
}
|
||||
// int range, should be finite
|
||||
val r0 = start?.toInt() ?: context.raiseArgumentError("start is not integer")
|
||||
var r1 = end?.toInt() ?: context.raiseArgumentError("end is not integer")
|
||||
if (isEndInclusive) r1++
|
||||
val i = index + r0
|
||||
if (i >= r1) context.raiseIndexOutOfBounds("index $index is not in range (${r1 - r0})")
|
||||
return if (isIntRange) ObjInt(i.toLong()) else ObjChar(i.toChar())
|
||||
}
|
||||
|
||||
|
||||
val isIntRange: Boolean by lazy {
|
||||
start is ObjInt && end is ObjInt
|
||||
}
|
||||
@@ -82,6 +64,13 @@ class ObjRange(val start: Obj?, val end: Obj?, val isEndInclusive: Boolean) : Ob
|
||||
start is ObjChar && end is ObjChar
|
||||
}
|
||||
|
||||
override suspend fun compareTo(context: Context, other: Obj): Int {
|
||||
return (other as? ObjRange)?.let {
|
||||
if( start == other.start && end == other.end ) 0 else -1
|
||||
}
|
||||
?: -1
|
||||
}
|
||||
|
||||
companion object {
|
||||
val type = ObjClass("Range", ObjIterable).apply {
|
||||
addFn("start") {
|
||||
@@ -110,50 +99,3 @@ class ObjRange(val start: Obj?, val end: Obj?, val isEndInclusive: Boolean) : Ob
|
||||
}
|
||||
}
|
||||
|
||||
class ObjRangeIterator(val self: ObjRange) : Obj() {
|
||||
|
||||
private var nextIndex = 0
|
||||
private var lastIndex = 0
|
||||
private var isCharRange: Boolean = false
|
||||
|
||||
override val objClass: ObjClass = type
|
||||
|
||||
fun Context.init() {
|
||||
if (self.start == null || self.end == null)
|
||||
raiseError("next is only available for finite ranges")
|
||||
isCharRange = self.isCharRange
|
||||
lastIndex = if (self.isIntRange || self.isCharRange) {
|
||||
if (self.isEndInclusive)
|
||||
self.end.toInt() - self.start.toInt() + 1
|
||||
else
|
||||
self.end.toInt() - self.start.toInt()
|
||||
} else {
|
||||
raiseError("not implemented iterator for range of $this")
|
||||
}
|
||||
}
|
||||
|
||||
fun hasNext(): Boolean = nextIndex < lastIndex
|
||||
|
||||
fun next(context: Context): Obj =
|
||||
if (nextIndex < lastIndex) {
|
||||
val x = if (self.isEndInclusive)
|
||||
self.start!!.toLong() + nextIndex++
|
||||
else
|
||||
self.start!!.toLong() + nextIndex++
|
||||
if( isCharRange ) ObjChar(x.toInt().toChar()) else ObjInt(x)
|
||||
}
|
||||
else {
|
||||
context.raiseError(ObjIterationFinishedError(context))
|
||||
}
|
||||
|
||||
companion object {
|
||||
val type = ObjClass("RangeIterator", ObjIterable).apply {
|
||||
addFn("hasNext") {
|
||||
thisAs<ObjRangeIterator>().hasNext().toObj()
|
||||
}
|
||||
addFn("next") {
|
||||
thisAs<ObjRangeIterator>().next(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package net.sergeych.ling
|
||||
|
||||
class ObjRangeIterator(val self: ObjRange) : Obj() {
|
||||
|
||||
private var nextIndex = 0
|
||||
private var lastIndex = 0
|
||||
private var isCharRange: Boolean = false
|
||||
|
||||
override val objClass: ObjClass = type
|
||||
|
||||
fun Context.init() {
|
||||
if (self.start == null || self.end == null)
|
||||
raiseError("next is only available for finite ranges")
|
||||
isCharRange = self.isCharRange
|
||||
lastIndex = if (self.isIntRange || self.isCharRange) {
|
||||
if (self.isEndInclusive)
|
||||
self.end.toInt() - self.start.toInt() + 1
|
||||
else
|
||||
self.end.toInt() - self.start.toInt()
|
||||
} else {
|
||||
raiseError("not implemented iterator for range of $this")
|
||||
}
|
||||
}
|
||||
|
||||
fun hasNext(): Boolean = nextIndex < lastIndex
|
||||
|
||||
fun next(context: Context): Obj =
|
||||
if (nextIndex < lastIndex) {
|
||||
val x = if (self.isEndInclusive)
|
||||
self.start!!.toLong() + nextIndex++
|
||||
else
|
||||
self.start!!.toLong() + nextIndex++
|
||||
if( isCharRange ) ObjChar(x.toInt().toChar()) else ObjInt(x)
|
||||
}
|
||||
else {
|
||||
context.raiseError(ObjIterationFinishedError(context))
|
||||
}
|
||||
|
||||
companion object {
|
||||
val type = ObjClass("RangeIterator", ObjIterable).apply {
|
||||
addFn("hasNext") {
|
||||
thisAs<ObjRangeIterator>().hasNext().toObj()
|
||||
}
|
||||
addFn("next") {
|
||||
thisAs<ObjRangeIterator>().next(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user