Align AXIS control flow and fix pause and program rendering

Document source UI gates, explicit native live-plot clearing, and remaining parity boundaries. Fix pause/resume transport continuity, repeated stepping, coordinate previews, and spindle override state. Optimize large program snapshots and rendering, and cover the control flows with native Tcl, WASM, and browser checks.

Validation: 22 native tests and source/browser checks pass. Worker/App regression: 113 of 123 pass; 10 pre-existing failures remain documented with no new failures.
This commit is contained in:
2026-09-08 10:46:27 +08:00
parent 845075f4a3
commit bade560372
55 changed files with 2495 additions and 286 deletions

View File

@@ -101,17 +101,12 @@ static int axis_index(char letter) {
static double *axis_pointer(sim_interpreter_state *state, int index) { return &state->x + index; }
static void machine_pose_for_state(const interpreter_meta *meta, const sim_interpreter_state *state, int machine_coordinates, sim_posemath_pose *pose) {
int coordinate = meta->coordinate_system > 0 ? meta->coordinate_system - 1 : 0;
const double *offset = meta->coordinate_offsets[coordinate];
pose->tran.x = state->x + (machine_coordinates ? 0.0 : offset[0]);
pose->tran.y = state->y + (machine_coordinates ? 0.0 : offset[1]);
pose->tran.z = state->z + (machine_coordinates ? 0.0 : offset[2]);
pose->a = state->a + (machine_coordinates ? 0.0 : offset[3]);
pose->b = state->b + (machine_coordinates ? 0.0 : offset[4]);
pose->c = state->c + (machine_coordinates ? 0.0 : offset[5]);
pose->u = state->u + (machine_coordinates ? 0.0 : offset[6]);
pose->v = state->v + (machine_coordinates ? 0.0 : offset[7]);
pose->w = state->w + (machine_coordinates ? 0.0 : offset[8]);
// The interpreter state already stores machine coordinates. Offsets are
// applied exactly once when accepting an absolute coordinate word.
(void)meta; (void)machine_coordinates;
pose->tran.x = state->x; pose->tran.y = state->y; pose->tran.z = state->z;
pose->a = state->a; pose->b = state->b; pose->c = state->c;
pose->u = state->u; pose->v = state->v; pose->w = state->w;
}
static void set_error(sim_interpreter *interpreter, interpreter_meta *meta, int code, uint32_t column) {
@@ -352,6 +347,7 @@ static int apply_g(sim_interpreter_state *state, interpreter_meta *meta, double
if (code_is(code, 80) || (code >= 81.0 && code <= 89.0 && floor(code) == code)) { if (meta) meta->cycle_mode = (int)code; return SIM_INTERP_OK; }
if (code_is(code, 61) || code_is_value(code, 61.1) || code_is(code, 64)) { if (++groups[7] > 1) return SIM_INTERP_ERR_STATE; return SIM_INTERP_OK; }
if (code_is(code, 54) || code_is(code, 55) || code_is(code, 56) || code_is(code, 57) || code_is(code, 58) || code_is(code, 59)) { if (meta) meta->coordinate_system = (int)code - 53; return SIM_INTERP_OK; }
if (code_is_value(code, 59.1) || code_is_value(code, 59.2) || code_is_value(code, 59.3)) { if (meta) meta->coordinate_system = 6 + (int)lround((code - 59.0) * 10.0); return SIM_INTERP_OK; }
if (code_is(code, 53)) return SIM_INTERP_OK;
if (code_is(code, 10)) return SIM_INTERP_OK;
return SIM_INTERP_ERR_UNKNOWN_CODE;
@@ -524,16 +520,14 @@ int sim_interpreter_execute(sim_interpreter *interpreter, const char *block, uin
coordinate = p_value == 0.0 ? (meta->coordinate_system > 0 ? meta->coordinate_system - 1 : 0) : (int)p_value - 1;
if (code_is(l_value, 20)) {
meta->coordinate_offsets[coordinate][axis] = *axis_pointer(&previous, (int)axis) - axis_value;
if (p_value == 0.0) meta->coordinate_l20 = 1;
*destination = axis_value;
} else {
meta->coordinate_offsets[coordinate][axis] = axis_value;
}
} else if (next.distance_mode == SIM_INTERP_INCREMENTAL) *destination += axis_value;
else *destination = axis_value + (seen_g53 || meta->coordinate_l20 ? 0.0 : meta->coordinate_offsets[meta->coordinate_system > 0 ? meta->coordinate_system - 1 : 0][axis]);
else *destination = axis_value + (seen_g53 ? 0.0 : meta->coordinate_offsets[meta->coordinate_system > 0 ? meta->coordinate_system - 1 : 0][axis]);
}
}
if (seen_g10 && !seen_axis[0] && !seen_axis[1] && !seen_axis[2]) { set_error(interpreter, meta, SIM_INTERP_ERR_PARAMETER, 1); return SIM_INTERP_ERR_PARAMETER; }
if (seen_g10 && !seen_axis[0] && !seen_axis[1] && !seen_axis[2] && !seen_axis[3] && !seen_axis[4] && !seen_axis[5] && !seen_axis[6] && !seen_axis[7] && !seen_axis[8]) { set_error(interpreter, meta, SIM_INTERP_ERR_PARAMETER, 1); return SIM_INTERP_ERR_PARAMETER; }
if (meta->cycle_mode >= 81 && meta->cycle_mode <= 89 && seen_r && seen_axis[2]) {
double return_plane = r_value;
if (next.units == SIM_INTERP_UNITS_INCH) return_plane *= 25.4;
@@ -635,3 +629,30 @@ int sim_interpreter_parameter_set(sim_interpreter *interpreter, uint32_t index,
int sim_interpreter_parameter_get(const sim_interpreter *interpreter, uint32_t index, double *value) {
interpreter_meta *meta = meta_for(interpreter, 0); if (meta == NULL || value == NULL || index < SIM_INTERPRETER_PARAMETER_MIN || index > SIM_INTERPRETER_PARAMETER_MAX) return SIM_INTERP_ERR_PARAMETER; *value = meta->parameters[index]; return SIM_INTERP_OK;
}
int sim_interpreter_get_coordinates(const sim_interpreter *interpreter, sim_coordinate_context *context) {
interpreter_meta *meta = meta_for(interpreter, 0);
if (meta == NULL || context == NULL) return SIM_INTERP_ERR_ARGUMENT;
memcpy(context->offsets, meta->coordinate_offsets, sizeof(context->offsets));
context->system = meta->coordinate_system > 0 ? meta->coordinate_system : 1;
return SIM_INTERP_OK;
}
int sim_interpreter_set_coordinates(sim_interpreter *interpreter, const sim_coordinate_context *context) {
interpreter_meta *meta = meta_for(interpreter, 0);
if (meta == NULL || context == NULL || context->system < 1 || context->system > 9) return SIM_INTERP_ERR_ARGUMENT;
memcpy(meta->coordinate_offsets, context->offsets, sizeof(meta->coordinate_offsets));
meta->coordinate_system = context->system;
return SIM_INTERP_OK;
}
int sim_interpreter_sync_position(sim_interpreter *interpreter, const sim_posemath_pose *position) {
interpreter_meta *meta = meta_for(interpreter, 0);
if (meta == NULL || position == NULL) return SIM_INTERP_ERR_ARGUMENT;
memcpy(&interpreter->state.x, &position->tran.x, 9 * sizeof(double));
meta->last_output_pose = *position;
meta->has_output_pose = 1;
meta->has_motion = 0;
interpreter->state.status = SIM_INTERP_OK;
return SIM_INTERP_OK;
}