Refactor evaluators to make use of supportedNodes() method

This commit is contained in:
2020-03-07 17:15:56 +01:00
parent 24eb2194cf
commit 5f92cab2bf
12 changed files with 73 additions and 57 deletions

View File

@@ -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))
}

View File

@@ -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)
}
}

View File

@@ -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<out Node>): 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<KClass<out Node>>
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) {

View File

@@ -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))
}

View File

@@ -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))
}

View File

@@ -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) }

View File

@@ -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 }

View File

@@ -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)

View File

@@ -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)

View File

@@ -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))
}

View File

@@ -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)

View File

@@ -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))
}