Migrate relation operators evaluator to Kotlin
This commit is contained in:
@@ -23,7 +23,8 @@ class DefaultEvaluator : Evaluator() {
|
||||
ProductOperatorEvaluator(),
|
||||
SumOperatorEvaluator(),
|
||||
AccessOperatorEvaluator(),
|
||||
LogicOperatorEvaluator()
|
||||
LogicOperatorEvaluator(),
|
||||
RelationOperatorEvaluator()
|
||||
).evaluate(node, environment)
|
||||
}
|
||||
}
|
||||
@@ -27,8 +27,8 @@ class ProductOperatorEvaluator : Evaluator() {
|
||||
|
||||
return EvaluatorOutput.value(
|
||||
when (operator) {
|
||||
TokenType.ASTERISK -> unify(lhs, rhs, intConsumer = { (l, r) -> Value.int(l * r) }, floatConsumer = { (l, r) -> Value.float(l * r) })
|
||||
TokenType.SLASH -> unify(lhs, rhs, intConsumer = { (l, r) -> Value.int(l / r) }, floatConsumer = { (l, r) -> Value.float(l / r) })
|
||||
TokenType.ASTERISK -> unify(lhs, rhs, int = { (l, r) -> Value.int(l * r) }, float = { (l, r) -> Value.float(l * r) })
|
||||
TokenType.SLASH -> unify(lhs, rhs, int = { (l, r) -> Value.int(l / r) }, float = { (l, r) -> Value.float(l / r) })
|
||||
else -> throw ShouldNeverReachThisLineException()
|
||||
}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package io.smnp.evaluation.evaluator
|
||||
|
||||
import io.smnp.data.model.Value
|
||||
import io.smnp.dsl.ast.model.node.Node
|
||||
import io.smnp.dsl.ast.model.node.RelationOperatorNode
|
||||
import io.smnp.dsl.ast.model.node.TokenNode
|
||||
import io.smnp.error.EvaluationException
|
||||
import io.smnp.error.ShouldNeverReachThisLineException
|
||||
import io.smnp.evaluation.environment.Environment
|
||||
import io.smnp.evaluation.model.entity.EvaluatorOutput
|
||||
import io.smnp.evaluation.util.NumberUnification.unify
|
||||
|
||||
class RelationOperatorEvaluator : Evaluator() {
|
||||
override fun supportedNodes() = listOf(RelationOperatorNode::class)
|
||||
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val evaluator = DefaultEvaluator()
|
||||
val (lhsNode, opNode, rhsNode) = (node as RelationOperatorNode)
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value!!
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value!!
|
||||
val operator = (opNode as TokenNode).token.rawValue
|
||||
|
||||
if (operator in listOf("==", "!=")) {
|
||||
return EvaluatorOutput.value(
|
||||
Value.bool(
|
||||
if (operator == "==") lhs.value == rhs.value
|
||||
else lhs.value != rhs.value
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (!lhs.type.isNumeric() || !rhs.type.isNumeric()) {
|
||||
throw EvaluationException("Operator $operator supports only numeric types", node.position)
|
||||
}
|
||||
|
||||
return EvaluatorOutput.value(
|
||||
when(operator) {
|
||||
">" -> unify(lhs, rhs, int = { (l, r) -> Value.bool(l > r) }, float = { (l, r) -> Value.bool(l > r) })
|
||||
"<" -> unify(lhs, rhs, int = { (l, r) -> Value.bool(l < r) }, float = { (l, r) -> Value.bool(l < r) })
|
||||
">=" -> unify(lhs, rhs, int = { (l, r) -> Value.bool(l >= r) }, float = { (l, r) -> Value.bool(l >= r) })
|
||||
"<=" -> unify(lhs, rhs, int = { (l, r) -> Value.bool(l <= r) }, float = { (l, r) -> Value.bool(l <= r) })
|
||||
else -> throw ShouldNeverReachThisLineException()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -26,8 +26,8 @@ class SumOperatorEvaluator : Evaluator() {
|
||||
}
|
||||
|
||||
return EvaluatorOutput.value(when(operator) {
|
||||
TokenType.PLUS -> unify(lhs, rhs, intConsumer = { (l, r) -> Value.int(l + r) }, floatConsumer = { (l, r) -> Value.float(l + r) })
|
||||
TokenType.MINUS -> unify(lhs, rhs, intConsumer = { (l, r) -> Value.int(l - r) }, floatConsumer = { (l, r) -> Value.float(l - r) })
|
||||
TokenType.PLUS -> unify(lhs, rhs, int = { (l, r) -> Value.int(l + r) }, float = { (l, r) -> Value.float(l + r) })
|
||||
TokenType.MINUS -> unify(lhs, rhs, int = { (l, r) -> Value.int(l - r) }, float = { (l, r) -> Value.float(l - r) })
|
||||
else -> throw ShouldNeverReachThisLineException()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@ import io.smnp.data.enumeration.DataType
|
||||
import io.smnp.data.model.Value
|
||||
|
||||
object NumberUnification {
|
||||
fun unify(vararg numbers: Value, intConsumer: (List<Int>) -> Value, floatConsumer: (List<Float>) -> Value): Value {
|
||||
fun unify(vararg numbers: Value, int: (List<Int>) -> Value, float: (List<Float>) -> Value): Value {
|
||||
if(numbers.any { it.type == DataType.FLOAT }) {
|
||||
return floatConsumer(numbers.map { (it.value as Number).toFloat() })
|
||||
return float(numbers.map { (it.value as Number).toFloat() })
|
||||
}
|
||||
|
||||
return intConsumer(numbers.map { (it.value as Number).toInt() })
|
||||
return int(numbers.map { (it.value as Number).toInt() })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user