lua/demo/demo_std.lua · 7632 字节 · 下载原文
-- demo_std.lua —— **第 1 层:标准输入输出**(Lua 的 print)
-- demo_std.lua — **Layer 1: standard input/output** (Lua's print)
--
-- 这一层就是语言自己的标准输出:往 stdout 写文本。
-- This layer is the language's own standard output: writing text to stdout.
-- 也是最基础的一层,也是**唯一有逐字节确定性判据**的一层 —— 下面的输出
-- It is also the most basic layer, and the **only one with a byte-exact deterministic criterion** — the output below
-- 跑两遍完全一样(不读输入、不用随机数、不看时间)。
-- is exactly the same when run twice (no input read, no random numbers, no clock).
--
-- ## 判据
-- ## Criterion
--
-- vmlcli Examples/lua/demo_std.lua
--
-- 期望 stdout 逐字节等于本文件末尾「期望输出」那段。
-- stdout is expected to be byte-for-byte identical to the "expected output" block at the end of this file.
--
-- ## ⚠ 本前端实测的三条限制(写 demo 时避开)
-- ## ⚠ Three limits of this frontend measured in practice (avoid them when writing demos)
--
-- · ~~**`..` 字符串拼接编不过** —— 链到 `lua_concat`,而库里没有这个标签~~
-- · ~~**`..` string concatenation does not compile** — it links to `lua_concat`, and the library has no such label~~
-- ✅ **已修好(2026-10-04 复验)**:`..` 现在编得过、拼出来的串也对
-- ✅ **Fixed (re-verified 2026-10-04)**: `..` now compiles and yields the right string
-- (实测 `local s = "AB" .. "CD"` 再 `print_str(s)` ⇒ `ABCD`;`a .. b` ⇒ `helloworld`)。
-- (measured: `local s = "AB" .. "CD"` then `print_str(s)` => `ABCD`; `a .. b` => `helloworld`.)
-- ⚠ 但要**用 `print_str` 打**它 —— `print` 拿到非字面量的字符串打的不是那个串
-- ⚠ But print it with `print_str` — `print` given a non-literal string does not print that string
-- (实测 `print("AB" .. "CD")` ⇒ `46825`)。本 demo 仍用 `print` 的多实参相连(写法无害)。
-- (measured: `print("AB" .. "CD")` => `46825`). This demo still uses `print`'s multi-argument joining (harmless).
-- · `print` **不插分隔符**:`print("line", i)` 打出 `line0`,不是 `line 0`。
-- · `print` **inserts no separator**: `print("line", i)` prints `line0`, not `line 0`.
-- (与 Python/Ruby 那些「多实参用空格连」的语言不同,写期望值时要注意。)
-- (Unlike Python/Ruby, where multiple arguments are joined by a space — be careful when writing expected output.)
-- · `putchar(n)` 打出来的不是那个字节 —— 实测**单条连着调**时是对的
-- · `putchar(n)` does not print that byte — measured: **a straight run of calls** is correct
-- (`putchar(65) putchar(66) putchar(27)` → `A B ESC`,逐字节核过),
-- (`putchar(65) putchar(66) putchar(27)` → `A B ESC`, verified byte by byte),
-- 但**中间夹一次别的库调用**它就读错实参了(`putchar(65)` `print_str("\n")` `putchar(27)`
-- but **wedging another library call in between** makes it read the wrong argument (`putchar(65)` `print_str("\n")` `putchar(27)`
-- → 第三个字节是 `A7 AD` 而不是 `1B`)。这跟 `Lib/` 那两套栈清理约定同源
-- → the third byte is `A7 AD` instead of `1B`). This has the same root cause as the two stack-cleanup conventions in `Lib/`
-- (见 CLAUDE.md ⑨ 与本仓 `int_to_str` 的同类现象)⇒ 彩色控制台那一层走
-- (see CLAUDE.md ⑨ and the same class of symptom in this repo's `int_to_str`) ⇒ the color-console layer goes with
-- **字符串字面量里的 `\x1b`**(Lua 支持),见 demo_tty.lua。
-- **`\x1b` inside string literals** (Lua supports it), see demo_tty.lua.
--
-- ~~另一条写法要求(沿用 `Examples/lua/life.lua`):**循环变量先 `local` 声明**
-- ~~One more writing requirement (following `Examples/lua/life.lua`): **declare the loop variable with `local` first**
-- 再进循环,否则循环体一次都不执行(v0.96.202 修的就是这条)。~~
-- before entering the loop, otherwise the loop body never runs even once (this is exactly what v0.96.202 fixed).~~
-- ✅ **已修好(2026-10-04 复验)**:不预先 `local` 也能跑(实测 `for i = 1, 5` 求和 ⇒ 15)。
-- ✅ **Fixed (re-verified 2026-10-04)**: it runs without a prior `local` (measured: `for i = 1, 5` summing => 15).
-- ── 显式引用 UI 库的声明文件 ────────────────────────────────────────────────
-- Explicit reference to the UI library's declaration file.
--
-- `Lib/lua/vml_ui.lua` 由 `GenLib -n -c vmlui -l lua` 从 `Lib/shared/src/vmlui.c` 生成(155 个 `ui_*`)。
-- `Lib/lua/vml_ui.lua` is produced by `GenLib -n -c vmlui -l lua` from `Lib/shared/src/vmlui.c` (155 `ui_*`).
-- **不要手写、也不要手改生成物**(要改就改生成器 `tools/GenLib`)。
-- Never hand-write it and never edit the generated file (change the generator `tools/GenLib` instead).
--
-- ⚠ 这条 `require` 对 Lua 是**文档级**引用:本前端按名字解析库函数,删掉它照样编得过、跑得对。
-- ⚠ For Lua this `require` is a **documentation-level** reference: the front end resolves library
-- functions by name, so removing it still compiles and runs.
-- 实测结论与命令见 `docs/UI库导入约定.md` 的「lua 实测结论」一节。
-- Measured results and the exact commands are in the UI-library import convention doc (Lua section).
require("vml_ui")
local lang = ui_scr_get_language()
print("=== demo_std (Lua) ===")
if lang == 0 then print("纯字符串一行")
else print("A pure string on one line") end
if lang == 0 then print("转义:制表\t反斜杠\\引号\"")
else print("escapes: tab\tbackslash\\quote\"") end
local a = 17
local b = 25
print("a=", a, " b=", b)
print("a+b=", a + b, " a-b=", a - b, " a*b=", a * b)
print("a/b=", a / b, " a%b=", a % b)
if lang == 0 then print("负数: ", 0 - a, " ", 0 - (a * b))
else print("negatives: ", 0 - a, " ", 0 - (a * b)) end
-- 循环算一个结果,证明这一层和语言本身是通的
-- A loop computes a result, proving this layer and the language itself are wired up
local i = 0
local total = 0
i = 1
while i <= 10 do
total = total + i * i
i = i + 1
end
print("1^2+...+10^2 = ", total)
-- 九九表的一小段(多行)
-- A short slice of the multiplication table (multiple lines)
i = 1
while i <= 5 do
print(i, " x 7 = ", i * 7)
i = i + 1
end
if lang == 0 then print("=== 完成 ===")
else print("=== done ===") end
-- ── 期望输出(逐字节)────────────────────────────────────────────
-- === demo_std (Lua) ===
-- 纯字符串一行
-- A pure string on one line
-- 转义:制表 反斜杠\引号"
-- escapes: tab backslash\quote"
-- a=17 b=25
-- a+b=42 a-b=-8 a*b=425
-- a/b=0 a%b=17
-- 负数: -17 -425
-- negatives: -17 -425
-- 1^2+...+10^2 = 385
-- 1 x 7 = 7
-- 2 x 7 = 14
-- 3 x 7 = 21
-- 4 x 7 = 28
-- 5 x 7 = 35
-- === 完成 ===
-- === done ===
-- ────────────────────────────────────────────────────────────────