Enable passing arguments to custom functions

This commit is contained in:
2020-03-11 22:16:29 +01:00
parent 7d61756273
commit 53bba579c1
11 changed files with 110 additions and 32 deletions

View File

@@ -15,15 +15,18 @@ object CustomFunction {
override fun define(new: FunctionDefinitionTool) {
val (_, argumentsNode, bodyNode) = node
val signature = FunctionSignatureParser.parseSignature(argumentsNode as FunctionDefinitionArgumentsNode)
val evaluator = BlockEvaluator()
val evaluator = BlockEvaluator(dedicatedScope = false)
new function signature body { env, args ->
val boundArguments = FunctionEnvironmentProvider.provideEnvironment(argumentsNode, args, env)
// TODO push boundArguments to variables scope
try {
env.pushScope(boundArguments.toMutableMap())
evaluator.evaluate(bodyNode, env)
} catch(value: Return) {
return@body value.value
} finally {
env.popScope()
}
Value.void()

View File

@@ -79,4 +79,14 @@ class DefaultEnvironment : Environment {
override fun defineMethod(method: Method) {
rootModule.addMethod(method)
}
override fun pushScope(scope: MutableMap<String, Value>) = callStack.top().pushScope(scope)
override fun popScope() = callStack.top().popScope()
override fun printScopes() = callStack.top().prettyScope()
override fun setVariable(name: String, value: Value) = callStack.top().setVariable(name, value)
override fun getVariable(name: String) = callStack.top().getVariable(name)
}

View File

@@ -6,15 +6,18 @@ import io.smnp.environment.Environment
import io.smnp.evaluation.model.entity.EvaluatorOutput
import io.smnp.evaluation.model.enumeration.EvaluationResult
class BlockEvaluator : Evaluator() {
class BlockEvaluator(private val dedicatedScope: Boolean) : Evaluator() {
override fun supportedNodes() = listOf(BlockNode::class)
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val evaluator = DefaultEvaluator()
if (dedicatedScope) environment.pushScope()
val ok = (node as BlockNode).statements.all {
evaluator.evaluate(it, environment).result != EvaluationResult.FAILED
}
if (dedicatedScope) environment.popScope()
return if(ok) EvaluatorOutput.ok() else EvaluatorOutput.fail()
return if (ok) EvaluatorOutput.ok() else EvaluatorOutput.fail()
}
}

View File

@@ -10,7 +10,7 @@ class DefaultEvaluator : Evaluator() {
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
return oneOf(
ConditionEvaluator(),
BlockEvaluator(),
BlockEvaluator(true),
ThrowEvaluator(),
ReturnEvaluator(),
ExpressionEvaluator()

View File

@@ -16,7 +16,8 @@ class ExpressionEvaluator : Evaluator() {
BoolLiteralEvaluator(),
NoteLiteralEvaluator(),
ListEvaluator(),
MapEvaluator(),
MapEvaluator(),
IdentifierEvaluator(),
MinusOperatorEvaluator(),
NotOperatorEvaluator(),

View File

@@ -0,0 +1,15 @@
package io.smnp.evaluation.evaluator
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 IdentifierEvaluator : Evaluator() {
override fun supportedNodes() = listOf(IdentifierNode::class)
override fun tryToEvaluate(node: Node, environment: Environment): EvaluatorOutput {
val identifier = (node as IdentifierNode).token.rawValue
return EvaluatorOutput.value(environment.getVariable(identifier))
}
}