diff --git a/docs/README.md b/docs/README.md index cdf5cc66..7409390a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -57,7 +57,7 @@ tracked in [`UPSTREAM_PROVENANCE.md`](UPSTREAM_PROVENANCE.md). | **E11** Documentation, SDK Reference & Published Manual (#197) | **Closed/Accepted** (2026-07-25) | [DD-013](design/DD-013-documentation-sdk-reference-and-published-manual.md) **Accepted** (D1–D7 as recommended). Completed E7/DD-008's docs ambit. **All four phases shipped:** typedoc API reference over the ten packages (#198), GitHub Pages + Chestnut Labs theme (#199), SDK manual — getting-started/guides/concepts (#200), accuracy gate + `eslint-plugin-tsdoc` + version stamp (#201). **Live: [chestnutlabs.github.io/gcode-preview](https://chestnutlabs.github.io/gcode-preview/)** (manual at `/`, API at `/api/`), auto-redeployed on merge/release. No package/IR/renderer change. Deferred: flip the `notDocumented` doc-coverage check to error once the 55 TSDoc-syntax gaps are filled | | **E8** Low-Resource Layer Mode (#9) | **Closed/Accepted** (2026-07-26) | [DD-014](design/DD-014-low-resource-layer-renderer.md) **Accepted** (D1–D5 as recommended; D6 build-now on the standing AnyBridge evidence). **All four §14 phases shipped** — #212 two new lockstep pkgs (`gcode-colors` shared ColorMode subsystem + `gcode-renderer-2d` Canvas 2D `LayerView2D`, no `three`/framework; renderer-three refactored onto the shared colorer) → **12 packages**; #213 adjacent "ghost" layers over a stable model frame; #214 **`renderer: '2d' \| '3d'` prop** through core + all 4 adapters (the 3D renderer is **loaded on demand** so a 2D-only bundle never ships Three.js) + 2D live-progress "cut"; #215 capability-honesty disclosures (non-planar/CNC via `renderer-unsupported`) + **§8 low-resource budget verified on a real device** (redraw ~0.2 ms median, ≤ 3.6 ms @ 6× CPU throttle vs the 16 ms budget; ~0 MB heap growth over 870 renders — no per-layer geometry) ([report](../tools/benchmark/results/e8-2d-lowresource-benchmark-2026-07-26.md)). §15 acceptance criteria met. Roadmap note (DD-008 §4.8): pure-Node GPU-less still rendering is a related deferred capability | | **Binary G-code (`.bgcode`) decode** (#188) | **Closed/Accepted** (2026-07-28) | [DD-011](design/DD-011-binary-gcode-decode-adapter.md) **Accepted**, preceded by [RR-003](research/RR-003-bgcode-licensing-and-format-audit.md). New 13th lockstep pkg `@chestnutlabs/gcode-bgcode` decodes Prusa `.bgcode` → plain G-code (None / DEFLATE-zlib / heatshrink w11+w12 / MeatPack; MeatPack MIT + heatshrink ISC clean-room, no AGPL); validated against real Prusa files (21 MB XL 856/856 CRC; cube golden byte-identical); [§7 security review](design/SECURITY-REVIEW-DD-011-bgcode.md) **signed off**. **Shipped in `v0.3.0`.** | -| **Non-extrusion toolpath — CNC / laser / plotter** (#189) | **Phases 1–5 built + merged; documented; experimental tier** | [DD-012](design/DD-012-non-extrusion-toolpath-and-modal-tool-state.md) **Accepted** (D1–D8), preceded by [RR-004](research/RR-004-non-extrusion-toolpath-coverage.md). **Phases 1–5 (#248–#255):** `MoveKind.Cut` + opt-in `ModalChannel`/`toolPower`; modal-motion + canned cycles (`G81`/`G82`/`G83`); GRBL-laser/GRBL-mill/LinuxCNC dialects + **validation tiers** (experimental → claims `inferred`); color-by-power + cut-vs-rapid; [compatibility matrix](compatibility/dialects-and-containers.md#dialects-non-extrusion--cnc--laser--plotter-dd-012-189) + support docs. **Real-file work:** lexer handles multi-command lines / `N`-numbers / bare-`S` (#256 — real LinuxCNC/TinyG now parse); evidence-based detection (#258, 0/6→3/6 real samples); [STL export](../tools/demo) (#152, #257). All FDM-byte-identical. **Remaining:** phase 6 — hardware validation → promote tiers to `validated`; larger gaps (LinuxCNC O-word subroutines/params/expressions). Rides the next lockstep release (`v0.4.0`). | +| **Non-extrusion toolpath — CNC / laser / plotter** (#189) | **Phases 1–5 built + merged; documented; experimental tier** | [DD-012](design/DD-012-non-extrusion-toolpath-and-modal-tool-state.md) **Accepted** (D1–D8), preceded by [RR-004](research/RR-004-non-extrusion-toolpath-coverage.md). **Phases 1–5 (#248–#255):** `MoveKind.Cut` + opt-in `ModalChannel`/`toolPower`; modal-motion + canned cycles (`G81`/`G82`/`G83`); GRBL-laser/GRBL-mill/LinuxCNC dialects + **validation tiers** (experimental → claims `inferred`); color-by-power + cut-vs-rapid; [compatibility matrix](compatibility/dialects-and-containers.md#dialects-non-extrusion--cnc--laser--plotter-dd-012-189) + support docs. **Real-file work:** lexer handles multi-command lines / `N`-numbers / bare-`S` (#256 — real LinuxCNC/TinyG now parse); evidence-based detection (#258, 0/6→3/6 real samples); [STL export](../tools/demo) (#152, #257). All FDM-byte-identical. **Phase 7 (RS274NGC programming layer) shipped `v0.18.0`:** parameters + expressions + O-word control flow + in-file subroutines ([DD-017](design/DD-017-rs274ngc-parametric-programs.md); [coverage](compatibility/gcode-motion-coverage.md#rs274ngc-parametric-programs-dd-017), [guide](manual/concept-parametric-programs.md)). **Remaining:** phase 6 — hardware validation → promote grbl-mill/linuxcnc tiers to `validated` (laser already validated). | | #152 STL export | Open, gated | Follows the **#118** chrome/showcase product decision, not an architecture DD (DD-009 §3) | Shipped so far: `packages/toolpath-core` (SoA `ToolpathIR`, capability model), `packages/gcode-parser` diff --git a/docs/compatibility/gcode-motion-coverage.md b/docs/compatibility/gcode-motion-coverage.md index 24aae6e6..2f73c30c 100644 --- a/docs/compatibility/gcode-motion-coverage.md +++ b/docs/compatibility/gcode-motion-coverage.md @@ -64,6 +64,34 @@ other geometry (positions, kinds, layers, source bytes) stayed byte-identical. `probe-position-runtime-dependent`; the native golden pins this, and the fixture is a documented, intentional divergence from the inherited engine (which ignored both `G31` and `G92 Z`). +## RS274NGC parametric programs (DD-017) + +Beyond the fixed motion codes above, the interpreter executes the **RS274NGC programming layer** — the +way LinuxCNC / CAM output *computes* geometry (parameters, expressions, control flow, subroutines). It +engages only when a line uses `#`, `[`, or a leading O-word; every other file takes the ordinary path +and is **byte-identical**. Shipped in v0.18.0 (DD-017 phases 1–3). See the +[parametric-programs guide](../manual/concept-parametric-programs.md) for a worked example. + +| Construct | Support | Disclosure on trouble | +|---|---|---| +| Parameters `#1`–`#5399`, `#`, `#<_global>`; assignment; indirect `##`; computed `#[expr]` | **honored** | read-before-write → `0` + `rs274-uninitialized-param` | +| System parameters | read-only allow-list (current position `#5420`–`#5422`) | others → `0` + `rs274-unsupported-sysparam` | +| Expressions `[ … ]` — full operator/function set, **degree** trig, LinuxCNC `MOD`/`EQ` | **honored** | malformed → word dropped + `rs274-bad-expression`; non-finite result → `rs274-non-finite-value` | +| `if` / `elseif` / `else` / `endif` | **honored** | — | +| `while` / `endwhile`, `do` / `while`, `repeat` / `endrepeat` | **honored** | total loop work capped → `rs274-iteration-limit` | +| `break` / `continue` | **honored** (innermost loop, frame-local) | outside a loop → `rs274-misplaced-control` | +| `sub` / `endsub`, `call [args]`, `return` — in-file, recursive, forward-referenceable | **honored** | recursion capped → `rs274-call-depth`; unknown sub → `rs274-unknown-sub`; redefined → `rs274-duplicate-sub` | +| External subprogram files (`M98 P…`, external `o call`), persistent `.var` params, `return` values | **out of scope** | — | + +**Bounds & honesty.** Two `ParseLimits` fields bound execution: `maxProgramIterations` (default +1,000,000) caps total loop work — charged per loop pass *and* per statement inside a loop or subroutine, +so a large body or an exponential recursive fan-out cannot exceed it — and `maxCallDepth` (default 50) +caps subroutine recursion. There is no `eval` and no I/O. Clean execution reports the +`parametricProgram` capability as `known`; any disclosure above drops it to `approximated`; a +non-parametric file reports `unavailable` — never a fabricated value. FDM / non-parametric input is +byte-identical (both golden suites unchanged). Design and the bounded-execution model: +[DD-017](../design/DD-017-rs274ngc-parametric-programs.md). + ## Remaining gaps The E10 motion-model gaps from the #154 audit are now all closed. Tracking issues: **#155** (G90/G91 + diff --git a/docs/design/DD-017-rs274ngc-parametric-programs.md b/docs/design/DD-017-rs274ngc-parametric-programs.md index 6894290b..8f5b00e8 100644 --- a/docs/design/DD-017-rs274ngc-parametric-programs.md +++ b/docs/design/DD-017-rs274ngc-parametric-programs.md @@ -1,9 +1,10 @@ # DD-017 — RS274NGC parametric programs: parameters, expressions & O-word flow (#189 phase 7) -**Status:** **Accepted (Phases 1–2)** — Phase 1 (parameters + expressions, D2/D3, §5.1) and Phase 2 -(O-word control flow — conditionals + bounded loops, D4/D5/D6 for `if`/`while`/`do`/`repeat`, §5.2) both -accepted & built 2026-08-27; **Phases 3–4 (subroutines, capability/docs polish) remain Proposed**, gated -on measured Phase 2 results. +**Status:** **Accepted — all phases built & shipped in v0.18.0** (2026-08-27). Phase 1 (parameters + +expressions, D2/D3, §5.1), Phase 2 (O-word control flow, D4/D5/D6, §5.2), Phase 3 (in-file subroutines + +`maxCallDepth`, §5.3), and Phase 4 (capability/disclosure surface + docs, §5.4). Remaining, out of the +accepted scope: subroutine **return-value** propagation and external subprogram files (`M98` — an explicit +§3 non-goal). **Authors/Owners:** Nathaniel Chestnut **Date:** 2026-07-29 · **Last revised:** 2026-08-27 **Owning Epic:** #189 (non-extrusion toolpath coverage), **phase 7** · **Milestone:** Future @@ -207,3 +208,5 @@ the existing SoA). No renderer/adapter/color changes (they consume the same segm | 2026-07-29 | DD-017 drafted as **Proposed** (D1–D8 open). Phase 7 of #189; the spec-derivable RS274NGC programming layer (params/expressions/O-words) flagged during real-file validation. Follows DD-012 §16 (spec-anchored CNC). | Chestnut Labs | | 2026-08-27 | **Phase 1 accepted & built** (parameters + expressions only; D2/D3/§5.1). New `packages/gcode-parser/src/rs274.ts` — a pure recursive-descent evaluator (RS274NGC operator/function set, degree trig, LinuxCNC MOD/EQ semantics, `MAX_EXPR_DEPTH` guard, no `eval`) + parameter store (numbered/named/global, indirect `##`, computed `#[expr]`, read-only system-param allow-list `#5420–#5422`), gated on a per-line `#`/`[` scan (FDM byte-identical, native goldens regenerated for the additive `parametricProgram` capability only; ~2.7% parse overhead from the gate, measured on 3DBenchy). O-word control flow (D4, Phases 2–4) explicitly **not** authorized until Phase 1 results are reviewed. | Chestnut Labs (lead) | | 2026-08-27 | **Phase 2 accepted & built** (O-word control flow — conditionals + bounded loops; D4/D5/D6, §5.2). New `packages/gcode-parser/src/rs274-flow.ts` — the program-buffered interpreter of D1 Option A: engaged only when `programUsesOWords(text)` (a cheap char-scan; FDM never enters it, byte-identical), it buffers the program, builds a **block tree**, and executes `if`/`elseif`/`else`/`endif`, `while`/`endwhile`, `do`/`while`, `repeat`/`endrepeat`, `break`/`continue` — re-feeding each plain line through the same `processLine` (one geometry path) and evaluating conditions/counts against the shared Phase-1 store (`Rs274Context.evalExpression`). **Bounded execution (D5):** new public `maxProgramIterations` limit (default 1M) charged per loop-body pass → `rs274-iteration-limit` + partial IR; internal `MAX_CONTROL_NESTING` cap; loops are iteration, not recursion, so only structural nesting (capped) uses JS stack — a hostile `o while [1]` wastes only bounded CPU, cannot hang/OOM/stack-overflow. **Honesty (D6):** clean flow → `parametricProgram: 'known'`; a degraded run (hit cap / unbalanced / unsupported / malformed condition) → `'approximated'` + a specific disclosure. `sub`/`call`/`return` disclosed unsupported and **not** executed (Phase 3). Streaming discloses + runs linearly (a partial stream can't re-run a line range, §4.1). Both golden suites unchanged; validated on a real LinuxCNC-idiom `while`-loop bolt circle (params + degree trig + flow). `maxCallDepth` (subroutine recursion) deferred to Phase 3. | Chestnut Labs (lead) | +| 2026-08-27 | **Phase 3 accepted & built** (in-file subroutines; §5.3). `sub`/`endsub`, `call [args]`, `return` in `rs274-flow.ts` + a scope stack in `rs274.ts`: recursion-safe LinuxCNC scoping (`#1`–`#30` and `#` per call frame; `#31`+ and `#<_global>` shared), args → `#1`–`#30`, forward-referenceable, recursive. New public `maxCallDepth` limit (default 50) → `rs274-call-depth` disclose+skip; a runtime exec-depth backstop bounds combined nesting + call-depth JS recursion; `break`/`continue`/`return` are frame-local. Adversarial review caught + fixed a HIGH bounded-execution hole (a loop-free recursive fan-out was uncharged → exponential; now every statement inside a loop OR subroutine is charged, so total call-tree size is bounded by `maxProgramIterations`) + 2 honesty nits (id-mismatched `endsub`, malformed `call` arg now disclosed). Return VALUES not propagated (documented limitation); external sub files (`M98`) = §3 non-goal. Both golden suites unchanged. | Chestnut Labs (lead) | +| 2026-08-27 | **Phase 4 done** (capability/disclosure surface + docs; §5.4). No engine change. Documented the `parametricProgram` capability tiers + the full `rs274-…` warning-code set in the compatibility coverage matrix ([gcode-motion-coverage.md](../compatibility/gcode-motion-coverage.md#rs274ngc-parametric-programs-dd-017), construct-by-construct table) and a user-facing manual guide ([concept-parametric-programs.md](../manual/concept-parametric-programs.md), worked bolt-circle example + honesty/bounds); added `parametricProgram` to the capability-model concept page; refreshed the #189 epic row + this DD's status. Real-file validation folded into the phase work (the LinuxCNC-idiom bolt-circle integration test). **DD-017 complete; shipped in v0.18.0.** | Chestnut Labs (lead) | diff --git a/docs/design/README.md b/docs/design/README.md index 3b4f57f1..e85524b0 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -28,7 +28,7 @@ boundary. Architecture-sensitive work is **blocked until its DD is Accepted** (g | [DD-013](DD-013-documentation-sdk-reference-and-published-manual.md) | Documentation, SDK Reference & Published Manual | E11 | Future | **Accepted** 2026-07-25 (D1–D7 as recommended) (#197) | | [DD-014](DD-014-low-resource-layer-renderer.md) | Low-Resource Layer Mode (2D/adjacent-layer renderer over IR) | E8 (#9) | Future | **Accepted** 2026-07-26 (D1–D5 as recommended; D6 build-now on the AnyBridge evidence artifact) | | [DD-016](DD-016-annotation-derived-move-kinds.md) | Annotation-Derived Move Kinds (Wipe & Seam) | E9 (#182) | Future | **Accepted** 2026-07-27 (D1–D6 as recommended; D2 = narrow additive DD-005 sink amendment so a slicer-comment signal can set `Wipe`; seam a non-goal) | -| [DD-017](DD-017-rs274ngc-parametric-programs.md) | RS274NGC Parametric Programs (parameters, expressions & O-word flow) | #189 phase 7 | Future | **Proposed** 2026-07-29 (D1–D8 open) — spec-derivable RS274NGC programming layer: on-demand interpreter engaged only on `#`/`[`/O-words (FDM byte-identical), bounded iteration/recursion limits; per [RR-004](../research/RR-004-non-extrusion-toolpath-coverage.md) §9 | +| [DD-017](DD-017-rs274ngc-parametric-programs.md) | RS274NGC Parametric Programs (parameters, expressions & O-word flow) | #189 phase 7 | Shipped | **Accepted — phases 1–3 built & shipped v0.18.0** (2026-08-27): parameters + expressions (#410), O-word control flow (#413), in-file subroutines (#415). On-demand interpreter engaged only on `#`/`[`/O-words (FDM byte-identical); bounded by `maxProgramIterations`/`maxCallDepth`; honesty-tiered `parametricProgram`. Phase 4 (capability/docs) done. Only the optional docs-polish tail + return-value propagation remain. Per [RR-004](../research/RR-004-non-extrusion-toolpath-coverage.md) §9 | | [DD-020](DD-020-interaction-aware-quality.md) | Interaction-aware render quality (progressive LOD) | #306 | M1 | **Accepted** 2026-08-24 — opt-in `interactionQuality:'auto'`: reduce render detail (pixel ratio, bounded frame-time step) while the camera moves, restore on settle; keeps the vertex-budget fallback; consumer maps High/Balanced/Performance. Additive, default off. | | [DD-018](DD-018-model-renderer.md) | ModelRenderer — source-model presentation rendering (STL/3MF) | ModelRenderer (new epic) | M1 | **Accepted** 2026-08-23 (all sections as proposed; §14 v1 = both STL+3MF sequential; §12 shared stage stays in gcode-renderer-three short-term) — new sibling `@chestnutlabs/gcode-model-renderer` for presentation/thumbnail renders of source STL/3MF (distinct from toolpath inspection); shared "stage" extraction, headless/offscreen (SwiftShader) contract with transparent+themed bg, multi-object + material-capable scene model from day one, deterministic export + `(sourceHash, options, envId)` cache key; consumer: AnyBridge thumbnail sidecar | | [DD-021](DD-021-interactive-model-viewer.md) | Interactive source-model viewer (`ModelViewer`) | ModelRenderer (DD-018 line) | M2 | **Accepted** 2026-08-24 (maintainer; AnyBridge boundary-reviewed, no blockers) — a distinct interactive `createModelViewer(canvas)` handle (orbit/zoom/pan of source STL/3MF, the live analogue of `renderModelStill`); reuses the shared stage + `ModelRenderer` scene core + the toolpath camera/controls + DD-020 quality; **generic open-`kind` model-source loader registry** (STL/3MF first, OBJ/STEP/PLY later w/o API change); distinct from ToolpathRenderer / ``; handle in `gcode-model-renderer`, shared-control extraction into `gcode-renderer-three`; components a later phase; consumer: AnyBridge "View in 3D" | diff --git a/docs/manual/concept-ir-capabilities.md b/docs/manual/concept-ir-capabilities.md index 354309e7..e2b28e72 100644 --- a/docs/manual/concept-ir-capabilities.md +++ b/docs/manual/concept-ir-capabilities.md @@ -34,9 +34,16 @@ Every derived claim is tagged with a confidence level: | `unavailable` | Cannot be determined from this input. | These live in the IR header's `capabilities` map — for example `extrusionMode`, `positioningMode`, -`layers`, `sourcePositions`. A consumer reads them to decide what UI to show: feature coloring only -when the feature was disclosed, a layer slider only when layers are `known`, an uncertainty band -when a position is `approximated`. +`layers`, `sourcePositions`, `parametricProgram`. A consumer reads them to decide what UI to show: +feature coloring only when the feature was disclosed, a layer slider only when layers are `known`, an +uncertainty band when a position is `approximated`. + +The same rule governs computed geometry. When a file uses the RS274NGC programming layer (parameters, +expressions, loops, subroutines — see [Parametric programs](concept-parametric-programs.md)), the +interpreter *computes* the coordinates rather than inferring them, so a clean run reports +`parametricProgram: 'known'`. If a resource limit was hit or a construct couldn't be executed, it +reports `approximated` and emits a specific warning (each `rs274-…` warning names what was lost) — the +geometry it did produce is still real, and what it couldn't do is stated, not faked. This is why the preview never silently lies: if a dialect didn't emit feature annotations, the stack says so rather than inventing them; if the extruder mode wasn't stated, it defaults *and tells diff --git a/docs/manual/concept-parametric-programs.md b/docs/manual/concept-parametric-programs.md new file mode 100644 index 00000000..2b4dd7ba --- /dev/null +++ b/docs/manual/concept-parametric-programs.md @@ -0,0 +1,87 @@ +--- +title: Parametric programs (RS274NGC) +group: Concepts +category: Concepts +--- + +# Parametric programs (RS274NGC) + +Some G-code doesn't spell out its geometry move by move — it **computes** it. A LinuxCNC or CAM +program can set a variable, evaluate an expression as a coordinate, loop, branch, and call a +subroutine, so a bolt circle is a `while` loop over an angle instead of twelve explicit `G1`s. The +parser runs that programming layer, so these files resolve to the real toolpath rather than rendering +empty or partial. + +This is the **RS274NGC** programming layer — the dialect LinuxCNC implements. FDM slicer output never +uses it; CNC / CAM output routinely does. + +## What runs + +- **Parameters** — numbered `#1`–`#5399`, named `#` (local) and `#<_global>` (global). Assign + with `#1 = 5`; read anywhere a number is expected (`X#1`). Indirect (`##1`) and computed + (`#[#1 + 1]`) references resolve too. +- **Expressions** — `[ … ]` anywhere a coordinate goes: `X[#1 + 2 * SIN[30]]`. The full RS274NGC + operator set (`+ - * / MOD **`, comparisons, `AND` / `OR` / `XOR`) and functions (`SIN COS TAN ATAN + ABS SQRT FIX FUP ROUND LN EXP` …) — trig in **degrees**, with LinuxCNC `MOD` / `EQ` semantics. +- **Control flow (O-words)** — `if` / `elseif` / `else` / `endif`, `while` / `endwhile`, `do` / + `while`, `repeat` / `endrepeat`, `break` / `continue`. +- **Subroutines** — in-file `sub` / `endsub`, `call [args]` (arguments bind to `#1`–`#30` in the call + frame), `return`. Subroutines may recurse and may be called before they are defined. + +A bolt circle, computed: + +```gcode +# = 50 +# = 40 +# = 20 +# = 6 +# = 0 +o100 while [# LT #] + # = [# * 360 / #] + G0 X[# + # * COS[#]] Y[# + # * SIN[#]] + # = [# + 1] +o100 endwhile +``` + +The six rapids land on the circle: the loop runs and the degree-trig expressions evaluate, so the +preview shows the pattern the machine would follow — not an empty plate. + +## It costs nothing on ordinary files + +The interpreter engages **only** when a program actually uses `#`, `[`, or an O-word. Every FDM and +plain-CNC file takes the ordinary parse path and produces byte-for-byte identical output — enabling +this changed nothing for files that don't use it. + +## Honesty and safety + +Computed geometry is real geometry. When a program runs to completion, the `parametricProgram` +capability is **`known`**: the coordinates are a deterministic function of the program, so the +interpreter computes them — it does not guess. If something is off — a resource limit was reached, an +O-word was unbalanced or unsupported, a condition was malformed — the capability drops to +**`approximated`** and a specific warning names exactly what was lost. A non-parametric file reports +`unavailable`. It never silently renders the wrong thing. + +A parametric program is a small program, so it is bounded like one. Two limits (part of the parser's +[`ParseLimits`](concept-workers.md)) keep a hostile or buggy file from hanging the parser: + +- **`maxProgramIterations`** (default 1,000,000) bounds total loop work — an `o while [1]` stops with a + partial result and a `rs274-iteration-limit` disclosure. +- **`maxCallDepth`** (default 50) bounds subroutine recursion — runaway or mutual recursion is + disclosed (`rs274-call-depth`) and skipped, never a stack overflow. + +There is no `eval` and no file I/O: the evaluator is a fixed arithmetic grammar over a fixed set of +functions, so an adversarial program can waste only bounded CPU. + +## Limits + +- **In-file subroutines only.** External subprogram files — Fanuc `M98 P…`, or an `o call` that + resolves to a separate `.ngc` — are out of scope; the parser does no file I/O. +- **Return values aren't propagated to the caller** yet; `return` acts as an early exit from the + subroutine. +- **Persistent parameters** (LinuxCNC's `.var` file) aren't read — a program is interpreted in + isolation. + +For the construct-by-construct coverage table and every warning code, see +[G-code motion & position coverage](../compatibility/gcode-motion-coverage.md#rs274ngc-parametric-programs-dd-017); +for the design and its bounded-execution model, see +[DD-017](../design/DD-017-rs274ngc-parametric-programs.md). diff --git a/docs/manual/index.md b/docs/manual/index.md index 56d339cc..890a6b50 100644 --- a/docs/manual/index.md +++ b/docs/manual/index.md @@ -64,7 +64,8 @@ viewer is reachable without switching APIs. - **Concepts** — [ToolpathIR & the capability model](concept-ir-capabilities.md), [Workers, streaming & performance](concept-workers.md), [Dialects & containers](concept-dialects-containers.md), - [Live progress & motion model](concept-progress-motion.md). + [Live progress & motion model](concept-progress-motion.md), + [Parametric programs (RS274NGC)](concept-parametric-programs.md). - **API reference** — pick a package in the sidebar (`toolpath-core`, `gcode-parser`, …). > **Status:** published — all fourteen `@chestnutlabs/*` packages are on npm (latest `v0.18.0`,