Create scaffolding for custom functions

This commit is contained in:
2020-03-11 19:59:29 +01:00
parent eb4fb1e980
commit e7bf085f58
10 changed files with 101 additions and 5 deletions

View File

@@ -0,0 +1,25 @@
package io.smnp.callable.function
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.type.model.Value
object CustomFunction {
fun create(node: FunctionDefinitionNode): Function {
val identifier = (node.identifier as IdentifierNode).token.rawValue
return object : Function(identifier) {
override fun define(new: FunctionDefinitionTool) {
val (_, argumentsNode, bodyNode) = node
val signature = FunctionSignatureParser.parseSignature(argumentsNode as FunctionDefinitionArgumentsNode)
new function signature define { env, args ->
val boundArguments = FunctionEnvironmentProvider.provideEnvironment(argumentsNode, args, env)
// TODO(Implement bodyNode evaluation)
Value.void()
}
}
}
}
}

View File

@@ -0,0 +1,26 @@
package io.smnp.callable.function
import io.smnp.dsl.ast.model.node.FunctionDefinitionArgumentsNode
import io.smnp.dsl.ast.model.node.IdentifierNode
import io.smnp.dsl.ast.model.node.OptionalFunctionDefinitionArgumentNode
import io.smnp.dsl.ast.model.node.RegularFunctionDefinitionArgumentNode
import io.smnp.environment.Environment
import io.smnp.error.ShouldNeverReachThisLineException
import io.smnp.evaluation.evaluator.ExpressionEvaluator
import io.smnp.type.model.Value
object FunctionEnvironmentProvider {
fun provideEnvironment(signature: FunctionDefinitionArgumentsNode, actualArgs: List<Value>, environment: Environment): Map<String, Value> {
val evaluator = ExpressionEvaluator()
return signature.items.mapIndexed { index, node ->
when (node) {
is RegularFunctionDefinitionArgumentNode -> (node.identifier as IdentifierNode).token.rawValue to actualArgs[index]
is OptionalFunctionDefinitionArgumentNode -> (node.identifier as IdentifierNode).token.rawValue to evaluator.evaluate(
node.defaultValue,
environment
).value!!
else -> throw ShouldNeverReachThisLineException()
}
}.toMap()
}
}