mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 21:21:33 +00:00
global: a working virtual machine for some of the use cases. APIs and validation still WIP.
This commit is contained in:
@ -0,0 +1,15 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.ast.gen.ArgumentSpec
|
||||
import gay.pizza.pork.execution.NativeProvider
|
||||
|
||||
class AdaptedNativeProvider(val provider: NativeProvider) : ExpandedNativeProvider {
|
||||
override fun provideNativeFunction(
|
||||
definitions: List<String>,
|
||||
arguments: List<ArgumentSpec>,
|
||||
inside: SlabContext
|
||||
): CallableFunction {
|
||||
val function = provider.provideNativeFunction(definitions)
|
||||
return CallableFunction { args, _ -> function.invoke(args) }
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
typealias ArgumentList = List<Any>
|
@ -1,5 +1,7 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.execution.ArgumentList
|
||||
|
||||
fun interface CallableFunction {
|
||||
fun call(arguments: ArgumentList, stack: CallStack): Any
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.ast.FunctionLevelVisitor
|
||||
import gay.pizza.pork.ast.gen.*
|
||||
import gay.pizza.pork.execution.None
|
||||
import kotlin.math.abs
|
||||
|
||||
@Suppress("JavaIoSerializableObjectMustHaveReadResolve")
|
||||
|
@ -1,24 +1,21 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.ast.gen.Symbol
|
||||
import gay.pizza.pork.execution.ExecutionContext
|
||||
import gay.pizza.pork.execution.ExecutionContextProvider
|
||||
import gay.pizza.pork.frontend.ImportLocator
|
||||
import gay.pizza.pork.frontend.Slab
|
||||
import gay.pizza.pork.frontend.World
|
||||
|
||||
class Evaluator(val world: World) : ExecutionContextProvider {
|
||||
class Evaluator(val world: World) {
|
||||
private val scope = Scope.root()
|
||||
private val contexts = mutableMapOf<Slab, SlabContext>()
|
||||
private val nativeProviders = mutableMapOf<String, NativeProvider>()
|
||||
private val nativeProviders = mutableMapOf<String, ExpandedNativeProvider>()
|
||||
|
||||
fun evaluate(locator: ImportLocator): Scope {
|
||||
val slabContext = context(locator)
|
||||
val slabContext = slabContext(locator)
|
||||
slabContext.finalizeScope()
|
||||
return slabContext.externalScope
|
||||
}
|
||||
|
||||
fun context(slab: Slab): SlabContext {
|
||||
fun slabContext(slab: Slab): SlabContext {
|
||||
val slabContext = contexts.computeIfAbsent(slab) {
|
||||
SlabContext(slab, this, scope)
|
||||
}
|
||||
@ -26,20 +23,14 @@ class Evaluator(val world: World) : ExecutionContextProvider {
|
||||
return slabContext
|
||||
}
|
||||
|
||||
fun context(locator: ImportLocator): SlabContext = context(world.load(locator))
|
||||
fun slabContext(locator: ImportLocator): SlabContext = slabContext(world.load(locator))
|
||||
|
||||
fun nativeFunctionProvider(form: String): NativeProvider {
|
||||
fun nativeFunctionProvider(form: String): ExpandedNativeProvider {
|
||||
return nativeProviders[form] ?:
|
||||
throw RuntimeException("Unknown native function form: $form")
|
||||
}
|
||||
|
||||
fun addNativeProvider(form: String, nativeProvider: NativeProvider) {
|
||||
fun addNativeProvider(form: String, nativeProvider: ExpandedNativeProvider) {
|
||||
nativeProviders[form] = nativeProvider
|
||||
}
|
||||
|
||||
override fun prepare(importLocator: ImportLocator, entryPointSymbol: Symbol): ExecutionContext {
|
||||
val slab = context(importLocator)
|
||||
slab.finalizeScope()
|
||||
return EvaluatorExecutionContext(this, slab, entryPointSymbol)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.ast.gen.Symbol
|
||||
import gay.pizza.pork.execution.ExecutionContext
|
||||
import gay.pizza.pork.execution.ExecutionContextProvider
|
||||
import gay.pizza.pork.execution.NativeRegistry
|
||||
import gay.pizza.pork.frontend.ImportLocator
|
||||
import gay.pizza.pork.frontend.World
|
||||
|
||||
class EvaluatorProvider(val world: World) : ExecutionContextProvider {
|
||||
override fun prepare(importLocator: ImportLocator, entryPointSymbol: Symbol, nativeRegistry: NativeRegistry): ExecutionContext {
|
||||
val evaluator = Evaluator(world)
|
||||
nativeRegistry.forEachProvider { form, provider ->
|
||||
evaluator.addNativeProvider(form, AdaptedNativeProvider(provider))
|
||||
}
|
||||
val slab = evaluator.slabContext(importLocator)
|
||||
slab.finalizeScope()
|
||||
return EvaluatorExecutionContext(evaluator, slab, entryPointSymbol)
|
||||
}
|
||||
}
|
@ -2,6 +2,6 @@ package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.ast.gen.ArgumentSpec
|
||||
|
||||
interface NativeProvider {
|
||||
interface ExpandedNativeProvider {
|
||||
fun provideNativeFunction(definitions: List<String>, arguments: List<ArgumentSpec>, inside: SlabContext): CallableFunction
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.ast.gen.FunctionDefinition
|
||||
import gay.pizza.pork.execution.ArgumentList
|
||||
|
||||
class FunctionContext(val slabContext: SlabContext, val node: FunctionDefinition) : CallableFunction {
|
||||
val name: String by lazy { "${slabContext.slab.location.commonFriendlyName} ${node.symbol.id}" }
|
||||
|
@ -1,55 +0,0 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.ast.gen.ArgumentSpec
|
||||
import gay.pizza.pork.common.unused
|
||||
|
||||
class InternalNativeProvider(val quiet: Boolean = false) : NativeProvider {
|
||||
private val functions = mutableMapOf(
|
||||
"print" to CallableFunction(::printValues),
|
||||
"println" to CallableFunction(::printLine),
|
||||
"listSet" to CallableFunction(::setInList),
|
||||
"listInitWith" to CallableFunction(::listInitWith)
|
||||
)
|
||||
|
||||
fun add(name: String, function: CallableFunction) {
|
||||
functions[name] = function
|
||||
}
|
||||
|
||||
override fun provideNativeFunction(
|
||||
definitions: List<String>,
|
||||
arguments: List<ArgumentSpec>,
|
||||
inside: SlabContext
|
||||
): CallableFunction {
|
||||
val definition = definitions[0]
|
||||
return functions[definition] ?: throw RuntimeException("Unknown Internal Function: $definition")
|
||||
}
|
||||
|
||||
private fun printValues(arguments: ArgumentList, stack: CallStack): Any {
|
||||
unused(stack)
|
||||
if (quiet || arguments.isEmpty()) return None
|
||||
print(arguments.joinToString(" "))
|
||||
return None
|
||||
}
|
||||
|
||||
private fun printLine(arguments: ArgumentList, stack: CallStack): Any {
|
||||
unused(stack)
|
||||
if (quiet) return None
|
||||
println(arguments.joinToString(" "))
|
||||
return None
|
||||
}
|
||||
|
||||
private fun setInList(arguments: ArgumentList, stack: CallStack): Any {
|
||||
unused(stack)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val list = arguments[0] as MutableList<Any>
|
||||
val value = arguments[2]
|
||||
list[(arguments[1] as Number).toInt()] = value
|
||||
return value
|
||||
}
|
||||
|
||||
private fun listInitWith(arguments: ArgumentList, stack: CallStack): Any {
|
||||
unused(stack)
|
||||
val size = (arguments[0] as Number).toInt()
|
||||
return MutableList(size) { arguments[1] }
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
data object None
|
@ -1,5 +1,7 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.execution.None
|
||||
|
||||
class Scope(
|
||||
var parent: Scope? = null,
|
||||
var inherits: List<Scope> = emptyList(),
|
||||
|
@ -16,7 +16,7 @@ class SlabContext(val slab: Slab, val evaluator: Evaluator, rootScope: Scope) {
|
||||
|
||||
fun ensureImportedContextsExist() {
|
||||
for (importedSlab in slab.importedSlabs) {
|
||||
evaluator.context(importedSlab)
|
||||
evaluator.slabContext(importedSlab)
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ class SlabContext(val slab: Slab, val evaluator: Evaluator, rootScope: Scope) {
|
||||
|
||||
private fun processFinalImportScopes() {
|
||||
for (importedSlab in slab.importedSlabs) {
|
||||
val importedSlabContext = evaluator.context(importedSlab)
|
||||
val importedSlabContext = evaluator.slabContext(importedSlab)
|
||||
importedSlabContext.processFinalImportScopes()
|
||||
internalScope.inherit(importedSlabContext.externalScope)
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
import gay.pizza.pork.execution.None
|
||||
|
||||
class ValueStore(var value: Any, var type: ValueStoreType) {
|
||||
var isCurrentlyFree = false
|
||||
|
||||
|
Reference in New Issue
Block a user