deploy webservice static-file routing for docsite folder URLs, per-instance step-cache db, and constant-height panel title bars.

This commit is contained in:
2026-08-27 14:51:37 +08:00
parent 1fc510af5e
commit 2a98ae7556
1468 changed files with 182837 additions and 18888 deletions
@@ -0,0 +1,332 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Namespace Hi.NcParsers.EvaluationSyntaxs.Heidenhain | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Namespace Hi.NcParsers.EvaluationSyntaxs.Heidenhain | HiAPI-C# 2025 ">
<link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css">
<meta name="docfx:navrel" content="../toc.html">
<meta name="docfx:tocrel" content="toc.html">
<meta name="docfx:rel" content="../">
<meta name="loc:inThisArticle" content="In this article">
<meta name="loc:searchResultsCount" content="{count} results for &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<meta name="loc:tocFilter" content="Filter by title">
<meta name="loc:nextArticle" content="Next">
<meta name="loc:prevArticle" content="Previous">
<meta name="loc:themeLight" content="Light">
<meta name="loc:themeDark" content="Dark">
<meta name="loc:themeAuto" content="Auto">
<meta name="loc:changeTheme" content="Change theme">
<meta name="loc:copy" content="Copy">
<meta name="loc:downloadPdf" content="Download PDF">
<script type="module" src="./../public/docfx.min.js"></script>
<script>
const theme = localStorage.getItem('theme') || 'auto'
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
</script>
</head>
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="ManagedReference">
<header class="bg-body border-bottom">
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
<div class="container-xxl flex-nowrap">
<a class="navbar-brand" href="../index.html">
<img id="logo" class="svg" src="../img/HiAPI.logo.png" alt="">
</a>
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
<i class="bi bi-three-dots"></i>
</button>
<div class="collapse navbar-collapse" id="navpanel">
<div id="navbar">
<form class="search" role="search" id="search">
<i class="bi bi-search"></i>
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
</form>
</div>
</div>
</div>
</nav>
</header>
<main class="container-xxl">
<div class="toc-offcanvas">
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<nav class="toc" id="toc"></nav>
</div>
</div>
</div>
<div class="content">
<div class="actionbar">
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
<i class="bi bi-list"></i>
</button>
<nav id="breadcrumb"></nav>
</div>
<article data-uid="Hi.NcParsers.EvaluationSyntaxs.Heidenhain">
<h1 id="Hi_NcParsers_EvaluationSyntaxs_Heidenhain" data-uid="Hi.NcParsers.EvaluationSyntaxs.Heidenhain" class="text-break">Namespace Hi.NcParsers.EvaluationSyntaxs.Heidenhain</h1>
<div class="markdown level0 summary"></div>
<div class="markdown level0 conceptual"></div>
<div class="markdown level0 remarks"></div>
<h3 id="classes">
Classes
</h3>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainExpressionParser.html">HeidenhainExpressionParser</a></dt>
<dd><p>Recursive-descent parser for Heidenhain klartext FN value expressions.
Produces the same <a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Evaluation.NcExpr.html">NcExpr</a> AST as the Fanuc
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Evaluation.NcExpressionParser.html">NcExpressionParser</a> so <a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Evaluation.NcExpressionEvaluator.html">NcExpressionEvaluator</a>
is reused unchanged. Pure: no variable lookup, no evaluation.</p>
<p>Grammar (lowest precedence at top):</p>
<pre><code class="lang-csharp">expr := add-expr
add-expr := term (('+' | '-') term)*
term := factor (('*' | '/' | 'DIV') factor)*
factor := ('+' | '-')? primary
primary := number
| '(' expr ')'
| 'Q' digits | 'QR' digits | 'QL' digits | 'QS' digits
| func primary → prefix form "SQRT 4" (FN 5)
| func '(' arglist ')' → paren form "SQRT(Q2)"</code></pre>
<p>
Dialect notes: Q-family tokens are canonicalised to uppercase
(<code>q1</code> → <code>Q1</code>) so <code>Parsing.Assignments</code> keys, table
lookups and same-block references agree. (Caveat shared with the
Siemens R canonicalisation: a lowercase-captured Assignments key
keeps its raw spelling in the evaluator's same-block dictionary, so
a later same-block reference resolves to the pre-block value instead
— klartext posts emit uppercase, corpus-zero.) <code>DIV</code> is the FN 4
division spelling (<code>FN 4: Q4 = +8 DIV +Q2</code>) and maps onto the
shared divide operator. Function names are limited to the klartext
math vocabulary (<code>SQRT SIN COS TAN ASIN ACOS ATAN ABS INT FRAC SGN
NEG LN LOG EXP</code>); <code>INT</code> normalises to the evaluator's
<code>FIX</code> (truncate toward zero), names the shared evaluator lacks
(<code>FRAC</code>/<code>SGN</code>/<code>NEG</code>/<code>LOG</code>) parse fine and fail
soft at evaluation. Any other identifier is a parse error — klartext
has no named variables, and rejecting bare words keeps the
evaluator's Parsing-tree pass from touching non-expression strings
(<code>MM</code>, <code>MAX</code>, tool-axis letters). Comparison/logical
operators are deliberately absent: FN 9–12 jump conditions are
pre-normalised by
<a class="xref" href="Hi.NcParsers.ParsingSyntaxs.Heidenhain.HeidenhainGotoParsingSyntax.html">HeidenhainGotoParsingSyntax</a>
into separate value operands plus a shared comparison word — never
parsed here.
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainGotoSyntax.html">HeidenhainGotoSyntax</a></dt>
<dd><p>Resolves Heidenhain FN 9–12 conditional jumps — the
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Fanuc.FanucGotoSyntax.html">FanucGotoSyntax</a> pattern with klartext <code>LBL</code>
targets and a structural condition. Triggered by
<code>Parsing.HeidenhainGoto</code> (written by
<a class="xref" href="Hi.NcParsers.ParsingSyntaxs.Heidenhain.HeidenhainGotoParsingSyntax.html">HeidenhainGotoParsingSyntax</a>); decides whether to fire,
and on fire calls
<a class="xref" href="Hi.Common.Collections.LazyLinkedList-1.html#Hi_Common_Collections_LazyLinkedList_1_ReplaceSource_System_Collections_Generic_IEnumerable__0__">ReplaceSource(IEnumerable&lt;T&gt;)</a> on
<code>layers[0]</code> with the re-segmented file content starting at the
target label line (inclusive — the definition marker is consumed by
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainSubProgramReturnSyntax.html">HeidenhainSubProgramReturnSyntax</a> downstream).</p>
<p>
The condition is compared here, not by the expression grammar: the
parsing owner pre-normalised the statement into two value operands
plus a shared comparison word (the P2 decision that keeps the
Heidenhain dialect free of comparison/logical layers). Each operand is
read polymorphically — numeric (typed at capture for literals, or
substituted in place by <a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.VariableEvaluatorSyntax.html">VariableEvaluatorSyntax</a> for
resolved Q references) fires the comparison; a still-string operand
means unresolved (the FN 18 SYSREAD target staying vacant is the
designed source) and the jump warns
<code>HeidenhainGoto--ConditionNotEvaluated</code> and falls through — no
fabricated values, both endings stay fail-soft.
</p>
<p>
The label scan is whole-file first-match through the runner's own
segmenter (<a class="xref" href="Hi.NcParsers.Dependencys.SystemWired.SegmenterDependency.html">SegmenterDependency</a>) with the P4 call-path
probe stack — klartext has no direction mnemonic and a TNC label is
unique per program, so the anchored directional overloads would add a
distinction the language does not have. Numeric labels canonicalize
(<code>"01"</code> ≡ <code>1</code>); <code>GOTO LBL 0</code> targets the
end-of-subprogram sentinel and is refused
(<code>HeidenhainGoto--Lbl0Target</code>, the
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainSubProgramCallSyntax.html">HeidenhainSubProgramCallSyntax</a> precedent). Jumps hosted
inside a P4 inlined body (<code>CALL LBL</code>/<code>CALL PGM</code> splice or a
<code>REP</code> section pass) are recognized but not simulated — the
redirect would discard the pending inline tail
(<code>HeidenhainGoto--InlinedContextUnsupported</code>, the Siemens P5
guard).
</p>
<p>
Pipeline placement: tail of the Heidenhain Evaluation bundle, after
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.VariableEvaluatorSyntax.html">VariableEvaluatorSyntax</a> (operand substitution) and the Q
reader. The <a class="xref" href="Hi.NcParsers.Dependencys.Heidenhain.HeidenhainGotoIterationDependency.html">HeidenhainGotoIterationDependency</a> watchdog
caps fired jumps per <code>(file, label)</code>; a missing watchdog disables
the cap (Fanuc parity).
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainQParameterReadingSyntax.html">HeidenhainQParameterReadingSyntax</a></dt>
<dd><p>Obtains values for Heidenhain Q parameters by consuming literal numeric
assignments from <code>Parsing.Assignments.Qn</code>/<code>QRn</code> and routing
them by id range — one reader for the single <code>Q</code> key shape, range
routing inside (the Heidenhain analogue of the Fanuc range-routed reader
trio):</p>
<ul><li><code>Q0-Q99</code> → <a class="xref" href="Hi.NcParsers.Dependencys.Heidenhain.HeidenhainQParameterTable.html">HeidenhainQParameterTable</a> free range
(hincproj-persisted; the table is the single source of truth — no JSON
mirror).</li><li><code>QRn</code> → the same table's permanent QR store.</li><li><code>Q100-Q199</code> → controller-written system parameters: the write
is consumed but not applied, with a
<code>HeidenhainQ--SystemReadOnly</code> warning (no fabricated values).</li><li><code>Q200+</code> → volatile range: dict-merged into
<code>Vars.Volatile</code> with canonical <code>Q</code>+id keys, carried
block-to-block like the Fanuc <a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.VolatileVariableReadingSyntax.html">VolatileVariableReadingSyntax</a>;
cleared at program end by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.ProgramEndCleanSyntax.html">ProgramEndCleanSyntax</a>.</li></ul>
<p>
The carry of the previous block's <code>Vars.Volatile</code> happens on every
block regardless of assignments, so the single-step traceback contract of
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainVolatileQLookup.html">HeidenhainVolatileQLookup</a> holds.
</p>
<p>
Only literal numeric RHS values are consumed
(<code>Q1 = 5000</code> ✓; <code>Q1 = Q1*.75</code> ✗). Non-literal RHS entries are
left untouched in <code>Parsing.Assignments</code>;
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.VariableEvaluatorSyntax.html">VariableEvaluatorSyntax</a> resolves them to literals earlier
on the same block, so by the time this syntax runs, every evaluable RHS
is literal. The two syntaxes are decoupled.
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainSubProgramCallSyntax.html">HeidenhainSubProgramCallSyntax</a></dt>
<dd><p>Consumes the <code>Parsing.CALL</code> record captured by
<a class="xref" href="Hi.NcParsers.ParsingSyntaxs.Heidenhain.HeidenhainCallSyntax.html">HeidenhainCallSyntax</a> and executes the three klartext
call mechanisms over the shared M98 inline machinery:</p>
<ul><li><b><code>CALL LBL n</code> / <code>CALL LBL "name"</code></b> (subprogram):
the host file is re-segmented through the runner's own segmenter
(<a class="xref" href="Hi.NcParsers.Dependencys.SystemWired.SegmenterDependency.html">SegmenterDependency</a>), scanned for the matching
<code>LBL</code> definition with <a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.LabelScanUtil.html">LabelScanUtil</a> and the
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainSubProgramCallSyntax.html#Hi_NcParsers_EvaluationSyntaxs_Heidenhain_HeidenhainSubProgramCallSyntax_LabelProbeSyntaxes">LabelProbeSyntaxes</a>, truncated at the first following
<code>LBL 0</code> (inclusive — its consumption pops the frame), and
prepended into <code>layers[0]</code> with a pushed <a class="xref" href="Hi.NcParsers.Keywords.CallStack.html">CallStack</a>
frame. A subprogram without <code>LBL 0</code> is a structured safe-skip
(inlining to EOF would double-execute the file tail).</li><li><b><code>CALL LBL n REP m</code></b> (program-section repeat — TNC
semantics: the section from <code>LBL n</code> up to, not including, the
call line runs m extra times): m fresh re-segmentation passes of that
slice are prepended. A loop, not a call — no new <a class="xref" href="Hi.NcParsers.Keywords.CallStack.html">CallStack</a>
frame is pushed, but the host block's stack propagates onto the
repeated pieces so nested calls inside the section still accumulate
depth against the rail; the repeat count itself is a literal bound.
Any <code>LBL 0</code> passed inside the section is a no-op for the return
syntax (null-safe pop).</li><li><b><code>CALL PGM name</code></b>: resolved through
<a class="xref" href="Hi.NcParsers.Dependencys.Generic.SubProgramFolderConfig.html#Hi_NcParsers_Dependencys_Generic_SubProgramFolderConfig_InternalFolder">InternalFolder</a> with the
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainSubProgramCallSyntax.html#Hi_NcParsers_EvaluationSyntaxs_Heidenhain_HeidenhainSubProgramCallSyntax_FilePatterns">FilePatterns</a> chain (<code>{0}.h</code> → <code>{0}.H</code> →
<code>{0}</code>) and inlined whole — the
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Siemens.SiemensSubProgramCallSyntax.html">SiemensSubProgramCallSyntax</a> mechanism verbatim,
including resolve-miss safe-skip
(<code>HeidenhainCall--Skipped</code>). The callee's <code>END PGM</code> pops
the frame via
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainSubProgramReturnSyntax.html">HeidenhainSubProgramReturnSyntax</a>; a unit switch inside
the callee is not restored on return (recorded limitation).</li></ul>
<p>
Recursion rail: like the Siemens call path, a self-recursive
<code>CALL LBL</code>/<code>CALL PGM</code> would splice forever; a call whose
host block already carries <a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainSubProgramCallSyntax.html#Hi_NcParsers_EvaluationSyntaxs_Heidenhain_HeidenhainSubProgramCallSyntax_MaxCallDepth">MaxCallDepth</a>
<a class="xref" href="Hi.NcParsers.Keywords.CallStack.html">CallStack</a> frames is consumed as a safe-skip with
<code>HeidenhainCall--DepthLimitExceeded</code>. No <a class="xref" href="Hi.NcParsers.Keywords.MacroFrame.html">MacroFrame</a>
is stamped — klartext subprograms share the caller's Q scope.
</p>
Pipeline placement: head of the Heidenhain <code>Evaluation</code> bundle
(the Fanuc discipline — call/inline ahead of all variable machinery).
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainSubProgramReturnSyntax.html">HeidenhainSubProgramReturnSyntax</a></dt>
<dd><p>Consumes the two klartext return spellings and the standalone label
markers:</p>
<ul><li><b><code>LBL 0</code></b> — end-of-subprogram sentinel: stamps
<a class="xref" href="Hi.NcParsers.Keywords.SubProgramReturn.html">SubProgramReturn</a> (<code>Term: "LBL 0"</code>) and pops the
<a class="xref" href="Hi.NcParsers.Keywords.CallStack.html">CallStack</a> frame (null-safe: an <code>LBL 0</code> reached in
the main flow — the 1.H head layout — is a no-op). Like the Fanuc
M99, the "return" itself is structural: the call syntax truncated the
inlined slice at this block, so the caller's tail follows
naturally.</li><li><b><code>LBL n</code> / <code>LBL "name"</code></b> — definition markers:
consumed into a block-root <a class="xref" href="Hi.NcParsers.Keywords.Heidenhain.HeidenhainLbl.html">HeidenhainLbl</a> record (no
motion; keeps the label visible for dumps and the P5 jump
family).</li><li><b><code>END PGM</code> with a non-empty <a class="xref" href="Hi.NcParsers.Keywords.CallStack.html">CallStack</a></b> —
the return of a <code>CALL PGM</code> callee: consumes <code>Parsing.PGM</code>
before the Logic program-header syntax can treat it as a real program
end (which would clear the volatile Q store mid-stream), stamps
<a class="xref" href="Hi.NcParsers.Keywords.SubProgramReturn.html">SubProgramReturn</a> (<code>Term: "END PGM"</code>), and pops the
frame. The main file's <code>END PGM</code> (empty stack) is untouched.</li></ul>
Pipeline placement: directly after
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainSubProgramCallSyntax.html">HeidenhainSubProgramCallSyntax</a> at the head of the
Evaluation bundle.
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainVolatileQLookup.html">HeidenhainVolatileQLookup</a></dt>
<dd><p>Reads Heidenhain volatile Q parameters (<code>Q200+</code>, the cycle/user
range that resets at program start) from <code>Vars.Volatile</code>. Self-gates
the id range so the evaluator's
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.VariableEvaluatorSyntax.html#Hi_NcParsers_EvaluationSyntaxs_VariableEvaluatorSyntax_RuntimeVariableLookups">RuntimeVariableLookups</a> chain can
fall through for other keys (<code>Q0-Q99</code>/<code>QRn</code> resolve on the
<a class="xref" href="Hi.NcParsers.Dependencys.Heidenhain.HeidenhainQParameterTable.html">HeidenhainQParameterTable</a> further
down the chain; <code>Q100-Q199</code> stay vacant by design). Sibling of the
Fanuc <a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Evaluation.VolatileVariableLookup.html">VolatileVariableLookup</a> with the same
single-step traceback contract:
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Heidenhain.HeidenhainQParameterReadingSyntax.html">HeidenhainQParameterReadingSyntax</a> dict-merges every block's
<code>Vars.Volatile</code> into the next block, so the entry — if it exists —
is on the current block or the immediately previous one.</p>
<p>
Keys are stored canonically as <code>Q</code> + id by the reader; this lookup
re-canonicalises the incoming key the same way, so lowercase raw
captures still resolve. Stateless and dependency-free.
</p>
</dd>
</dl>
</article>
<div class="contribution d-print-none">
</div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>