Improve callstack() debug function and rename it to stacktrace()
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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" }
|
||||
}
|
||||
@@ -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())}"
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user