Refactor Value and EvaluatorOutput models in order to get rid of optionals(?)

This commit is contained in:
2020-03-14 13:25:42 +01:00
parent d8744670ed
commit 5b03f55cd4
30 changed files with 60 additions and 78 deletions

View File

@@ -39,6 +39,6 @@ object FunctionEnvironmentProvider {
index: Int
) = (node.identifier as IdentifierNode).token.rawValue to
if (index < actualArgs.size) actualArgs[index]
else evaluator.evaluate(node.defaultValue, environment).value!!
else evaluator.evaluate(node.defaultValue, environment).value
}

View File

@@ -14,7 +14,7 @@ class AccessOperatorEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val evaluator = ExpressionEvaluator()
val (lhsNode, _, rhsNode) = (node as AccessOperatorNode)
val lhs = evaluator.evaluate(lhsNode, environment).value!!
val lhs = evaluator.evaluate(lhsNode, environment).value
return when (rhsNode) {
is IdentifierNode -> {
@@ -33,7 +33,7 @@ class AccessOperatorEvaluator : Evaluator() {
val (identifierNode, argsNode) = rhsNode
val identifier = (identifierNode as IdentifierNode).token.rawValue
val arguments =
(argsNode as FunctionCallArgumentsNode).items.map { evaluator.evaluate(it, environment).value!! }
(argsNode as FunctionCallArgumentsNode).items.map { evaluator.evaluate(it, environment).value }
try {
return EvaluatorOutput.value(environment.invokeMethod(lhs, identifier, arguments))
} catch(e: MethodInvocationException) {

View File

@@ -18,7 +18,7 @@ class AssignmentOperatorEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val (identifierNode, _, valueNode) = node as AssignmentOperatorNode
val identifier = (identifierNode as IdentifierNode).token.rawValue
val value = evaluator.evaluate(valueNode, environment).value!!
val value = evaluator.evaluate(valueNode, environment).value
if (value.type == DataType.VOID) {
throw PositionException(

View File

@@ -18,7 +18,7 @@ class ConditionEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val (conditionNode, trueBranchNode, falseBranchNode) = (node as ConditionNode)
val condition = expressionEvaluator.evaluate(conditionNode, environment).value!!
val condition = expressionEvaluator.evaluate(conditionNode, environment).value
if (condition.type != DataType.BOOL) {
throw PositionException(
@@ -30,7 +30,7 @@ class ConditionEvaluator : Evaluator() {
)
}
if (condition.value!! as Boolean) {
if (condition.value as Boolean) {
return defaultEvaluator.evaluate(trueBranchNode, environment)
} else if (falseBranchNode !is NoneNode) {
return defaultEvaluator.evaluate(falseBranchNode, environment)

View File

@@ -18,7 +18,7 @@ class FunctionCallEvaluator : Evaluator() {
val evaluator = assert(ExpressionEvaluator(), "expression")
val (identifierNode, argsNode) = node as FunctionCallNode
val identifier = (identifierNode as IdentifierNode).token.rawValue
val arguments = (argsNode as FunctionCallArgumentsNode).items.map { evaluator.evaluate(it, environment).value!! }
val arguments = (argsNode as FunctionCallArgumentsNode).items.map { evaluator.evaluate(it, environment).value }
try {
return EvaluatorOutput.value(environment.invokeFunction(identifier, arguments))

View File

@@ -13,7 +13,7 @@ class ListEvaluator : Evaluator() {
val atomEvaluator = ExpressionEvaluator()
val items = (node as ListNode).items
.map { atomEvaluator.evaluate(it, environment) }
.map { it.value!! }
.map { it.value }
return EvaluatorOutput.value(Value.list(items))
}
}

View File

@@ -19,8 +19,8 @@ class LogicOperatorEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val evaluator = ExpressionEvaluator()
val (lhsNode, opNode, rhsNode) = (node as LogicOperatorNode)
val lhs = evaluator.evaluate(lhsNode, environment).value!!
val rhs = evaluator.evaluate(rhsNode, environment).value!!
val lhs = evaluator.evaluate(lhsNode, environment).value
val rhs = evaluator.evaluate(rhsNode, environment).value
val operator = (opNode as TokenNode).token.type
if (lhs.type != DataType.BOOL) {

View File

@@ -19,7 +19,7 @@ class LoopEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val (iteratorNode, parametersNode, statementNode, filterNode) = node as LoopNode
val iterator = expressionEvaluator.evaluate(iteratorNode, environment).value!!
val iterator = expressionEvaluator.evaluate(iteratorNode, environment).value
environment.pushScope()
val output = when (iterator.type) {
@@ -159,7 +159,7 @@ class LoopEvaluator : Evaluator() {
}
return output { outputs ->
while (expressionEvaluator.evaluate(iteratorNode, environment).value!!.value as Boolean) {
while (expressionEvaluator.evaluate(iteratorNode, environment).value.value as Boolean) {
outputs.add(defaultEvaluator.evaluate(statementNode, environment))
}
}
@@ -177,7 +177,7 @@ class LoopEvaluator : Evaluator() {
private fun filter(filterNode: Node, environment: Environment): Boolean {
if (filterNode != Node.NONE) {
val condition = expressionEvaluator.evaluate(filterNode, environment).value!!
val condition = expressionEvaluator.evaluate(filterNode, environment).value
if (condition.type != BOOL) {
throw PositionException(
EnvironmentException(
@@ -200,7 +200,7 @@ class LoopEvaluator : Evaluator() {
evaluate(outputs)
return when {
outputs.all { it.result == EvaluationResult.VALUE } -> EvaluatorOutput.value(Value.list(outputs.map { it.value!! }))
outputs.all { it.result == EvaluationResult.VALUE } -> EvaluatorOutput.value(Value.list(outputs.map { it.value }))
// Disclaimer: It musn't be ok() because ExpressionEvaluator expects non-ok success output from each
// of subevaluators.

View File

@@ -20,7 +20,7 @@ class MapEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val value = (node as MapNode).items
.map { it as MapEntryNode }
.map { getKey(it.key, environment) to evaluator.evaluate(it.value, environment).value!! }
.map { getKey(it.key, environment) to evaluator.evaluate(it.value, environment).value }
.toMap()
return EvaluatorOutput.value(Value.map(value))
@@ -29,7 +29,7 @@ class MapEvaluator : Evaluator() {
private fun getKey(keyNode: Node, environment: Environment): Value {
val key = when (keyNode) {
is IdentifierNode -> Value.string(keyNode.token.rawValue)
else -> evaluator.evaluate(keyNode, environment).value!!
else -> evaluator.evaluate(keyNode, environment).value
}
if (key.type !in listOf(BOOL, INT, NOTE, STRING)) {

View File

@@ -19,7 +19,7 @@ class MinusOperatorEvaluator : Evaluator() {
val operand = evaluator.evaluate(operandNode, environment)
return EvaluatorOutput.value(
when (operand.value!!.type) {
when (operand.value.type) {
DataType.INT -> Value.int(-1 * operand.value.value as Int)
DataType.FLOAT -> Value.float(-1.0f * operand.value.value as Float)
DataType.STRING -> Value.string((operand.value.value as String).reversed())

View File

@@ -16,7 +16,7 @@ class NotOperatorEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val (_, operandNode) = (node as NotOperatorNode)
val operand = evaluator.evaluate(operandNode, environment).value!!
val operand = evaluator.evaluate(operandNode, environment).value
if (operand.type != DataType.BOOL) {
throw PositionException(

View File

@@ -16,8 +16,8 @@ class PowerOperatorEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val (lhsNode, _, rhsNode) = (node as PowerOperatorNode)
val evaluator = ExpressionEvaluator()
val lhs = evaluator.evaluate(lhsNode, environment).value!!
val rhs = evaluator.evaluate(rhsNode, environment).value!!
val lhs = evaluator.evaluate(lhsNode, environment).value
val rhs = evaluator.evaluate(rhsNode, environment).value
if (!lhs.type.isNumeric() || !rhs.type.isNumeric()) {
throw PositionException(

View File

@@ -19,8 +19,8 @@ class ProductOperatorEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val evaluator = ExpressionEvaluator()
val (lhsNode, opNode, rhsNode) = (node as ProductOperatorNode)
val lhs = evaluator.evaluate(lhsNode, environment).value!!
val rhs = evaluator.evaluate(rhsNode, environment).value!!
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()) {

View File

@@ -18,8 +18,8 @@ class RelationOperatorEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val evaluator = ExpressionEvaluator()
val (lhsNode, opNode, rhsNode) = (node as RelationOperatorNode)
val lhs = evaluator.evaluate(lhsNode, environment).value!!
val rhs = evaluator.evaluate(rhsNode, environment).value!!
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("==", "!=")) {

View File

@@ -5,7 +5,6 @@ import io.smnp.dsl.ast.model.node.ReturnNode
import io.smnp.environment.Environment
import io.smnp.evaluation.model.entity.EvaluatorOutput
import io.smnp.evaluation.model.exception.Return
import io.smnp.type.model.Value
class ReturnEvaluator : Evaluator() {
override fun supportedNodes() = listOf(ReturnNode::class)
@@ -13,7 +12,7 @@ class ReturnEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val evaluator = ExpressionEvaluator()
val (valueNode) = node as ReturnNode
val value = evaluator.evaluate(valueNode, environment).value ?: Value.void()
val value = evaluator.evaluate(valueNode, environment).value
// Disclaimer
// Exception system usage to control program execution flow is really bad idea.

View File

@@ -20,8 +20,8 @@ class SumOperatorEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val evaluator = ExpressionEvaluator()
val (lhsNode, opNode, rhsNode) = (node as SumOperatorNode)
val lhs = evaluator.evaluate(lhsNode, environment).value!!
val rhs = evaluator.evaluate(rhsNode, environment).value!!
val lhs = evaluator.evaluate(lhsNode, environment).value
val rhs = evaluator.evaluate(rhsNode, environment).value
val operator = (opNode as TokenNode).token.type
return EvaluatorOutput.value(
@@ -37,9 +37,9 @@ class SumOperatorEvaluator : Evaluator() {
return if (areNumeric(lhs, rhs))
unify(lhs, rhs, int = { (l, r) -> Value.int(l + r) }, float = { (l, r) -> Value.float(l + r) })
else if (lhs.type == DataType.STRING)
Value.string(lhs.value!! as String + rhs.value.toString())
Value.string(lhs.value as String + rhs.value.toString())
else if (areLists(lhs, rhs))
Value.list(lhs.value!! as List<Value> + rhs.value!! as List<Value>)
Value.list(lhs.value as List<Value> + rhs.value as List<Value>)
else throw PositionException(
EnvironmentException(
EvaluationException(

View File

@@ -14,6 +14,6 @@ class ThrowEvaluator : Evaluator() {
val valueNode = (node as ThrowNode).value
val value = evaluator.evaluate(valueNode, environment)
throw CustomException(value.value!!.value.toString())
throw CustomException(value.value.value.toString())
}
}

View File

@@ -3,15 +3,15 @@ package io.smnp.evaluation.model.entity
import io.smnp.evaluation.model.enumeration.EvaluationResult
import io.smnp.type.model.Value
class EvaluatorOutput private constructor(val result: EvaluationResult, val value: Value?) {
class EvaluatorOutput private constructor(val result: EvaluationResult, val value: Value) {
override fun toString(): String {
return "$result(${value ?: ""})"
return "$result(${if(result == EvaluationResult.VALUE) value.toString() else ""})"
}
companion object {
fun ok(): EvaluatorOutput {
return EvaluatorOutput(EvaluationResult.OK, null)
return EvaluatorOutput(EvaluationResult.OK, Value.void())
}
fun value(value: Value): EvaluatorOutput {
@@ -19,7 +19,7 @@ class EvaluatorOutput private constructor(val result: EvaluationResult, val valu
}
fun fail(): EvaluatorOutput {
return EvaluatorOutput(EvaluationResult.FAILED, null)
return EvaluatorOutput(EvaluationResult.FAILED, Value.void())
}
}
}