global: a working virtual machine for some of the use cases. APIs and validation still WIP.

This commit is contained in:
2023-11-21 22:18:05 -08:00
parent 0a2d029c5c
commit 6211ad4ff1
53 changed files with 434 additions and 182 deletions

View File

@ -0,0 +1,5 @@
package gay.pizza.pork.execution
typealias ArgumentList = List<Any>
inline fun <reified T> ArgumentList.at(index: Int): T = this[index] as T

View File

@ -4,5 +4,5 @@ import gay.pizza.pork.ast.gen.Symbol
import gay.pizza.pork.frontend.ImportLocator
interface ExecutionContextProvider {
fun prepare(importLocator: ImportLocator, entryPointSymbol: Symbol): ExecutionContext
fun prepare(importLocator: ImportLocator, entryPointSymbol: Symbol, nativeRegistry: NativeRegistry): ExecutionContext
}

View File

@ -0,0 +1,45 @@
package gay.pizza.pork.execution
class InternalNativeProvider(val quiet: Boolean = false) : NativeProvider {
private val functions = mutableMapOf(
"print" to NativeFunction(::printValues),
"println" to NativeFunction(::printLine),
"listSet" to NativeFunction(::setInList),
"listInitWith" to NativeFunction(::listInitWith)
)
fun add(name: String, function: NativeFunction) {
functions[name] = function
}
override fun provideNativeFunction(definitions: List<String>): NativeFunction {
val definition = definitions[0]
return functions[definition] ?:
throw RuntimeException("Unknown internal function: $definition")
}
private fun printValues(arguments: ArgumentList): Any {
if (quiet || arguments.isEmpty()) return None
print(arguments.at<List<*>>(0).joinToString(" ") { it.toString() })
return None
}
private fun printLine(arguments: ArgumentList): Any {
if (quiet) return None
println(arguments.at<List<*>>(0).joinToString(" ") { it.toString() })
return Unit
}
private fun setInList(arguments: ArgumentList): Any {
@Suppress("UNCHECKED_CAST")
val list = arguments[0] as MutableList<Any>
val value = arguments[2]
list[(arguments.at<Number>(0)).toInt()] = value
return value
}
private fun listInitWith(arguments: ArgumentList): Any {
val size = arguments.at<Number>(0).toInt()
return MutableList(size) { arguments[1] }
}
}

View File

@ -0,0 +1,5 @@
package gay.pizza.pork.execution
fun interface NativeFunction {
fun invoke(args: ArgumentList): Any
}

View File

@ -0,0 +1,5 @@
package gay.pizza.pork.execution
interface NativeProvider {
fun provideNativeFunction(definitions: List<String>): NativeFunction
}

View File

@ -0,0 +1,18 @@
package gay.pizza.pork.execution
class NativeRegistry {
private val providers = mutableMapOf<String, NativeProvider>()
fun add(form: String, provider: NativeProvider) {
providers[form] = provider
}
fun forEachProvider(block: (String, NativeProvider) -> Unit) {
for ((form, provider) in providers) {
block(form, provider)
}
}
fun of(form: String): NativeProvider =
providers[form] ?: throw RuntimeException("Unknown native form: ${form}")
}

View File

@ -0,0 +1,3 @@
package gay.pizza.pork.execution
data object None