Class SyntaxPiece
One NC block's source line paired with its parsed JSON payload during soft-NC processing.
public class SyntaxPiece : ISentenceCarrier, IGetSentence, ISentenceIndexed
- Inheritance
-
SyntaxPiece
- Implements
- Inherited Members
- Extension Methods
Remarks
The design pattern of Sentence and JsonObject are one-one mapping.
JSON value type convention: Prefer base types (double, int) over string for numeric values in JsonObject. This applies to both parsing syntaxes and logic syntaxes. Strings should only be used when the value is genuinely textual (e.g., macro variable references like "#1", "Q2", coordinate IDs like "G54") or when the value cannot be parsed to a number. Use FloatTagValueSyntax, IntegerTagValueSyntax, or FloatParamPrefixes / IntParamPrefixes to store typed values at parse time.
Constructors
SyntaxPiece(Sentence, JsonObject, int)
Creates a piece binding sentence to jsonObject with its sentenceIndex, the block's identity on its NC pipeline (SentenceIndex).
public SyntaxPiece(Sentence sentence, JsonObject jsonObject, int sentenceIndex)
Parameters
sentenceSentencejsonObjectJsonObjectsentenceIndexint
Properties
IsFrozen
True when the parse result is held as a frozen UTF-8 snapshot instead of a live JsonObject graph — see Freeze().
public bool IsFrozen { get; }
Property Value
JsonObject
Structured parse result built by syntax passes.
While the piece is live (the default), this is the one mutable JsonObject every pipeline stage reads and writes. After Freeze(), the getter re-parses the frozen UTF-8 snapshot and returns a FRESH object on every call — treat it as a read-only snapshot: mutations land on the transient copy and are lost, and two calls return different object references. All mutating consumers run before the freeze boundary (see Freeze()), so downstream readers (NC optimization, writeback composition, GUI JSON panels) see identical content either way. Setting this property replaces the live object and discards any frozen snapshot.
public JsonObject JsonObject { get; set; }
Property Value
PlayOrdinal
Internal Use Only. The block's ordinal among the blocks played on the session's NC pipeline since it was built (0 again after Reset(): a power reset, a runner switch, a runtime reset), taken where PlayStepIndex is, a nested run's blocks in the order they played (AllocateBlockPlayOrdinal()): the tie-break of PlayStepIndex between blocks that built no step. -1 until the block plays on a hosted session. Pipeline state, not serialized.
public int PlayOrdinal { get; set; }
Property Value
PlayStepIndex
Internal Use Only. Where this block's own acts began playing: the strip's count on the play thread – the index the next strip position takes – as the block's first act that is not an embedded script arrived (its line end, when it has none), recorded by RunNcLines(INcRunner, string, IEnumerable<string>, CancellationToken) before that entry's handlers run: the blocks of a nested run the block's begin script played come before it, those of a run its end script plays after it. -1 until the block plays on a hosted session. The NC optimization orders the blocks that built no step by it (NcOptPieceClassifier). Pipeline state, not serialized.
public int PlayStepIndex { get; set; }
Property Value
Sentence
Indexed source line and block text for this piece.
public Sentence Sentence { get; set; }
Property Value
SentenceIndex
0-based identity of this block on the session's NC pipeline: unique among
the pieces the pipeline built since it was built afresh, and numbered from
0 again each time it is (a power reset, a runtime reset, a switch of the
controller brand or preset, a session begun again), so the steps of a
strip kept across such a reset carry two numberings.
Stamped at piece construction time, where the runner wraps a sentence
into its piece, from the session's
SentenceIndexCounterDependency:
each piece allocates the next counter value as the lazy pipeline
materializes it, so values increase in materialization (pull) order —
subprogram / macro bodies inlined by SubProgramCallSyntax and
friends interleave correctly between lazily read host blocks,
including nested calls. Useful as a cross-process identity key
(messages, ClStripPos, MachiningStep) — unlike the
(FileIndex, LineIndex) source position, it tells apart every pass
of a block that plays more than once (a subprogram called twice, the
rounds of a loop).
Pull order is not play order, in two shapes. A body inlined from an
eagerly numbered slice (eager label scans, LabelScanUtil /
RewindToLine, number the whole re-segmented file at once) takes
its values when it is pulled, after the whole slice, so the values step
back down at the body's return. A nested run (a file an NC-embedded
script plays inside the play) is appended behind the remainder of the
outer file, which the pipeline drains first, so its blocks are numbered
after outer blocks that play after them. The play order is the strip's,
and for a block that built no step PlayStepIndex and
PlayOrdinal; the NC optimization takes this value as
identity only. Nor are the values contiguous per file: the eager label
scans discard the pre-label prefix, leaving gaps.
Never negative — -1 stays reserved as the "not in pipeline"
sentinel on downstream carriers. When the counter dependency is
absent (legacy XML preset), numbering falls back to the caller's
contiguous begin-index sequence, which can double-book across
inline boundaries.
Required at construction: the index is identity, not optional metadata. Read-only after construction; the pipeline guarantees one stamping per piece at the wrapping chokepoint.
public int SentenceIndex { get; }
Property Value
Methods
Freeze()
Replaces the live JsonObject graph with its compact UTF-8 serialization (~13× smaller live-memory footprint per retained piece), keeping the piece readable through the JsonObject getter via on-demand re-parse. Uses CompactNanOptions — the exact leaf encoding of ToLeafCompactJsonString(JsonNode, JsonSerializerOptions) — so the JSON projection of a frozen piece is byte-identical to the live one (NaN / Infinity serialize as quoted literal strings; explicit nulls survive).
Call only after every mutating consumer of this piece has run — the
session pipeline freezes a piece once it left the executing window
(its semantics completed plus a lag margin; see
MachiningProcs.NcRunnerSessionState). Idempotent; a piece with a
null JsonObject stays null. Thread-safe against
concurrent readers: they observe either the live graph or the frozen
snapshot, never a torn state.
public void Freeze()
GetSentence()
Returns the source Sentence carried by this object.
public Sentence GetSentence()
Returns
ToString()
Serialize with Hi.NcParsers.Syntaxs.NcSyntaxUtil.Options to support NaN/Infinity.
public override string ToString()