You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: restructure CLI around subcommands (run/test/disasm/build), hard-break the old mode flags
--test, --disasm, --emit-gbc <path>, and --emit-gbc-module <path> were
flags dressed up as different modes (run vs. run-test-blocks vs.
compile-only-and-disassemble vs. compile-only-and-write-an-artifact)
rather than ordinary settings. gengo bundle already exists as a real
subcommand for exactly this reason; extended that same argv[1]-dispatch
pattern to run/test/disasm/build, routed through the existing flag-parsing
loop so every modifier flag (--heap, --cap, --mount, --modules, --max-ops,
--backend, --no-fusion, --net-listen-allow, --net-dial-allow,
--verify-source) keeps working identically under every subcommand with no
duplicated parsing logic.
gengo <script.gengo> (no subcommand) is unchanged -- still the default,
implicit run. gengo run/test/disasm/build <script> are the new explicit
forms; build takes -o/--output <path> (required) and --lib for the
linkable-module variant.
Hard break, not a soft deprecation: the old flags are gone entirely.
Hitting one now fails with a specific migration message instead of being
silently misparsed as a script path -- the existing arg loop had no
"unknown flag" branch at all, so simply deleting the flag blocks would
have made `gengo --test script.gengo` try to open a file literally named
--test.
Updated every doc referencing the removed flags (docs/cli.md,
docs/language.md, docs/changelog.md, docs/known-limitations.md) in the
same pass. No CI workflow, git hook, or tooling script used any of the
four removed flags to begin with, confirmed via a full grep sweep before
starting.
Verified under standard, -Dpreset=stress, and -Dgc_stress=true builds.
Copy file name to clipboardExpand all lines: docs/changelog.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -30,8 +30,8 @@
30
30
31
31
### Tooling (unreleased)
32
32
33
-
-**`gengo --test --profile`** — reports each `test` block's instruction count and peak heap bytes/stack depth/live object count, plus a final peak-across-all-blocks summary line, so integrators can size `engine_init_with_config`'s resource ceilings from measured workload data instead of guessing. Does not affect pass/fail behavior or the exit code; does cost real speed (forces per-instruction accounting on for the run), so it's a diagnostic flag, not something to leave on by default.
34
-
- **`gengo --emit-gbc path` / running a `.gbc` directly** — an early GBC (Gengo Bytecode Cache) implementation: `--emit-gbc` compiles a script and writes a `.gbc` artifact instead of running it; a `.gbc` file passed as the script argument (recognized by magic bytes) loads and runs directly, skipping parsing and compilation. Covers plain and generic functions (real parameter/return types, so interface conformance checks keep working on a loaded function; a generic function's type parameters erase to `any` on the wire, matching their own runtime semantics — constraint checking is unaffected, since it runs at each call site's own compile time against the caller's concrete type arguments, not by inspecting a loaded callee's stored types), `std`/native calls, and struct, named-type, `variant`, `interface`, `enum`, and task/actor declarations (including range/cycle/clamp-constrained named types, a named type's `default` value and `scale`, a module/type-scope `predicate`, variants with shared fields and record/single-payload/no-payload arms, enums with explicit representation values, auto-incremented ordinals, and enum subtypes, spawning/sending/receiving through a task type loaded from a `.gbc` (running one now correctly drives the same task scheduler a normally-compiled program uses, not a one-shot run with no scheduler at all), and a predicate declared inside a function body that closes over the function's own locals, re-capturing fresh on every call exactly as it does compiled normally (this last one turned out to already work once checked directly — a closure with real captures is always built by ordinary `make_closure` bytecode at the point it's declared, never handed to the writer as a literal constant object, so there was nothing to reject in the first place). See `dev-docs/design/gbc-spec.md` and GitHub issue #5 for the full format and remaining scope; the CLI does not yet check a `.gbc`'s recorded source hash against the current source before running it, so regenerate one by hand when its source changes.
33
+
-**`gengo test --profile`** — reports each `test` block's instruction count and peak heap bytes/stack depth/live object count, plus a final peak-across-all-blocks summary line, so integrators can size `engine_init_with_config`'s resource ceilings from measured workload data instead of guessing. Does not affect pass/fail behavior or the exit code; does cost real speed (forces per-instruction accounting on for the run), so it's a diagnostic flag, not something to leave on by default.
34
+
- **`gengo build script.gengo -o path` / running a `.gbc` directly** — an early GBC (Gengo Bytecode Cache) implementation: `build` compiles a script and writes a `.gbc` artifact instead of running it; a `.gbc` file passed as the script argument (recognized by magic bytes) loads and runs directly, skipping parsing and compilation. Covers plain and generic functions (real parameter/return types, so interface conformance checks keep working on a loaded function; a generic function's type parameters erase to `any` on the wire, matching their own runtime semantics — constraint checking is unaffected, since it runs at each call site's own compile time against the caller's concrete type arguments, not by inspecting a loaded callee's stored types), `std`/native calls, and struct, named-type, `variant`, `interface`, `enum`, and task/actor declarations (including range/cycle/clamp-constrained named types, a named type's `default` value and `scale`, a module/type-scope `predicate`, variants with shared fields and record/single-payload/no-payload arms, enums with explicit representation values, auto-incremented ordinals, and enum subtypes, spawning/sending/receiving through a task type loaded from a `.gbc` (running one now correctly drives the same task scheduler a normally-compiled program uses, not a one-shot run with no scheduler at all), and a predicate declared inside a function body that closes over the function's own locals, re-capturing fresh on every call exactly as it does compiled normally (this last one turned out to already work once checked directly — a closure with real captures is always built by ordinary `make_closure` bytecode at the point it's declared, never handed to the writer as a literal constant object, so there was nothing to reject in the first place). See `dev-docs/design/gbc-spec.md` and GitHub issue #5 for the full format and remaining scope; pass `--verify-source path` when running a `.gbc` to check it against the current source (`SourceGraphStale` on drift) — omitted by default, so a `.gbc` remains runnable standalone without its source present.
Run a source file — no subcommand needed, `run` is implicit:
14
14
15
15
```bash
16
16
gengo hello.gengo
17
17
```
18
18
19
+
`gengo run hello.gengo` does exactly the same thing; the subcommand is there
20
+
for scripts/docs that want to be explicit, or to sit alongside `test`/
21
+
`disasm`/`build` as a sibling. The other subcommands switch what "compile
22
+
this script" actually does instead of running it normally:
23
+
24
+
| Command | Meaning |
25
+
|---|---|
26
+
|`run <script>`| Compile and run (the default — also what a bare `gengo <script>` does). |
27
+
|`test <script>`| Run top-level `test` blocks rather than ordinary script execution. A failed test exits unsuccessfully. |
28
+
|`disasm <script>`| Compile and print a bytecode disassembly without running the script. This is an implementation-debugging aid, not language semantics. |
29
+
|`build <script> -o path`| Compile the script and write a GBC (Gengo Bytecode Cache) artifact to `path`; do not run. Add `--lib` to write a linkable GBC module artifact instead. See below. |
30
+
|`bundle`| Package a script and its imports into a zip archive. See `gengo bundle --help`. |
31
+
19
32
Use `-e` or `--eval` for a short program. It cannot be combined with a script
20
33
path:
21
34
@@ -29,14 +42,18 @@ script from standard input instead.
29
42
30
43
## Options
31
44
45
+
Modifier flags below work identically with or without a subcommand — they
46
+
apply the same way to `gengo script.gengo`, `gengo test script.gengo`,
47
+
`gengo build script.gengo -o out.gbc`, and so on.
48
+
32
49
| Option | Meaning |
33
50
|---|---|
34
51
|`--help`, `-h`| Print the option summary and exit. |
35
52
|`--version`| Print the CLI version and exit. |
36
-
|`--disasm`|Compile and print a bytecode disassembly without running the script. This is an implementation-debugging aid, not language semantics. |
37
-
|`--emit-gbc path`|Compile the script and write a GBC (Gengo Bytecode Cache) artifact to `path`; do not run. See below. |
38
-
|`--test`|Run top-level `test` blocks rather than ordinary script execution. A failed test exits unsuccessfully. |
39
-
|`--profile`|With `--test`, print each block's instruction count and peak heap bytes/stack depth/live object count, plus a final peak-across-all-blocks summary line. Does not affect pass/fail behavior or the exit code. Forces per-instruction instruction counting on for the run, which costs real speed — a diagnostic aid, not something to leave on by default. |
53
+
|`-o`, `--output path`|`build`-only: the artifact path to write. Required with `build`. |
54
+
|`--lib`|`build`-only: write a linkable GBC module artifact instead of a normal one. |
55
+
|`--verify-source path`|When running a `.gbc` directly, reject it (`SourceGraphStale`) if it no longer matches this source file. See below. |
56
+
|`--profile`|`test`-only: print each block's instruction count and peak heap bytes/stack depth/live object count, plus a final peak-across-all-blocks summary line. Does not affect pass/fail behavior or the exit code. Forces per-instruction instruction counting on for the run, which costs real speed — a diagnostic aid, not something to leave on by default. |
40
57
|`--cap name`| Enable one named capability. Repeat for several capabilities. See `capabilities.md`; no capability is enabled merely by importing it. `cap:ffi` requires `--cap ffi` and is native-CLI only. |
41
58
|`--cap net=scope1,scope2`| Scope the `net` capability instead of granting it unscoped. Scopes are `dial` and `listen`, comma-separated (`--cap net=dial`, `--cap net=listen`, `--cap net=dial,listen`). Bare `--cap net` (no `=`) still means dial-only, unchanged from before scopes existed — upgrading never silently grants listen. This general `name=scope1,scope2` syntax is available for any capability that defines scopes, not just `net`. |
42
59
|`--net-listen-allow pattern[:port]`| Add an allow rule to `net.listen`'s bind policy, which defaults to deny-all (see `security.md`). Repeatable. `pattern` accepts the same shapes as the embedding API's policy rules (`"*"`, exact IPv4/IPv6, CIDR, hostname wildcard); an optional `:port` suffix restricts to one port (bracket the pattern for a literal IPv6 address with a port, e.g. `"[::1]:8080"`). With no rules, `--cap net=listen` alone still makes `net.listen(...)` compile and import but refuse every call. |
@@ -78,13 +95,14 @@ for traversal, symlink, and host-platform limits.
78
95
79
96
## GBC (Bytecode Cache)
80
97
81
-
`--emit-gbc path` compiles a script and writes a `.gbc` artifact instead of
82
-
running it. A `.gbc` file passed as the script argument runs directly,
83
-
skipping parsing and compilation entirely — the file is recognized by its
84
-
magic bytes, not its extension, though naming it `.gbc` is the convention:
98
+
`gengo build script.gengo -o path` compiles a script and writes a `.gbc`
99
+
artifact instead of running it. A `.gbc` file passed as the script argument
100
+
runs directly, skipping parsing and compilation entirely — the file is
101
+
recognized by its magic bytes, not its extension, though naming it `.gbc` is
102
+
the convention:
85
103
86
104
```bash
87
-
gengo --emit-gbc app.gbc app.gengo# compile once
105
+
gengo build app.gengo -o app.gbc # compile once
88
106
gengo app.gbc # run the cached artifact, repeatedly
89
107
```
90
108
@@ -105,16 +123,19 @@ This is early — the current implementation covers a first milestone (see
105
123
attached via ordinary bytecode execution rather than embedded as a
106
124
constant, both work), or a generic function declaration (generic struct
107
125
and variant types alone round-trip correctly; the rejection triggers only
108
-
when the script declares a `func` with type parameters). `--emit-gbc`
109
-
fails with a clear error naming the limitation rather than producing a
110
-
broken artifact.
111
-
- The artifact records a hash of the source it was compiled from, but the
112
-
CLI does not yet check it against the current source file before running
113
-
a `.gbc` — nothing currently stops you from running a `.gbc` that no
114
-
longer matches its `.gengo` source. Treat a `.gbc` as something you
115
-
regenerate whenever its source changes, not as a transparent, self-invalidating
116
-
cache yet.
117
-
-`--emit-gbc` is not currently supported when running the WASI build.
126
+
when the script declares a `func` with type parameters). `build` fails
127
+
with a clear error naming the limitation rather than producing a broken
128
+
artifact.
129
+
- The artifact always records a hash of the source it was compiled from, but
130
+
running a `.gbc` doesn't check it by default — nothing stops you from
131
+
running a `.gbc` that no longer matches its `.gengo` source unless you ask
132
+
for the check. Pass `--verify-source path` (naming the original `.gengo`
133
+
file) when running a `.gbc` to opt in: a mismatch fails with
134
+
`SourceGraphStale` instead of silently executing stale bytecode.
135
+
```bash
136
+
gengo --verify-source app.gengo app.gbc
137
+
```
138
+
-`gengo build` is not currently supported when running the WASI build.
Copy file name to clipboardExpand all lines: docs/known-limitations.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,8 +34,8 @@ The relevant specifications include
34
34
35
35
| Area | Current behaviour | Practical consequence |
36
36
|---|---|---|
37
-
|`--emit-gbc` source hash | The artifact records a hash of the source it was compiled from, but the CLI does not yet verify it before running the artifact. | Regenerate the`.gbc`whenever its `.gengo`source changes; do not rely on automatic invalidation. |
38
-
|`--emit-gbc` on WASI |`--emit-gbc` is not supported in the WASI build. | Use the native CLI for GBC emission; run the artifact from WASI if needed. |
37
+
|`gengo build` source hash | The artifact always records a hash of the source it was compiled from, but running a `.gbc` only verifies it against `--verify-source path` when that flag is given — a`.gbc`must remain runnable standalone with no source present, so verification can't be mandatory. | Pass `--verify-source path` when the original `.gengo`file is available and drift should fail loudly (`SourceGraphStale`); otherwise regenerate the `.gbc` by hand whenever its source changes. |
38
+
|`gengo build` on WASI |`gengo build` is not supported in the WASI build. | Use the native CLI for GBC emission; run the artifact from WASI if needed. |
Copy file name to clipboardExpand all lines: docs/language.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1918,10 +1918,10 @@ test "range check" {
1918
1918
1919
1919
**Normal execution skips test blocks.** Running `gengo script.gengo` executes the script body but ignores all `test` blocks entirely. No test code runs, and no test infrastructure is paid for.
1920
1920
1921
-
**`--test` activates them:**
1921
+
**`gengo test` activates them:**
1922
1922
1923
1923
```bash
1924
-
gengo script.gengo --test
1924
+
gengo testscript.gengo
1925
1925
```
1926
1926
1927
1927
Each test block runs in order. Results go to stderr:
0 commit comments