Migrate product operator evaluator to Kotlin
This commit is contained in:
@@ -2,6 +2,7 @@ package io.smnp.data.model
|
||||
|
||||
import io.smnp.data.entity.Note
|
||||
import io.smnp.data.enumeration.DataType
|
||||
import io.smnp.error.ShouldNeverReachThisLineException
|
||||
|
||||
class Value private constructor(val type: DataType, val value: Any?, val properties: Map<String, Value> = emptyMap()) {
|
||||
init {
|
||||
@@ -23,6 +24,14 @@ class Value private constructor(val type: DataType, val value: Any?, val propert
|
||||
return Value(DataType.FLOAT, value)
|
||||
}
|
||||
|
||||
fun numeric(value: Number): Value {
|
||||
return when(value::class) {
|
||||
Int::class -> int(value.toInt())
|
||||
Float::class -> float(value.toFloat())
|
||||
else -> throw ShouldNeverReachThisLineException()
|
||||
}
|
||||
}
|
||||
|
||||
fun string(value: String): Value {
|
||||
return Value(DataType.STRING, value, hashMapOf(
|
||||
Pair("length", int(value.length))
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package io.smnp.error
|
||||
|
||||
class ShouldNeverReachThisLineException : Exception(
|
||||
"This exception should never be thrown. Please check stack trace and investigate the source of error."
|
||||
)
|
||||
@@ -19,7 +19,8 @@ class DefaultEvaluator : Evaluator() {
|
||||
|
||||
MinusOperatorEvaluator(),
|
||||
NotOperatorEvaluator(),
|
||||
PowerOperatorEvaluator()
|
||||
PowerOperatorEvaluator(),
|
||||
ProductOperatorEvaluator()
|
||||
).evaluate(node, environment)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package io.smnp.evaluation.evaluator
|
||||
|
||||
import io.smnp.data.enumeration.DataType
|
||||
import io.smnp.data.model.Value
|
||||
import io.smnp.dsl.ast.model.node.Node
|
||||
import io.smnp.dsl.ast.model.node.ProductOperatorNode
|
||||
import io.smnp.dsl.ast.model.node.TokenNode
|
||||
import io.smnp.dsl.token.model.enumeration.TokenType
|
||||
import io.smnp.error.EvaluationException
|
||||
import io.smnp.error.ShouldNeverReachThisLineException
|
||||
import io.smnp.evaluation.environment.Environment
|
||||
import io.smnp.evaluation.model.entity.EvaluatorOutput
|
||||
|
||||
class ProductOperatorEvaluator : Evaluator() {
|
||||
override fun supportedNodes() = listOf(ProductOperatorNode::class)
|
||||
|
||||
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
|
||||
val evaluator = DefaultEvaluator()
|
||||
val (lhsNode, opNode, rhsNode) = (node as ProductOperatorNode)
|
||||
val lhs = evaluator.evaluate(lhsNode, environment).value!!
|
||||
val rhs = evaluator.evaluate(rhsNode, environment).value!!
|
||||
val operator = (opNode as TokenNode).token.type
|
||||
|
||||
if (!lhs.type.isNumeric() || !rhs.type.isNumeric()) {
|
||||
throw EvaluationException("Operator $operator supports only numeric types", node.position)
|
||||
}
|
||||
|
||||
return EvaluatorOutput.value(
|
||||
when (operator) {
|
||||
TokenType.ASTERISK -> product(lhs, rhs)
|
||||
TokenType.SLASH -> quotient(lhs, rhs)
|
||||
else -> throw ShouldNeverReachThisLineException()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun product(lhs: Value, rhs: Value): Value {
|
||||
if(listOf(lhs.type, rhs.type).contains(DataType.FLOAT)) {
|
||||
return Value.float((lhs.value as Number).toFloat() * (rhs.value as Number).toFloat())
|
||||
}
|
||||
|
||||
return Value.int((lhs.value as Int) * (rhs.value as Int))
|
||||
}
|
||||
|
||||
private fun quotient(lhs: Value, rhs: Value): Value {
|
||||
if(listOf(lhs.type, rhs.type).contains(DataType.FLOAT)) {
|
||||
return Value.float((lhs.value as Number).toFloat() / (rhs.value as Number).toFloat())
|
||||
}
|
||||
|
||||
return Value.int((lhs.value as Int) / (rhs.value as Int))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user