Add support for defining custom methods

This commit is contained in:
2020-03-12 21:46:11 +01:00
parent e7268bf18a
commit 26d072d46f
10 changed files with 106 additions and 12 deletions

View File

@@ -0,0 +1,42 @@
package io.smnp.callable.method
import io.smnp.callable.util.FunctionEnvironmentProvider
import io.smnp.callable.util.FunctionSignatureParser
import io.smnp.dsl.ast.model.node.FunctionDefinitionArgumentsNode
import io.smnp.dsl.ast.model.node.FunctionDefinitionNode
import io.smnp.dsl.ast.model.node.IdentifierNode
import io.smnp.evaluation.evaluator.BlockEvaluator
import io.smnp.evaluation.model.exception.Return
import io.smnp.type.matcher.Matcher
import io.smnp.type.model.Value
object CustomMethod {
fun create(type: Matcher, objectIdentifier: String, node: FunctionDefinitionNode): Method {
val identifier = (node.identifier as IdentifierNode).token.rawValue
return object : Method(type, identifier) {
override fun define(new: MethodDefinitionTool) {
val (_, argumentsNode, bodyNode) = node
val signature = FunctionSignatureParser.parseSignature(argumentsNode as FunctionDefinitionArgumentsNode)
val evaluator = BlockEvaluator(dedicatedScope = false)
new method signature body { env, obj, args ->
val boundArguments =
FunctionEnvironmentProvider.provideEnvironment(argumentsNode, args, env).toMutableMap()
boundArguments[objectIdentifier] = obj
try {
env.pushScope(boundArguments)
evaluator.evaluate(bodyNode, env)
} catch (value: Return) {
return@body value.value
} finally {
env.popScope()
}
Value.void()
}
}
}
}
}