Table of Contents

Class NcPatchWriter

Namespace
Hi.NcParsers.NcWriteback
Assembly
HiMech.dll

Patch-mode INcPieceConverter: re-emits each piece's verbatim BlockText, applying only the anchored token edits registered in EditsBySentenceIndex. An untouched piece is reproduced byte-identically; an edited piece changes only in the addressed token spans — this is the conservative text-regeneration strategy the NC optimizer output path requires (same dialect as the source; dispatch rule per INcPieceConverter: source dialect must equal TargetBrand). Stage one of the two-stage writeback pattern: each source piece converts to exactly one destination piece (1:1 NcPieceMap) whose block text is the patched draft; stage two is ToLines(IEnumerable<SyntaxPiece>), which also splits a multi-line block back into its original lines.

The converter reproduces the executed piece stream as-is (expansion semantics): a sentence replayed by a loop or subprogram call appears once per execution, exactly like the final pipeline layer. Line-sequence-equal round-trips therefore hold for linear programs (byte-level fidelity — newline style, EOF newline, encoding — is owned by the serialization layer that writes the lines); for call/loop programs the output is the expanded execution sequence, not the source file.

Edits inside comments never happen: CommentSpanProvider (default GetFanucCommentSpans(string)) masks comment spans, so a literal like (F100 TEST) is never mistaken for an F word. A tag whose value is a variable or bracket expression is refused with Writeback-Patch--VariableValue instead of rewritten.

public class NcPatchWriter : INcPieceConverter
Inheritance
NcPatchWriter
Implements
Inherited Members
Extension Methods

Constructors

NcPatchWriter(string)

Creates a patch writer for the given dialect (default Fanuc). The brand selects the parser-matching defaults for VarPrefix, CommentSpanProvider, and KeywordValues. P1 acceptance covers the Fanuc family; Siemens address=value words (X=100, F=R103) are outside the patch value grammar and are not yet editable (P3).

public NcPatchWriter(string targetBrand = "Fanuc")

Parameters

targetBrand string

Properties

CommentSpanProvider

Computes the comment spans an edit must never touch. The constructor pairs it with the brand (GetFanucCommentSpans(string) or GetHeidenhainCommentSpans(string)).

public Func<string, IReadOnlyList<(int Start, int Length)>> CommentSpanProvider { get; set; }

Property Value

Func<string, IReadOnlyList<(int Start, int Length)>>

CoordinateFormat

Format for coordinate words (X/Y/Z/I/J/K and rotary degrees). Trailing zeros after the decimal point are trimmed, keeping the dot (HardNc convention: -50.2500-50.25, 10.000010.).

public string CoordinateFormat { get; set; }

Property Value

string

EditsBySentenceIndex

Registered edits, keyed by SentenceIndex (the execution-order identity — with a SentenceIndexCounterDependency in the pipeline, as all built-in brand presets have, each execution instance under loops has its own index, so an edit addresses one instance; a legacy counter-less preset can double-book indices across inline boundaries, and one edit then hits every piece sharing the index — see SentenceIndex). An edit whose index matches no piece in the stream is reported as Writeback-Patch–EditUnmatched after the stream drains.

public Dictionary<int, List<NcTagEdit>> EditsBySentenceIndex { get; }

Property Value

Dictionary<int, List<NcTagEdit>>

FeedrateFormat

Format for the F word (mm/min).

public string FeedrateFormat { get; set; }

Property Value

string

KeywordValues

Dialect keywords that can stand where a tag's number would be (Heidenhain FMAX/FAUTO); a keyword-valued tag is refused with Writeback-Patch–KeywordValue instead of being treated as absent. Null for dialects without keyword values.

public IReadOnlyList<string> KeywordValues { get; set; }

Property Value

IReadOnlyList<string>

TargetBrand

Target dialect token; one of the CncBrandDependency brand constants.

public string TargetBrand { get; }

Property Value

string

VarPrefix

Variable index prefix used to recognize (and refuse) variable values, e.g. Fanuc #, Heidenhain Q.

public string VarPrefix { get; set; }

Property Value

string

Methods

AddEdit(int, string, double, string)

Registers a tag edit for the piece with the given SentenceIndex.

public void AddEdit(int sentenceIndex, string tag, double value, string format = null)

Parameters

sentenceIndex int
tag string
value double
format string

Convert(IEnumerable<SyntaxPiece>, NcDstPieceFactory, NcDiagnosticProgress)

Converts the executed source piece stream into the destination piece stream plus the src↔dst map. Pieces must come from a single source file, in execution order. Problems are reported through conversionProgress with the source piece as the sentence anchor.

public NcConversion Convert(IEnumerable<SyntaxPiece> syntaxPieces, NcDstPieceFactory dstPieceFactory, NcDiagnosticProgress conversionProgress)

Parameters

syntaxPieces IEnumerable<SyntaxPiece>

Finished source pieces (final pipeline layer), execution order.

dstPieceFactory NcDstPieceFactory

Factory stamping identity (file path / file index / fresh SentenceIndex) onto the destination pieces.

conversionProgress NcDiagnosticProgress

Diagnostic sink for the manipulation scenario (conversion/optimization) — keep it separate from the NC play diagnostic home; may be null.

Returns

NcConversion

The destination stream and mapping; never null.

GetFanucCommentSpans(string)

Fanuc-family comment spans, mirroring the parser's consumption (QuoteCommentSyntax/HardNcUtil.GrabComment): a block that starts with % at column 0 is comment for its whole first line (the parser's ^%.*$ is string-anchored); otherwise the greedy first-(-to-last-) span of each line is comment (the parser's greedy regex treats (a) X1 (b) as one comment, so the patch side must too).

public static IReadOnlyList<(int Start, int Length)> GetFanucCommentSpans(string blockText)

Parameters

blockText string

Returns

IReadOnlyList<(int Start, int Length)>

GetHeidenhainCommentSpans(string)

Heidenhain comment spans, mirroring the parser's registration order (HeidenhainSyntaxUtil): the earliest // runs to the end of the line, the greedy paren span is comment, and the earliest ; outside double quotes runs to the end of the line. The union of the three protects every region a comment syntax would consume.

public static IReadOnlyList<(int Start, int Length)> GetHeidenhainCommentSpans(string blockText)

Parameters

blockText string

Returns

IReadOnlyList<(int Start, int Length)>