Namespace Hi.NcParsers.EvaluationSyntaxs.Evaluation
Classes
- LocalVariableLookup
Reads Fanuc-style local macro variables (
#1-#33) fromVars.Localon the current SyntaxPiece JSON, falling back to the immediately previous block when they share the same MacroFrame id. Self-gates the id range so the evaluator's RuntimeVariableLookups chain can fall through to the next lookup for out-of-range keys.Two-step lookup (mirrors VolatileVariableLookup): the current block sees writes that FanucMacroCallSyntax stamped at inline time (the call-line argument bindings) and writes that FanucLocalVariableReadingSyntax applied on this block before the lookup runs; the previous block (frame-checked) supplies body-internal writes from the prior block in the same macro frame. Looking past the previous block is unnecessary because the reader carries forward block-by-block within a frame.
Frame isolation via MacroFrame: a previous block whose frame id differs from the current block's is skipped — a macro body's body-internal locals are invisible to the caller after return, and the caller's main-frame locals are invisible inside the macro. M98/M198 subprogram inlining (SubProgramCallSyntax) deliberately does not stamp MacroFrame on its inlined blocks, so the callee inherits the caller's frame and sees the caller's locals — matching real Fanuc M98 semantics.
Stateless and dependency-free — instances are interchangeable.
- NcBinaryExpr
Binary operation on two operands. Covers arithmetic (
+ - * //MOD), comparison (EQ NE GT GE LT LE, yielding1.0/0.0), and logical bitwise (AND OR XOR, operands truncated to long).
- NcExpr
AST root for a Fanuc Custom Macro B value expression. Concrete leaves and combinators sit alongside NcExpressionParser; walking is the job of NcExpressionEvaluator.
- NcExpressionEvaluator
Walks an NcExpr AST and produces an EvalResult. Resolves
#nnnvia an IVariableLookup; built-in function names are matched case-insensitively against a fixed table.Phase-1 supports:
SIN COS TAN ASIN ACOS ATAN SQRT ABS ROUND FIX FUP LN EXP POW. Trigonometric arguments and results are in degrees, matching Fanuc Custom Macro B convention. Unknown function names surface as UnsupportedFunctionCode; arity mismatches as ArgumentMismatchCode; division / MOD by zero and domain errors (e.g.SQRT[-1]) as MathErrorCode; vacant operands as VacantErrorCode.Numeric domain & type conventions. All values are IEEE 754 double — there is no separate bool / int type at runtime. Comparison ops (
EQ NE GT GE LT LE) yield1.0(true) or0.0(false), using strict double equality / ordering (NaN compares as IEEE specifies —NaN EQ NaNis0.0). Logical ops (AND OR XOR) truncate each operand to a 64-bit signed integer (Truncate(double) then cast to long) before applying the bitwise operation; non-finite or out-of-range operands surface MathErrorCode rather than silently wrapping. Truthiness at caller-sideIF / WHILEgates isvalue != 0— any non-zero value (bit, float, comparator result) is true.
- NcExpressionParser
Recursive-descent parser for Fanuc Custom Macro B value expressions. Pure: takes a string, produces an NcExpr AST. Performs no variable lookup and no evaluation.
Grammar (lowest precedence at top):
expr := or-expr or-expr := and-expr (('OR' | 'XOR') and-expr)* and-expr := cmp-expr ('AND' cmp-expr)* cmp-expr := add-expr (('EQ' | 'NE' | 'GT' | 'GE' | 'LT' | 'LE') add-expr)* add-expr := term (('+' | '-') term)* term := factor (('*' | '/' | 'MOD') factor)* factor := ('+' | '-')? primary primary := number | '#' integer | '#' '[' expr ']' | '[' expr ']' | ident '[' arglist ']' ('/' '[' expr ']')? arglist := expr (',' expr)*Function names and keyword operators (
MOD,EQ NE GT GE LT LE,AND OR XOR) are case-insensitive (SIN=sin,EQ=eq); each keyword requires a non-identifier character on its right boundary soEQ1is not theEQoperator followed by1. Whitespace is skipped between tokens. The'/' '[' expr ']'tail captures the dual-bracket form Fanuc uses forATAN[a]/[b]; non-ATAN callers that happen to use it produce a function with an extra arg, which the evaluator rejects with an arity error.Operator precedence intentionally puts boolean / logical layers below arithmetic so
#1 + 1 GT 0parses as(#1 + 1) GT 0and#1 GT 0 AND #2 LT 10parses as(#1 GT 0) AND (#2 LT 10), matching the Fanuc Custom Macro B spec forIF [..] GOTO/IF [..] THEN/WHILE [..] DOconditions.
- NcFunctionExpr
Built-in function call like
SIN[x],SQRT[x],ATAN[a]/[b].
- NcIndirectVariableExpr
Indirect variable reference
#[expr]. The inner expression is evaluated and truncated toward zero to obtain an integer; the lookup key is then Prefix concatenated with that integer (e.g.Prefix="#", computed124→"#124").
- NcLiteralExpr
Numeric literal (e.g.
1.5,15.,.5,1e-3).
- NcUnaryExpr
Unary
+or-applied to an operand.
- NcVariableExpr
Direct variable reference; Key is the raw source token (e.g.
"#124") passed verbatim to Get(string).
- VolatileVariableLookup
Reads Fanuc-style non-retained common variables (
#100-#499) fromVars.Volatile. Self-gates the id range so the evaluator's RuntimeVariableLookups chain can fall through to the next lookup for out-of-range keys.Single-step lookup: VolatileVariableReadingSyntax already dict-merges every block's
Vars.Volatileinto the next block, so the entry — if it exists — must be on the current block (when this lookup runs after the reader) or on the immediately previous block (when this lookup runs before the reader on the same block, which is the Fanuc preset's order — evaluator first, reader second). No arbitrary walk-back: such a walk would be defensive overkill given the reader's carry guarantee.Stateless and dependency-free — instances are interchangeable. Reads stay decoupled from the reader (read side here; write side in the reader).
Structs
- EvalResult
Outcome of evaluating an NcExpr. Either a successful numeric value, or a failure with an error code matching the diagnostic catalogue used by reading / evaluator syntaxes.
Interfaces
- IRuntimeVariableLookup
Stateless variable lookup that needs per-block runtime context — the current SyntaxPiece node (for Previous traceback into runtime-state sections like
MachineCoordinateState/ProgramXyz) and the dependency list (so the lookup can read from sibling dependencies without holding a static reference).Distinguished from IVariableLookup: that one is for long-lived dependencies that already hold their own data (parameter tables, tool-offset wrappers, retained-variable tables) and need no block context.
IRuntimeVariableLookupis for context-sensitive resolutions configured declaratively on RuntimeVariableLookups.Implementations should be brand-specific (e.g. Fanuc
#5001-#5043position reads) and returnnullfor keys outside their range so the evaluator's chain can fall through to the next lookup.Implementations are XML-serialised as part of VariableEvaluatorSyntax's round-trip: each impl exposes a static
XName, registers itself with Generators, and implements MakeXmlSource(string, string, bool). Since impls are stateless, the typical body is just an empty element carrying the type name; brand identity is restored by XFactory dispatch.
- IVariableLookup
Resolves a Custom Macro B variable reference to its current numeric value, or
nullfor vacant (Fanuc<vacant>) and out-of-scope alike.The key is the raw source token — Fanuc
"#124", Heidenhain"Q1", Siemens"R1"— so the interface itself is brand-agnostic. Implementations are typically narrow (one per id range / per brand prefix) and parse the prefix locally; chain them at the call site by trying each in priority order until one returns a non-nullvalue.A returned
nullis treated by NcExpressionEvaluator as vacant and surfaces as aVariable--Vacantfailure when the value is consumed in arithmetic context.
Enums
- NcBinaryOp
Binary operators allowed in Fanuc Custom Macro B value expressions.
- NcUnaryOp
Unary operators allowed in Fanuc Custom Macro B value expressions.