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 printModules(printContent: Boolean)
|
||||||
fun invokeFunction(name: String, arguments: List<Value>): Value
|
fun invokeFunction(name: String, arguments: List<Value>): Value
|
||||||
fun invokeMethod(obj: Value, 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 stackTrace(): String
|
||||||
fun defineFunction(function: Function)
|
fun defineFunction(function: Function)
|
||||||
fun defineMethod(method: Method)
|
fun defineMethod(method: Method)
|
||||||
|
|||||||
@@ -6,24 +6,30 @@ import io.smnp.type.module.Module
|
|||||||
|
|
||||||
|
|
||||||
class CallStack {
|
class CallStack {
|
||||||
private val items = Stack.of<CallStackFrame>()
|
private val items = Stack.of<CallStackFrame>()
|
||||||
|
|
||||||
fun push(module: Module, name: String, arguments: List<Value>) {
|
fun push(module: Module, name: String, arguments: List<Value>) {
|
||||||
items.push(CallStackFrame(module, name, arguments))
|
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
|
val size: Int
|
||||||
get() = items.size
|
get() = items.size
|
||||||
|
|
||||||
fun pretty() {
|
fun pretty(scopes: Boolean = false) {
|
||||||
items.asReversed().forEachIndexed { index, item -> println("[${items.size - index - 1}] $item") }
|
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 name: String,
|
||||||
val arguments: List<Value>
|
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()) {
|
fun pushScope(scope: MutableMap<String, Value> = mutableMapOf()) {
|
||||||
scopes.push(scope)
|
scopesStack.push(scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun popScope() = scopes.pop()
|
fun popScope() = scopesStack.pop()
|
||||||
|
|
||||||
val scopesCount: Int
|
val scopesCount: Int
|
||||||
get() = scopes.size
|
get() = scopesStack.size
|
||||||
|
|
||||||
fun setVariable(name: String, value: Value) {
|
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
|
scope[name] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getVariable(name: String): 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() {
|
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())}"
|
override fun toString() = "${module.canonicalName}::$name${ActualSignatureFormatter.format(arguments.toTypedArray())}"
|
||||||
}
|
}
|
||||||
@@ -123,12 +123,12 @@ class DefaultEnvironment : Environment {
|
|||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun printCallStack() {
|
override fun printCallStack(scopes: Boolean) {
|
||||||
callStack.pretty()
|
callStack.pretty(scopes)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun stackTrace(): String {
|
override fun stackTrace(): String {
|
||||||
return callStack.stackTrace()
|
return callStack.stackTrace.joinToString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun defineFunction(function: Function) {
|
override fun defineFunction(function: Function) {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package io.smnp.ext
|
package io.smnp.ext
|
||||||
|
|
||||||
import io.smnp.ext.function.CallStackFunction
|
import io.smnp.ext.function.StackTraceFuction
|
||||||
import org.pf4j.Extension
|
import org.pf4j.Extension
|
||||||
|
|
||||||
@Extension
|
@Extension
|
||||||
class DebugModule : NativeModuleProvider("smnp.lang.debug") {
|
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