diff --git a/RFCs/0027-cli-check-mode.md b/RFCs/0027-cli-check-mode.md index f7feeb0..07f0a3f 100644 --- a/RFCs/0027-cli-check-mode.md +++ b/RFCs/0027-cli-check-mode.md @@ -4,7 +4,7 @@ ## 决议 -`qcoffee --check FILE`(FILE 可为 `-`)读取源码,执行词法、解析、编译与 `Chunk::verify`,但绝不创建执行 Context 或运行字节码。成功时无标准输出并以零退出;读取、语法、编译或验证错误以非零退出。它不能与 `--dump-bytecode` 组合。 +`qcoffee --check FILE`(FILE 可为 `-`)读取源码,执行词法、解析、编译与 `Chunk::verify`,但绝不创建执行 Context 或运行字节码。成功时无标准输出并以零退出;读取、语法、编译或验证错误以非零退出。它不能与 `--dump-bytecode` 组合,也不能与 `-e`、脚本路径或第二个源码模式重复指定输入。 该模式面向 CI、编辑器与文学文档流程:例如无限循环是有效程序,`qcoffee --fuel 1 --check program.qc` 必须成功,因为 fuel 仅限制执行。 diff --git a/RFCs/0079-qtest-tap-output.md b/RFCs/0079-qtest-tap-output.md index b7b8244..b2b8700 100644 --- a/RFCs/0079-qtest-tap-output.md +++ b/RFCs/0079-qtest-tap-output.md @@ -11,6 +11,8 @@ `qtest --tap FILE_OR_DIRECTORY...` 输出 TAP version 13。所有输入递归发现的文件合并后按路径全局排序并去重,然后每个文件恰输出一条编号记录:成功为 `ok N - path`,失败为 `not ok N - path`。失败详情紧随其后按 `# ` 注释行输出;详情中的换行分割为多条注释,避免伪造新的测试记录。末尾输出 `1..N`,其中 `N` 是去重后发现的测试文件数。 +递归目录时允许文件系统符号链接,但规范化后的目录路径只访问一次;自引用或环状链接被跳过,不得造成无限递归或栈耗尽。 + `--tap` 与 `--json` 互斥,冲突以用法错误退出码 2 结束。读取错误或找不到测试文件时,在已输出 TAP 版本后输出 `Bail out!` 并以非零状态退出。测试失败仍返回非零状态;`--stats` 继续只写标准错误,不污染 TAP 标准输出。 ## 验收 diff --git a/RFCs/0080-cli-bytecode-fingerprint.md b/RFCs/0080-cli-bytecode-fingerprint.md index d75bc86..127068c 100644 --- a/RFCs/0080-cli-bytecode-fingerprint.md +++ b/RFCs/0080-cli-bytecode-fingerprint.md @@ -11,7 +11,7 @@ `qcoffee --fingerprint FILE` 读取、编译并验证文件(`FILE` 可为 `-`),然后在标准输出输出一个不带前缀的 16 位小写十六进制 `u64` 和换行。它不执行脚本,不创建脚本全局状态,也不输出 fuel 统计。 -`--fingerprint` 与 `--check`、`--dump-bytecode`、`--interactive`、`--stats` 互斥;冲突或缺少文件参数为用法错误,退出码为 2。读取、解析或验证错误沿用普通 CLI 的非零退出与结构化错误文本。相同源码必须产生相同指纹,不同有效字节码内容应产生不同指纹(碰撞概率遵循 64 位指纹的通常边界)。 +`--fingerprint` 与 `--check`、`--dump-bytecode`、`--interactive`、`--stats` 互斥,且只能指定一个源码输入;冲突或缺少文件参数为用法错误,退出码为 2。读取、解析或验证错误沿用普通 CLI 的非零退出与结构化错误文本。相同源码必须产生相同指纹,不同有效字节码内容应产生不同指纹(碰撞概率遵循 64 位指纹的通常边界)。 ## 验收 diff --git a/docs/manual.classical-zh.html b/docs/manual.classical-zh.html index cd92eb1..aea453b 100644 --- a/docs/manual.classical-zh.html +++ b/docs/manual.classical-zh.html @@ -10,7 +10,7 @@
! 同 not,严反 Bool;!= 仍严不等。
严等与数较可相连,中项惟求一遍,前否则后不求。
qcoffee - 者,自标准输入读其文也。
-qcoffee --stats 则书所试指令与余燃料于标准错误,程序之标准输出不改。
+qcoffee --stats 则书所试指令与余燃料于标准错误,程序之标准输出不改;每次惟一源码输入,执行模式相冲则报用法之误。
qcoffee --check FILE 者,析编验其文而不行也。
qcoffee --interactive(或 -i)者,逐行共用一 Context;:help 示命,:quit 出之。
qcoffee --interactive --stats 惟非空行之行而行或运行时有误者,书指令与余燃料一条;析验之误不更书。
diff --git a/docs/manual.classical-zh.md b/docs/manual.classical-zh.md index 3c2ab20..cce4f91 100644 --- a/docs/manual.classical-zh.md +++ b/docs/manual.classical-zh.md @@ -17,7 +17,7 @@ QuickCoffee 者,Rust 所为字节码机也,非 JavaScript 之运行时。其 欲试之,曰:`qcoffee -e "print(range(1, 4))"`。`--check FILE` 者,析、编、验其文而不行;`--fuel N` 者,限所行指令之数也;数尽则止而报误。内府有 `print`、`len`、`type`、`range`、`str`、`keys`、`values`、`join`、`split`、`assert`;`range(a, b)` 取自 a 至 b 前。 `qcoffee -` 自标准输入读其文,便于管道;`qcoffee --dump-bytecode -` 则析其指令而不行之。 -`qcoffee --stats` 则书所试指令与余燃料于标准错误,程序之标准输出不改;不可与 `--check`、`--dump-bytecode` 并用。 +`qcoffee --stats` 则书所试指令与余燃料于标准错误,程序之标准输出不改;每次惟一源码输入,执行模式相冲则报用法之误。 `qcoffee --interactive`(或 `-i`)逐行共用一 Context;`:help` 示其命,`:quit`/`:exit` 出之。管道输入不见提示。 交互而加 `--stats`,每一非空行亦书所试指令与余燃料于标准错误。`for character, index in 'a☕中' then index` 得 `[0, 1, 2]`;字符串循 Unicode 标量,不受 `by`。`[head, tail...] = [1, 2, 3]`,tail 得 `[2, 3]`;数组之 rest 必居末。 diff --git a/docs/manual.devanagari-sa.html b/docs/manual.devanagari-sa.html index 858f80c..55f82a1 100644 --- a/docs/manual.devanagari-sa.html +++ b/docs/manual.devanagari-sa.html @@ -5,7 +5,7 @@ऋण-सूचकाङ्केन क्रमस्य अन्तिमं पदं लभ्यते।
स्रोतः पठ्यते, सत्यापित-bytecode मध्ये संकल्यते, fuel-सीमया चालयते।
qcoffee - मानक-input तः QuickCoffee-program पठति।
-qcoffee --stats instruction-संख्या तथा अवशिष्ट-fuel standard error मध्ये लिखति, stdout अपरिवर्तितं स्थापयति।
+qcoffee --stats instruction-संख्या तथा अवशिष्ट-fuel standard error मध्ये लिखति, stdout अपरिवर्तितं स्थापयति; एकमेव source ग्राह्यः, विरोधि execution-mode तु usage-दोषं जनयति।
qcoffee --check FILE स्रोतं verify करोति, न चालयति।
qcoffee --interactive (वा -i) एकं Context पङ्क्ति-क्रमेण धारयति; :help दर्शयति, :quit निर्गच्छति।
qcoffee --interactive --stats केवलं कार्यितायै वा runtime-दोषयुक्तायै non-empty पङ्क्त्यै instruction तथा fuel लेखं लिखति; parse अथवा verify-दोषे नूतनं लेखं न लिखति।
diff --git a/docs/manual.devanagari.sa.md b/docs/manual.devanagari.sa.md index 6ec0982..2dc2466 100644 --- a/docs/manual.devanagari.sa.md +++ b/docs/manual.devanagari.sa.md @@ -17,7 +17,7 @@ strict अथवा numeric-comparison श्रृङ्खला भवति: `qcoffee -e "print(range(1, 4))"` प्रयुञ्जीत। `qcoffee --check FILE` स्रोतं compile-verify करोति, न चालयति; `--fuel N` निर्देश-संख्यां सीमयति। `print`, `len`, `type`, `range`, `str`, `keys`, `values`, `join`, `split`, `assert` मानक-सहायकाः; `range(a, b)` मध्ये `b` न गृह्यते। `qcoffee -` मानक-input तः स्रोतः पठति; `qcoffee --dump-bytecode -` तमेव स्रोतं चालनं विना विच्छिनत्ति। -`qcoffee --stats` instruction-संख्या तथा अवशिष्ट-fuel standard error मध्ये लिखति, stdout अपरिवर्तितं स्थापयति; `--check` अथवा `--dump-bytecode` सह न योज्यम्। +`qcoffee --stats` instruction-संख्या तथा अवशिष्ट-fuel standard error मध्ये लिखति, stdout अपरिवर्तितं स्थापयति; एकमेव source ग्राह्यः, विरोधि execution-mode तु usage-दोषं जनयति। `qcoffee --interactive` (वा `-i`) पङ्क्तिषु एकं Context धारयति; `:help` आदेशान् दर्शयति, `:quit`/`:exit` सत्रं समापयतः। pipe-input मध्ये prompt न भवति। `for character, index in 'a☕中' then index` `[0, 1, 2]` ददाति; string Unicode-scalar-क्रमेण चलति, `by` न स्वीकरोति। diff --git a/docs/manual.en.html b/docs/manual.en.html index 9e38307..e4393f4 100644 --- a/docs/manual.en.html +++ b/docs/manual.en.html @@ -2,7 +2,7 @@Source is parsed, compiled to verified bytecode, and executed with a fuel budget.
qcoffee - reads a QuickCoffee program from standard input.
-qcoffee --stats writes instruction and remaining-fuel counters to stderr while preserving program stdout.
+qcoffee --stats writes instruction and remaining-fuel counters to stderr while preserving program stdout; qcoffee accepts one source input and rejects conflicting execution modes.
qcoffee --check FILE parses, compiles, and verifies without executing FILE.
qcoffee --interactive (or -i) keeps one Context for a line-oriented session; :help and :quit are built-in commands.
qcoffee --interactive --stats writes one instruction/fuel record for each non-empty line that executes or reaches a runtime error; parse and verify errors write none.
diff --git a/docs/manual.en.md b/docs/manual.en.md index df5287c..965f217 100644 --- a/docs/manual.en.md +++ b/docs/manual.en.md @@ -17,7 +17,7 @@ Adjacent strict or numeric comparisons may chain: `1 < middle() < 3` evaluates ` Run `qcoffee -e "print(range(1, 4))"`, `qcoffee --fuel 10000 program.qc`, `qcoffee --check program.qc`, or `qcoffee --dump-bytecode program.qc`. `--check` parses, compiles, and verifies without executing. Fuel limits executed instructions; exhaustion is a safe error. The small standard library contains `print`, `len`, `type`, end-exclusive `range(a, b)`, `str`, `keys`, `values`, `join`, `split`, and `assert`. `qcoffee -` reads source from standard input, which is convenient in pipelines; `qcoffee --dump-bytecode -` disassembles that same input instead of executing it. -`qcoffee --stats` writes instruction and remaining-fuel counters to stderr while preserving program stdout; it cannot be combined with `--check` or `--dump-bytecode`. +`qcoffee --stats` writes instruction and remaining-fuel counters to stderr while preserving program stdout; qcoffee accepts one source input and rejects conflicting execution modes. `qcoffee --interactive` (or `-i`) keeps one Context across input lines; `:help` lists commands and `:quit`/`:exit` leave the session. Piped input receives no prompts. With `--stats`, each non-empty interactive line that executes or reaches a runtime error writes its instruction and remaining-fuel counters to stderr; parse and verify errors write no fresh record. diff --git a/docs/manual.latin.html b/docs/manual.latin.html index 9f64d48..b6d43db 100644 --- a/docs/manual.latin.html +++ b/docs/manual.latin.html @@ -5,7 +5,7 @@Indices negativi in seriebus et textu Unicode extremum elementum petunt.
Fons legitur, in bytecodicem verificatum compilatur, et cum limite fuel currit.
qcoffee - programma QuickCoffee ex initio normali legit.
-qcoffee --stats numeros instructionum et alimenti reliqui ad errorem ordinarium scribit, dum exitus programmatis intactus manet.
+qcoffee --stats numeros instructionum et alimenti reliqui ad errorem ordinarium scribit, dum exitus programmatis intactus manet; unus tantum fons admittitur et modi contrarii errorem usus reddunt.
qcoffee --check FILE fontem verificat sine cursu.
qcoffee --interactive (vel -i) unum Context per lineas servat; :help docet, :quit exit.
qcoffee --interactive --stats unam instructionum et alimenti reliqui notam lineae non vacuae exsecutæ vel errorem currendi ferenti scribit; errores analysi vel verificationis nihil scribunt.
diff --git a/docs/manual.latin.md b/docs/manual.latin.md index d07bc4c..8493d84 100644 --- a/docs/manual.latin.md +++ b/docs/manual.latin.md @@ -17,7 +17,7 @@ Comparationes strictae vel numericae conecti possunt: `1 < middle() < 3` medium Utere `qcoffee -e "print(range(1, 4))"`; `qcoffee --check FILE` fontem compilat atque verificat sine cursu; `--fuel N` numerum instructionum finit. Bibliotheca parva habet `print`, `len`, `type`, `range(a, b)`, `str`, `keys`, `values`, `join`, `split`, et `assert`; finis in `range` exclusus est. `qcoffee -` fontem ex initio normali legit; `qcoffee --dump-bytecode -` illum fontem sine cursu explicat. -`qcoffee --stats` numeros instructionum et alimenti reliqui ad errorem ordinarium scribit, dum exitus programmatis intactus manet; cum `--check` aut `--dump-bytecode` coniungi non potest. +`qcoffee --stats` numeros instructionum et alimenti reliqui ad errorem ordinarium scribit, dum exitus programmatis intactus manet; unus tantum fons admittitur et modi contrarii errorem usus reddunt. `qcoffee --interactive` (vel `-i`) unum Context inter lineas servat; `:help` imperia ostendit, `:quit`/`:exit` sessionem finiunt. Input per fistulam promptum non accipit. `for character, index in 'a☕中' then index` indices `[0, 1, 2]` reddit; stringae per scalas Unicode iterantur et `by` non admittunt. diff --git a/docs/manual.zh-CN.html b/docs/manual.zh-CN.html index 80b798c..ef8698f 100644 --- a/docs/manual.zh-CN.html +++ b/docs/manual.zh-CN.html @@ -2,7 +2,7 @@QuickCoffee 先将源码解析并编译为经验证的字节码,随后由带 fuel 限制的 VM 执行。
qcoffee - 可从标准输入读取 QuickCoffee 程序。
-qcoffee --stats 将指令数与剩余燃料写入标准错误,同时保持程序标准输出不变。
+qcoffee --stats 将指令数与剩余燃料写入标准错误,同时保持程序标准输出不变;qcoffee 每次只接受一个源码输入,冲突执行模式会报用法错误。
qcoffee --check FILE 只解析、编译并验证 FILE,不执行它。
qcoffee --interactive(或 -i)逐行复用同一 Context;:help 显示命令,:quit 退出。
qcoffee --interactive --stats 仅为实际执行或运行时失败的非空输入行输出指令/燃料统计;解析、验证错误不输出新记录。
diff --git a/docs/manual.zh-CN.md b/docs/manual.zh-CN.md index 4d95143..2fd3e8e 100644 --- a/docs/manual.zh-CN.md +++ b/docs/manual.zh-CN.md @@ -22,7 +22,7 @@ qcoffee --dump-bytecode program.qc ``` `qcoffee -` 从标准输入读取源码,便于接入管道;`qcoffee --check FILE`(FILE 可为 `-`)只解析、编译和验证而不执行;`qcoffee --dump-bytecode -` 则反汇编标准输入而不执行。 -`qcoffee --stats` 将指令数与剩余 fuel 写入标准错误,同时保持程序标准输出不变;不可与 `--check` 或 `--dump-bytecode` 合用。 +`qcoffee --stats` 将指令数与剩余 fuel 写入标准错误,同时保持程序标准输出不变;qcoffee 每次只接受一个源码输入,冲突执行模式会报用法错误。 `qcoffee --interactive`(或 `-i`)在输入行之间保持同一 Context;`:help` 列出命令,`:quit`/`:exit` 退出会话。管道输入不输出提示符。 交互模式加 `--stats` 时,仅实际执行或运行时失败的非空输入行把指令数与剩余 fuel 写入标准错误;解析、验证错误不生成新记录。 diff --git a/manuals/manual.classical-zh.qc b/manuals/manual.classical-zh.qc index 0434150..0c2be39 100644 --- a/manuals/manual.classical-zh.qc +++ b/manuals/manual.classical-zh.qc @@ -10,7 +10,7 @@ ## ! 同 not,严反 Bool;!= 仍严不等。 ## 严等与数较可相连,中项惟求一遍,前否则后不求。 ## qcoffee - 者,自标准输入读其文也。 -## qcoffee --stats 则书所试指令与余燃料于标准错误,程序之标准输出不改。 +## qcoffee --stats 则书所试指令与余燃料于标准错误,程序之标准输出不改;每次惟一源码输入,执行模式相冲则报用法之误。 ## qcoffee --check FILE 者,析编验其文而不行也。 ## qcoffee --interactive(或 -i)者,逐行共用一 Context;:help 示命,:quit 出之。 ## qcoffee --interactive --stats 惟非空行之行而行或运行时有误者,书指令与余燃料一条;析验之误不更书。 diff --git a/manuals/manual.devanagari-sa.qc b/manuals/manual.devanagari-sa.qc index 86f9f44..3f3de48 100644 --- a/manuals/manual.devanagari-sa.qc +++ b/manuals/manual.devanagari-sa.qc @@ -5,7 +5,7 @@ ## ऋण-सूचकाङ्केन क्रमस्य अन्तिमं पदं लभ्यते। ## स्रोतः पठ्यते, सत्यापित-bytecode मध्ये संकल्यते, fuel-सीमया चालयते। ## qcoffee - मानक-input तः QuickCoffee-program पठति। -## qcoffee --stats instruction-संख्या तथा अवशिष्ट-fuel standard error मध्ये लिखति, stdout अपरिवर्तितं स्थापयति। +## qcoffee --stats instruction-संख्या तथा अवशिष्ट-fuel standard error मध्ये लिखति, stdout अपरिवर्तितं स्थापयति; एकमेव source ग्राह्यः, विरोधि execution-mode तु usage-दोषं जनयति। ## qcoffee --check FILE स्रोतं verify करोति, न चालयति। ## qcoffee --interactive (वा -i) एकं Context पङ्क्ति-क्रमेण धारयति; :help दर्शयति, :quit निर्गच्छति। ## qcoffee --interactive --stats केवलं कार्यितायै वा runtime-दोषयुक्तायै non-empty पङ्क्त्यै instruction तथा fuel लेखं लिखति; parse अथवा verify-दोषे नूतनं लेखं न लिखति। diff --git a/manuals/manual.en.qc b/manuals/manual.en.qc index 8644a70..96b55ea 100644 --- a/manuals/manual.en.qc +++ b/manuals/manual.en.qc @@ -2,7 +2,7 @@ ## ## Source is parsed, compiled to verified bytecode, and executed with a fuel budget. ## qcoffee - reads a QuickCoffee program from standard input. -## qcoffee --stats writes instruction and remaining-fuel counters to stderr while preserving program stdout. +## qcoffee --stats writes instruction and remaining-fuel counters to stderr while preserving program stdout; qcoffee accepts one source input and rejects conflicting execution modes. ## qcoffee --check FILE parses, compiles, and verifies without executing FILE. ## qcoffee --interactive (or -i) keeps one Context for a line-oriented session; :help and :quit are built-in commands. ## qcoffee --interactive --stats writes one instruction/fuel record for each non-empty line that executes or reaches a runtime error; parse and verify errors write none. diff --git a/manuals/manual.latin.qc b/manuals/manual.latin.qc index 6595508..e0dbdd0 100644 --- a/manuals/manual.latin.qc +++ b/manuals/manual.latin.qc @@ -5,7 +5,7 @@ ## Indices negativi in seriebus et textu Unicode extremum elementum petunt. ## Fons legitur, in bytecodicem verificatum compilatur, et cum limite fuel currit. ## qcoffee - programma QuickCoffee ex initio normali legit. -## qcoffee --stats numeros instructionum et alimenti reliqui ad errorem ordinarium scribit, dum exitus programmatis intactus manet. +## qcoffee --stats numeros instructionum et alimenti reliqui ad errorem ordinarium scribit, dum exitus programmatis intactus manet; unus tantum fons admittitur et modi contrarii errorem usus reddunt. ## qcoffee --check FILE fontem verificat sine cursu. ## qcoffee --interactive (vel -i) unum Context per lineas servat; :help docet, :quit exit. ## qcoffee --interactive --stats unam instructionum et alimenti reliqui notam lineae non vacuae exsecutæ vel errorem currendi ferenti scribit; errores analysi vel verificationis nihil scribunt. diff --git a/manuals/manual.zh-CN.qc b/manuals/manual.zh-CN.qc index ec09888..1f944d1 100644 --- a/manuals/manual.zh-CN.qc +++ b/manuals/manual.zh-CN.qc @@ -2,7 +2,7 @@ ## ## QuickCoffee 先将源码解析并编译为经验证的字节码,随后由带 fuel 限制的 VM 执行。 ## qcoffee - 可从标准输入读取 QuickCoffee 程序。 -## qcoffee --stats 将指令数与剩余燃料写入标准错误,同时保持程序标准输出不变。 +## qcoffee --stats 将指令数与剩余燃料写入标准错误,同时保持程序标准输出不变;qcoffee 每次只接受一个源码输入,冲突执行模式会报用法错误。 ## qcoffee --check FILE 只解析、编译并验证 FILE,不执行它。 ## qcoffee --interactive(或 -i)逐行复用同一 Context;:help 显示命令,:quit 退出。 ## qcoffee --interactive --stats 仅为实际执行或运行时失败的非空输入行输出指令/燃料统计;解析、验证错误不输出新记录。 diff --git a/src/bin/qtest.rs b/src/bin/qtest.rs index af60be0..3e24036 100644 --- a/src/bin/qtest.rs +++ b/src/bin/qtest.rs @@ -2,17 +2,28 @@ use quickcoffee::{Context, Value}; use std::{ + collections::HashSet, env, fs, path::{Path, PathBuf}, process::ExitCode, }; -fn collect(path: &Path, files: &mut Vec