From d24f1d72c741c0abebd79c6cf0ab598e37a4be75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Sun, 8 Mar 2020 00:10:26 +0100 Subject: [PATCH] Create function definition tools --- .../kotlin/io/smnp/api/callable/Function.kt | 25 +++++++++++++++++++ .../smnp/api/callable/FunctionDefinition.kt | 7 ++++++ .../api/callable/FunctionDefinitionTool.kt | 20 +++++++++++++++ .../kotlin/io/smnp/api/model/ArgumentsList.kt | 4 +-- 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/io/smnp/api/callable/Function.kt create mode 100644 src/main/kotlin/io/smnp/api/callable/FunctionDefinition.kt create mode 100644 src/main/kotlin/io/smnp/api/callable/FunctionDefinitionTool.kt diff --git a/src/main/kotlin/io/smnp/api/callable/Function.kt b/src/main/kotlin/io/smnp/api/callable/Function.kt new file mode 100644 index 0000000..28c2347 --- /dev/null +++ b/src/main/kotlin/io/smnp/api/callable/Function.kt @@ -0,0 +1,25 @@ +package io.smnp.api.callable + +import io.smnp.api.environment.Environment +import io.smnp.api.model.Value + +abstract class Function(val name: String) { + private var definitions: List = mutableListOf() + + abstract fun define(new: FunctionDefinitionTool) + + init { + definitions = FunctionDefinitionTool().apply { define(this) }.definitions + } + + fun call(environment: Environment, vararg arguments: Value): Value { + val (definition, args) = definitions + .map { Pair(it, it.signature.parse(arguments.toList())) } + .first { (_, args) -> args.signatureMatched } + // TODO: Throw exception if signature is not matched + return definition.body(environment, args.arguments) + } + + val signature: String + get() = definitions.joinToString("\nor\n") { "$name${it.signature}" } +} \ No newline at end of file diff --git a/src/main/kotlin/io/smnp/api/callable/FunctionDefinition.kt b/src/main/kotlin/io/smnp/api/callable/FunctionDefinition.kt new file mode 100644 index 0000000..5ab86c3 --- /dev/null +++ b/src/main/kotlin/io/smnp/api/callable/FunctionDefinition.kt @@ -0,0 +1,7 @@ +package io.smnp.api.callable + +import io.smnp.api.environment.Environment +import io.smnp.api.model.Value +import io.smnp.api.signature.Signature + +class FunctionDefinition(val signature: Signature, val body: (Environment, List) -> Value) \ No newline at end of file diff --git a/src/main/kotlin/io/smnp/api/callable/FunctionDefinitionTool.kt b/src/main/kotlin/io/smnp/api/callable/FunctionDefinitionTool.kt new file mode 100644 index 0000000..82e177f --- /dev/null +++ b/src/main/kotlin/io/smnp/api/callable/FunctionDefinitionTool.kt @@ -0,0 +1,20 @@ +package io.smnp.api.callable + +import io.smnp.api.environment.Environment +import io.smnp.api.model.Value +import io.smnp.api.signature.Signature + +class FunctionDefinitionTool { + val definitions: MutableList = mutableListOf() + + infix fun function(signature: Signature): FunctionDefinitionToolStage2 { + return FunctionDefinitionToolStage2(signature) + } + + inner class FunctionDefinitionToolStage2(private val signature: Signature) { + infix fun define(body: (Environment, List) -> Value) { + definitions.add(FunctionDefinition(signature, body)) + } + } + +} diff --git a/src/main/kotlin/io/smnp/api/model/ArgumentsList.kt b/src/main/kotlin/io/smnp/api/model/ArgumentsList.kt index afff450..102df15 100644 --- a/src/main/kotlin/io/smnp/api/model/ArgumentsList.kt +++ b/src/main/kotlin/io/smnp/api/model/ArgumentsList.kt @@ -1,11 +1,11 @@ package io.smnp.api.model -class ArgumentsList(val isValid: Boolean, val arguments: List) { +class ArgumentsList(val signatureMatched: Boolean, val arguments: List) { operator fun get(index: Int) = arguments[index] fun toArray() = arguments.toTypedArray() - override fun toString() = if(isValid) "valid($arguments)" else "invalid" + override fun toString() = if(signatureMatched) "valid($arguments)" else "invalid" companion object { fun valid(arguments: List): ArgumentsList {