kotlin/demo/demo_std.kt · 10033 字节 · 下载原文
// demo_std.kt —— **第 1 层:标准输入输出**(Kotlin 的 `print` / `println`)
// demo_std.kt — **Layer 1: standard input/output** (Kotlin's `print` / `println`)
//
// 这一层是每门语言自己的"往标准输出写文本"。
// This layer is each language's own way of "writing text to stdout".
//
// ## `+` 字符串拼接**已修好**(2026-10-04 复验)
// ## `+` string concatenation is **fixed** (re-verified 2026-10-04)
//
// ~~写之前先量过:Kotlin 前端的 `+` 字符串拼接不可用~~ —— 2026-09-24 那一版实测会打出一串数字,
// ~~Measured before writing: the Kotlin frontend's `+` could not concatenate strings~~ -- the 2026-09-24 build printed a run of digits,
// 根因是模板/拼接那段按 `$` 现拆、每一段发一条 `print_int`(2026-09-30 已修,见 `FRONTEND_DEFECTS.md` 的 Kotlin 一节)。
// because the template/concat path split on `$` and emitted one `print_int` per segment (fixed 2026-09-30; see the Kotlin section of `FRONTEND_DEFECTS.md`).
//
// 实测(2026-10-04,`vmlcli Examples/kotlin/demo_std.kt` 的最小探针):
// Measured (2026-10-04, minimal probes against `vmlcli`):
// print("num=" + n + " str=" + s + "\n") ⇒ num=7 str=hello (之前是那串数字)
// print("num=" + n + " str=" + s + "\n") => num=7 str=hello (was that run of digits)
// println("n=$n") ⇒ n=7
// println("t=${a + b}") ⇒ t=3
// println("a" + "b") ⇒ ab
//
// 本 demo 仍按 `print(标签)` + `print(值)` 分开写 —— 那一直是好的,**能跑就别动;新写的代码不必再绕**。
// This demo still writes `print(label)` + `print(value)` separately — that was always fine; **leave working code alone; new code need not work around it**.
//
// ## 转义序列:`\uXXXX` 仍不认,`\n` / `\t` 都可以
// ## Escape sequences: `\uXXXX` is still unsupported; `\n` / `\t` both work
//
// `print("\u001b[31m")` 仍会原样打出 `u001b[31m`(2026-10-04 复验);而 ~~`\t` 同样不可靠~~ ——
// `print("\u001b[31m")` still prints `u001b[31m` literally (re-verified 2026-10-04); but ~~`\t` is just as unreliable~~ --
// 实测 `print("A\tB")` 打出的就是真正的 0x09 制表符(2026-10-04)。
// measured: `print("A\tB")` emits a real 0x09 tab (2026-10-04).
// 要发 ESC 仍只能 `putchar(27)`(见 `demo_tty.kt`)。本 demo 只用 `\n`。
// Emitting ESC still needs `putchar(27)` (see `demo_tty.kt`). This demo uses only `\n`.
//
// ## 判据
// ## Criteria
//
// vmlcli Examples/kotlin/demo_std.kt
//
// 期望 stdout 逐字节等于文件末尾那段「期望输出」。
// Expects stdout to equal the "expected output" block at the end of the file, byte for byte.
// Kotlin 调库函数**不用声明**(对不认识的函数名发裸标签 CALL、实参右到左)——
// Kotlin library calls **need no declaration** (unknown function names become bare-label CALLs with arguments right-to-left) —
// 与 Java(必须 `static native`)/ Dart(必须 `external`)都不一样。
// Unlike Java (which requires `static native`) / Dart (which requires `external`).
// `println_str` / `println_int` 这些由 `Lib/shared/io.vml` 提供,
// `println_str` / `println_int` and the like are provided by `Lib/shared/io.vml`,
// 经 `builtins.vml`(`vmltool.config.xml` 的 `DefaultLibs`)进每一门语言的链接。
// They enter every language's link through `builtins.vml` (`DefaultLibs` in `vmltool.config.xml`).
// ── 显式引用:下面用到的 `ui_*` 来自共享库 vmlui.vml ──────────────────
// ── Explicit reference: the `ui_*` used below come from the shared library vmlui.vml ──
// ⚠ `.*` 必须有:`import vmlui`(无 `.*`)会被 `ExtractImports` 的正则**静默忽略**。
// ⚠ The `.*` is required: `import vmlui` (without `.*`) is silently ignored by `ExtractImports`.
// ⚠ 但整行删掉也照样编、照样跑 —— 前端靠 `ui_` 前缀**自动**链 `vmlui.vml`。
// ⚠ But deleting the whole line still compiles and runs — the frontend auto-links `vmlui.vml` from the `ui_` prefix.
// ⇒ 所以这条是**文档级**的显式声明,不是强制开关(判据见 `FRONTEND_DEFECTS.md` 的 Kotlin 一节)。
// ⇒ So this is a **documentation-level** explicit reference, not a hard switch (see the Kotlin section of `FRONTEND_DEFECTS.md`).
// ✅ 2026-10-04 复验仍成立:三种写法(`import vmlui` / `import vmlui.*` / 整行删掉)产出的指令数完全相同(59377 条)。
// ✅ Re-verified 2026-10-04, still holds: all three forms (`import vmlui` / `import vmlui.*` / line deleted) produce the identical instruction count (59377).
#include "../../../Lib/kotlin/vml_ui.kt"
import vmlui.*
fun main() {
var a = 17
var b = 25
var i = 0
var sum = 0
// 界面语言:开局查一次(`ui_scr_get_language` 是 syscall,别每处都调)
// UI language: queried once at start (`ui_scr_get_language` is a syscall, do not call it everywhere)
var lang = ui_scr_get_language()
// ⚠ 语言分支写成**单行 `if/else`** —— **C 风格三目 `cond ? a : b` 仍然不能用**
// ⚠ Language branches are written as a **one-line `if/else`** -- the **C-style ternary `cond ? a : b` still cannot be used**
// (2026-10-04 复验:**实参位置**静默错编 —— 两个字符串都不进数据段、传下去的是条件 0/1,其余实参整体错位一格;
// (re-verified 2026-10-04: in **argument position** it silently miscompiles -- neither string reaches the data section, the condition 0/1 is passed and the remaining args shift by one;
// `print(...)` / 赋值位置则直接报 `Expected ')'`)。~~`?:` 也不支持~~ —— Kotlin 的 Elvis `?:` **已经能用**
// in `print(...)` / assignment position it errors `Expected ')'`). ~~`?:` is unsupported too~~ -- Kotlin's Elvis `?:` **works now**
// (实测 `ui_2d_text(0,0,u ?: "FALLBACK",…)` 正确渲染、`println(null ?: 7)` 得 7)。
// (measured: `ui_2d_text(0,0,u ?: "FALLBACK",…)` renders correctly, `println(null ?: 7)` gives 7).
// ── 1. 字符串 ──
// ── 1. Strings ──
print("=== demo_std (Kotlin) ===\n")
if (lang == 0) { print("纯字面量一行\n") } else { print("a plain literal, one line\n") }
// ── 2. 标签 + 值 分开写(本来就好的写法;`+` 拼接 2026-10-04 复验也已修,见文件头)──
// ── 2. Label + value written separately (always fine; `+` concatenation is fixed too, re-verified 2026-10-04 — see the header) ──
print("a="); println(a)
print("b="); println(b)
print("a+b="); println(a + b)
print("a-b="); println(a - b)
print("a*b="); println(a * b)
print("a/b="); println(a / b)
print("a%b="); println(a % b)
if (lang == 0) { print("负数:") } else { print("Negative: ") }; println(0 - a)
// ── 3. 进制与宽度(这里只演示值;格式化宽度在 Kotlin 侧没有等价物)──
// ── 3. Number bases and widths (only values are demonstrated here; Kotlin has no equivalent of formatted width) ──
if (lang == 0) { print("十进制=") } else { print("Decimal=") }; println(255)
if (lang == 0) { print("十六进制=") } else { print("Hex=") }; println(255)
// ── 4. 局部函数 + 递归 ──
// ── 4. Local functions + recursion ──
print("square(9)="); println(square(9))
print("fib(10)="); println(fib(10))
// ── 5. 数组 + 循环 ──
// ── 5. Arrays + loops ──
// ~~数组必须留在 main 里(`catch.kt` 记的实测:文件级 `arrayOf` 读回 0)~~ —— 2026-10-04 复验**已修**:
// ~~Arrays must stay inside main (the `catch.kt` measurement: a file-level `arrayOf` reads back 0)~~ -- **fixed**, re-verified 2026-10-04:
// 文件级 `var A = arrayOf(0,1,2,3,4)` 的 `A[0]+A[3]` 得 **10**。本 demo 的状态与逻辑仍在 main 内(能跑就别动)。
// a file-level `var A = arrayOf(0,1,2,3,4)` gives `A[0]+A[3]` = **10**. This demo's state and logic still live inside main (leave working code alone).
var v = arrayOf(1, 4, 9, 16, 25, 36)
while (i < 6) {
sum = sum + v[i]
i = i + 1
}
print("1^2+...+6^2 = "); println(sum)
// ── 6. 九九表的一小段 ──
// ── 6. A small slice of the multiplication table ──
i = 1
while (i <= 5) {
print(i)
print(" x 7 = ")
println(i * 7)
i = i + 1
}
if (lang == 0) { print("=== 完成 ===\n") } else { print("=== done ===\n") }
}
// 纯函数可以抽出去(不碰任何数组/全局状态)
// Pure functions can be pulled out (they touch no arrays/global state)
fun square(v: Int): Int {
return v * v
}
fun fib(n: Int): Int {
if (n < 2) {
return n
}
return fib(n - 1) + fib(n - 2)
}
// ── 期望输出(逐字节)────────────────────────────────────────────
// === demo_std (Kotlin) ===
// 纯字面量一行
// A plain literal, one line
// a=17
// b=25
// a+b=42
// a-b=-8
// a*b=425
// a/b=0
// a%b=17
// 负数:-17
// Negative: -17
// 十进制=255
// Decimal=255
// 十六进制=255
// square(9)=81
// fib(10)=55
// 1^2+...+6^2 = 91
// 1 x 7 = 7
// 2 x 7 = 14
// 3 x 7 = 21
// 4 x 7 = 28
// 5 x 7 = 35
// === 完成 ===
// === done ===
// ────────────────────────────────────────────────────────────────