[orx-expression-evaluator-typed] Add list index operator, list minBy/maxBy/sortedBy/min/max/sorted/first/last
This commit is contained in:
@@ -14,12 +14,35 @@ internal fun String.memberFunctions(n: String): ((Array<Any>) -> Any)? {
|
||||
|
||||
internal fun List<*>.memberFunctions(n: String): ((Array<Any>) -> Any)? {
|
||||
return when (n) {
|
||||
"first" -> { n -> this.first() ?: error("empty list") }
|
||||
"last" -> { n -> this.last() ?: error("empty list") }
|
||||
"take" -> { n -> this.take((n[0] as Number).toInt()) }
|
||||
"drop" -> { n -> this.drop((n[0] as Number).toInt()) }
|
||||
"takeLast" -> { n -> this.takeLast((n[0] as Number).toInt()) }
|
||||
"dropLast" -> { n -> this.takeLast((n[0] as Number).toInt()) }
|
||||
"map" -> { n -> val lambda = (n[0] as (Any)->Any); this.map { lambda(it!!) } }
|
||||
"filter" -> { n -> val lambda = (n[0] as (Any)->Any); this.filter { (lambda(it!!) as Double).roundToInt() != 0 } }
|
||||
"map" -> { n -> val lambda = (n[0] as (Any) -> Any); this.map { lambda(it!!) } }
|
||||
"filter" -> { n ->
|
||||
val lambda = (n[0] as (Any) -> Any); this.filter { (lambda(it!!) as Double).roundToInt() != 0 }
|
||||
}
|
||||
|
||||
"max" -> { n -> (this as List<Comparable<Any>>).max() }
|
||||
"min" -> { n -> (this as List<Comparable<Any>>).min() }
|
||||
"maxBy" -> { n ->
|
||||
val lambda = (n[0] as (Any) -> Any); this.maxByOrNull { lambda(it!!) as Comparable<Any> } ?: error("no max")
|
||||
}
|
||||
|
||||
"minBy" -> { n ->
|
||||
val lambda = (n[0] as (Any) -> Any); this.minByOrNull { lambda(it!!) as Comparable<Any> } ?: error("no max")
|
||||
}
|
||||
"sorted" -> { n -> (this as List<Comparable<Any>>).sorted() }
|
||||
"sortedBy" -> { n ->
|
||||
val lambda = (n[0] as (Any) -> Any); this.sortedBy { lambda(it!!) as Comparable<Any> }
|
||||
}
|
||||
"sortedByDescending" -> { n ->
|
||||
val lambda = (n[0] as (Any) -> Any); this.sortedByDescending { lambda(it!!) as Comparable<Any> }
|
||||
}
|
||||
"reversed" -> { n -> this.reversed() }
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -97,10 +97,29 @@ abstract class TypedExpressionListenerBase(
|
||||
|
||||
override fun exitListLiteral(ctx: KeyLangParser.ListLiteralContext) {
|
||||
val s = state
|
||||
if (s.inFunctionLiteral > 0) {
|
||||
return
|
||||
}
|
||||
val list = (0 until ctx.getExpression().size).map { s.valueStack.pop() }
|
||||
s.valueStack.push(list.reversed())
|
||||
}
|
||||
|
||||
override fun exitIndexExpression(ctx: KeyLangParser.IndexExpressionContext) {
|
||||
val s = state
|
||||
if (s.inFunctionLiteral > 0) {
|
||||
return
|
||||
}
|
||||
val index = (s.valueStack.pop() as? Double)?.roundToInt() ?: error("index is not a number")
|
||||
val listValue = s.valueStack.pop()
|
||||
|
||||
val value = when (listValue) {
|
||||
is List<*> -> listValue[index] ?: error("got null")
|
||||
is Function<*> -> (listValue as (Int)->Any)(index)
|
||||
else -> error("can't index on '$listValue'")
|
||||
}
|
||||
s.valueStack.push(value)
|
||||
}
|
||||
|
||||
override fun enterFunctionLiteral(ctx: KeyLangParser.FunctionLiteralContext) {
|
||||
val s = state
|
||||
s.inFunctionLiteral++
|
||||
@@ -689,6 +708,7 @@ abstract class TypedExpressionListenerBase(
|
||||
is Vector4 -> current.property(property)
|
||||
is ColorRGBa -> current.property(property)
|
||||
is Matrix44 -> current.property(property)
|
||||
is String -> current.property(property)
|
||||
else -> error("can't look up: ${current::class} '$current', root:'$root' ${ctx.text} ")
|
||||
}
|
||||
s.valueStack.push(current)
|
||||
|
||||
@@ -22,6 +22,7 @@ expression : INTLIT # int
|
||||
| expression DOT ID LPAREN expression COMMA expression RPAREN # memberFunctionCall2Expression
|
||||
| expression DOT ID LPAREN expression COMMA expression COMMA expression RPAREN # memberFunctionCall3Expression
|
||||
| expression DOT ID LPAREN expression COMMA expression COMMA expression COMMA expression RPAREN # memberFunctionCall4Expression
|
||||
| expression LBRACKET expression RBRACKET # indexExpression
|
||||
| ID LPAREN RPAREN # functionCall0Expression
|
||||
| ID LPAREN expression RPAREN # functionCall1Expression
|
||||
| ID LPAREN expression COMMA expression RPAREN # functionCall2Expression
|
||||
|
||||
Reference in New Issue
Block a user