From 5f92cab2bf9d707546f17153cd804ef5609290c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Sat, 7 Mar 2020 17:15:56 +0100 Subject: [PATCH] Refactor evaluators to make use of supportedNodes() method --- .../evaluator/BoolLiteralEvaluator.kt | 6 ++- .../evaluation/evaluator/DefaultEvaluator.kt | 30 +++++++-------- .../io/smnp/evaluation/evaluator/Evaluator.kt | 37 ++++++++++--------- .../evaluator/FloatLiteralEvaluator.kt | 6 ++- .../evaluator/IntegerLiteralEvaluator.kt | 6 ++- .../evaluation/evaluator/ListEvaluator.kt | 6 ++- .../smnp/evaluation/evaluator/MapEvaluator.kt | 6 ++- .../evaluator/MinusOperatorEvaluator.kt | 6 ++- .../evaluator/NotOperatorEvaluator.kt | 7 ++-- .../evaluator/NoteLiteralEvaluator.kt | 6 ++- .../evaluation/evaluator/RootEvaluator.kt | 8 ++-- .../evaluator/StringLiteralEvaluator.kt | 6 ++- 12 files changed, 73 insertions(+), 57 deletions(-) diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/BoolLiteralEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/BoolLiteralEvaluator.kt index b8e4fbc..9cb4d93 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/BoolLiteralEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/BoolLiteralEvaluator.kt @@ -6,8 +6,10 @@ import io.smnp.dsl.ast.model.node.Node import io.smnp.evaluation.environment.Environment import io.smnp.evaluation.model.entity.EvaluatorOutput -class BoolLiteralEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { +class BoolLiteralEvaluator : Evaluator() { + override fun supportedNodes() = listOf(BoolLiteralNode::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val value = (node as BoolLiteralNode).token.value as Boolean return EvaluatorOutput.value(Value.bool(value)) } diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/DefaultEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/DefaultEvaluator.kt index c908bc2..4dbd43d 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/DefaultEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/DefaultEvaluator.kt @@ -1,24 +1,24 @@ package io.smnp.evaluation.evaluator -import io.smnp.dsl.ast.model.node.* +import io.smnp.dsl.ast.model.node.Node import io.smnp.evaluation.environment.Environment -import io.smnp.evaluation.evaluator.Evaluator.Companion.forward -import io.smnp.evaluation.evaluator.Evaluator.Companion.oneOf import io.smnp.evaluation.model.entity.EvaluatorOutput -class DefaultEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { - return oneOf( - forward(IntegerLiteralEvaluator(), IntegerLiteralNode::class), - forward(FloatLiteralEvaluator(), FloatLiteralNode::class), - forward(StringLiteralEvaluator(), StringLiteralNode::class), - forward(BoolLiteralEvaluator(), BoolLiteralNode::class), - forward(NoteLiteralEvaluator(), NoteLiteralNode::class), - forward(ListEvaluator(), ListNode::class), - forward(MapEvaluator(), MapNode::class), +class DefaultEvaluator : Evaluator() { + override fun supportedNodes() = listOf(Node::class) - forward(MinusOperatorEvaluator(), MinusOperatorNode::class), - forward(NotOperatorEvaluator(), NotOperatorNode::class) + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { + return oneOf( + IntegerLiteralEvaluator(), + FloatLiteralEvaluator(), + StringLiteralEvaluator(), + BoolLiteralEvaluator(), + NoteLiteralEvaluator(), + ListEvaluator(), + MapEvaluator(), + + MinusOperatorEvaluator(), + NotOperatorEvaluator() ).evaluate(node, environment) } } \ No newline at end of file diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/Evaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/Evaluator.kt index 72225eb..ed5e0fe 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/Evaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/Evaluator.kt @@ -7,25 +7,24 @@ import io.smnp.evaluation.model.entity.EvaluatorOutput import io.smnp.evaluation.model.enumeration.EvaluationResult import kotlin.reflect.KClass -interface Evaluator { - fun evaluate(node: Node, environment: Environment): EvaluatorOutput - - companion object { - fun forward(evaluator: Evaluator, vararg nodes: KClass): Evaluator { - return object : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { - if(nodes.any { it.isInstance(node) }) { - return evaluator.evaluate(node, environment) - } - - return EvaluatorOutput.fail() - } - } +abstract class Evaluator { + fun evaluate(node: Node, environment: Environment): EvaluatorOutput { + if(supportedNodes().any { it.isInstance(node) }) { + return tryToEvaluate(node, environment) } + return EvaluatorOutput.fail() + } + + protected abstract fun supportedNodes(): List> + protected abstract fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput + + companion object { fun oneOf(vararg evaluators: Evaluator): Evaluator { - return object : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { + return object : Evaluator() { + override fun supportedNodes() = listOf(Node::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { for(evaluator in evaluators) { val output = evaluator.evaluate(node, environment) if(output.result != EvaluationResult.FAILED) { @@ -39,8 +38,10 @@ interface Evaluator { } fun assert(evaluator: Evaluator, expected: String): Evaluator { - return object : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { + return object : Evaluator() { + override fun supportedNodes() = listOf(Node::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val output = evaluator.evaluate(node, environment) if(output.result == EvaluationResult.FAILED) { diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/FloatLiteralEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/FloatLiteralEvaluator.kt index 181635d..194247e 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/FloatLiteralEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/FloatLiteralEvaluator.kt @@ -6,8 +6,10 @@ import io.smnp.dsl.ast.model.node.Node import io.smnp.evaluation.environment.Environment import io.smnp.evaluation.model.entity.EvaluatorOutput -class FloatLiteralEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { +class FloatLiteralEvaluator : Evaluator() { + override fun supportedNodes() = listOf(FloatLiteralNode::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val value = (node as FloatLiteralNode).token.value as Float return EvaluatorOutput.value(Value.float(value)) } diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/IntegerLiteralEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/IntegerLiteralEvaluator.kt index e33f9d4..e7affbe 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/IntegerLiteralEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/IntegerLiteralEvaluator.kt @@ -6,8 +6,10 @@ import io.smnp.dsl.ast.model.node.Node import io.smnp.evaluation.environment.Environment import io.smnp.evaluation.model.entity.EvaluatorOutput -class IntegerLiteralEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { +class IntegerLiteralEvaluator : Evaluator() { + override fun supportedNodes() = listOf(IntegerLiteralNode::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val value = (node as IntegerLiteralNode).token.value as Int return EvaluatorOutput.value(Value.int(value)) } diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/ListEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/ListEvaluator.kt index d60d13c..2a5b080 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/ListEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/ListEvaluator.kt @@ -6,8 +6,10 @@ import io.smnp.dsl.ast.model.node.Node import io.smnp.evaluation.environment.Environment import io.smnp.evaluation.model.entity.EvaluatorOutput -class ListEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { +class ListEvaluator : Evaluator() { + override fun supportedNodes() = listOf(ListNode::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val atomEvaluator = DefaultEvaluator() val items = (node as ListNode).items .map { atomEvaluator.evaluate(it, environment) } diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/MapEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/MapEvaluator.kt index 4ffe8ee..9c2503a 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/MapEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/MapEvaluator.kt @@ -7,8 +7,10 @@ import io.smnp.dsl.ast.model.node.Node import io.smnp.evaluation.environment.Environment import io.smnp.evaluation.model.entity.EvaluatorOutput -class MapEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { +class MapEvaluator : Evaluator() { + override fun supportedNodes() = listOf(MapNode::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val atomEvaluator = DefaultEvaluator() val value = (node as MapNode).items .map { it as MapEntryNode } diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/MinusOperatorEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/MinusOperatorEvaluator.kt index dfb819c..5227594 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/MinusOperatorEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/MinusOperatorEvaluator.kt @@ -8,8 +8,10 @@ import io.smnp.error.EvaluationException import io.smnp.evaluation.environment.Environment import io.smnp.evaluation.model.entity.EvaluatorOutput -class MinusOperatorEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { +class MinusOperatorEvaluator : Evaluator() { + override fun supportedNodes() = listOf(MinusOperatorNode::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val evaluator = DefaultEvaluator() val (_, operandNode) = (node as MinusOperatorNode) val operand = evaluator.evaluate(operandNode, environment) diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/NotOperatorEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/NotOperatorEvaluator.kt index c5beb15..ec9349d 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/NotOperatorEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/NotOperatorEvaluator.kt @@ -4,11 +4,12 @@ import io.smnp.data.model.Value import io.smnp.dsl.ast.model.node.Node import io.smnp.dsl.ast.model.node.NotOperatorNode import io.smnp.evaluation.environment.Environment -import io.smnp.evaluation.evaluator.Evaluator.Companion.assert import io.smnp.evaluation.model.entity.EvaluatorOutput -class NotOperatorEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { +class NotOperatorEvaluator : Evaluator() { + override fun supportedNodes() = listOf(NotOperatorNode::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val evaluator = BoolLiteralEvaluator() val (_, operandNode) = (node as NotOperatorNode) val operand = assert(evaluator, "bool").evaluate(operandNode, environment) diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/NoteLiteralEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/NoteLiteralEvaluator.kt index eeacbf2..6631e4c 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/NoteLiteralEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/NoteLiteralEvaluator.kt @@ -7,8 +7,10 @@ import io.smnp.dsl.ast.model.node.NoteLiteralNode import io.smnp.evaluation.environment.Environment import io.smnp.evaluation.model.entity.EvaluatorOutput -class NoteLiteralEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { +class NoteLiteralEvaluator : Evaluator() { + override fun supportedNodes() = listOf(NoteLiteralNode::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val value = (node as NoteLiteralNode).token.value as Note return EvaluatorOutput.value(Value.note(value)) } diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/RootEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/RootEvaluator.kt index 69206aa..71e7f72 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/RootEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/RootEvaluator.kt @@ -6,12 +6,10 @@ import io.smnp.evaluation.environment.Environment import io.smnp.evaluation.model.entity.EvaluatorOutput import io.smnp.evaluation.model.enumeration.EvaluationResult -class RootEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { - if(node !is RootNode) { - return EvaluatorOutput.fail() - } +class RootEvaluator : Evaluator() { + override fun supportedNodes() = listOf(RootNode::class) + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val evaluator = DefaultEvaluator() for(child in node.children) { val output = evaluator.evaluate(child, environment) diff --git a/src/main/kotlin/io/smnp/evaluation/evaluator/StringLiteralEvaluator.kt b/src/main/kotlin/io/smnp/evaluation/evaluator/StringLiteralEvaluator.kt index c8c0c60..2d9f2b5 100644 --- a/src/main/kotlin/io/smnp/evaluation/evaluator/StringLiteralEvaluator.kt +++ b/src/main/kotlin/io/smnp/evaluation/evaluator/StringLiteralEvaluator.kt @@ -6,8 +6,10 @@ import io.smnp.dsl.ast.model.node.StringLiteralNode import io.smnp.evaluation.environment.Environment import io.smnp.evaluation.model.entity.EvaluatorOutput -class StringLiteralEvaluator : Evaluator { - override fun evaluate(node: Node, environment: Environment): EvaluatorOutput { +class StringLiteralEvaluator : Evaluator() { + override fun supportedNodes() = listOf(StringLiteralNode::class) + + override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput { val value = (node as StringLiteralNode).token.value as String return EvaluatorOutput.value(Value.string(value)) }