Enable passing arguments to custom functions

This commit is contained in:
2020-03-11 22:16:29 +01:00
parent 7d61756273
commit 53bba579c1
11 changed files with 110 additions and 32 deletions

View File

@@ -0,0 +1,25 @@
package io.smnp.collection
class Stack<T> private constructor(private val list: MutableList<T>) : List<T> by list {
fun push(item: T) {
list.add(item)
}
fun pop(): T? {
if(list.isEmpty()) {
return null
}
val last = list.last()
list.removeAt(list.size-1)
return last
}
fun top() = list.last()
companion object {
fun <T> of(vararg items: T): Stack<T> {
return Stack(mutableListOf(*items))
}
}
}

View File

@@ -12,4 +12,9 @@ interface Environment {
fun printCallStack()
fun defineFunction(function: Function)
fun defineMethod(method: Method)
fun pushScope(scope: MutableMap<String, Value> = mutableMapOf())
fun popScope(): Map<String, Value>?
fun printScopes()
fun setVariable(name: String, value: Value)
fun getVariable(name: String): Value
}

View File

@@ -1,28 +1,22 @@
package io.smnp.runtime.model
import io.smnp.collection.Stack
import io.smnp.type.model.Value
import io.smnp.type.module.Module
class CallStack {
private val items = mutableListOf<CallStackItem>()
private val items = Stack.of<CallStackFrame>()
fun push(module: Module, name: String, arguments: List<Value>) {
items.add(CallStackItem(module, name, arguments))
items.push(CallStackFrame(module, name, arguments))
}
fun push(item: CallStackItem) {
items.add(item)
}
fun push(frame: CallStackFrame) = items.push(frame)
fun pop(): CallStackItem? {
if(items.isEmpty()) {
return null
}
fun pop() = items.pop()
val last = items.last()
items.removeAt(items.size-1)
return last
}
fun top() = items.top()
fun pretty() {
items.asReversed().forEachIndexed { index, item -> println("[${items.size - index - 1}] $item") }

View File

@@ -0,0 +1,35 @@
package io.smnp.runtime.model
import io.smnp.callable.signature.ActualSignatureFormatter
import io.smnp.collection.Stack
import io.smnp.type.model.Value
import io.smnp.type.module.Module
data class CallStackFrame(
val module: Module,
val name: String,
val arguments: List<Value>
) {
private val scopes = Stack.of<MutableMap<String, Value>>(mutableMapOf())
fun pushScope(scope: MutableMap<String, Value> = mutableMapOf()) {
scopes.push(scope)
}
fun popScope() = scopes.pop()
fun setVariable(name: String, value: Value) {
val scope = scopes.lastOrNull { it.containsKey(name) } ?: scopes.top()
scope[name] = value
}
fun getVariable(name: String): Value {
return scopes.lastOrNull { it.containsKey(name) }?.get(name) ?: throw RuntimeException("Variable `$name` not found")
}
fun prettyScope() {
scopes.asReversed().forEachIndexed { index, item -> println("[${scopes.size - index - 1}] $item") }
}
override fun toString() = "${module.canonicalName}::$name${ActualSignatureFormatter.format(arguments.toTypedArray())}"
}

View File

@@ -1,13 +0,0 @@
package io.smnp.runtime.model
import io.smnp.callable.signature.ActualSignatureFormatter
import io.smnp.type.model.Value
import io.smnp.type.module.Module
data class CallStackItem(
val module: Module,
val name: String,
val arguments: List<Value>
) {
override fun toString() = "${module.canonicalName}::$name${ActualSignatureFormatter.format(arguments.toTypedArray())}"
}