mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 13:11:32 +00:00
evaluator: cache native function resolution
This commit is contained in:
@ -3,20 +3,27 @@ package gay.pizza.pork.evaluator
|
||||
import gay.pizza.pork.ast.FunctionDefinition
|
||||
|
||||
class FunctionContext(val compilationUnitContext: CompilationUnitContext, val node: FunctionDefinition) : CallableFunction {
|
||||
private fun resolveMaybeNative(): CallableFunction? = if (node.native == null) {
|
||||
null
|
||||
} else {
|
||||
val native = node.native!!
|
||||
val nativeFunctionProvider =
|
||||
compilationUnitContext.evaluator.nativeFunctionProvider(native.form.id)
|
||||
nativeFunctionProvider.provideNativeFunction(native.definition.text)
|
||||
}
|
||||
|
||||
private val nativeCached by lazy { resolveMaybeNative() }
|
||||
|
||||
override fun call(arguments: Arguments): Any {
|
||||
if (nativeCached != null) {
|
||||
return nativeCached!!.call(arguments)
|
||||
}
|
||||
|
||||
val scope = compilationUnitContext.internalScope.fork()
|
||||
for ((index, argumentSymbol) in node.arguments.withIndex()) {
|
||||
scope.define(argumentSymbol.id, arguments.values[index])
|
||||
}
|
||||
|
||||
if (node.native != null) {
|
||||
val native = node.native!!
|
||||
val nativeFunctionProvider =
|
||||
compilationUnitContext.evaluator.nativeFunctionProvider(native.form.id)
|
||||
val nativeFunction = nativeFunctionProvider.provideNativeFunction(native.definition.text)
|
||||
return nativeFunction.call(arguments)
|
||||
}
|
||||
|
||||
if (node.block == null) {
|
||||
throw RuntimeException("Native or Block is required for FunctionDefinition")
|
||||
}
|
||||
|
Reference in New Issue
Block a user