From 4f45b391ea56a15fb662b1dc39ec29fb92392940 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 14 Oct 2026 16:51:51 +0800 Subject: [PATCH] =?UTF-8?q?fix(viperc/diag):=20=E4=BF=9D=E7=95=99=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=AE=9A=E4=B9=89=E5=B8=A7=EF=BC=8C=E4=B8=8D=E8=A6=86?= =?UTF-8?q?=E7=9B=96=E6=A0=88=E5=B8=A7=E4=BD=8D=E7=BD=AE=EF=BC=88=E8=A1=A5?= =?UTF-8?q?=E9=BD=90=E2=80=9C=E5=AE=9A=E4=B9=89=E5=B8=A7=20+=20=E5=87=BA?= =?UTF-8?q?=E9=94=99=E8=AF=AD=E5=8F=A5=E5=B8=A7=E2=80=9D=E4=B8=A4=E5=B8=A7?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 上一版 B 把最内层栈帧的位置改写成“当前语句”,结果它与错误帧落在同一 file:line, 被去重合并 —— 输出只剩一帧,`_start` 那帧(函数定义)反而没了。 改为:栈帧只记录**被调函数的定义位置**(不随语句推进覆盖);“当前语句/具体表达式” 统一由错误帧给出(CurArg 兜底,见 TypeGenErr)。这样能得到完整两帧: File "./Apps/HelloWorld/main.vp", line 11 export def _start() -> int: ← 定义帧 File "./Apps/HelloWorld/main.vp", line 36 ... &_on_submit) ← 出错语句帧 同时删除已无调用的 TypeGenBase.update_top_trace_position。 --- App/lib/core/Gen/Stmt/StmtGenMixin.vp | 8 ++++---- App/lib/core/Gen/Type/TypeGenBase.vp | 10 ---------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/App/lib/core/Gen/Stmt/StmtGenMixin.vp b/App/lib/core/Gen/Stmt/StmtGenMixin.vp index 127448d..ae14c5d 100644 --- a/App/lib/core/Gen/Stmt/StmtGenMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenMixin.vp @@ -32,11 +32,11 @@ novirtual class StmtGenMixin(StmtGenDeclMixin.StmtGenDeclMixin): # define). Every instruction then carries ", !dbg !N". if node is not None and trans._cur_builder is not None: DebugInfoGen.SetStatement(trans.Pool, trans._cur_builder, node.lineno, node.col_offset + 1) - # 让最内层栈帧跟踪“当前语句”位置:报错时栈帧给出的是调用点所在语句,而非函数定义行 - #(Python traceback 口径;配合 TypeGenBase.set_cur_arg 可得到“调用点 + 具体表达式”两帧)。 + # 注意:**不要**用当前语句位置覆盖栈帧(那会把“函数定义帧”与错误帧叠成同一位置、 + # 被去重合并,反而丢掉 `_start` 那帧)。栈帧保留“被调函数的定义位置”, + # “当前语句/具体表达式”由错误帧给出(见 TypeGenErr 的 CurArg 兜底)。 + # 仅在语句边界清掉上一条语句遗留的实参位置,避免兜底定位串味。 if node is not None: - self.Gen.TypeGenBase.update_top_trace_position(node.lineno, node.col_offset + 1) - # 语句边界处清掉上一条语句遗留的实参位置,避免兜底定位“串味”到旧实参 self.Gen.TypeGenBase.set_cur_arg(None, 0, 0) if trans.TranslateDepth >= HT.TRANSLATE_MAX_DEPTH: self.Gen.TypeGenErr.fatal_error(node, "statement translation nested too deeply (likely an AST self-reference cycle or a translation bug)", "RecursionError") trans.TranslateDepth += 1 diff --git a/App/lib/core/Gen/Type/TypeGenBase.vp b/App/lib/core/Gen/Type/TypeGenBase.vp index ab06724..c048ddd 100644 --- a/App/lib/core/Gen/Type/TypeGenBase.vp +++ b/App/lib/core/Gen/Type/TypeGenBase.vp @@ -207,16 +207,6 @@ novirtual class TypeGenBase: frame.lineno = 0 frame.col_start = 0 frame.col_end = 0 - # update_top_trace_position - 让最内层栈帧跟踪“当前语句”位置(Python traceback 口径: - # 帧行号随语句推进而更新)。这样报错时栈帧给出的是**调用点所在语句**,而不是函数定义行; - # 配合 set_cur_arg,即可得到“调用点 + 具体表达式”两帧。 - def update_top_trace_position(self, lineno: int, col_start: int) -> None: - """Track the current statement on the innermost trace frame.""" - if self.TraceCount <= 0 or lineno <= 0: return - frame: GenTypes.TraceFrame* = self._get_trace_frame(self.TraceCount - 1) - if frame is None: return - frame.lineno = lineno - frame.col_start = col_start # set_cur_arg - 记录正在翻译的实参位置(file/line/col),供“合成节点无行号”时兜底定位。 def set_cur_arg(self, file_name: str, lineno: int, col_start: int) -> None: """Remember the argument position currently being translated."""