按规划持续工作

This commit is contained in:
2026-06-09 06:13:28 +08:00
parent 902c6ecaea
commit 2658ee3b72
255 changed files with 12487 additions and 150 deletions

View File

@@ -12,6 +12,12 @@ The primary native validation command is:
wasm-port/tests/native/verify_native_probes.sh
```
The native LinuxCNC `nc_files` basic/example validation command is:
```bash
wasm-port/tests/native/verify_nc_files.sh
```
The current WASM smoke validation command is:
```bash
@@ -24,6 +30,18 @@ The current WASM interpreter-core smoke validation command is:
wasm-port/tests/wasm/node/verify_interp_wasm.sh
```
The current WASM sim-config smoke validation command is:
```bash
wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh
```
The current WASM `nc_files` smoke validation command is:
```bash
wasm-port/tests/wasm/node/verify_nc_files_wasm.sh
```
The current WASM trajectory-planner smoke validation command is:
```bash
@@ -74,10 +92,58 @@ The native validation script runs these checks in order:
5. `tools/build_native_probes.sh`
Builds native source probes and standalone harnesses from vendored
LinuxCNC source plus narrow runtime wrappers.
6. `tests/native/verify_native_probes.sh`
6. `tests/native/verify_sim_configs.sh`
Runs LinuxCNC `configs/sim` `.ngc` programs through the upstream
`../linuxcnc/bin/rs274` standalone entry point, using nearest or explicit
sim INI/tool-table mappings and classifying main programs, macro-load
checks, and remap subroutines separately.
7. `tests/native/verify_nc_files.sh`
Runs the basic/example subset of upstream `linuxcnc/nc_files` through
`../linuxcnc/bin/rs274`, with complete programs executed strictly and
macro/library files wrapped only for load/parse validation.
8. `tests/native/verify_native_probes.sh`
Checks probe exit codes, source-probe coverage, harness stdout, canonical
fixture events, and expected error behavior.
Current `nc_files` basic-suite baseline:
```text
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0
```
The six expected failures are LinuxCNC-native entry-point/context edges:
`cone.ngc` needs a W-axis 5-axis machine context; `g76.ngc` and
`lathe-g76.ngc` need lathe cutter-compensation/tool context;
`lathe_g70_71_demo.ngc` needs lathe profile/tool context; `nestedcall.ngc`
uses an upstream O-word `callsub` syntax edge; and `tool-length-probe.ngc`
needs probe runtime context.
The same runner also supports exploratory full-directory inventory:
```bash
wasm-port/tests/native/verify_nc_files.sh --all
```
Current full-directory `nc_files` inventory:
```text
total: 247
pass: 219
fail: 28
timeout: 0
expected_fail: 28
unexpected_fail: 0
```
The additional expected failures are probe/plasmac runtime-context files and
one NURBS sample using `G2.2`, which the current upstream `bin/rs274`
standalone entry point reports as `Unknown g code used`.
The WASM INI smoke script builds `runtime/ui/ini-panel/linuxcnc_ini.js` and
`linuxcnc_ini.wasm` from vendored LinuxCNC `inifile.cc`, then loads that
module through `runtime/sdk/src/index.js` in Node and verifies INI string and
@@ -109,8 +175,10 @@ Emscripten filesystem through the SDK and runs them through LinuxCNC
`Interp::open()`, `Interp::read()`, and `Interp::execute()` to validate the
file execution path. It also writes the vendored LinuxCNC `xyzac-trt` and
`xyzbc-trt` table-rotary-tilting sample machine INI, `remap_subs/*.ngc`, and
`xyzac_switchkins.ngc`/`xyzbc_switchkins.ngc`, `boat-xyzac.ngc`,
`boat-xyzbc.ngc`, and `impeller-7bl-xyzac.ngc` demo files into the Emscripten
`xyzac_switchkins.ngc`/`xyzbc_switchkins.ngc`,
`xyzac_switchkins_test_1.ngc`, `xyzac_switchkins_test_2.ngc`,
`xyzac_switchkins_test_3.ngc`, `boat-xyzac.ngc`, `boat-xyzbc.ngc`, and
`impeller-7bl-xyzac.ngc` demo files into the Emscripten
filesystem. It also writes the vendored LinuxCNC `xyzab-tdr` table-dual-rotary
INI, tool table, `remap_subs/*.ngc`, and `xyzab-tdr-demo.ngc` into the
Emscripten filesystem. It also writes the vendored LinuxCNC bridge-mill
@@ -119,7 +187,52 @@ Emscripten filesystem. These checks validate the WASM C ABI/SDK path for
vendored LinuxCNC `REMAP` parsing, vendored LinuxCNC tool-table loading from
the machine INI, O-word remap execution, `M68`/`M66` HAL synchronization, and
file `open()`/`read()`/`execute()` completion without JavaScript M-code or
kinematics semantics. The same Node smoke writes
kinematics semantics. The same Node smoke writes the vendored LinuxCNC
`tests/remap/duplicate-o-word`, NGC-only `tests/remap/fail/args.0`,
`tests/remap/fail/args.1`, `tests/remap/fail/args.2`,
`tests/remap/fail/body-ngc`, `tests/remap/m30-interaction`,
`tests/remap/nested-remaps-oword`, `tests/remap/posargs.0`, and
`tests/remap/sequencing` INI, program, and remap subroutines into the
Emscripten filesystem and validates those
upstream NGC remap regressions through the generic `runRemapFile()` C ABI/SDK
path, which only reads LinuxCNC INI `SUBROUTINE_PATH`, `REMAP`, and
`OWORD_NARGS` entries and calls vendored `Interp::parse_remap()`, `open()`,
`read()`, and `execute()`. The NGC-only failure cases that match upstream
`rs274 -n 0` flow use the sibling `runRemapFileContinueOnError()` C ABI/SDK
path, which records LinuxCNC error text and continues the same vendored
`open()`/`read()`/`execute()` loop without implementing failure semantics in
JavaScript. The same Node smoke also writes the NGC-only LinuxCNC
`tests/remap/remap-io/test-ngc.ini` and `io_*.ngc` subroutines into the
Emscripten filesystem, then calls `runRemapIoMdiSequence()` to feed the
upstream test-driver MDI sequence into vendored `Interp::execute()`. The SDK
does not implement M62-M68, M66 input, or REMAP semantics; the standalone
boundary only pre-seeds deterministic external input values and captures
LinuxCNC canonical events. The same WASM interpreter smoke also writes minimal `M110` and
`M111` fixtures into the Emscripten filesystem, marks the `M1xx` files
executable, and validates that the standalone machine-config boundary mirrors
LinuxCNC task-layer `[DISPLAY]PROGRAM_PREFIX` plus `[RS274NGC]USER_M_PATH`
lookup by registering `USER_DEFINED_FUNCTION` entries and recording
deterministic `USER_M_COMMAND` events instead of spawning host processes. The
same Node smoke writes the vendored LinuxCNC
`tests/interp/do-while-break`, `tests/interp/oword-bug315`,
`tests/interp/oword-bug315-p2`, `tests/interp/exists`,
`tests/interp/return-value`, `tests/interp/subs-follow-main`,
`tests/interp/fractional-linenumbers`, `tests/interp/namedparam-bug424`,
selected `tests/interp/rotation` pure interpreter cases, `tests/interp/iniparam`,
`tests/interp/iniparam-failassign`,
`tests/interp/sub-call-from-sub`, `tests/interp/sequence-number`, and
`tests/interp/nested-sub-error`, `tests/interp/nested-sub-in-file-error`, and
`tests/interp/abort-hot-comment`
files into the Emscripten filesystem and validates those upstream interpreter
regressions through `runFile()` or
`runFileWithIni()`, which only reads LinuxCNC INI `SUBROUTINE_PATH` where
needed and calls vendored LinuxCNC `Interp::open()`, `read()`, and `execute()`.
The `iniparam` fixtures validate vendored LinuxCNC `_ini[...]` lookup, missing
INI-parameter error text, and read-only named-parameter assignment rejection
through the `INI_FILE_NAME` runtime edge. It checks LinuxCNC canonical messages,
canonical motion/events, and final interpreter state without JavaScript O-word,
subroutine lookup, INI-variable, or read-only-parameter semantics. The
same Node smoke writes
LinuxCNC-format parameter files into the Emscripten filesystem and validates
vendored `Interp::restore_parameters()` and `Interp::save_parameters()`,
including the saved parameter values, missing required numeric parameter
@@ -203,14 +316,59 @@ override INI-derived names before OPFS text is copied into the LinuxCNC-backed
WASM filesystem, and that absent INI file-name values use the default OPFS
parameter/tool-table paths in a real browser session. It also writes vendored
LinuxCNC `xyzac-trt`/`xyzbc-trt` INI, remap subroutines, and switchkins demo
files, including the larger `boat-xyzac.ngc`, `boat-xyzbc.ngc`, and
`impeller-7bl-xyzac.ngc` demos, into the browser WASM filesystem. It also
files, including `xyzac_switchkins_test_1.ngc`,
`xyzac_switchkins_test_2.ngc`, `xyzac_switchkins_test_3.ngc`, and the larger
`boat-xyzac.ngc`, `boat-xyzbc.ngc`, and `impeller-7bl-xyzac.ngc` demos, into
the browser WASM filesystem. It also
writes vendored LinuxCNC `xyzab-tdr` machine files and `xyzab-tdr-demo.ngc`
into the browser WASM filesystem. It also writes vendored LinuxCNC bridge-mill
machine files and `5axisgui.ngc` into the browser WASM filesystem. The browser
smoke verifies `runFiveAxisRemapFile()` for the table-rotary-tilting,
table-dual-rotary, and bridge-mill sample machines through the exported
LinuxCNC remap/tool-table/file execution path.
LinuxCNC remap/tool-table/file execution path. It also verifies the vendored
LinuxCNC `configs/sim/axis/foam/foam.ngc`, `axis/geometry/xyzc.ngc`, and
`axis/external_offsets/dyn_demo.ngc` programs through `runSimConfigProgram()`,
which writes the browser WASM filesystem files and forwards to
`runFileWithIni()`. It also verifies the bridge-mill
`axis/vismach/5axis/bridgemill/5axisgui.ngc` program through
`runSimConfigProgram()` with `executionMode: "fiveAxisRemap"`, which forwards
to `runFiveAxisRemapFile()`. These paths use the real vendored executable
`M110` and `M111` files for `USER_M_PATH` registration without spawning host
processes. It
also verifies the vendored
LinuxCNC `tests/remap/duplicate-o-word`, NGC-only `tests/remap/fail/args.0`,
`tests/remap/fail/args.1`, `tests/remap/fail/args.2`,
`tests/remap/fail/body-ngc`, `tests/remap/m30-interaction`,
`tests/remap/nested-remaps-oword`, `tests/remap/posargs.0`, and
`tests/remap/sequencing` regressions through `runRemapFile()` or
`runRemapFileContinueOnError()`, using the browser WASM filesystem and
vendored LinuxCNC REMAP/O-word/file execution path without JavaScript remap
semantics. It also writes the NGC-only vendored LinuxCNC
`tests/remap/remap-io/test-ngc.ini` and `io_*.ngc` subroutines into the
browser WASM filesystem and validates `runRemapIoMdiSequence()` through
vendored LinuxCNC REMAP parsing and MDI execution without JavaScript M-code or
I/O semantics. It also writes vendored LinuxCNC `tests/interp/do-while-break`,
`tests/interp/oword-bug315`, `tests/interp/oword-bug315-p2`,
`tests/interp/exists`, `tests/interp/return-value`,
`tests/interp/subs-follow-main`, `tests/interp/fractional-linenumbers`,
`tests/interp/namedparam-bug424`, and selected `tests/interp/rotation`
`.ngc` files plus
`tests/interp/sub-call-from-sub` `test.ini`, `test.ngc`, and `subs/*.ngc`
files and `tests/interp/sequence-number` `test.ini`, `test.ngc`, and
`rm400.ngc` plus `tests/interp/nested-sub-error` `test.ini`, `test.ngc`, and
`subs/nested.ngc` and `tests/interp/nested-sub-in-file-error` `test.ini`,
`test.ngc`, and `subs/sequential.ngc`, plus `tests/interp/abort-hot-comment`
`test.ini` and `test.ngc`, plus `tests/interp/m19` `test.ini` and `test.ngc`,
plus `tests/interp/magic_comments/param_format_printing` `test.ngc`,
plus selected pure-interpreter `tests/interp/m98m99` cases covering
Fanuc-style `M98/M99`, parameter scope, nested numbered subprograms,
subprograms after main program text, leading-zero O-word lookup, named and
numbered main programs, and expression-based O-sub/M98 calls,
into the browser WASM filesystem and
validates those upstream
interpreter regressions through `runFile()` or `runFileWithIni()`, without
JavaScript O-word, parameter, line-number, spindle-speed, spindle-orient,
magic-comment formatting, M98/M99, subroutine lookup, or branch semantics.
The aggregate host smoke script builds the INI, interpreter-core, and
trajectory-planner WASM artifacts once, then runs the Node WASM smokes, the
@@ -240,7 +398,8 @@ The validation fails if:
| `linuxcnc_interp_init_harness` | Validates vendored LinuxCNC `Interp::init()` emits canonical initialization boundaries, reads metric/inch machine units, and synchronizes current/selected tool slots through standalone status adapters. |
| `linuxcnc_indexer_harness` | Validates vendored LinuxCNC single-axis rotary indexer dispatch emits lock/unlock and motion boundaries through the standalone event sink. |
| `linuxcnc_remap_hal_sync_harness` | Validates vendored LinuxCNC `M68`/`M66` execution can drive the standalone HAL adapter boundary used by 5-axis switchkins remap files, including `_hal[motion.switchkins-type]` readback. |
| `linuxcnc_5axis_remap_execute_harness` | Validates vendored LinuxCNC `REMAP` parsing plus NGC remap execution for the 5-axis `M429 -> M428 -> M430 -> M429` switchkins path in the `xyzac-trt` and `xyzbc-trt` sample machines, the two-remap `M429 -> M428 -> M429` path in the `xyzab-tdr` sample machine, and the bridge-mill `M429 -> M428 -> M430 -> M429` path where M428 selects the default bridge-mill kinematics. It loads vendored machine tool tables through LinuxCNC `tooldata_load()`, then runs vendored `xyzac_switchkins.ngc`, `xyzbc_switchkins.ngc`, `xyzac_switchkins_test_1.ngc`, `xyzac_switchkins_test_3.ngc`, `boat-xyzac.ngc`, `boat-xyzbc.ngc`, `impeller-7bl-xyzac.ngc`, `xyzab-tdr-demo.ngc`, and `5axisgui.ngc` through the LinuxCNC file `open/read/execute` path. |
| `linuxcnc_5axis_remap_execute_harness` | Validates vendored LinuxCNC `REMAP` parsing plus NGC remap execution for the 5-axis `M429 -> M428 -> M430 -> M429` switchkins path in the `xyzac-trt` and `xyzbc-trt` sample machines, the two-remap `M429 -> M428 -> M429` path in the `xyzab-tdr` sample machine, and the bridge-mill `M429 -> M428 -> M430 -> M429` path where M428 selects the default bridge-mill kinematics. It loads vendored machine tool tables through LinuxCNC `tooldata_load()`, then runs vendored `xyzac_switchkins.ngc`, `xyzbc_switchkins.ngc`, `xyzac_switchkins_test_1.ngc`, `xyzac_switchkins_test_2.ngc`, `xyzac_switchkins_test_3.ngc`, `boat-xyzac.ngc`, `boat-xyzbc.ngc`, `impeller-7bl-xyzac.ngc`, `xyzab-tdr-demo.ngc`, and `5axisgui.ngc` through the LinuxCNC file `open/read/execute` path. |
| `linuxcnc_duplicate_oword_remap_harness` | Validates vendored LinuxCNC upstream `tests/remap/duplicate-o-word`, NGC-only `tests/remap/fail/args.0`, `tests/remap/fail/args.1`, `tests/remap/fail/args.2`, `tests/remap/fail/body-ngc`, `tests/remap/m30-interaction`, `tests/remap/nested-remaps-oword`, `tests/remap/posargs.0`, `tests/remap/sequencing`, and the NGC-only `tests/remap/remap-io/test-ngc.ini` branch through LinuxCNC `REMAP` parsing, O-word remap dispatch, `OWORD_NARGS`, error-text reporting, G/M remap sequencing, remapped M62-M68/M66 MDI execution, and file `open/read/execute`. The standalone harness only supplies INI/file path setup, deterministic external input values, and canonical-event capture; it can continue after LinuxCNC errors for upstream `rs274 -n 0` style tests and does not implement duplicate-label, O-word, M30, positional-argument, failure, sequencing, M62-M68, M66 input, or remap semantics. |
| `linuxcnc_tp_api_probe` | Validates vendored LinuxCNC trajectory planner calls for linear, arc, and queued motion paths. |
| `linuxcnc_kinematics_probe` | Validates vendored LinuxCNC `trivkins.c` plus `kins_util.c` initialize and perform identity forward/inverse mapping through the standalone HAL/RTAPI boundary. |
| `linuxcnc_5axis_kinematics_probe` | Validates vendored LinuxCNC `5axiskins.c` through `switchkins.c`, including 5-axis forward/inverse round-trip behavior and switching to identity kinematics. |
@@ -265,11 +424,13 @@ The validation fails if:
| Harness | Purpose |
| --- | --- |
| `tests/wasm/node/verify_ini_wasm.sh` | Validates the browser-facing INI WASM module can be built from vendored LinuxCNC `inifile.cc`, loaded through the JS SDK in Node, and queried through the exported C ABI, including LinuxCNC-backed boolean conversion and machine-session file-name string lookup. |
| `tests/wasm/node/verify_interp_wasm.sh` | Validates the interpreter-core WASM module can be built from vendored LinuxCNC interpreter/remap source, loaded through the interpreter JS SDK, run the first fixture group through `Interp::execute()` and selected file fixtures through `Interp::open()`/`read()`/`execute()`, match the native canonical event plus required state readback fixtures, run vendored `xyzac-trt`/`xyzbc-trt` switchkins remap demo files through the WASM C ABI/SDK path, and run parameter-file restore/save through vendored LinuxCNC `Interp::restore_parameters()` and `Interp::save_parameters()`. |
| `tests/wasm/node/verify_interp_wasm.sh` | Validates the interpreter-core WASM module can be built from vendored LinuxCNC interpreter/remap source, loaded through the interpreter JS SDK, run the first fixture group through `Interp::execute()` and selected file fixtures plus vendored upstream `tests/interp` regression files through `Interp::open()`/`read()`/`execute()`, match the native canonical event plus required state readback fixtures, run vendored `xyzac-trt`/`xyzbc-trt` switchkins remap demo files through the WASM C ABI/SDK path, and run parameter-file restore/save through vendored LinuxCNC `Interp::restore_parameters()` and `Interp::save_parameters()`. |
| `tests/wasm/node/verify_sim_configs_wasm.sh` | Validates representative vendored LinuxCNC `configs/sim` programs in Node WASM through `runSimConfigProgram()`, copying `axis/foam`, `axis/geometry`, and `axis/external_offsets` INI/G-code/user-M assets into the Emscripten filesystem before forwarding to `runFileWithIni()`, plus bridge-mill `5axis.ini`, tool table, `remap_subs/*.ngc`, and `5axisgui.ngc` before forwarding to `runFiveAxisRemapFile()`. This covers INI-driven `U/V/W` axis mask handling, real `USER_M_PATH` registration for executable `M110`/`M111`, and vendored LinuxCNC bridge-mill NGC remap execution without spawning host processes. |
| `tests/wasm/node/verify_nc_files_wasm.sh` | Validates representative vendored LinuxCNC `nc_files` examples in Node WASM by copying `arcspiral.ngc`, `hole-circle.ngc`, `factorial.ngc`, and `m6demo.ngc` into the Emscripten filesystem and forwarding to the LinuxCNC-backed `Interp::open()`/`read()`/`execute()` path. JavaScript only stages files and checks LinuxCNC output; it does not implement G-code, O-word, tool-change, or M-code behavior. |
| `tests/wasm/node/verify_tp_wasm.sh` | Validates a standalone trajectory-planner WASM module can be built from vendored LinuxCNC TP/TC/Ruckig support source, loaded in Node, and run the same linear, arc, and queued-line planner probe paths covered by the native TP harness. |
| `tests/opfs/node/verify_file_service.sh` | Validates the host-owned OPFS text-file adapter, path model, session snapshot store including custom filenames and envelope/path rejection paths, machine file store, G-code text store including filename rejection paths, OPFS-to-WASM parameter/tool-table bridges, and grouped machine-session loading without moving file persistence, parameter semantics, or tool-table semantics into the WASM core. |
| `tests/browser/verify_ini_panel_browser.sh` | Validates the INI SDK, INI/interpreter WASM module loading, LinuxCNC-backed INI machine-session file-name string lookup, OPFS text-file round trip, generic session snapshot round trip plus custom filename and envelope/path rejection paths, machine file text round trip, G-code text round trip plus filename rejection paths, and the INI panel UI's machine-session load with default OPFS parameter/tool-table file mapping, G-code run, canonical-event display paths, and 5-axis remap demo action in a real browser runtime. |
| `tests/browser/verify_interp_browser.sh` | Validates the interpreter-core WASM module loads through the interpreter JS SDK in a real browser runtime and runs selected positive and negative canonical fixtures through vendored LinuxCNC `Interp::execute()` plus `Interp::open()`/`read()`/`execute()` via the exported C ABI, including direct browser SDK and OPFS-backed parameter-file restore/save, non-random/random tool-table load/save through vendored LinuxCNC source, and vendored `xyzac-trt`/`xyzbc-trt` switchkins remap demo execution. |
| `tests/browser/verify_interp_browser.sh` | Validates the interpreter-core WASM module loads through the interpreter JS SDK in a real browser runtime and runs selected positive and negative canonical fixtures plus vendored upstream `tests/interp` regression files through vendored LinuxCNC `Interp::execute()` and `Interp::open()`/`read()`/`execute()` via the exported C ABI, including direct browser SDK and OPFS-backed parameter-file restore/save, non-random/random tool-table load/save through vendored LinuxCNC source, vendored `xyzac-trt`/`xyzbc-trt` switchkins remap demo execution, representative vendored `configs/sim` `foam`, `geometry`, `external_offsets`, and bridge-mill programs through `runSimConfigProgram()`, and representative vendored `nc_files` examples through `runFile()`. |
| `tests/host/verify_host_smokes.sh` | Runs the current host-side Node, WASM interpreter-core, WASM trajectory-planner, OPFS, and browser smoke validation with shared WASM builds. |
## Fixture Coverage
@@ -593,7 +754,15 @@ comparable canonical runtime edge and program-end cleanup calls. The
standalone vendored-source harness, Node WASM smoke, and browser smoke also
pin `coordinate_offsets` MDI/file-path, `feed_control_modes`, the
`position_params` MDI/file-path, `tool_semantics`, and `canon_runtime_edges`
post-program modal, override, spindle, mist, and flood `_setup` state. The same upstream baseline also
post-program modal, override, spindle, mist, and flood `_setup` state. Native
and WASM standalone checks also cover the user M-code registration boundary for
INI-declared `M110`/`M111` handlers while keeping process execution outside the
browser/WASM runtime. Node and browser WASM sim-config coverage now run the real
vendored `axis/geometry/xyzc.ngc` and
`axis/external_offsets/dyn_demo.ngc` programs with their executable
`M110`/`M111` files, `axis/foam/foam.ngc` with its `U/V` machine
configuration, and bridge-mill `5axisgui.ngc` with its `W` machine
coordinates. The same upstream baseline also
validates the current negative fixture error text and absent canonical-event
constraints. Fixtures that depend on standalone-only runtime
adapters, HAL state, upstream `rs274` output gaps such as
@@ -633,3 +802,38 @@ resulting `_setup.m_remapped` descriptors for each machine's LinuxCNC-defined
`M428`/`M429`/`M430` set. Python callbacks remain runtime boundaries. Native
and WASM validation now execute the NGC remap/file paths through vendored
LinuxCNC O-word dispatch and the standalone HAL adapter boundary.
`linuxcnc_duplicate_oword_remap_harness` vendors LinuxCNC's upstream
`tests/remap/duplicate-o-word` and `tests/remap/m30-interaction` files
unchanged and runs each `test.ngc` with its `test.ini` through vendored
`Interp::parse_remap()`, `open()`, `read()`, and `execute()`. Native, Node
WASM, and browser interpreter validation assert the same successful LinuxCNC
regression paths, including the remapped `M207`/`M208` messages and final
`FINISH()` event for duplicate O-word, and the `M400 M30` remap-level
interaction with `PROGRAM_END`.
`linuxcnc_interp_minimal_harness` now also runs selected vendored LinuxCNC
upstream `tests/interp/*/test.ngc` files through vendored `Interp::open()`,
`read()`, and `execute()`, using LinuxCNC INI `SUBROUTINE_PATH` for
`tests/interp/sub-call-from-sub`, `tests/interp/sequence-number`, and
`tests/interp/nested-sub-error`, `tests/interp/nested-sub-in-file-error`, and
`tests/interp/abort-hot-comment`, plus LinuxCNC `[RS274NGC]ORIENT_OFFSET` for
`tests/interp/m19`.
Native, Node WASM, and browser interpreter validation assert the LinuxCNC
canonical messages, canonical events, error texts, and interpreter state for
O-word loop/break/subroutine paths, dynamic O-word calls, `EXISTS[]`,
subroutine return values, subroutines after main programs, fractional line
numbers, named-parameter parsing, M19 spindle-orient offset and wait timeout
canonical events, magic-comment parameter formatting, valid external subroutine calls from another
external subroutine, external-subroutine `#<_line>` reporting,
nested-subroutine-definition rejection, and blocked forward seek to a later
numbered subroutine in the same external file, selected `tests/interp/rotation`
absolute-position `#<_abs_x>`, `#<_abs_y>`, and `#<_abs_z>` reporting under
G54, G92, XY rotation, and unit changes plus rotated-coordinate `G28` and
`G53` endpoint behavior, selected `tests/interp/m98m99`
Fanuc-style `M98/M99` subprogram calls, parameter-scope differences,
nested numbered subprograms, subprograms after main program text,
leading-zero O-word lookup, named/numbered main programs, and O-expression
calls, plus `(ABORT,...)` hot-comment numbered, named, and INI-parameter
expansion, with skipped branch/subroutine messages and post-abort program end
asserted absent where applicable.