diff --git a/wasm-port/docs/porting-steps-standalone.md b/wasm-port/docs/porting-steps-standalone.md index eff1b42..574a655 100644 --- a/wasm-port/docs/porting-steps-standalone.md +++ b/wasm-port/docs/porting-steps-standalone.md @@ -354,6 +354,12 @@ Current verified progress: - The same validation is now fixture-driven through `tests/fixtures/gcode/minimal_linear.ngc` and `tests/fixtures/canon/minimal_linear.events`. +- `tests/fixtures/gcode/modal_incremental.ngc` and + `tests/fixtures/canon/modal_incremental.events` add `G90`/`G91` + distance-mode switching plus modal `G1` carry-forward coverage. The + temporary wrapper behavior is based on LinuxCNC + `interp_convert.cc::convert_distance_mode()` and + `interp_convert.cc::convert_straight()`. - This proves the current extracted interpreter slice can parse and execute a simple traverse and feed move through a standalone canonical event sink. @@ -654,8 +660,9 @@ Keep these documents under `wasm-port/docs/`: Continue expanding the standalone interpreter core from the verified minimal traverse path: -1. add another fixture for incremental mode and modal carry-forward, -2. replace the temporary minimal `convert_g()` implementation with thin +1. replace the temporary minimal `convert_g()` implementation with thin wrappers around more vendored interpreter conversion code, +2. add fixture coverage for `Z` moves and multi-axis current-position + parameter updates, 3. keep all source changes inside `wasm-port/` and leave `../linuxcnc/` read-only. diff --git a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp index 46deedc..2d7bb24 100644 --- a/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp +++ b/wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_runtime.cpp @@ -351,27 +351,40 @@ bool Interp::is_any_m_code_remapped(block_pointer, setup_pointer) { return false int Interp::convert_m(block_pointer, setup_pointer) { return INTERP_OK; } int Interp::convert_g(block_pointer block, setup_pointer settings) { + const int distance_mode = block->g_modes[GM_DISTANCE_MODE]; + if (distance_mode == G_90) { + settings->distance_mode = DISTANCE_MODE::ABSOLUTE; + } else if (distance_mode == G_91) { + settings->distance_mode = DISTANCE_MODE::INCREMENTAL; + } + if (block->f_flag) { settings->feed_rate = block->f_number; SET_FEED_RATE(block->f_number); } + const bool incremental = settings->distance_mode == DISTANCE_MODE::INCREMENTAL; if (block->x_flag) { - settings->current_x = block->x_number; + settings->current_x = incremental ? settings->current_x + block->x_number + : block->x_number; } if (block->y_flag) { - settings->current_y = block->y_number; + settings->current_y = incremental ? settings->current_y + block->y_number + : block->y_number; } if (block->z_flag) { - settings->current_z = block->z_number; + settings->current_z = incremental ? settings->current_z + block->z_number + : block->z_number; } if (block->motion_to_be == G_0) { + settings->motion_mode = G_0; STRAIGHT_TRAVERSE(block->line_number, settings->current_x, settings->current_y, settings->current_z, settings->AA_current, settings->BB_current, settings->CC_current, settings->u_current, settings->v_current, settings->w_current); } else if (block->motion_to_be == G_1) { + settings->motion_mode = G_1; STRAIGHT_FEED(block->line_number, settings->current_x, settings->current_y, settings->current_z, settings->AA_current, settings->BB_current, settings->CC_current, diff --git a/wasm-port/tests/fixtures/canon/modal_incremental.events b/wasm-port/tests/fixtures/canon/modal_incremental.events new file mode 100644 index 0000000..4401130 --- /dev/null +++ b/wasm-port/tests/fixtures/canon/modal_incremental.events @@ -0,0 +1,5 @@ +canon_event=STRAIGHT_TRAVERSE line=1 x=1 y=1 z=0 a=0 b=0 c=0 u=0 v=0 w=0 +canon_event=SET_FEED_RATE rate=60 +canon_event=STRAIGHT_FEED line=2 x=3 y=1 z=0 a=0 b=0 c=0 u=0 v=0 w=0 +canon_event=STRAIGHT_FEED line=3 x=3 y=4 z=0 a=0 b=0 c=0 u=0 v=0 w=0 +canon_event=STRAIGHT_TRAVERSE line=4 x=0 y=0 z=0 a=0 b=0 c=0 u=0 v=0 w=0 diff --git a/wasm-port/tests/fixtures/gcode/modal_incremental.ngc b/wasm-port/tests/fixtures/gcode/modal_incremental.ngc new file mode 100644 index 0000000..7043268 --- /dev/null +++ b/wasm-port/tests/fixtures/gcode/modal_incremental.ngc @@ -0,0 +1,4 @@ +G90 G0 X1.0 Y1.0 +G91 G1 X2.0 F60.0 +G1 Y3.0 +G90 G0 X0.0 Y0.0 diff --git a/wasm-port/tests/native/verify_native_probes.sh b/wasm-port/tests/native/verify_native_probes.sh index 248147f..b7dda83 100755 --- a/wasm-port/tests/native/verify_native_probes.sh +++ b/wasm-port/tests/native/verify_native_probes.sh @@ -3,7 +3,8 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)" BUILD_DIR="$ROOT_DIR/build/native" -EXPECTED_EVENTS="$ROOT_DIR/tests/fixtures/canon/minimal_linear.events" +GCODE_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/gcode" +CANON_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/canon" "$ROOT_DIR/tools/build_native_probes.sh" @@ -33,16 +34,47 @@ check_exitcode linuxcnc_interp_minimal_harness check_exitcode linuxcnc_interp_minimal_harness.run check_exitcode linuxcnc_rs274_compile_probe +check_fixture_output() { + local fixture="$1" + local expected="$2" + local stdout_file="$3" + + grep -Fq "read=0" "$stdout_file" + grep -Fq "parse_line=0" "$stdout_file" + + local line_count + line_count="$(grep -cv '^[[:space:]]*$' "$fixture")" + local line_number + for ((line_number = 1; line_number <= line_count; line_number += 1)); do + grep -Fq "execute_line_${line_number}=0" "$stdout_file" + done + + while IFS= read -r expected_event; do + [[ -z "$expected_event" ]] && continue + grep -Fq "$expected_event" "$stdout_file" + done < "$expected" +} + RUN_STDOUT="$BUILD_DIR/linuxcnc_interp_minimal_harness.run.stdout.log" +check_fixture_output \ + "$GCODE_FIXTURE_DIR/minimal_linear.ngc" \ + "$CANON_FIXTURE_DIR/minimal_linear.events" \ + "$RUN_STDOUT" -grep -Fq "read=0" "$RUN_STDOUT" -grep -Fq "execute_line_1=0" "$RUN_STDOUT" -grep -Fq "execute_line_2=0" "$RUN_STDOUT" -grep -Fq "parse_line=0" "$RUN_STDOUT" +for fixture in "$GCODE_FIXTURE_DIR"/*.ngc; do + name="$(basename "$fixture" .ngc)" + expected="$CANON_FIXTURE_DIR/$name.events" + if [[ ! -f "$expected" ]]; then + echo "missing expected canon fixture: $expected" >&2 + exit 1 + fi -while IFS= read -r expected_event; do - [[ -z "$expected_event" ]] && continue - grep -Fq "$expected_event" "$RUN_STDOUT" -done < "$EXPECTED_EVENTS" + stdout_file="$BUILD_DIR/linuxcnc_interp_minimal_harness.$name.stdout.log" + stderr_file="$BUILD_DIR/linuxcnc_interp_minimal_harness.$name.stderr.log" + "$BUILD_DIR/linuxcnc_interp_minimal_harness" "$fixture" \ + >"$stdout_file" \ + 2>"$stderr_file" + check_fixture_output "$fixture" "$expected" "$stdout_file" +done echo "native probe validation complete"