Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture

This is the canonical architecture page for the repository.

Parser and Runtime Design (v1 Draft)

1. Purpose

This document defines how the codebase will be organized to satisfy the current PRD requirements, with a Siemens-840D-compatible syntax model and configuration-driven runtime semantics.

2. Confirmed v1 Decisions

  • Siemens syntax compatibility: Yes
  • Siemens runtime semantics: Optional via profile/config
  • Baseline controller profile: 840D
  • Unknown M-code policy: Error
  • Modal conflicts: Error
  • Machine-related behavior: Config-driven (not hardcoded)

3. High-Level Pipeline

flowchart LR
  A[NC Text Chunks] --> B[StreamingExecutionEngine]
  B --> C[Line Assembly]
  C --> D[Parser<br/>grammar + AST]
  D --> E[Semantic Normalizer<br/>canonical statements]
  E --> F[Modal/Context Engine<br/>group states + validation]
  F --> G[AIL Lowering<br/>deterministic executable IR]
  G --> H[IExecutionSink / IRuntime]
  H --> I[Blocked / Resume / Cancel]
  G --> J[Legacy Message/Packet Output]
  A --> PS[ParseSession<br/>line edits + resume]
  PS --> D
  PS --> E
  K[MachineProfile + Policies] --> E
  K --> F
  K --> G
  K --> H

Streaming-first direction:

  • the primary execution surface is a stateful streaming engine
  • batch parse/lower APIs remain transitional compatibility surfaces
  • runtime work must cross injected interfaces, not direct global bindings

4. Code Organization (Target)

flowchart TB
  subgraph parser["Parser Layer"]
    G4["grammar/GCode.g4"]
    GP["src/gcode_parser.cpp"]
    AST["src/ast.h"]
  end

  subgraph semantic["Semantic Layer (new/expanded)"]
    SN["src/semantic_normalizer.*"]
    SR["src/semantic_rules.cpp"]
  end

  subgraph modal["Modal/Context Layer (new)"]
    ME["src/modal_engine.*"]
    MR["src/modal_registry.*"]
  end

  subgraph ail["AIL Layer"]
    AL["src/ail.cpp"]
    AJ["src/ail_json.cpp"]
  end

  subgraph runtime["Runtime Layer"]
    SE["StreamingExecutionEngine"]
    RI["Runtime / Sink Interfaces"]
    EX["AilExecutor (compatibility path)"]
    PL["Policy Interfaces"]
  end

  G4 --> GP --> AST --> SN --> ME --> AL --> SE
  SR --> SN
  MR --> ME
  AL --> AJ
  PL --> SE
  RI --> SE

5. Config and Policy Model

classDiagram
  class MachineProfile {
    +controller: ControllerKind
    +tool_change_mode: ToolChangeMode
    +tool_management: bool
    +unknown_mcode_policy: ErrorPolicy
    +modal_conflict_policy: ErrorPolicy
    +supported_work_offsets: RangeSet
  }

  class ModalRules {
    +group_conflict_matrix
    +group_precedence
    +validateTransition(...)
  }

  class ToolPolicy {
    <<interface>>
    +resolveToolSelection(...)
  }

  class MCodePolicy {
    <<interface>>
    +validateAndMapMCode(...)
  }

  class RuntimePolicy {
    +tool_policy: ToolPolicy
    +mcode_policy: MCodePolicy
  }

  MachineProfile --> ModalRules
  MachineProfile --> RuntimePolicy

6. Modal State Strategy

  • Keep a single modal registry keyed by Siemens group IDs.
  • Grouped state includes at minimum:
    • Group 1: motion type family (G0/G1/G2/G3 as baseline in current scope)
    • Group 6: working-plane selection (G17/G18/G19)
    • Group 7: G40/G41/G42
    • Group 8: G500/G54..G57/G505..G599
    • Group 10: G60/G64..G645
    • Group 11: G9 (block-scope)
    • Group 12: G601/G602/G603
    • Group 13: G70/G71/G700/G710
    • Group 14: G90/G91
    • Group 15: feed type family
  • Related non-group/aux state (modeled alongside modal groups):
    • rapid interpolation control (RTLION / RTLIOF) affecting G0 behavior
    • block-scope suppress contexts (G53/G153/SUPA)

6.1 Incremental Parse Session Strategy

  • ParseSession owns editable source lines and cached lowering boundary metadata.
  • Resume contract:
    • preserve immutable prefix before resume line
    • reparse + relower suffix from resume line
    • merge diagnostics/instructions/messages deterministically by 1-based line
  • Resume entry points:
    • explicit line (reparseFromLine(line))
    • first error (reparseFromFirstError())
  • v1 scope:
    • deterministic prefix/suffix merge semantics and API behavior
    • parser-internal tree-reuse optimization is a later performance enhancement
  • Detailed API/merge design:
stateDiagram-v2
  [*] --> BlockStart
  BlockStart --> ApplyModalWords
  ApplyModalWords --> ValidateConflicts
  ValidateConflicts --> EmitError: conflict/invalid
  ValidateConflicts --> ApplyBlockScope
  ApplyBlockScope --> LowerInstruction
  LowerInstruction --> BlockEnd
  BlockEnd --> BlockStart

7. Parse vs Runtime Responsibility

  • Parser layer:
    • recognizes syntax and preserves source form/location
    • does not hardcode machine-specific behaviors
  • Semantic/modal layers:
    • resolve meaning under MachineProfile
    • enforce modal/conflict policies
  • Runtime layer:
    • executes lowered line/AIL results with injected policy/runtime hooks
    • applies machine-specific actions (tool/mcode behavior)

7.0 Streaming Execution Boundary

  • streaming engine owns:
    • chunk intake
    • logical-line assembly
    • sequencing
    • blocked/resume/cancel state
  • runtime interfaces own:
    • machine-visible side effects
    • slow/blocking operations such as motion submission and variable reads
  • sink interfaces own:
    • deterministic emitted event visibility for tests/integration

7.1 Instruction-First Execution Contract

  • Any machine-visible action must exist as an explicit executable instruction in AIL (or future equivalent runtime IR).
  • Execution transport is instruction-dependent:
    • motion instructions: may emit motion packets for planner/queue consumers
    • non-motion control instructions: may execute via runtime control-command path without standalone motion packets
  • Therefore, “not packetized” does not imply “not executable”; it means the instruction is routed through a non-motion execution path.

8. Current Coverage Snapshot

9. Implementation Sequence (High Level)

  1. Build modal registry + machine profile skeleton.
  2. Move existing modal logic into modal engine.
  3. Introduce semantic normalizer output schema.
  4. Add one feature family at a time (comments, M, groups, feed, dimensions).
  5. Keep each slice test-first with ./dev/check.sh.