Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

QuickCoffee 是一台以 Rust 编写、受 CoffeeScript 启发的字节码脚本引擎。它保留紧凑、可读的表达式语法,却不兼容 JavaScript:没有原型链、`this`、`eval` 或嵌入 JavaScript。

当前实现遵循 [RFCs/0000-project-scope.md](RFCs/0000-project-scope.md) 至 [RFCs/0112-qbench-workload-selection.md](RFCs/0112-qbench-workload-selection.md)。
当前实现遵循 [RFCs/0000-project-scope.md](RFCs/0000-project-scope.md) 至 [RFCs/0113-numeric-standard-library.md](RFCs/0113-numeric-standard-library.md)。
构建要求 Rust 1.85 或更新版本(Edition 2024);CI 同时验证 MSRV 与 stable 工具链。

```coffee
Expand Down
2 changes: 1 addition & 1 deletion RFCs/0000-project-scope.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ QuickCoffee 是一个 Rust 实现的、受 CoffeeScript 2016 启发的脚本引

本仓库中的测试即 0.1 的语义基线。对语法或运行时的新增特性必须先以 RFC 补充定义,并至少添加:成功测试、错误测试及字节码验证测试。

当前已实现的后续语义与工具 RFC 延伸至 RFC 0112;其中 RFC 0077 定义 JSON 输出、RFC 0079 定义 TAP 输出、RFC 0080 定义 CLI 字节码指纹、RFC 0081 定义可机器读取的基准输出、RFC 0082 规范化指纹编码、RFC 0083 定义 Markdown 文学编程产物、RFC 0084 定义嵌入上下文 fuel 控制、RFC 0085 定义可执行 Rust 嵌入示例、RFC 0086 定义 crate 发布元数据、RFC 0094 定义 qdocco 最终值门禁、RFC 0095 定义字符串步进迭代、RFC 0096 定义其性能基准、RFC 0097 定义 `do` 参数转发、RFC 0098 定义 RFC 索引门禁、RFC 0099 定义 `!` 否定别名、RFC 0100 定义有符号 `by` 步长、RFC 0101 定义 qdocco 原子输出、RFC 0102 定义 qtest 规范文件去重、RFC 0103 定义 qbench schema 版本、RFC 0104 定义 qdocco 块注释代码保留、RFC 0105 定义 qbench 重复采样中位数、RFC 0106 定义 crate 发布包验收门禁、RFC 0107 定义 release qbench 持续门禁、RFC 0108 定义 qtest 可执行示例语料、RFC 0109 定义 qbench 核心负载全套护栏、RFC 0110 定义 Rust MSRV 契约、RFC 0111 定义 release profile 完整测试门禁、RFC 0112 定义 qbench 负载枚举与选择,均不改变脚本语言值模型的原型无关约束。
当前已实现的后续语义与工具 RFC 延伸至 RFC 0113;其中 RFC 0077 定义 JSON 输出、RFC 0079 定义 TAP 输出、RFC 0080 定义 CLI 字节码指纹、RFC 0081 定义可机器读取的基准输出、RFC 0082 规范化指纹编码、RFC 0083 定义 Markdown 文学编程产物、RFC 0084 定义嵌入上下文 fuel 控制、RFC 0085 定义可执行 Rust 嵌入示例、RFC 0086 定义 crate 发布元数据、RFC 0094 定义 qdocco 最终值门禁、RFC 0095 定义字符串步进迭代、RFC 0096 定义其性能基准、RFC 0097 定义 `do` 参数转发、RFC 0098 定义 RFC 索引门禁、RFC 0099 定义 `!` 否定别名、RFC 0100 定义有符号 `by` 步长、RFC 0101 定义 qdocco 原子输出、RFC 0102 定义 qtest 规范文件去重、RFC 0103 定义 qbench schema 版本、RFC 0104 定义 qdocco 块注释代码保留、RFC 0105 定义 qbench 重复采样中位数、RFC 0106 定义 crate 发布包验收门禁、RFC 0107 定义 release qbench 持续门禁、RFC 0108 定义 qtest 可执行示例语料、RFC 0109 定义 qbench 核心负载全套护栏、RFC 0110 定义 Rust MSRV 契约、RFC 0111 定义 release profile 完整测试门禁、RFC 0112 定义 qbench 负载枚举与选择、RFC 0113 定义严格数值标准库函数,均不改变脚本语言值模型的原型无关约束。
2 changes: 1 addition & 1 deletion RFCs/0001-language-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ UTF-8 文本,以换行或分号分隔语句。缩进可形成 `if`、`unless`

RFC 0095 扩展字符串 `for` 也可使用 `by` 步长;RFC 0100 规定其支持非零有限有符号整数并以负步长倒序;RFC 0097 规定 `do (name) -> ...` 从同名外层变量转发立即调用实参。

预置函数是普通名称,不是对象原型方法:`print(value...)`、`len(value)`、`type(value)`、`range(start, end)`、`str(value)`、`keys(map)`、`values(map)`、`join(array, separator)`、`split(string, separator)`、`assert(bool, message?)`。它们的行为由 RFC 0003 的宿主接口定义。不存在 `console`、`Object.prototype`、`Array.prototype`。
预置函数是普通名称,不是对象原型方法:`print(value...)`、`len(value)`、`type(value)`、`range(start, end)`、`str(value)`、`abs(number)`、`sum(array)`、`min(array)`、`max(array)`、`keys(map)`、`values(map)`、`join(array, separator)`、`split(string, separator)`、`assert(bool, message?)`。数值聚合只接受有限数;空数组的 `sum` 为 `0`,`min`/`max` 要求非空。它们的行为由 RFC 0003 与 RFC 0113 的宿主接口定义。不存在 `console`、`Object.prototype`、`Array.prototype`。

### 后续契约修订

Expand Down
20 changes: 20 additions & 0 deletions RFCs/0113-numeric-standard-library.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# RFC 0113:严格数值标准库函数

- 状态:已采纳
- 依赖:RFC 0001、RFC 0043、RFC 0108、RFC 0111

## 动机

QuickCoffee 的标准库是普通函数,而非 JavaScript 原型方法。已有容器与字符串函数足以演示数据流,但数值脚本仍需宿主自行注册最常见的绝对值和聚合操作。内建这些函数可让 qtest 语料、嵌入宿主和性能负载共享同一严格语义。

## 契约

- `abs(number)` 接受恰好一个有限数,返回其绝对值。
- `sum(array)` 接受恰好一个数组;数组元素必须都是有限数,空数组和为 `0`。
- `min(array)` 与 `max(array)` 接受恰好一个非空数组;元素必须都是有限数,分别返回最小值或最大值。
- 参数数量、容器类型、元素类型或有限性不满足时,函数返回结构化运行时错误;不发生隐式转换,也不读取原型或成员方法。
- 返回值仍是普通 `Number`,不改变字节码验证、fuel 或宿主注册函数规则。

## 验收

`tests/scripts/stdlib.qc` 验证成功路径;核心测试验证空数组、错误参数和非有限宿主数值的错误边界;五份文学手册列出函数。`make check` 必须继续通过 debug/release 全量测试及 qdocco 门禁。
2 changes: 1 addition & 1 deletion docs/manual.classical-zh.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<p>Cargo 包志指仓、docs.rs API、README 与许可证,使嵌者易寻其用。</p>
<p>Context::last_execution() 示所试指令与余燃料,而不露 VM 之帧。</p>
<p>-- 后之参,以常字符串数组 argv 见于文中。</p>
<p>其内府皆常函,如 print、len、type、range、str、keys、values、join、split、assert。</p>
<p>其内府皆常函,如 print、len、type、range、str、abs、sum、min、max、keys、values、join、split、assert;数聚函唯受有限数之列。</p>
<p>函式取词法之境;末常参可书 y = 2,参缺或传 nil 则于函中取其值;末有余参,则书 tail...。</p>
<p>常名之参可省其括:left, right -&gt; left + right;常值、余参与解构仍须括之。</p>
<p>return expression 惟函中可用,反其值而终此函;徒 return 得 nil,且清环行 finally。</p>
Expand Down
2 changes: 1 addition & 1 deletion docs/manual.classical-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ QuickCoffee 者,Rust 所为字节码机也,非 JavaScript 之运行时。其

严等与数之比较,相连可书 `1 < middle() < 3`;中项惟求一遍,前较既否,后项不求。

欲试之,曰:`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 -e "print(range(1, 4))"`。`--check FILE` 者,析、编、验其文而不行;`--fuel N` 者,限所行指令之数也;数尽则止而报误。内府有 `print`、`len`、`type`、`range`、`str`、`abs`、`sum`、`min`、`max`、`keys`、`values`、`join`、`split`、`assert`;数聚函唯受有限数之列;`range(a, b)` 取自 a 至 b 前。

`qcoffee -` 自标准输入读其文,便于管道;`qcoffee --dump-bytecode -` 则析其指令而不行之。
`qcoffee --stats` 则书所试指令与余燃料于标准错误,程序之标准输出不改;每次惟一源码输入,执行模式相冲则报用法之误。
Expand Down
2 changes: 1 addition & 1 deletion docs/manual.devanagari-sa.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<p>yes/on true, no/off false; is/isnt strict-साम्यम् स्तः।</p>
<p>! strict-Bool not-पर्यायः अस्ति; != strict-असाम्यमेव तिष्ठति।</p>
<p>chained-comparison मध्ये मध्य-मूल्य एकवारं, पूर्व-false चेत् short-circuit भवति।</p>
<p>सामान्य-library साधारण-function रूपेण print, len, type, range, str, keys, values, join, split, assert ददाति।</p>
<p>सामान्य-library साधारण-function रूपेण print, len, type, range, str, abs, sum, min, max, keys, values, join, split, assert ददाति; संख्या-संग्रहाः केवलं finite-संख्याः गृह्णन्ति।</p>
<p>कार्यं lexical-environment गृह्णाति; y = 2 omitting अथवा nil दत्ते कार्यस्य अन्तरे default भवति; अन्तिमः rest-parameter tail... इति लिख्यते।</p>
<p>bare-name lambda left, right -&gt; left + right भवति; default, rest, pattern तु parentheses गृह्णन्ति।</p>
<p>return expression केवलं वर्तमान-कार्यं समाप्तं करोति; केवलः return nil फलति, loop शुद्धीकरोति, finally च चलयति।</p>
Expand Down
2 changes: 1 addition & 1 deletion docs/manual.devanagari.sa.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ CoffeeScript-नामानि type न परिवर्तयन्ति: `

strict अथवा numeric-comparison श्रृङ्खला भवति: `1 < middle() < 3` मध्ये middle एकवारं मूल्यते, पूर्वं false चेत् परं न मूल्यते।

`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 -e "print(range(1, 4))"` प्रयुञ्जीत। `qcoffee --check FILE` स्रोतं compile-verify करोति, न चालयति; `--fuel N` निर्देश-संख्यां सीमयति। `print`, `len`, `type`, `range`, `str`, `abs`, `sum`, `min`, `max`, `keys`, `values`, `join`, `split`, `assert` मानक-सहायकाः; संख्या-संग्रहाः केवलं finite-संख्याः गृह्णन्ति; `range(a, b)` मध्ये `b` न गृह्यते।

`qcoffee -` मानक-input तः स्रोतः पठति; `qcoffee --dump-bytecode -` तमेव स्रोतं चालनं विना विच्छिनत्ति।
`qcoffee --stats` instruction-संख्या तथा अवशिष्ट-fuel standard error मध्ये लिखति, stdout अपरिवर्तितं स्थापयति; एकमेव source ग्राह्यः, विरोधि execution-mode तु usage-दोषं जनयति।
Expand Down
2 changes: 1 addition & 1 deletion docs/manual.en.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<p>yes/on and no/off are Boolean aliases; is/isnt preserve strict equality.</p>
<p>! is a strict Bool alias for not; != remains strict inequality.</p>
<p>Chained strict or numeric comparisons keep the middle value once and short-circuit.</p>
<p>The standard library is ordinary functions: print, len, type, range, str, keys, values, join, split, and assert.</p>
<p>The standard library is ordinary functions: print, len, type, range, str, abs, sum, min, max, keys, values, join, split, and assert. Numeric aggregators accept strict finite-number arrays.</p>
<p>switch/when selects one strict-equality branch without fallthrough.</p>
<p>try/catch/finally handles QuickCoffee runtime errors without JavaScript Error objects.</p>
<p>Integer ranges use [1..3] for an inclusive end and [1...3] for an exclusive end.</p>
Expand Down
2 changes: 1 addition & 1 deletion docs/manual.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ CoffeeScript-style spellings are available without changing runtime types: `yes`

Adjacent strict or numeric comparisons may chain: `1 < middle() < 3` evaluates `middle()` once and stops before later operands when an earlier comparison is false.

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`.
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`, `abs`, `sum`, `min`, `max`, `keys`, `values`, `join`, `split`, and `assert`; numeric aggregators accept strict finite-number arrays.

`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; qcoffee accepts one source input and rejects conflicting execution modes.
Expand Down
2 changes: 1 addition & 1 deletion docs/manual.latin.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<p>yes/on sunt true, no/off false; is/isnt aequalitatem strictam servant.</p>
<p>! est negatio Bool stricta sicut not; != inaequalitas stricta manet.</p>
<p>Comparationes conectae medium semel servant atque priore falso breviant.</p>
<p>Bibliotheca communis functiones ordinarias habet: print, len, type, range, str, keys, values, join, split, assert.</p>
<p>Bibliotheca communis functiones ordinarias habet: print, len, type, range, str, abs, sum, min, max, keys, values, join, split, assert; aggregationes numericae solum series numerorum finitorum accipiunt.</p>
<p>Functiones ambitum lexicalem capiunt; y = 2 omissus vel nil intra functionem adhibetur; rest ultimus scribitur tail....</p>
<p>Nomina nuda parentheses omittere possunt: sinister, dexter -&gt; sinister + dexter; default, rest, pattern eas servant.</p>
<p>return expressio functionem praesentem finit; nudum return nil dat, iterata purgat, et finally circumstantia peragit.</p>
Expand Down
2 changes: 1 addition & 1 deletion docs/manual.latin.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Voces CoffeeScript sine mutatione generum valent: `yes`/`on` sunt `true`, `no`/`

Comparationes strictae vel numericae conecti possunt: `1 < middle() < 3` medium semel aestimat et, priore falso, posteriora non aestimat.

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.
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`, `abs`, `sum`, `min`, `max`, `keys`, `values`, `join`, `split`, et `assert`; aggregationes numericae solum series numerorum finitorum accipiunt; 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; unus tantum fons admittitur et modi contrarii errorem usus reddunt.
Expand Down
2 changes: 1 addition & 1 deletion docs/manual.zh-CN.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<p>yes/on 与 no/off 是布尔别名;is/isnt 保持严格相等。</p>
<p>! 是严格 Bool 的 not 别名;!= 仍为严格不等。</p>
<p>严格或数值比较可成链,保留中间值且前段失败会短路。</p>
<p>标准库皆为普通函数:print、len、type、range、str、keys、values、join、split 与 assert。</p>
<p>标准库皆为普通函数:print、len、type、range、str、abs、sum、min、max、keys、values、join、split 与 assert;数值聚合只收严格有限数数组。</p>
<p>映射字面量可从左至右展开:{...defaults, theme: 'dark'};后写键覆盖先写键。</p>
<p>映射解构末尾可用 ...metadata 捕获未列键,所得映射不可变。</p>
<p>数组与 Unicode 字符串支持负索引,-1 取末项。</p>
Expand Down
2 changes: 1 addition & 1 deletion docs/manual.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ qcoffee --dump-bytecode program.qc

`--` 之后的参数以普通字符串数组 `argv` 提供:`qcoffee program.qc -- first second` 中 `len(argv)` 为 `2`。引擎不会暴露宿主进程或环境对象。

`--fuel` 是每次执行的指令上限,耗尽会安全失败。标准库包括 `print`、`len`、`type`、`range`、`str`、`keys`、`values`、`join`、`split` 与 `assert`;`range(a, b)` 生成 `[a, b)`。
`--fuel` 是每次执行的指令上限,耗尽会安全失败。标准库包括 `print`、`len`、`type`、`range`、`str`、`abs`、`sum`、`min`、`max`、`keys`、`values`、`join`、`split` 与 `assert`;数值聚合只接受严格有限数数组,`range(a, b)` 生成 `[a, b)`。

## 语法示例

Expand Down
2 changes: 2 additions & 0 deletions docs/syntax.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Destructuring array and map members may use dynamic defaults (`[first = 1, secon

This is the English index of RFC 0001. An omitted CoffeeScript 2016 feature is deliberately unsupported, not silently compatible.

The standard library is ordinary functions: `print`, `len`, `type`, `range`, `str`, `abs`, `sum`, `min`, `max`, `keys`, `values`, `join`, `split`, and `assert`. Numeric aggregators accept one array of finite numbers; `sum([])` is `0`, while `min([])` and `max([])` are errors.

Ordinary single- and double-quoted strings decode `\\0`, `\\b`, `\\f`, `\\n`, `\\r`, `\\t`, `\\v`, quote/backslash escapes, two-digit `\\xNN`, four-digit `\\uNNNN`, and one-to-six-digit `\\u{...}` Unicode escapes. They may span physical lines; a normal newline becomes one space and indentation inside the string is ignored. A single unescaped backslash at the line end removes both the backslash and the newline. Double-quoted multiline strings retain `#{expression}` interpolation, while single-quoted strings remain literal. Triple-quoted heredocs preserve newlines: `"""…"""` interpolates and `'''…'''` is literal; an unclosed delimiter or invalid escape is a lexical error.

`for` uses strict recursive patterns for its bindings: `for [left, right] in pairs then left + right` and `for own _, value of record then value` are supported. A pattern mismatch is a runtime error and never partially updates that iteration's bindings.
Expand Down
2 changes: 2 additions & 0 deletions docs/syntax.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

这是 RFC 0001 的中文索引;未列出的 CoffeeScript 2016 特性不是“隐式兼容”,而是明确不支持。Cargo 包元数据提供仓库、README、许可证和 docs.rs API 链接。

标准库是普通函数:`print`、`len`、`type`、`range`、`str`、`abs`、`sum`、`min`、`max`、`keys`、`values`、`join`、`split` 与 `assert`。数值聚合只收一个有限数数组;`sum([])` 为 `0`,`min([])` 与 `max([])` 报错。

| 类别 | 支持 | 不支持(本版) |
|---|---|---|
| 字面量 | 十进制、十六进制 `0xff`、二进制 `0b1010`、八进制 `0o755` 与科学计数法数字、字符串、双引号 `#{expr}` 插值、保留换行的 `"""…"""` 插值 heredoc 与 `'''…'''` 字面 heredoc、`true`/`yes`/`on`、`false`/`no`/`off`、`nil`、数组与 `[head, items...]` 展开、整数区间 `[1..3]`(含上界)/`[1...3]`(不含上界)、映射、`{name}` 简写与映射展开 `{...base, key: value}` | 正则、JS 插值、`undefined` |
Expand Down
Loading