Improve callstack() debug function and rename it to stacktrace()

This commit is contained in:
2020-03-14 16:44:28 +01:00
parent 5c56060e70
commit 8ee3195bef
7 changed files with 53 additions and 41 deletions

View File

@@ -10,7 +10,7 @@ interface Environment {
fun printModules(printContent: Boolean)
fun invokeFunction(name: String, arguments: List<Value>): Value
fun invokeMethod(obj: Value, name: String, arguments: List<Value>): Value
fun printCallStack()
fun printCallStack(scopes: Boolean = false)
fun stackTrace(): String
fun defineFunction(function: Function)
fun defineMethod(method: Method)

View File

@@ -6,24 +6,30 @@ import io.smnp.type.module.Module
class CallStack {
private val items = Stack.of<CallStackFrame>()
private val items = Stack.of<CallStackFrame>()
fun push(module: Module, name: String, arguments: List<Value>) {
items.push(CallStackFrame(module, name, arguments))
}
fun push(module: Module, name: String, arguments: List<Value>) {
items.push(CallStackFrame(module, name, arguments))
}
fun push(frame: CallStackFrame) = items.push(frame)
fun push(frame: CallStackFrame) = items.push(frame)
fun pop() = items.pop()
fun pop() = items.pop()
fun top() = items.top()
fun top() = items.top()
val size: Int
get() = items.size
val size: Int
get() = items.size
fun pretty() {
items.asReversed().forEachIndexed { index, item -> println("[${items.size - index - 1}] $item") }
}
fun pretty(scopes: Boolean = false) {
items.asReversed().mapIndexed { index, item ->
println("[${items.size - index - 1}] $item")
if (scopes) {
item.scopes.forEach { println(" $it") }
}
}
}
fun stackTrace() = items.asReversed().mapIndexed { index, item -> "[${items.size - index - 1}] $item" }.joinToString("\n")
val stackTrace: List<String>
get() = items.asReversed().mapIndexed { index, item -> "[${items.size - index - 1}] $item" }
}

View File

@@ -11,29 +11,32 @@ data class CallStackFrame(
val name: String,
val arguments: List<Value>
) {
private val scopes = Stack.of<MutableMap<String, Value>>(mutableMapOf())
private val scopesStack = Stack.of<MutableMap<String, Value>>(mutableMapOf())
fun pushScope(scope: MutableMap<String, Value> = mutableMapOf()) {
scopes.push(scope)
scopesStack.push(scope)
}
fun popScope() = scopes.pop()
fun popScope() = scopesStack.pop()
val scopesCount: Int
get() = scopes.size
get() = scopesStack.size
fun setVariable(name: String, value: Value) {
val scope = scopes.lastOrNull { it.containsKey(name) } ?: scopes.top()
val scope = scopesStack.lastOrNull { it.containsKey(name) } ?: scopesStack.top()
scope[name] = value
}
fun getVariable(name: String): Value {
return scopes.lastOrNull { it.containsKey(name) }?.get(name) ?: throw EvaluationException("Undefined variable `$name`")
return scopesStack.lastOrNull { it.containsKey(name) }?.get(name) ?: throw EvaluationException("Undefined variable `$name`")
}
fun prettyScope() {
scopes.asReversed().forEachIndexed { index, item -> println("[${scopes.size - index - 1}] $item") }
scopes.forEach { println(it) }
}
val scopes: List<String>
get() = scopesStack.asReversed().mapIndexed { index, item -> "[${scopesStack.size - index - 1}] $item" }
override fun toString() = "${module.canonicalName}::$name${ActualSignatureFormatter.format(arguments.toTypedArray())}"
}

View File

@@ -123,12 +123,12 @@ class DefaultEnvironment : Environment {
return value
}
override fun printCallStack() {
callStack.pretty()
override fun printCallStack(scopes: Boolean) {
callStack.pretty(scopes)
}
override fun stackTrace(): String {
return callStack.stackTrace()
return callStack.stackTrace.joinToString("\n")
}
override fun defineFunction(function: Function) {

View File

@@ -1,9 +1,9 @@
package io.smnp.ext
import io.smnp.ext.function.CallStackFunction
import io.smnp.ext.function.StackTraceFuction
import org.pf4j.Extension
@Extension
class DebugModule : NativeModuleProvider("smnp.lang.debug") {
override fun functions() = listOf(CallStackFunction())
override fun functions() = listOf(StackTraceFuction())
}

View File

@@ -1,15 +0,0 @@
package io.smnp.ext.function
import io.smnp.callable.function.Function
import io.smnp.callable.function.FunctionDefinitionTool
import io.smnp.callable.signature.Signature
import io.smnp.type.model.Value
class CallStackFunction : Function("callstack") {
override fun define(new: FunctionDefinitionTool) {
new function Signature.simple() body { env, _ ->
env.printCallStack()
Value.void()
}
}
}

View File

@@ -0,0 +1,18 @@
package io.smnp.ext.function
import io.smnp.callable.function.Function
import io.smnp.callable.function.FunctionDefinitionTool
import io.smnp.callable.signature.Signature
import io.smnp.type.enumeration.DataType.BOOL
import io.smnp.type.matcher.Matcher.Companion.ofType
import io.smnp.type.matcher.Matcher.Companion.optional
import io.smnp.type.model.Value
class StackTraceFuction : Function("stacktrace") {
override fun define(new: FunctionDefinitionTool) {
new function Signature.simple(optional(ofType(BOOL))) body { env, args ->
env.printCallStack(args.getOrNull(0)?.value as Boolean? ?: false)
Value.void()
}
}
}