Table of Contents

Namespace Hi.NcParsers.Keywords

Classes

BlockSkip

Optional block skip marker extracted from the head of an NC block. ISO 6983 / Fanuc calls this feature Block Delete (BDT switch); Siemens / Syntec / Mazak use the same / prefix with matching behaviour.

The section is only present on blocks that carry a / prefix. Whether the block's NC commands are actually skipped at runtime depends on IBlockSkipConfig:

  • Config absent or the Layer bit OFF → the / prefix is consumed, Body is left null, and the rest of the line parses as a regular NC block (comments still take effect).
  • Config present and the Layer bit ON → the rest of the line is moved into Body and cleared from UnparsedText, so downstream parsing syntaxes see nothing and no NC action is emitted. Comment syntaxes run before this one so comments (and any embedded CsScript) still take effect.
Not a comment: a comment is static metadata, block skip is a runtime toggle that can change per machine/operator setting.
CallFrame

One entry in Frames. Holds the caller-side information consumers need to “unwind” or “look back” — currently only the relative file path of the caller, used by SubProgramReturnSyntax on M99 P{seq} to locate the caller's N{seq} block.

CallStack

JSON-section data shape representing the active call-frame stack on a block — pushed by call-and-inline syntaxes (SubProgramCallSyntax for M98/M198, FanucMacroCallSyntax for G65, and FanucModalMacroSyntax's expansion phase for G66 implicit triggers) and popped by SubProgramReturnSyntax on M99. Every block between push and pop carries the section forward via ModalCarrySyntax; the caller's blocks before push and after pop carry the surrounding stack state (typically empty when running from the main file).

The section is wrapped in a JsonObject rather than exposed as a bare JsonArray so it fits ModalCarry's "deep-clone JsonObject" carry pattern — the array of frames lives inside Frames.

CannedCycle

Section key holder + concrete implementation for ICannedCycleDef.

Comment

Comment extracted from an NC block. Symbol identifies the comment style; Text holds the content without the symbol. Downstream syntaxes (e.g., CsScript) may further trim Text after extracting embedded markers.

CompoundMotion

Section key holder + concrete implementation for ICompoundMotionDef.

Coolant

Section key holder + concrete implementation for ICoolantDef.

CoordinateOffset

Work coordinate offset state written by IsoCoordinateOffsetSyntax. Property names are used as JSON keys via nameof.

Managed commands (ISO): G54, G55, G56, G57, G58, G59, G59.1–G59.9. Siemens: G54–G57 + G505–G599 (extended), G500 to cancel. Heidenhain: CYCL DEF 247 (Datum Preset) / CYCL DEF 7 (Datum Shift).

CsScript

Section-key holder for inline C# scripts attached to an NC block. Carries BeginScript (run before the block's acts) and EndScript (run after). Resolved by CsScriptBeginSemantic and CsScriptEndSemantic.

Dwell

Section key holder + concrete implementation for IDwellDef.

FanucGoto

Fanuc Custom Macro B GOTO record. Stamped on the host block by FanucGotoSyntax after the control-flow decision has been made; produced earlier by FanucGotoParsingSyntax as a parsing-stage sub-section (Parsing.FanucGoto) carrying the raw captured fields.

Two source forms map to the same shape:

  • GOTO <n> — unconditional jump. Condition is null.
  • IF [<bool-expr>] GOTO <n> — conditional jump. Condition holds the expression text from inside the brackets.

At parsing time N is a raw token from the source — it may be a literal ("100"), a variable reference ("#1"), or a bracketed expression ("#[#2+5]"). VariableEvaluatorSyntax substitutes a resolved literal back into the same field in the Evaluation bundle; FanucGotoSyntax then int.TryParses the final string to produce an int target.

Lifecycle of the condition fields.

FanucHpcc

Section data holder for IFanucHpccDef.

FanucIfThen

Fanuc Custom Macro B IF [<cond>] THEN <body> single-block conditional record. Stamped on the host block by FanucIfThenSyntax after the gate decision; produced earlier by FanucIfThenParsingSyntax as a parsing-stage sub-section (Parsing.FanucIfThen) carrying the raw captured fields plus an internal PendingAssignments sub-object harvested from the body text.

Spec: IF [bool-expr] THEN <stmt> executes <stmt> only when the condition is truthy. Unlike FanucGoto's conditional form there is no jump — the body affects the current block only, no source splice, no label scan, no iteration watchdog. The most common body shape is a single Custom Macro B assignment (#nnn = <expr>); multiple assignments in one body are also accepted and lifted together.

Condition is held as a string at parsing time so VariableEvaluatorSyntax's pass-2 tree walk can substitute it to a numeric JsonValue in place; the FanucIfThenSyntax tail then reads the resolved node polymorphically via the same ReadCondition shape used by FanucGotoSyntax.

FanucMacroCall

One-shot custom-macro-call record written by FanucMacroCallSyntax. Lives on both the G65 host block (the caller) and every inlined block of the macro body — so a cache-dump reader can land on any block inside the macro and immediately see “this block belongs to a G65 call of FileName with these argument bindings” without back-walking to find the host.

Each inlined block additionally carries the resolved Vars.Local #1-#26 bindings derived from Args (see FanucMacroArgumentMap), so LocalVariableLookup resolves macro args in a single-block lookup. Frame isolation is structural: caller blocks never have Vars.Local written, so after the macro body ends, the next caller block reads null for any #1-#26 without any explicit frame marker.

FanucModalMacro

Modal-macro-call record left by FanucModalMacroSyntax. Carries Fanuc G66 setup state forward block-to-block until cancelled by G67. The section is also written on the G67 block itself (with Term = “G67”) so cache dumps show the cancel edge; subsequent blocks then carry no section at all.

Per-block expansion of the modal call into an actual macro inline at every positioning move is not yet implemented — a FanucModalMacro--NotExpanded warning is emitted on the setup block to flag the simulation gap. The setup state itself is captured faithfully so external tooling can detect "this block sits inside a G66 modal" via the carried section.

FanucPathSmoothing

Section data holder for IFanucPathSmoothingDef.

FanucProgramNumber

Fanuc-family program identifier header that follows a TapeBoundary line — e.g. O1234 or <O1234>. Wrapper records the surface form so a parsed block can be emitted back to the original notation.

FanucWhileDo

Fanuc Custom Macro B WHILE/END bounded-loop record. Stamped on the host block by FanucWhileDoSyntax after the control-flow decision has been made; produced earlier by FanucWhileDoParsingSyntax as a parsing-stage sub-section (Parsing.FanucWhileDo) carrying the raw captured fields.

Two phrases map to the same shape, distinguished by Term:

  • WHILE [<bool-expr>] DO <m> — loop entry. Condition holds the expression text from inside the brackets at parsing time; substituted to a numeric JsonValue by VariableEvaluatorSyntax in place. ConditionEvaluated carries the host-level truthy outcome at stamp time.
  • END <m> — loop terminator. Carries no condition; unconditionally reverse-jumps to the matching WHILE block on every execution (re-evaluation of the entry condition is the WHILE block's responsibility).

LoopId is the spec-named "identification number for nesting" (the m in DO m / END m). Nested loops must use distinct LoopIds; matching is by exact value. Same-LoopId nesting is spec-undefined and not given special handling here.

Active loop frames are carried block-to-block via the top-level WhileFrames JSON section (a JsonObject keyed by LoopId-as-string, each entry recording the BeginLineNo of the WHILE block that opened that frame). Carried by ModalCarrySyntax as part of its Logic tracked keys (mutated in Evaluation, must reach Logic-stage consumers and downstream blocks unchanged).

Feedrate

Section key holder + concrete implementation for IFeedrateDef.

IncrementalWords

One-shot block-root record of the axis words this block programmed as increments — under modal G91, or through a per-word Incremental entry (Siemens IC(), klartext IX+/IC+) — valued with the programmed delta and shaped like the Parsing tree the word came from: a root word is a root key ({ “X”: 10 }, { “C”: 20 }), a word inside a nested record sits under that record's key ({ “G28”: { “X”: 0, “C”: 10 } }, { “CC”: { “X”: 0, “Y”: 11 } }).

Why it exists: the resolve is in place. IncrementalResolveSyntax rewrites the word inside Parsing to its absolute value and McAbcSyntax writes the accumulated angle into MachineCoordinateState, while the modal Positioning section must keep saying G91 for the next block's lookback. From that point on { "Positioning": G91, "Parsing": { "G28": { "X": 100 } } } is byte-identical to a program that wrote G90 G28 X100., and once the consumer has taken the word out of Parsing the programmed text is gone from the JSON altogether. This section is the trace that the word was an increment, and of what it was.

Written by IncrementalResolveSyntax (the words at its working paths — root, G28, the klartext CC record) and McAbcSyntax (root rotary words). Read by IncrementalResolveSyntax as an idempotency guard — a word already listed at its path is never converted twice, whatever the syntax list looks like (a project file whose serialized list carries two instances, a re-run over a frozen piece) — and by McAbcCyclicPathSyntax, where a listed rotary axis is a signed traverse that passes the shortest-path wrap literally, whichever spelling made it incremental. Not listed in any ModalCarrySyntax key set — it never carries to later blocks.

Not recorded: coded-position words (Siemens CIC() counts indexing positions, not an angle — its trace is the rewritten PositioningOverride entry), and the words the two consumers ahead of the shared resolve take for themselves (HeidenhainCannedCycleSyntax's cycle words, MachineCoordSelectSyntax's machine-frame words): both consume the word into their own section, so no absolute-looking copy is left in Parsing to be mistaken for a programmed absolute.

IndexNote

JSON-section data shape pairing a single-character address symbol (e.g. ‘O’, ‘N’) with its numeric index, used to annotate program/sequence numbers on an NC block.

IsoLocalCoordinateOffset

ISO/Fanuc-family local coordinate offset state (G52) written by IsoLocalCoordinateOffsetSyntax. Property names are used as JSON keys via nameof.

G52 X Y Z installs a local coordinate-system shift that stacks on top of the active G54-G59 work offset. The cancel mechanism is to write G52 X0 Y0 Z0 (or hit M30 / reset) — there is no separate G code for "cancel". The offset vector is therefore always modal: zero is a valid modal value, not a "disabled" state, so the section is recorded on every block.

Brand-specific kin: Siemens TRANS/ATRANS (which can also carry rotation/scale/mirror) and Heidenhain TRANS DATUM are handled by their own syntaxes and write to their own sections — they do not share this key, because their data shapes are richer.

MachineCoordinateState

Section key holder for IMachineCoordinateStateDef.

MacroFrame

Top-level integer marker stamped onto a SyntaxPiece's JSON to identify which call frame the block belongs to. Brand-agnostic by design — written by FanucMacroCallSyntax today, reusable by any future call-inlining syntax (Fanuc G66 modal expansion, Heidenhain LBL CALL, …) that needs local-variable isolation across call boundaries.

Semantics: the value is an opaque id; only equality matters. Two blocks with the same MacroFrame id share a call frame (locals visible across them via single-step carry); two blocks with different ids do not. The id 0 is reserved for the main program frame and is returned by Get(JsonObject) when the field is absent — so a plain caller block needs no stamp and yet compares distinct from any inlined frame.

Stored as a top-level JSON int (not an object section) so it stays lightweight on every inlined block. Decoupled from FanucMacroCall: that section is a diagnostic record of the call (what file, what args), while MacroFrame is the purely functional marker the local-variable I/O syntaxes consult.

MotionEvent

Section key holder + concrete implementation for IMotionEventDef.

MotionState

Section key holder + concrete implementation for IMotionStateDef.

PathSmoothing

Section key holder for IPathSmoothingDef.

PlaneSelect

Section key holder for IPlaneSelectDef.

PolarInterpolation

Inner-key constants of the PolarInterpolationState section.

Positioning

Section key holder + concrete implementation for IPositioningDef.

PositioningOverride

Per-word positioning override — a non-modal block-root section keyed by word name (axis words and the I/J/K interpolation parameters) whose values are Absolute / Incremental / Shortest / PositiveOnly / NegativeOnly, plus the coded-position (indexing axis) family CodedAbsolute / CodedIncremental / CodedShortest / CodedPositiveOnly / CodedNegativeOnly. Overrides the modal G90/G91 Positioning state (and, for I/J/K, the default incremental center reading) for the listed words on this block only.

Written by SiemensAcIcSyntax when a word carries one of the Siemens per-word coordinate function wrappers AC() / IC() / DC() / ACP() / ACN() or their coded-position counterparts CAC() / CIC() / CDC() / CACP() / CACN(), and by the Heidenhain L / C / CC / CYCL CALL POS parsers (through HeidenhainIncrementalAxisWordUtil) for the klartext I-prefixed incremental words IX+20 / IC+90 — always Incremental there, keyed by the plain axis letter. Not written for the CYCL DEF 7 datum-shift words: those are increments of the active shift, not of the tool position, and stay inside the cycle's own record. Consumed by IncrementalResolveSyntax (linear axes) and McAbcSyntax (rotary axes) — both treat every non-Incremental value as an absolute write, both follow the modal Positioning state for a word that has no entry, and both resolve a coded entry's indexing position number through CodedPositionUtil and rewrite the entry to its plain counterpart in place — by McAbcCyclicPathSyntax (the directional window for PositiveOnly / NegativeOnly and the non-modular-axis boundary warning; it never sees a coded value, and it does not read an Incremental entry — the literal pass-through follows the IncrementalWords record the rotary writer leaves), and by SiemensCircularMotionSyntax (absolute I/J/K center components) — and, ahead of the shared resolve, by two consumers that take the raw word before it can see it: HeidenhainCannedCycleSyntax (CYCL CALL POS words and the M99/M89 root words, resolved against the last programmed position on the spot) and MachineCoordSelectSyntax (a distance in the machine frame); words without an entry keep the default behavior unchanged. The section is not listed in any ModalCarry key set — it never carries to later blocks. It describes the programmed spelling; what the write stage actually converted, with the programmed delta, is the IncrementalWords record.

ProgramEnd

Section key holder for IProgramEndDef.

ProgramStop

Section key holder + concrete implementation for IProgramStopDef.

RadiusCompensation

Section key holder + concrete implementation for IRadiusCompensationDef.

RotaryWords

One-shot block-root record of the rotary axis words the block itself commanded — keyed by axis name (A/B/C), valued with the word as programmed: degrees for a plain word, the signed delta for a per-word incremental word (Siemens IC(), klartext IC+), the indexing position number for a coded-position word (CAC()/CIC()/…). The resolved absolute angle lives in MachineCoordinateState; this section only says which rotary axes this block spoke.

Written by McAbcSyntax when it consumes A/B/C from Parsing into MachineCoordinateState — and only for axes the IMachineAxisConfig declares rotary. After the PostLogic carry MachineCoordinateState is a modal record (key presence never means "commanded"), so consumers that must know whether this block carried a rotary word read this section instead: CannedCycleResolveSyntax (a rotary-only block under an active canned cycle is a modal repeat — Fanuc's any-axis-word rule, HardNc parity: the table indexes, then the cycle drills again) and WriteCompoundMotion(JsonObject, string, JsonArray, Vec3d) (the cycle's pre-positioning item carries the block's MC A/B/C so the physical rotary state matches the root record instead of lagging one block behind) and PivotTransformUtil (the tilted-feature-frame re-anchor on a rotary-word block). Not listed in any ModalCarrySyntax key set — it never carries to later blocks.

This section says which rotary words the block spoke, not how: an absolute C40. and an incremental C40. both record 40. Which of them were increments — and so which MC angles are accumulations rather than programmed absolutes — is the sibling IncrementalWords record, the one McAbcCyclicPathSyntax reads for its literal pass-through.

SpindleControl

Section key holder + concrete implementation for ISpindleControlDef.

SpindleOrientation

Section key holder + concrete implementation for ISpindleOrientationDef.

SpindleSpeed

Section key holder + concrete implementation for ISpindleSpeedDef.

SubProgramCall

Subprogram call record left by SubProgramCallSyntax on the M98 / M198 host block and on every inlined body block. The call itself emits no motion act; this section is bookkeeping so cache dumps and diagnostic readers can see "this block triggered (or sits inside) an inline of program P".

M98 and M198 share the exact same section shape. The difference between them is purely environmental — which folder the resolver looks in (SubProgramFolderConfig.InternalFolder vs ExternalFolder) — and that lives on the dependency, not in this JSON record.

SubProgramReturn

Subprogram return record left on the M99 host block by SubProgramReturnSyntax. Return blocks produce no motion acts; this section makes the consumed M99 visible in cache dumps and surfaces the M99 P{seq} jump decision.

TapeBoundary

Tape leader / trailer line — the literal % that historically marked the start and end of a punched paper-tape program. ISO-style controllers (Fanuc, Mazak, Syntec, Siemens) all preserve it as a file-level boundary marker. Distinct from a comment: the controller uses it as a tape/file delimiter, not as embedded operator text.

TiltTransform

Concrete class for ITiltTransformDef section serialization.

ToolHeightCompensation

Section key holder for IToolHeightCompensationDef.

Unit

Section key holder + concrete implementation for IUnitDef.

Vars

JSON section schema for per-block variable storage. Each sub-property names a sub-section that holds a { “#nnn”: value } dictionary keyed by Fanuc-style variable id.

The sub-sections partition the variable space by lifetime:

  • Local#1-#33, scope: macro call frame (pushed/popped by G65 / G66 / M99).
  • Volatile#100-#499, non-retained common; carries block-to-block, cleared by ProgramEndCleanSyntax on M02 / M30.
  • SystemControl#3000-#3999, controller-side system variables; offline-only round-trip record (real controller effects such as clock reset / alarm trigger / message pause are not simulated).

The property types are JsonObject rather than strongly-typed dictionaries because each sub-section's keys are dynamic Fanuc variable ids (#100, #5001, …) discovered at parse time, not a fixed schema. This class exists solely to give the section name and sub-keys stable nameof() targets — instances are never constructed at runtime.

Interfaces

IArcMotionDef

Arc motion data written by CircularMotionSyntax. Stored under the MotionEvent JSON section alongside IMotionEventDef properties. The arc plane is read from the modal PlaneSelect section via GetPlaneNormalDir(JsonObject) rather than cached on the event — same source of truth as IsoG68RotationSyntax.

ICannedCycleDef

Canned cycle modal state (Group 09). Captures which cycle is currently active, its return mode (G98/G99), and the resolved absolute parameter set used for modal lookback.

Written by CannedCycleResolveSyntax on every block that belongs to the canned-cycle group: cycle code present (G81/G82/G83/G73/G84/G74/G85/G86/G89/G76/G87), modal repeat (cycle still active, only coordinates given), or explicit cancel (G80).

Term = "G80" is the explicit-cancel sentinel used by FindPreviousActiveCycle(LazyLinkedListNode<SyntaxPiece>, string[]) to terminate modal lookback without ambiguity; regular blocks (e.g. G00 X.. Y..) simply omit the section entirely.

ICompoundMotionDef

Compound motion section definition for commands that produce multiple sub-operations (G28, G53.1, G81, G82, etc.). Contains a ItemsKey array resolved by Hi.NcParsers.Semantics.CompoundMotionSemanticUtil.

Item types (discriminated by key presence):

ICoolantDef

Coolant state (M07 mist / M08 flood / M09 off). Written by CoolantSyntax. Modal — persists until changed.

IsOn is the on/off convenience flag (true for M07 and M08, false for M09). Mode carries the abstract kind (Flood / Mist / Off) for consumers that need to distinguish flood vs mist.

IDwellDef

Dwell/pause section definition for use inside Sequence items. Resolved by Hi.NcParsers.Semantics.CompoundMotionSemanticUtil into ActDelay.

IFanucHpccDef

Block-root section recording a consumed bare Fanuc G05 P{n} (HPCC family selection), written by FanucPathSmoothingSyntax.

P is a function-selection code — not a quantity, dwell time, or look-ahead block count. P10000 enters high-precision contour control (HPCC: RISC-board multi-block look-ahead, pre-interpolation acceleration/deceleration, curvature-based feed clamping); P0 cancels it. P10001–P10999 call high-speed cycle machining: the control executes cycle data pre-registered in its variable area — real axis motion, so an offline run that ignores the call misses that machining (FanucPathSmoothingSyntax emits a Warning for it). Small P values select the high-speed remote buffer modes (binary DNC transfer; exact semantics vary by model). HPCC itself never alters the programmed coordinates, so P10000/P0 are recognized, intentionally not simulated, safe offline (the SiemensStopreSyntax pattern).

Deliberately separate from the modal PathSmoothing section (G05.1, IFanucPathSmoothingDef): this section is block-local like Stopre and is NOT tracked by ModalCarrySyntax — it exists for diagnostics and bidirectional NC-text reconstruction only.

IFanucPathSmoothingDef

Fanuc-specific path smoothing state written by FanucPathSmoothingSyntax.

Extends IPathSmoothingDef with the Fanuc G05.1 R argument (precision / smoothness level number, R1..R10 mapping to controller-internal tuning macro variables). Q is binary in current Fanuc firmware (Q0 disable / Q1 enable), so IsEnabled covers it directly — no raw Q field is stored.

JSON section key remains nameof(PathSmoothing) so generic readers (cache dumps, modal carry, UI) can cast to IPathSmoothingDef across all controller brands; brand-specific readers cast to IFanucPathSmoothingDef for the extra fields.

IFeedrateDef

Feedrate state written by FeedrateSyntax. Property names are used as JSON keys via nameof.

ISO standard: F command + G94 (per minute) / G95 (per revolution). Supported by all major CNC brands.

IFlagsDef

JSON section schema describing the modal/non-modal flags that take effect on an NC block. Each entry in Flags is a brand-specific keyword recognized by the soft-NC runtime.

IMachineCoordinateStateDef

Modal machine-coordinate state — absolute six-axis machine position after the block has executed. Written on every block by motion-related LogicSyntaxs (McAbcSyntax, McAbcXyzFallbackSyntax, McXyzSyntax, MachineCoordSelectSyntax, G53p1RotaryPositionSyntax, ReferenceReturnSyntax); seeded on the init block by HomeMcInitializer; carried across non-motion blocks — and per-key completed on partially-written blocks (an XYZ-only motion block receives the carried modal rotary values) — by ModalCarrySyntax.

Only configured axes appear as keys (X/Y/Z/A/B/C). Non-existent axes (e.g., A/B/C on a 3-axis machine) are omitted rather than written as NaN sentinels.

After the PostLogic carry the section is a MODAL record: key presence means "state known", never "this block commanded the axis". Consumers needing "commanded" must read the block's Parsing words, the one-shot RotaryWords record (the rotary words this block itself spoke, written by McAbcSyntax), or compare values against the previous block (see LinearMotionUtil.HasRotaryMotion). The only presence-as-commanded carve-out is CompoundMotion.Items[*] item-level sections, which the carry never touches.

IMotionEventDef

One-shot motion event — present on every block whose source programmed a motion command, regardless of whether the resulting displacement is non-zero. A redundant G01 X10 on a block already at X10 still gets a MotionEvent; the motion semantics (McLinearMotionSemantic, McArcMotionSemantic, ClLinearMcMotionSemantic) then early-return on distance <= 0 and emit no IAct. NOT carried forward across blocks.

Reason for the "programmed, not displaced" definition: Fanuc G66 modal macro fires once per programmed motion command (per Fanuc spec — no distance gate), so FanucModalMacroSyntax.Expansion uses MotionEvent presence as its trigger. Suppressing the section on zero-distance moves would silently change G66 behaviour. The modal sibling MotionState separately latches the Group-01 mode for readers that only need to know "what G-code is active".

Property names are used as JSON keys via nameof.
IMotionStateDef

Modal motion state — Group 01 G-code mode (G00 / G01 / G02 / G03 ...). Written on every block by LinearMotionSyntax / CircularMotionSyntax; carried across non-motion blocks by ModalCarrySyntax. Property names are used as JSON keys via nameof.

Unlike sibling modal sections (Unit, PlaneSelect, Positioning) which carry both a brand-specific Term and a brand-neutral conventional field, MotionState intentionally keeps only Term: the brand-neutral semantic ("what kind of motion happened") lives on the sibling one-shot MotionEvent (Form = McLinear / McArc / ClLinear / ClArc). State here is purely the modal latch of the last Group-01 G-code so downstream FindPrevious* can resume motion-mode bookkeeping.

IParsingDef

JSON section schema carrying the raw, brand-specific parsing trace for an NC block. The Parsing node holds intermediate parser output used by downstream syntaxes and diagnostics.

IPathSmoothingDef

Path smoothing state. The base interface is brand-agnostic; controller brands extend it with their own argument fields (e.g. IFanucPathSmoothingDef for Fanuc G05.1 R precision-level). Fanuc-flavour writes are produced by FanucPathSmoothingSyntax.

ISO/Fanuc G05.1 Q1 (enable) / G05.1 Q0 (disable): high-precision contour control / AICC / Nano Smoothing. Controller-internal interpolation black box — simulation records the state but does not alter the tool path.

IPlaneSelectDef

Active plane selection state written by PlaneSelectSyntax. Property names are used as JSON keys via nameof.

ISO: G17/G18/G19. Heidenhain: implicit from L/CC syntax. Term carries the brand-specific G-code; Plane stores the conventional, brand-neutral axis-pair name (XY/ZX/YZ).

IPolarInterpolationDef

JSON section schemas for Fanuc Polar Coordinate Interpolation (G12.1/G13.1). Property names are used as JSON keys via nameof.

PolarInterpolationState is the modal valve: its presence on a block means polar interpolation is active there. It is written by PolarInterpolationSyntax on the G12.1 block and re-materialized onto every following block until a G13.1 block ends the mode (single-step lookback carry, same pattern as PositioningSyntax — not registered on ModalCarrySyntax).

ProgramPolarRxcz is the per-block polar position, relative to the G12.1 anchor (InitRxcz). Rxcz axes: X = radius-direction linear axis in mm (the NC word X is a diameter and is halved on parse), Y = hypothetical rotary-substitute axis in mm, Z = real Z in mm. The absolute (rotation-center-origin) position used by the math is InitRxcz + ProgramPolarRxcz, mirroring HardNc PolarEntry.CentralProgramPolarRxcz.

IPositioningDef

Modal positioning state — ISO Group 03 (G90 absolute / G91 incremental). Written by PositioningSyntax, consumed by IncrementalResolveSyntax (linear words), McAbcSyntax (rotary words: G91 accumulates anchor + delta) and McAbcCyclicPathSyntax (the wrap pass keeps the axes the IncrementalWords record lists literal), canned cycle syntaxes, and MachineCoordSelectSyntax. A per-word PositioningOverride entry beats this modal state for its word. The section stays G91 after the consumers have rewritten the block's words to absolutes (the next block's lookback needs it); the words that were converted are listed in the one-shot IncrementalWords record. Property names are used as JSON keys via nameof.

Term is the brand-specific G-code (Fanuc/ISO G90/G91); Mode is the conventional, brand-neutral name (Absolute / Incremental).

IProgramEndDef

Program end marker (M02/M30). Written by ProgramEndSyntax. Other syntaxes (e.g. IsoLocalCoordinateOffsetSyntax) read this section to reset modal state instead of detecting M30 directly.

IProgramStopDef

Program-stop marker (M00 unconditional / M01 optional). Written by ProgramStopSyntax on each block that carries an M00/M01 flag. Non-modal: the section appears only on the exact block where the stop code is present.

Distinct from IProgramEndDef (M02/M30, end of program).

M00 halts execution unconditionally; the operator must press Cycle Start to resume. M01 is an optional stop gated by the operator's "Optional Stop" panel switch — ignored when the switch is off. This parsing-layer section records the NC intent; runtime / semantic layers decide whether to actually pause.

IProgramXyzDef

JSON section schema carrying the program-coordinate position commanded on the current block. Written by ProgramXyzSyntax before the ProgramToMcTransform chain composes it into machine coordinates.

IRadiusCompensationDef

Radius compensation state written by RadiusCompensationSyntax. Property names are used as JSON keys via nameof.

Managed commands (ISO): G41 (left), G42 (right), G40 (cancel). Heidenhain Klartext maps RL → G41, RR → G42, R0 → G40. When active, the tool path is offset perpendicular to the programmed path by Radius_mm; Side determines left vs right. The root ProgramXyz retains the user-programmed position; MachineCoordinate is overwritten to reflect the compensated path.

ISpindleControlDef

Spindle control item for use inside ItemsKey arrays. Resolved by Hi.NcParsers.Semantics.CompoundMotionSemanticUtil into ActSpindleDirection.

ISpindleOrientationDef

Oriented spindle stop item for use inside ItemsKey arrays. Commands the spindle to stop at a specific angular position (OSS). Resolved by Hi.NcParsers.Semantics.CompoundMotionSemanticUtil into ActSpindleOrientation.

ISpindleSpeedDef

Spindle speed and direction state written by SpindleSpeedSyntax. Property names are used as JSON keys via nameof.

ISO: S command for speed, M03/M04/M05 for direction. Heidenhain: M3/M4/M5. Siemens: M3/M4/M5 or SPOS. Direction is stored as the conventional SpindleDirection enum name (CW/CCW/STOP), not as brand-specific M-codes.

ITiltTransformDef

Tilt transform state written by tilt transform syntaxes. Property names are used as JSON keys via nameof.

Managed commands (ISO/Fanuc): G68 (2D rotation), G68.2 (tilted work plane), G69 (cancel). Siemens equivalent: CYCLE800, ROT/AROT (handled by separate syntax). Heidenhain equivalent: PLANE SPATIAL / PLANE RESET (handled by separate syntax).

IToolHeightCompensationDef

Tool height compensation state written by ToolHeightOffsetSyntax. Property names are used as JSON keys via nameof. The JSON section can be deserialized to an instance implementing this interface.

Managed commands (ISO/Fanuc): G43, G44, G49. Fanuc extension: G43.4 (TCPM — parsed only in Fanuc syntax list). Siemens equivalent: TRAFOOF/TRAORI (handled by separate syntax). Heidenhain equivalent: TOOL CALL / M128/M129 (handled by separate syntax).

ITransformationDef

Chain of named ProgramXyz → MachineCoordinate transformation entries. Stored as a JsonArray of entries, each with “Source”, “Kind”, and “Mat4d” keys. Each contributing INcSyntax adds or replaces its own entry by source name. GetComposedTransform(JsonObject) composes entries in order: McXyz = ProgramXyz * T[0] * T[1] * ... * T[n].

Kind contour-validity classification. Each entry is either:

  • "Static" — the Mat4d is valid for any point along the contour. Tilt, coord-offset, and the kinematic pivot in non-RTCP / rotary-stable blocks are all Static.
  • "Dynamic" — the Mat4d is a block-endpoint snapshot of a rotary-state-dependent transform (RTCP rotary-dynamic). Composition still yields a correct endpoint MC, but the matrix is not contour-valid: intermediate CL-point positions cannot be derived by applying it to an interpolated ProgramXyz. The semantic layer (ClLinearMcMotionSemantic) handles per-step IK separately.
Use HasDynamicEntry(JsonObject) to detect the presence of any Dynamic entry on this block.
IUnitDef

Unit-system state (ISO Group 06: G20 inch / G21 metric). Written by UnitModeSyntax. Modal.

HiNC's NC pipeline works exclusively in millimetres. G21 is therefore a no-op confirmation of the default; G20 is reported as an Unsupported Error and callers are expected to pre-convert the NC program to metric before loading.

IUnparsedTextDef

JSON section schema carrying the residual block text that was not consumed by any registered syntax. Used for diagnostics and round-trip preservation.