Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/plotnik-bytecode/src/bytecode/nav.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Navigation determines how the VM moves through the tree-sitter AST.

/// Navigation command for VM execution.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]
pub enum Nav {
/// Epsilon transition: pure control flow, no cursor movement or node check.
/// Used for branching, quantifier loops, and effect-only transitions.
Expand Down
42 changes: 2 additions & 40 deletions crates/plotnik-compiler/src/compile/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use super::compiler::CompileCtx;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum SemanticOp {
/// Navigation (non-epsilon only, full detail preserved).
Nav(NavKind),
Nav(Nav),

/// Named node match with optional type name.
MatchNamed(Option<String>),
Expand Down Expand Up @@ -58,44 +58,6 @@ pub enum SemanticOp {
CycleMarker(usize),
}

/// Navigation kind for fingerprinting.
///
/// Preserves full detail including Skip/Exact variants since these are semantically
/// significant (determined by anchors).
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum NavKind {
Stay,
StayExact,
Next,
NextSkip,
NextExact,
Down,
DownSkip,
DownExact,
Up(u8),
UpSkipTrivia(u8),
UpExact(u8),
}

impl From<Nav> for NavKind {
fn from(nav: Nav) -> Self {
match nav {
Nav::Epsilon => unreachable!("Epsilon should be filtered"),
Nav::Stay => Self::Stay,
Nav::StayExact => Self::StayExact,
Nav::Next => Self::Next,
Nav::NextSkip => Self::NextSkip,
Nav::NextExact => Self::NextExact,
Nav::Down => Self::Down,
Nav::DownSkip => Self::DownSkip,
Nav::DownExact => Self::DownExact,
Nav::Up(n) => Self::Up(n),
Nav::UpSkipTrivia(n) => Self::UpSkipTrivia(n),
Nav::UpExact(n) => Self::UpExact(n),
}
}
}

/// A semantic path: sequence of operations along one execution path.
pub type Path = Vec<SemanticOp>;

Expand All @@ -115,7 +77,7 @@ fn collect_ops_from_match(instr: &MatchIR, ctx: &CompileCtx) -> Vec<SemanticOp>

// Epsilons are pure control flow - they don't navigate or check node types
if instr.nav != Nav::Epsilon {
ops.push(SemanticOp::Nav(instr.nav.into()));
ops.push(SemanticOp::Nav(instr.nav));

// Only non-epsilons perform actual node type checks
match &instr.node_type {
Expand Down