Add support for modules dependencies
This commit is contained in:
@@ -3,91 +3,105 @@ package io.smnp.environment
|
||||
import io.smnp.callable.function.Function
|
||||
import io.smnp.callable.method.Method
|
||||
import io.smnp.callable.signature.ActualSignatureFormatter.format
|
||||
import io.smnp.ext.DefaultModuleRegistry
|
||||
import io.smnp.ext.DefaultModuleRegistry.requestModulesForPath
|
||||
import io.smnp.ext.ModuleDefinition
|
||||
import io.smnp.runtime.model.CallStack
|
||||
import io.smnp.type.model.Value
|
||||
import io.smnp.type.module.Module
|
||||
|
||||
class DefaultEnvironment : Environment {
|
||||
private val rootModule = Module("<root>")
|
||||
private val loadedModules = mutableListOf<String>()
|
||||
private val callStack = CallStack()
|
||||
private val rootModule = Module("<root>")
|
||||
private val loadedModules = mutableListOf<String>()
|
||||
private val callStack = CallStack()
|
||||
|
||||
init {
|
||||
callStack.push(rootModule, "<entrypoint>", emptyList())
|
||||
}
|
||||
init {
|
||||
callStack.push(rootModule, "<entrypoint>", emptyList())
|
||||
}
|
||||
|
||||
override fun loadModule(path: String) {
|
||||
if(!loadedModules.contains(path)) {
|
||||
DefaultModuleRegistry.requestModulesForPath(path).forEach {
|
||||
rootModule.addSubmodule(it)
|
||||
loadedModules.add(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun loadModule(path: String) {
|
||||
requestModulesForPath(path).let {
|
||||
loadModule(it)
|
||||
loadDependencies(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun printModules(printContent: Boolean) {
|
||||
rootModule.pretty(printContent)
|
||||
}
|
||||
private fun loadModule(moduleDefinition: ModuleDefinition) {
|
||||
rootModule.addSubmodule(moduleDefinition.module())
|
||||
loadedModules.add(moduleDefinition.path)
|
||||
}
|
||||
|
||||
override fun invokeFunction(name: String, arguments: List<Value>): Value {
|
||||
val foundFunctions = rootModule.findFunction(name)
|
||||
if(foundFunctions.isEmpty()) {
|
||||
throw RuntimeException("No function found with name of '$name'")
|
||||
}
|
||||
private fun loadDependencies(moduleDefinition: ModuleDefinition) {
|
||||
moduleDefinition.dependencies().forEach { dependencyPath ->
|
||||
if (!loadedModules.contains(dependencyPath)) {
|
||||
val dependency = requestModulesForPath(dependencyPath)
|
||||
loadModule(dependency)
|
||||
loadDependencies(dependency)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(foundFunctions.size > 1) {
|
||||
throw RuntimeException("Found ${foundFunctions.size} functions with name of $name: [${foundFunctions.map { it.module.canonicalName }.joinToString()}]")
|
||||
override fun printModules(printContent: Boolean) {
|
||||
rootModule.pretty(printContent)
|
||||
}
|
||||
|
||||
}
|
||||
override fun invokeFunction(name: String, arguments: List<Value>): Value {
|
||||
val foundFunctions = rootModule.findFunction(name)
|
||||
if (foundFunctions.isEmpty()) {
|
||||
throw RuntimeException("No function found with name of '$name'")
|
||||
}
|
||||
|
||||
val function = foundFunctions[0]
|
||||
if (foundFunctions.size > 1) {
|
||||
throw RuntimeException("Found ${foundFunctions.size} functions with name of $name: [${foundFunctions.map { it.module.canonicalName }.joinToString()}]")
|
||||
|
||||
callStack.push(function.module, function.name, arguments)
|
||||
val value = function.call(this, *arguments.toTypedArray())
|
||||
callStack.pop()
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
val function = foundFunctions[0]
|
||||
|
||||
override fun invokeMethod(obj: Value, name: String, arguments: List<Value>): Value {
|
||||
val foundMethods = rootModule.findMethod(obj, name)
|
||||
if(foundMethods.isEmpty()) {
|
||||
throw RuntimeException("No method found with name of '$name' for ${format(obj)}")
|
||||
}
|
||||
callStack.push(function.module, function.name, arguments)
|
||||
val value = function.call(this, *arguments.toTypedArray())
|
||||
callStack.pop()
|
||||
|
||||
if(foundMethods.size > 1) {
|
||||
throw RuntimeException("Found ${foundMethods.size} methods with name of $name for ${format(obj)}: [${foundMethods.map { it.module.canonicalName }.joinToString()}]")
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
val method = foundMethods[0]
|
||||
override fun invokeMethod(obj: Value, name: String, arguments: List<Value>): Value {
|
||||
val foundMethods = rootModule.findMethod(obj, name)
|
||||
if (foundMethods.isEmpty()) {
|
||||
throw RuntimeException("No method found with name of '$name' for ${format(obj)}")
|
||||
}
|
||||
|
||||
callStack.push(method.module, "${method.typeMatcher}.${method.name}", arguments)
|
||||
val value = method.call(this, obj, *arguments.toTypedArray())
|
||||
callStack.pop()
|
||||
if (foundMethods.size > 1) {
|
||||
throw RuntimeException("Found ${foundMethods.size} methods with name of $name for ${format(obj)}: [${foundMethods.map { it.module.canonicalName }.joinToString()}]")
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
val method = foundMethods[0]
|
||||
|
||||
override fun printCallStack() {
|
||||
callStack.pretty()
|
||||
}
|
||||
callStack.push(method.module, "${method.typeMatcher}.${method.name}", arguments)
|
||||
val value = method.call(this, obj, *arguments.toTypedArray())
|
||||
callStack.pop()
|
||||
|
||||
override fun defineFunction(function: Function) {
|
||||
rootModule.addFunction(function)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun defineMethod(method: Method) {
|
||||
rootModule.addMethod(method)
|
||||
}
|
||||
override fun printCallStack() {
|
||||
callStack.pretty()
|
||||
}
|
||||
|
||||
override fun pushScope(scope: MutableMap<String, Value>) = callStack.top().pushScope(scope)
|
||||
override fun defineFunction(function: Function) {
|
||||
rootModule.addFunction(function)
|
||||
}
|
||||
|
||||
override fun popScope() = callStack.top().popScope()
|
||||
override fun defineMethod(method: Method) {
|
||||
rootModule.addMethod(method)
|
||||
}
|
||||
|
||||
override fun printScopes() = callStack.top().prettyScope()
|
||||
override fun pushScope(scope: MutableMap<String, Value>) = callStack.top().pushScope(scope)
|
||||
|
||||
override fun setVariable(name: String, value: Value) = callStack.top().setVariable(name, value)
|
||||
override fun popScope() = callStack.top().popScope()
|
||||
|
||||
override fun getVariable(name: String) = callStack.top().getVariable(name)
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user