lookup.py: exempt code-anchored ASCII identifiers from the mixed zh/en gate so exact hits are no longer dropped; dedup parent/child sections in results; validate write-prelude anchors in --check. references: correct interpreter-verified facts (case-as-expression, control-flow semicolons, __line__/__stack_frame, tslObjects order, destroy timing, ErrDefine, truncated outputs), fix headings, scope qualifiers and reversed quotes; strip dead preamble metadata from all 24 pages. packaging: exclude __pycache__/*.pyc from playbook and bundle copies; update build test file-count assertion to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.3 KiB
6.3 KiB
TSL 调试与性能分析器
这一篇收拢本页明确的调试、计时、性能分析器和调用栈相关入口。
本篇职责
回答“goto、debugReturn、debugRunEnv、mtic / mtoc、setProfiler、__line__ 和 __stack_frame 怎样写、会怎样表现”。
智能体调试/性能分析器判断流程
- 先判断任务需要跳转、提前返回、运行环境调试、计时还是性能分析器。
- 普通控制流的事实见 07_control_flow.md,本页只处理调试补充工具。
debugReturn会结束整段脚本,不能当成普通函数返回。- 计时和性能分析器只照文档最小调用写,不要补未写入文档参数。
- 没有对应代码块时不要发明调试/性能分析器写法。
核心规则
goto label_name;属于文档明确写法,但目标位置以label label_name; statement这种内联形式作为默认生成形态。- 本页正向边界只覆盖“跳到同一函数 / 同一脚本体后面的位置”,不要先把更复杂的跨层跳转边界写成事实。
debugReturn value;会直接结束整段脚本,后面的语句不会继续执行。debugRunEnv(0)和debugRunEnv(1)可直接调用;它们面向调试客户端的副作用,不作为本页输出事实。debugRunEnvDo Func(...)可直接写,并且会返回被调用函数的结果。mtic会生成一个计时起点;mtoc和mtoc(tick)都会返回秒数。setProfiler(...)和getProfilerInfo(...)的参数规格使用tsl-api-referenceskill 按名查询;本页只保留性能分析器行为示例。setProfiler(7)配合getProfilerInfo(1),可以在不弹窗的情况下拿到性能分析器信息。__line__会返回所在代码行号。__stack_frame会返回调用栈帧数组;最小toStn(...)观察结果里,每一项是(line, "function")这一类二元组。
可直接照写示例
goto
代码块身份:可直接照写示例
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和第一条目标语句放在同一行
跨函数跳转不作为可写事实:
代码块身份:反例 / 不可照写
Inner();
label out_label; writeLn(1);
function Inner();
begin
goto out_label;
end;
结果说明:
- 上面这段会运行报错,核心信息是
Goto label can not found! - 本页正向边界只覆盖“同一函数 / 同一脚本体后面的位置”
- 不要把
goto泛化成能跨函数跳到外层label
目标 label 单独成行不作为可写事实:
代码块身份:反例 / 不可照写
goto done_label;
label done_label;
writeLn("after");
结果说明:
- 上面这种把
label单独放一行、下一行再写目标语句的最小例子,会报Statement missing terminator - 因此本页只把
label name; statement这种内联形式写成文档事实
debugReturn
代码块身份:可直接照写示例
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):
代码块身份:可直接照写示例
a := 1;
debugRunEnv(0);
debugRunEnv(1);
writeLn(1);
结果说明:
- 输出
1 - 说明这两个调用能正常执行,不会中断后续语句
- 但它们把变量 / 系统参数送到调试窗口的效果,不作为本页输出事实
debugRunEnvDo Func(...):
代码块身份:可直接照写示例
result := debugRunEnvDo Demo(2);
writeLn(result);
function Demo(x);
begin
y := x + 1;
return y;
end;
结果说明:
- 输出
3 - 说明
debugRunEnvDo Demo(2)可以直接写 - 也说明它会把被调用函数的结果继续返回给外层
mtic 与 mtoc
代码块身份:可直接照写示例
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
代码块身份:可直接照写示例
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__:
代码块身份:可直接照写示例
line_number := __line__;
writeLn(line_number);
结果说明:
- 输出
1 - 说明
__line__直接返回它所在的代码行号(这里__line__在脚本第 1 行)
__stack_frame:
代码块身份:可直接照写示例
stack := Outer();
writeLn(toStn(stack));
function Inner();
begin
return __stack_frame;
end;
function Outer();
begin
return Inner();
end;
结果说明:
代码块身份:输出片段
array(
(1,"__main__"),
(10,"Outer"))
- 说明
__stack_frame返回的是调用栈帧数组 - 在这个最小例子里,可以直接看到调用位置行号和调用者函数名:
__main__在第 1 行调用Outer(),Outer在第 10 行调用Inner()
禁止项
- 不要把
debugReturn当成普通函数return使用。 - 不要假设
goto可以跨函数、跨脚本体或跳到单独成行的label。 - 不要给计时或性能分析器调用补未写入文档参数。
- 不要把调试客户端副作用写成普通输出事实。