# TSL 调试与性能分析器 这一篇收拢本页明确的调试、计时、性能分析器和调用栈相关入口。 ## 本篇职责 回答“`goto`、`debugReturn`、`debugRunEnv`、`mtic` / `mtoc`、`setProfiler`、`__line__` 和 `__stack_frame` 怎样写、会怎样表现”。 ## 智能体调试/性能分析器判断流程 1. 先判断任务需要跳转、提前返回、运行环境调试、计时还是性能分析器。 2. 普通控制流的事实见 [07_control_flow.md](07_control_flow.md),本页只处理调试补充工具。 3. `debugReturn` 会结束整段脚本,不能当成普通函数返回。 4. 计时和性能分析器只照文档最小调用写,不要补未写入文档参数。 5. 没有对应代码块时不要发明调试/性能分析器写法。 ## 核心规则 本页示例只说明调试与分析结构中的调用位置和源码外形。相关 API 的精确签名、参数、返回行为、平台 scope、目标环境或解释器可用性必须使用 `tsl-api-reference` skill 重新核对,不能由本页示例反推。 - `goto label_name;` 属于文档明确写法,但目标位置以 `label label_name; statement` 这种内联形式作为默认生成形态。 - 本页正向边界只覆盖“跳到同一函数 / 同一脚本体后面的位置”,不要先把更复杂的跨层跳转边界写成事实。 - `debugReturn value;` 会直接结束整段脚本,后面的语句不会继续执行。 - `debugRunEnv(0)` 和 `debugRunEnv(1)` 可直接调用;它们面向调试客户端的副作用,不作为本页输出事实。 - `debugRunEnvDo Func(...)` 可直接写,并且会返回被调用函数的结果。 - `mtic` 会生成一个计时起点;`mtoc` 和 `mtoc(tick)` 都会返回秒数。 - `setProfiler(...)` 和 `getProfilerInfo(...)` 的参数规格使用 `tsl-api-reference` skill 按名查询;本页只保留性能分析器行为示例。 - `setProfiler(7)` 配合 `getProfilerInfo(1)`,可以在不弹窗的情况下拿到性能分析器信息。 - `__line__` 会返回所在代码行号。 - `__stack_frame` 会返回调用栈帧数组;最小 `toStn(...)` 观察结果里,每一项是 `(line, "function")` 这一类二元组。 ## 可直接照写示例 ### `goto` 代码块身份:可直接照写示例 ```tsl data := array((1, 2), (3, 4)); target := 3; found := 0; for i := 0 to length(data) - 1 do begin for j := 0 to length(data[i]) - 1 do begin if data[i][j] = target then goto found_label; end end writeLn(0); goto done_label; label found_label; found := 1; writeLn(found); label done_label; writeLn(9); ``` 结果说明: - 依次输出 `1`、`9` - 说明 `goto found_label;` 可以跳到后面的 `label found_label; ...` - 也说明默认目标写法是把 `label` 和第一条目标语句放在同一行 跨函数跳转不作为可写事实: 代码块身份:反例 / 不可照写 ```text Inner(); label out_label; writeLn(1); function Inner(); begin goto out_label; end; ``` 结果说明: - 上面这段会运行报错,核心信息是 `Goto label can not found!` - 本页正向边界只覆盖“同一函数 / 同一脚本体后面的位置” - 不要把 `goto` 泛化成能跨函数跳到外层 `label` 目标 `label` 单独成行不作为可写事实: 代码块身份:反例 / 不可照写 ```text goto done_label; label done_label; writeLn("after"); ``` 结果说明: - 上面这种把 `label` 单独放一行、下一行再写目标语句的最小例子,会报 `Statement missing terminator` - 因此本页只把 `label name; statement` 这种内联形式写成文档事实 ### `debugReturn` 代码块身份:可直接照写示例 ```tsl writeLn("before"); a := Inner(3); writeLn("after"); function Inner(value); begin debugReturn value; end; ``` 结果说明: - 只输出 `before` - 说明 `debugReturn value;` 不只是结束 `Inner(...)`,而是直接让整段脚本提前返回 - 因此 `Inner(3)` 后面的 `writeLn("after")` 不会执行 ### `debugRunEnv` 与 `debugRunEnvDo` `debugRunEnv(0)` / `debugRunEnv(1)`: 代码块身份:可直接照写示例 ```tsl a := 1; debugRunEnv(0); debugRunEnv(1); writeLn(1); ``` 结果说明: - 输出 `1` - 说明这两个调用能正常执行,不会中断后续语句 - 但它们把变量 / 系统参数送到调试窗口的效果,不作为本页输出事实 `debugRunEnvDo Func(...)`: 代码块身份:可直接照写示例 ```tsl result := debugRunEnvDo Demo(2); writeLn(result); function Demo(x); begin y := x + 1; return y; end; ``` 结果说明: - 输出 `3` - 说明 `debugRunEnvDo Demo(2)` 可以直接写 - 也说明它会把被调用函数的结果继续返回给外层 ### `mtic` 与 `mtoc` 代码块身份:可直接照写示例 ```tsl tick1 := mtic; sum := 0; for i := 0 to 9999 do sum := sum + i; elapsed1 := mtoc(tick1); tick2 := mtic; for j := 0 to 9999 do sum := sum + j; elapsed2 := mtoc; writeLn(elapsed1 >= 0); writeLn(elapsed2 >= 0); ``` 结果说明: - 依次输出 `1`、`1` - 说明 `mtoc(t1)` 和无参 `mtoc` 都能返回可用的秒数结果 ### `setProfiler` 与 `getProfilerInfo` 代码块身份:可直接照写示例 ```tsl setProfiler(7); value := 99; str := intToStr(value); random := rand(10, 1); info := getProfilerInfo(1); writeLn(ifArray(info)); writeLn(length(info) > 0); ``` 结果说明: - 依次输出 `1`、`1` - 说明 `setProfiler(7)` 可以开启性能分析器统计 - 说明 `getProfilerInfo(1)` 会直接返回性能分析器信息,而且结果是非空数组 ### `__line__` 与 `__stack_frame` `__line__`: 代码块身份:可直接照写示例 ```tsl line_number := __line__; writeLn(line_number); ``` 结果说明: - 输出 `1` - 说明 `__line__` 直接返回它所在的代码行号(这里 `__line__` 在脚本第 1 行) `__stack_frame`: 代码块身份:可直接照写示例 ```tsl stack := Outer(); writeLn(toStn(stack)); function Inner(); begin return __stack_frame; end; function Outer(); begin return Inner(); end; ``` 结果说明: 代码块身份:输出片段 ```text array( (1,"__main__"), (10,"Outer")) ``` - 说明 `__stack_frame` 返回的是调用栈帧数组 - 在这个最小例子里,可以直接看到调用位置行号和调用者函数名:`__main__` 在第 1 行调用 `Outer()`,`Outer` 在第 10 行调用 `Inner()` ## 禁止项 - 不要把 `debugReturn` 当成普通函数 `return` 使用。 - 不要假设 `goto` 可以跨函数、跨脚本体或跳到单独成行的 `label`。 - 不要给计时或性能分析器调用补未写入文档参数。 - 不要把调试客户端副作用写成普通输出事实。