_selftest/test_error.py · 4522 字节 · 下载原文
# test_error.py —— VML 诊断自测用例(**故意含错,不参与编译通过性检查**)
# test_error.py -- VML diagnostic self-test case (**deliberately contains errors, not part of the compile-cleanliness check**)
#
# 用途:验证编译器的错误/警告输出、诊断列表、以及编辑器能否显示气泡。
# Purpose: verify the compiler's error/warning output, the diagnostic list, and whether the editor can show a squiggle.
# 预期:1 个错误、**0 个警告**(详见下)。
# Expected: 1 error, **0 warnings** (see below).
# 约束:确定性 —— 无随机数、不读文件、不交互、无死循环;错误来自源码本身。
# Constraints: deterministic -- no randomness, no file reads, no interaction, no infinite loops; the error comes from the source itself.
#
# ⚠ ~~python 前端**不检查未声明的变量**(查不到局部/全局表就静默发一个 0)~~ ✅ **已修好(2026-10-04 复验)**:
# ⚠ ~~The python frontend **does not check undeclared variables** (when the local/global table has no entry it silently emits a 0)~~ ✅ **fixed (re-checked 2026-10-04)**:
# 实测 `print(undefined_thing)` 现在报 `error: 未声明的变量 'undefined_thing' [CodeGen_UndefinedVariable]`(带 文件:行:列 + 诊断码);
# measured `print(undefined_thing)` now reports `error: undeclared variable 'undefined_thing' [CodeGen_UndefinedVariable]` (with file:line:col + diag-code);
# 赋值右值 / 表达式里的读也都报(`x = undefined_a`、`y = undefined_b + 1` 各报一条)。
# reads in assignment RHS / expressions report too (`x = undefined_a` and `y = undefined_b + 1` each report one).
# 本文件仍由**调用未声明的函数**触发(那样只产 1 条错误):编译期不报,
# This file is still triggered by **calling an undeclared function** (that keeps it to a single error): not reported at compile time,
# 链接器报 `未定义的函数 'undefined_func'(引用 1 次)`,位置是 `文件:行`(**无列**)。
# the linker reports `undefined function 'undefined_func' (referenced 1 time)`, positioned at `file:line` (**no column**).
# ⚠ `unused_var` 是刻意留的「未使用变量」探针;python 前端不报未使用变量
# ⚠ `unused_var` is a deliberately kept "unused variable" probe; the python frontend does not report unused variables
# (WarnUnused 只有 CCompiler 在调),故本文件只产 1 条错误。MCU 那两条
# (WarnUnused is called only by CCompiler), so this file produces only 1 error. The two MCU
# 「yield/await 被忽略」警告走 WarningEmitter、被 WarningLevel 门控(默认 0)
# "yield/await ignored" warnings go through WarningEmitter, gated by WarningLevel (default 0)
# ⇒ vmlcli 与手机端都不开启,实测全静默。
# => neither vmlcli nor the mobile client enables it, and measurement shows they are entirely silent.
# ↳ 2026-10-04 复验:门控与「await 被静默忽略」仍成立(`await 1` 实测编译通过、无输出);
# ↳ Re-checked 2026-10-04: the gating and "await silently ignored" still hold (`await 1` compiles with no output);
# 但 **`yield` 不再是"静默"** —— 最小复现 `def g():` / ` yield 1` 实测**编译期内部错误**
# but **`yield` is no longer "silent"** -- the minimal repro `def g():` / ` yield 1` measures a **compile-time internal error**
# `Object reference not set to an instance of an object`(前端缺陷,与本用例无关)。
# `Object reference not set to an instance of an object` (a frontend defect, unrelated to this case).
# ⚠ 注释**一律独占一行**,不写行尾注释:`#` 是 python 注释符,而 VML 这一层跑的是
# ⚠ Comments **always occupy a line of their own**; no trailing comments are used: `#` is python's comment marker, while this layer of VML runs the
# C 风格预处理器 —— 行尾的 `#` 会让它丢掉行号映射,诊断变成 `<input>:6`
# C-style preprocessor -- a trailing `#` makes it lose the line mapping, and the diagnostic becomes `<input>:6`
# (文件名丢失 + 行号退化成预处理后的行号,指到别处)。把注释挪到上一行即恢复。
# (the filename is lost + the line number degrades to the post-preprocessing line number and points elsewhere). Moving the comment to the previous line restores it.
unused_var = 5
total = 0
x = total + 1
total = x
print(total)
undefined_func(1)