java/demo/demo_std.java · 10827 字节 · 下载原文
// demo_std.java —— **第 1 层:标准输入输出**(Java 的 `System.out`)
// demo_std.java — **Layer 1: standard input/output** (Java's `System.out`)
//
// 这一层是每门语言自己的"往标准输出写文本"。
// 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)
//
// ~~写之前先量过:Java 前端的 `+` 字符串拼接不可用~~ —— 2026-09-24 那一版实测
// ~~Measured before writing: the Java frontend's `+` could not concatenate strings~~ -- the 2026-09-24 build, measured,
// `System.out.println("num=" + n + " str=" + s)` 打成 `1063` / `str=hello`。根因是 `+` 的类型推断不认识
// printed `1063` / `str=hello` for `System.out.println("num=" + n + " str=" + s)`. The root cause was `+`'s type inference not knowing
// `String`(链长 ≥ 3 段才露馅),2026-09-30 已修(`FRONTEND_DEFECTS.md` 的 Java 一节)。
// `String` (it only showed on a chain of >= 3 parts); fixed 2026-09-30 (Java section of `FRONTEND_DEFECTS.md`).
//
// 实测(2026-10-04):`"n=" + n` 得 `n=7`、`"score " + a + " pts"` 得 `score 3 pts`、`"n=" + n + " s=" + s` 也得。
// Measured (2026-10-04): `"n=" + n` gives `n=7`, `"score " + a + " pts"` gives `score 3 pts`, and `"n=" + n + " s=" + s` too.
// 本 demo 仍按 `print(标签)` + `println(值)` 两段写 —— 那一直是好的,**能跑就别动;新写的代码不必再绕**。
// This demo still writes `print(label)` + `println(value)` as two parts — that was always fine; **leave working code alone; new code need not work around it**.
//
// ## ⚠ 字符串字面量里的 `\u001b` 也不认
// ## ⚠ `\u001b` inside a string literal is not recognized either
//
// `"\u001b[31m"` 会**原样打出** `\u001b[31m`(六个字符),不是 ESC。
// `"\u001b[31m"` is **printed literally** as `\u001b[31m` (six characters), not ESC.
// ✅ 2026-10-04 复验仍成立(`"\u001b[31mX\n"` 打成 `\u001b[31mX` + 一个反斜杠 + 换行)。
// ✅ Re-verified 2026-10-04, still holds (`"\u001b[31mX\n"` prints `\u001b[31mX` + a backslash + a newline).
// 要发 ESC 只能 `putchar(27)`(见 `demo_tty.java`)。
// The only way to emit ESC is `putchar(27)` (see `demo_tty.java`).
//
// ## 判据
// ## Criteria
//
// vmlcli Examples/java/demo_std.java
//
// 期望 stdout 逐字节等于文件末尾那段「期望输出」。
// Expects stdout to equal the "expected output" block at the end of the file, byte for byte.
#include "../../../Lib/java/vml_ui.java"
public class DemoStd {
// ⚠ Java 调库函数**必须声明成 `static native`** —— `asm()` 已从 Java 前端移除
// ⚠ Java library calls **must be declared `static native`** — `asm()` has been removed from the Java frontend
// (`CodeGenerator.Expressions.cs` 注明「仅限 C/ObjC/C++」)。不声明就发
// (`CodeGenerator.Expressions.cs` notes "C/ObjC/C++ only"). Without a declaration it emits
// `CALL method_xxx`,链接期找不到标签。
// `CALL method_xxx`, whose label cannot be found at link time.
//
// 这三个标签由 `Lib/shared/io.vml` 提供,而 `io.vml` 经 `builtins.vml`
// These three labels are provided by `Lib/shared/io.vml`, and `io.vml` enters every language's link
// (`vmltool.config.xml` 的 `DefaultLibs`)进每一门语言的链接。
// through `builtins.vml` (`DefaultLibs` in `vmltool.config.xml`).
static native void println_str(String s);
static native void print_str(String s);
static native void println_int(int n);
static native int ui_scr_get_language();
// 自由函数:证明语言本身是通的(算术、控制流、数组、递归)
// Free functions: proving the language itself works (arithmetic, control flow, arrays, recursion)
static int square(int v) {
return v * v;
}
static int fib(int n) {
if (n < 2) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
static String digitName(int d) {
if (d == 0) { return "zero"; }
if (d == 1) { return "one"; }
if (d == 2) { return "two"; }
return "many";
}
public static void main(String[] args) {
// 界面语言:开局查一次(`ui_scr_get_language` 是 syscall)—— 文案按它取
// UI language: queried once at startup (`ui_scr_get_language` is a syscall) — the strings are picked by it
int lang = ui_scr_get_language();
// ⚠ 文案必须先取进 `String` 局部变量再打印 —— `System.out.print/println` 是**前端特判**的
// ⚠ Text must go into a `String` local first —— `System.out.print/println` is a **frontend-special-cased**
// 一条路,直接喂三元会把字符串当成整数打出来(实测打印出数字地址,如 1024、1)。
// path: feeding it a ternary prints the string as an integer (measured output is a numeric address such as 1024 or 1).
// ⚠ 而且**必须写在声明处的初始化器里**(`String m = 三元;`)—— 先声明、再赋值
// ⚠ It must also sit in the **declaration's initializer** (`String m = ternary;`) —— declaring first and assigning
// 会丢掉类型,打印时照样退化成整数(两种写法都实测过)。
// later loses the type and degrades to an integer at print time just the same (both shapes were measured).
// ✅ 2026-10-04 复验仍成立:`println(lang == 0 ? "CH" : "EN")` 打成 `1032`;`String m = …; println(m)` 打成 `CH2`。
// ✅ Re-verified 2026-10-04, still holds: `println(lang == 0 ? "CH" : "EN")` prints `1032`; `String m = …; println(m)` prints `CH2`.
int a = 17;
int b = 25;
int i;
int sum = 0;
// ── 1. 字符串 ──
// ── 1. Strings ──
System.out.println("=== demo_std (Java) ===");
String msg1 = lang == 0 ? "纯字面量一行" : "A plain literal, one line";
System.out.println(msg1);
// ⚠ 这一行**刻意不写任何转义**:Java 前端的转义序列会**把反斜杠一起留下**
// ⚠ This line **deliberately avoids every escape**: the Java frontend's escapes **keep the backslash**,
// 实测(2026-10-04):`"X\nY"` 打出的字节是 `X` + **反斜杠** + 换行 + `Y`(C 侧同串是 `X` + 换行 + `Y`);
// measured (2026-10-04): `"X\nY"` emits `X` + **a backslash** + newline + `Y` (the same string in C is `X` + newline + `Y`);
// `"A\tB"` 打出「反斜杠 + 制表符」,`"C\\D"` 打出两个反斜杠,`"\u001b"` 原样打出。
// `"A\tB"` emits "a backslash + a tab", `"C\\D"` emits two backslashes, `"\u001b"` is printed as-is.
// 都是探针实测出来的,不是推测。
// All measured with a probe, not guessed.
String msg2 = lang == 0 ? "转义:只有换行符是好的(见本行上面的注释)" : "Escapes: only the newline is sound (see the comment above this line)";
System.out.println(msg2);
// ── 2. 标签 + 值 分开写(本来就好的写法;`+` 拼接 2026-10-04 复验也已修,见文件头)──
// ── 2. Label + value written separately (always fine; `+` concatenation is fixed too, re-verified 2026-10-04 — see the header) ──
System.out.print("a="); System.out.println(a);
System.out.print("b="); System.out.println(b);
System.out.print("a+b="); System.out.println(a + b);
System.out.print("a-b="); System.out.println(a - b);
System.out.print("a*b="); System.out.println(a * b);
System.out.print("a/b="); System.out.println(a / b);
System.out.print("a%b="); System.out.println(a % b);
String msg3 = lang == 0 ? "负数:" : "Negative: ";
System.out.print(msg3); System.out.println(0 - a);
// ── 3. 进制与宽度 ──
// ── 3. Number bases and widths ──
String msg4 = lang == 0 ? "十进制=" : "Decimal=";
System.out.print(msg4); System.out.println(255);
String msg5 = lang == 0 ? "十六进制=" : "Hex=";
System.out.print(msg5); System.out.println(255);
// ── 4. 函数调用(含递归)──
// ── 4. Function calls (including recursion) ──
System.out.print("square(9)="); System.out.println(square(9));
System.out.print("fib(10)="); System.out.println(fib(10));
System.out.print("digitName: ");
System.out.print(digitName(0)); System.out.print(" ");
System.out.print(digitName(1)); System.out.print(" ");
System.out.print(digitName(2)); System.out.print(" ");
System.out.println(digitName(9));
// ── 5. 数组 + 循环 ──
// ── 5. Arrays + loops ──
int[] v = new int[6];
v[0] = 1; v[1] = 4; v[2] = 9; v[3] = 16; v[4] = 25; v[5] = 36;
for (i = 0; i < 6; i = i + 1) {
sum = sum + v[i];
}
System.out.print("1^2+...+6^2 = "); System.out.println(sum);
// ── 6. 九九表的一小段 ──
// ── 6. A small slice of the multiplication table ──
for (i = 1; i <= 5; i = i + 1) {
System.out.print(i);
System.out.print(" x 7 = ");
System.out.println(i * 7);
}
String msg6 = lang == 0 ? "=== 完成 ===" : "=== done ===";
System.out.println(msg6);
}
}
// ── 期望输出(逐字节)────────────────────────────────────────────
// === demo_std (Java) ===
// 纯字面量一行
// A plain literal, one line
// 转义:只有换行符是好的(见本行上面的注释)
// Escapes: only the newline is sound (see the comment above this 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
// digitName: zero one two many
// 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 ===
// ────────────────────────────────────────────────────────────────