← 都来码 / Dolaima← 例程索引lua/demo/demo_std.lua原文

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 ===

-- ────────────────────────────────────────────────────────────────