Add support for function/methods invocation on Evaluator

This commit is contained in:
2020-03-10 22:16:40 +01:00
parent d29ef61245
commit ab82ee8628
4 changed files with 32 additions and 7 deletions

View File

@@ -1,6 +1,9 @@
package io.smnp.dsl.ast.model.node package io.smnp.dsl.ast.model.node
class FunctionCallNode(identifier: Node, arguments: Node) : Node(2, identifier.position) { class FunctionCallNode(identifier: Node, arguments: Node) : Node(2, identifier.position) {
operator fun component1() = children[0]
operator fun component2() = children[1]
val identifier: Node val identifier: Node
get() = children[0] get() = children[0]

View File

@@ -1,9 +1,6 @@
package io.smnp.evaluation.evaluator package io.smnp.evaluation.evaluator
import io.smnp.dsl.ast.model.node.AccessOperatorNode import io.smnp.dsl.ast.model.node.*
import io.smnp.dsl.ast.model.node.FunctionCallNode
import io.smnp.dsl.ast.model.node.IdentifierNode
import io.smnp.dsl.ast.model.node.Node
import io.smnp.environment.Environment import io.smnp.environment.Environment
import io.smnp.error.EvaluationException import io.smnp.error.EvaluationException
import io.smnp.evaluation.model.entity.EvaluatorOutput import io.smnp.evaluation.model.entity.EvaluatorOutput
@@ -22,8 +19,10 @@ class AccessOperatorEvaluator : Evaluator() {
EvaluatorOutput.value(lhs.properties[rhs] ?: throw EvaluationException("Unknown property $rhs of type ${lhs.type.name.toLowerCase()}", rhsNode.position)) EvaluatorOutput.value(lhs.properties[rhs] ?: throw EvaluationException("Unknown property $rhs of type ${lhs.type.name.toLowerCase()}", rhsNode.position))
} }
is FunctionCallNode -> { is FunctionCallNode -> {
// todo Implement when methods become available val (identifierNode, argsNode) = rhsNode
EvaluatorOutput.fail() val identifier = (identifierNode as IdentifierNode).token.rawValue
val arguments = (argsNode as FunctionCallArgumentsNode).items.map { evaluator.evaluate(it, environment).value!! }
return EvaluatorOutput.value(environment.invokeMethod(lhs, identifier, arguments))
} }
else -> { else -> {
throw EvaluationException("Invalid property access type - only property name and method call are allowed", rhsNode.position) throw EvaluationException("Invalid property access type - only property name and method call are allowed", rhsNode.position)

View File

@@ -25,7 +25,9 @@ class ExpressionEvaluator : Evaluator() {
SumOperatorEvaluator(), SumOperatorEvaluator(),
AccessOperatorEvaluator(), AccessOperatorEvaluator(),
LogicOperatorEvaluator(), LogicOperatorEvaluator(),
RelationOperatorEvaluator() RelationOperatorEvaluator(),
FunctionCallEvaluator()
).evaluate(node, environment) ).evaluate(node, environment)
if(output.result == EvaluationResult.OK) { if(output.result == EvaluationResult.OK) {

View File

@@ -0,0 +1,21 @@
package io.smnp.evaluation.evaluator
import io.smnp.dsl.ast.model.node.FunctionCallArgumentsNode
import io.smnp.dsl.ast.model.node.FunctionCallNode
import io.smnp.dsl.ast.model.node.IdentifierNode
import io.smnp.dsl.ast.model.node.Node
import io.smnp.environment.Environment
import io.smnp.evaluation.model.entity.EvaluatorOutput
class FunctionCallEvaluator : Evaluator() {
override fun supportedNodes() = listOf(FunctionCallNode::class)
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
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!! }
return EvaluatorOutput.value(environment.invokeFunction(identifier, arguments))
}
}