From 1406a3fa6ff6d05ec45d06de06f3ed13b8ec57da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Sat, 7 Mar 2020 17:31:57 +0100 Subject: [PATCH] Migrate power operator evaluator to Kotlin --- .../io/smnp/data/enumeration/DataType.kt | 4 +++ .../model/node/BinaryOperatorAbstractNode.kt | 4 +++ .../evaluation/evaluator/DefaultEvaluator.kt | 3 ++- .../evaluator/PowerOperatorEvaluator.kt | 26 +++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/io/smnp/evaluation/evaluator/PowerOperatorEvaluator.kt diff --git a/src/main/kotlin/io/smnp/data/enumeration/DataType.kt b/src/main/kotlin/io/smnp/data/enumeration/DataType.kt index 497442e..6c6b11f 100644 --- a/src/main/kotlin/io/smnp/data/enumeration/DataType.kt +++ b/src/main/kotlin/io/smnp/data/enumeration/DataType.kt @@ -22,6 +22,10 @@ enum class DataType(val kotlinType: KClass?) { return kotlinType.isInstance(value) } + fun isNumeric(): Boolean { + return this == INT || this == FLOAT + } + override fun toString(): String { return super.toString().toLowerCase() } diff --git a/src/main/kotlin/io/smnp/dsl/ast/model/node/BinaryOperatorAbstractNode.kt b/src/main/kotlin/io/smnp/dsl/ast/model/node/BinaryOperatorAbstractNode.kt index 94d6a22..0783b06 100644 --- a/src/main/kotlin/io/smnp/dsl/ast/model/node/BinaryOperatorAbstractNode.kt +++ b/src/main/kotlin/io/smnp/dsl/ast/model/node/BinaryOperatorAbstractNode.kt @@ -1,6 +1,10 @@ package io.smnp.dsl.ast.model.node abstract class BinaryOperatorAbstractNode(lhs: Node, operator: Node, rhs: Node) : Node(3, operator.position) { + operator fun component1() = children[0] + operator fun component2() = children[1] + operator fun component3() = children[2] + val lhs: Node get() = children[0] diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/DefaultEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/DefaultEvaluator.kt index 4dbd43d..e2836d4 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/DefaultEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/DefaultEvaluator.kt @@ -18,7 +18,8 @@ class DefaultEvaluator : Evaluator() { MapEvaluator(), MinusOperatorEvaluator(), - NotOperatorEvaluator() + NotOperatorEvaluator(), + PowerOperatorEvaluator() ).evaluate(node, environment) } } \ No newline at end of file diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/PowerOperatorEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/PowerOperatorEvaluator.kt new file mode 100644 index 0000000..3b81b9a --- /dev/null +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/PowerOperatorEvaluator.kt @@ -0,0 +1,26 @@ +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.PowerOperatorNode +import io.smnp.error.EvaluationException +import io.smnp.evaluation.environment.Environment +import io.smnp.evaluation.model.entity.EvaluatorOutput +import kotlin.math.pow + +class PowerOperatorEvaluator : Evaluator() { + override fun supportedNodes() = listOf(PowerOperatorNode::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { + val (lhsNode, _, rhsNode) = (node as PowerOperatorNode) + val evaluator = DefaultEvaluator() + val lhs = evaluator.evaluate(lhsNode, environment).value!! + val rhs = evaluator.evaluate(rhsNode, environment).value!! + + if(!lhs.type.isNumeric() || !rhs.type.isNumeric()) { + throw EvaluationException("Operator ** supports only numeric types", node.position) + } + + return EvaluatorOutput.value(Value.float((lhs.value as Number).toFloat().pow((rhs.value as Number).toFloat()))) + } +} \ No newline at end of file