Create method and function invocation exception along with arguments formatter
This commit is contained in:
@@ -1,11 +1,6 @@
|
||||
package io.smnp
|
||||
|
||||
import io.smnp.api.enumeration.DataType
|
||||
import io.smnp.api.environment.Environment
|
||||
import io.smnp.api.matcher.Matcher.Companion.listOf
|
||||
import io.smnp.api.matcher.Matcher.Companion.ofType
|
||||
import io.smnp.api.model.Value
|
||||
import io.smnp.api.signature.Signature
|
||||
import io.smnp.dsl.ast.parser.RootParser
|
||||
import io.smnp.dsl.token.tokenizer.DefaultTokenizer
|
||||
import io.smnp.evaluation.evaluator.DefaultEvaluator
|
||||
@@ -23,10 +18,4 @@ fun main(args: Array<String>) {
|
||||
|
||||
val value = evaluator.evaluate(ast.node.children[0], Environment()).value!!
|
||||
|
||||
val signature = Signature.vararg(ofType(DataType.INT), ofType(
|
||||
DataType.BOOL), listOf(DataType.NOTE))
|
||||
|
||||
println(signature)
|
||||
|
||||
println(signature.parse(value.value!! as List<Value>))
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package io.smnp.api.callable
|
||||
|
||||
import io.smnp.api.environment.Environment
|
||||
import io.smnp.api.model.Value
|
||||
import io.smnp.error.FunctionInvocationException
|
||||
|
||||
abstract class Function(val name: String) {
|
||||
private var definitions: List<FunctionDefinition> = mutableListOf()
|
||||
@@ -15,8 +16,9 @@ abstract class Function(val name: String) {
|
||||
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
|
||||
.firstOrNull { (_, args) -> args.signatureMatched }
|
||||
?: throw FunctionInvocationException(this, arguments)
|
||||
|
||||
return definition.body(environment, args.arguments)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.smnp.api.callable
|
||||
import io.smnp.api.environment.Environment
|
||||
import io.smnp.api.matcher.Matcher
|
||||
import io.smnp.api.model.Value
|
||||
import io.smnp.error.MethodInvocationException
|
||||
|
||||
abstract class Method(val typeMatcher: Matcher, val name: String) {
|
||||
private var definitions: List<MethodDefinition> = mutableListOf()
|
||||
@@ -18,8 +19,9 @@ abstract class Method(val typeMatcher: Matcher, val name: String) {
|
||||
fun call(environment: Environment, obj: Value, 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
|
||||
.firstOrNull { (_, args) -> args.signatureMatched }
|
||||
?: throw MethodInvocationException(this, obj, arguments)
|
||||
|
||||
return definition.body(environment, obj, args.arguments)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package io.smnp.api.signature
|
||||
|
||||
import io.smnp.api.enumeration.DataType
|
||||
import io.smnp.api.model.Value
|
||||
|
||||
object ActualSignatureFormatter {
|
||||
fun format(arguments: Array<out Value>, parentheses: Boolean = true): String {
|
||||
val output = mutableListOf<String>()
|
||||
for(argument in arguments) {
|
||||
output.add(when(argument.type) {
|
||||
DataType.LIST -> listTypes(argument.value as List<Value>)
|
||||
DataType.MAP -> mapTypes(argument.value as Map<Value, Value>)
|
||||
else -> argument.type.name.toLowerCase()
|
||||
})
|
||||
}
|
||||
|
||||
return if(parentheses) "(${output.joinToString()})" else output.joinToString()
|
||||
}
|
||||
|
||||
private fun listTypes(list: List<Value>, output: MutableList<String> = mutableListOf()): String {
|
||||
for (item in list) {
|
||||
output.add(when (item.type) {
|
||||
DataType.LIST -> listTypes(item.value as List<Value>)
|
||||
DataType.MAP -> mapTypes(item.value as Map<Value, Value>)
|
||||
else -> item.type.name.toLowerCase()
|
||||
})
|
||||
}
|
||||
|
||||
return "list<${output.toSet().joinToString()}>"
|
||||
}
|
||||
|
||||
private fun mapTypes(map: Map<Value, Value>, output: MutableMap<Value, String> = mutableMapOf()): String {
|
||||
for ((k, v) in map) {
|
||||
output[k] = when (v.type) {
|
||||
DataType.LIST -> listTypes(v.value as List<Value>)
|
||||
DataType.MAP -> mapTypes(v.value as Map<Value, Value>)
|
||||
else -> v.type.name.toLowerCase()
|
||||
}
|
||||
}
|
||||
|
||||
return "map<${output.keys.toSet().joinToString()}><${output.values.toSet().joinToString()}}>"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package io.smnp.error
|
||||
|
||||
import io.smnp.api.callable.Function
|
||||
import io.smnp.api.model.Value
|
||||
import io.smnp.api.signature.ActualSignatureFormatter.format
|
||||
|
||||
class FunctionInvocationException(private val function: Function, private val passedArguments: Array<out Value>) : Exception() {
|
||||
override fun toString() = "Invalid signature: ${function.name}${format(passedArguments)}\nAllowed signatures:\n${function.signature}"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package io.smnp.error
|
||||
|
||||
import io.smnp.api.callable.Method
|
||||
import io.smnp.api.model.Value
|
||||
import io.smnp.api.signature.ActualSignatureFormatter.format
|
||||
|
||||
class MethodInvocationException(private val method: Method, private val obj: Value, private val passedArguments: Array<out Value>) : Exception() {
|
||||
override fun toString() = "Invalid signature: $obj.${method.name}${format(passedArguments)}\nAllowed signatures:\n${method.signature}"
|
||||
}
|
||||
Reference in New Issue
Block a user