diff --git a/crates/plotnik-cli/src/commands/dump.rs b/crates/plotnik-cli/src/commands/dump.rs index 558eeee..cc7fbe9 100644 --- a/crates/plotnik-cli/src/commands/dump.rs +++ b/crates/plotnik-cli/src/commands/dump.rs @@ -4,7 +4,7 @@ use plotnik_lib::Colors; use plotnik_lib::QueryBuilder; use plotnik_lib::bytecode::{Module, dump}; -use super::lang_resolver::{resolve_lang, resolve_lang_required, suggest_language}; +use super::lang_resolver::require_lang; use super::query_loader::load_query_source; pub struct DumpArgs { @@ -38,49 +38,19 @@ pub fn run(args: DumpArgs) { } }; - // Resolve language (optional - enables linking) - let lang = if let Some(lang_name) = &args.lang { - match resolve_lang_required(lang_name) { - Ok(l) => Some(l), - Err(msg) => { - eprintln!("error: {}", msg); - if let Some(suggestion) = suggest_language(lang_name) { - eprintln!(); - eprintln!("Did you mean '{}'?", suggestion); - } - eprintln!(); - eprintln!("Run 'plotnik langs' for the full list."); - std::process::exit(1); - } - } - } else { - resolve_lang(None, args.query_path.as_deref()) - }; + let lang = require_lang(args.lang.as_deref(), args.query_path.as_deref(), "dump"); - let bytecode = if let Some(lang) = lang { - let linked = query.link(&lang); - if !linked.is_valid() { - eprint!( - "{}", - linked - .diagnostics() - .render_colored(linked.source_map(), args.color) - ); - std::process::exit(1); - } - linked.emit().expect("bytecode emission failed") - } else { - if !query.is_valid() { - eprint!( - "{}", - query - .diagnostics() - .render_colored(query.source_map(), args.color) - ); - std::process::exit(1); - } - query.emit().expect("bytecode emission failed") - }; + let linked = query.link(&lang); + if !linked.is_valid() { + eprint!( + "{}", + linked + .diagnostics() + .render_colored(linked.source_map(), args.color) + ); + std::process::exit(1); + } + let bytecode = linked.emit().expect("bytecode emission failed"); let module = Module::load(&bytecode).expect("module loading failed"); let colors = Colors::new(args.color); diff --git a/crates/plotnik-cli/src/commands/infer.rs b/crates/plotnik-cli/src/commands/infer.rs index b78b92d..ca8f4ca 100644 --- a/crates/plotnik-cli/src/commands/infer.rs +++ b/crates/plotnik-cli/src/commands/infer.rs @@ -6,7 +6,7 @@ use plotnik_lib::QueryBuilder; use plotnik_lib::bytecode::Module; use plotnik_lib::typegen::typescript; -use super::lang_resolver::{resolve_lang, resolve_lang_required, suggest_language}; +use super::lang_resolver::require_lang; use super::query_loader::load_query_source; pub struct InferArgs { @@ -53,49 +53,19 @@ pub fn run(args: InferArgs) { } }; - // Resolve language (optional - enables linking) - let lang = if let Some(lang_name) = &args.lang { - match resolve_lang_required(lang_name) { - Ok(l) => Some(l), - Err(msg) => { - eprintln!("error: {}", msg); - if let Some(suggestion) = suggest_language(lang_name) { - eprintln!(); - eprintln!("Did you mean '{}'?", suggestion); - } - eprintln!(); - eprintln!("Run 'plotnik langs' for the full list."); - std::process::exit(1); - } - } - } else { - resolve_lang(None, args.query_path.as_deref()) - }; + let lang = require_lang(args.lang.as_deref(), args.query_path.as_deref(), "infer"); - let bytecode = if let Some(lang) = lang { - let linked = query.link(&lang); - if !linked.is_valid() { - eprint!( - "{}", - linked - .diagnostics() - .render_colored(linked.source_map(), args.color) - ); - std::process::exit(1); - } - linked.emit().expect("bytecode emission failed") - } else { - if !query.is_valid() { - eprint!( - "{}", - query - .diagnostics() - .render_colored(query.source_map(), args.color) - ); - std::process::exit(1); - } - query.emit().expect("bytecode emission failed") - }; + let linked = query.link(&lang); + if !linked.is_valid() { + eprint!( + "{}", + linked + .diagnostics() + .render_colored(linked.source_map(), args.color) + ); + std::process::exit(1); + } + let bytecode = linked.emit().expect("bytecode emission failed"); let module = Module::load(&bytecode).expect("module loading failed"); // Emit TypeScript types diff --git a/crates/plotnik-cli/src/commands/lang_resolver.rs b/crates/plotnik-cli/src/commands/lang_resolver.rs index 33c2ed6..4c1543c 100644 --- a/crates/plotnik-cli/src/commands/lang_resolver.rs +++ b/crates/plotnik-cli/src/commands/lang_resolver.rs @@ -28,6 +28,40 @@ pub fn resolve_lang_required(lang_name: &str) -> Result { plotnik_langs::from_name(lang_name).ok_or_else(|| format!("unknown language: '{}'", lang_name)) } +/// Resolve language with user-friendly error handling. +/// Tries explicit flag first, then infers from query path. +/// Exits with error message if language cannot be determined. +pub fn require_lang( + explicit: Option<&str>, + query_path: Option<&std::path::Path>, + command: &str, +) -> Lang { + if let Some(lang_name) = explicit { + match resolve_lang_required(lang_name) { + Ok(l) => return l, + Err(msg) => { + eprintln!("error: {}", msg); + if let Some(suggestion) = suggest_language(lang_name) { + eprintln!(); + eprintln!("Did you mean '{}'?", suggestion); + } + eprintln!(); + eprintln!("Run 'plotnik langs' for the full list."); + std::process::exit(1); + } + } + } + + if let Some(l) = resolve_lang(None, query_path) { + return l; + } + + eprintln!("error: language is required for {}", command); + eprintln!(); + eprintln!("hint: use -l to specify the target language"); + std::process::exit(1); +} + /// Suggest similar language names for typos. pub fn suggest_language(input: &str) -> Option { let input_lower = input.to_lowercase(); diff --git a/crates/plotnik-cli/src/commands/run_common.rs b/crates/plotnik-cli/src/commands/run_common.rs index 5cc80da..ee38632 100644 --- a/crates/plotnik-cli/src/commands/run_common.rs +++ b/crates/plotnik-cli/src/commands/run_common.rs @@ -8,7 +8,7 @@ use arborium_tree_sitter as tree_sitter; use plotnik_langs::Lang; use plotnik_lib::QueryBuilder; use plotnik_lib::bytecode::{Entrypoint, Module}; -use plotnik_lib::emit::emit_linked; +use plotnik_lib::emit::emit; use super::lang_resolver::{resolve_lang_required, suggest_language}; use super::query_loader::load_query_source; @@ -193,7 +193,7 @@ pub fn prepare_query(input: QueryInput) -> PreparedQuery { std::process::exit(1); } - let bytecode = emit_linked(&query).expect("emit failed"); + let bytecode = emit(&query).expect("emit failed"); let module = Module::load(&bytecode).expect("module load failed"); let entrypoint = resolve_entrypoint(&module, input.entry); diff --git a/crates/plotnik-lib/src/analyze/type_check/type_check_tests.rs b/crates/plotnik-lib/src/analyze/type_check/type_check_tests.rs index 96fe409..8f1aa06 100644 --- a/crates/plotnik-lib/src/analyze/type_check/type_check_tests.rs +++ b/crates/plotnik-lib/src/analyze/type_check/type_check_tests.rs @@ -117,7 +117,7 @@ fn capture_with_custom_type() { #[test] fn named_node_with_field_capture() { - let input = "Q = (function name: (identifier) @name)"; + let input = "Q = (function_declaration name: (identifier) @name)"; let res = Query::expect_valid_types(input); @@ -137,9 +137,9 @@ fn named_node_with_field_capture() { #[test] fn named_node_multiple_field_captures() { let input = indoc! {r#" - Q = (function + Q = (function_declaration name: (identifier) @name - body: (block) @body + body: (statement_block) @body ) "#}; @@ -164,9 +164,9 @@ fn named_node_captured_with_internal_captures() { // Capturing a named node does NOT create a scope boundary. // Internal captures bubble up alongside the outer capture. let input = indoc! {r#" - Q = (function + Q = (function_declaration name: (identifier) @name :: string - body: (block) @body + body: (statement_block) @body ) @func :: FunctionInfo "#}; @@ -192,8 +192,8 @@ fn named_node_captured_with_internal_captures() { #[test] fn nested_named_node_captures() { let input = indoc! {r#" - Q = (call - function: (member target: (identifier) @target) + Q = (call_expression + function: (member_expression object: (identifier) @target) ) "#}; @@ -279,7 +279,7 @@ fn scalar_list_with_string_annotation_one_or_more() { #[test] fn row_list_basic() { let input = indoc! {r#" - Q = {(key) @k (value) @v}* @rows + Q = {(identifier) @k (number) @v}* @rows "#}; let res = Query::expect_valid_types(input); @@ -305,7 +305,7 @@ fn row_list_basic() { #[test] fn row_list_non_empty() { let input = indoc! {r#" - Q = {(key) @k (value) @v}+ @rows + Q = {(identifier) @k (number) @v}+ @rows "#}; let res = Query::expect_valid_types(input); @@ -350,7 +350,7 @@ fn optional_single_capture() { #[test] fn optional_group_bubbles_fields() { let input = indoc! {r#" - Q = {(modifier) @mod (decorator) @dec}? + Q = {(identifier) @mod (decorator) @dec}? "#}; let res = Query::expect_valid_types(input); @@ -371,7 +371,7 @@ fn optional_group_bubbles_fields() { #[test] fn sequence_merges_fields() { let input = indoc! {r#" - Q = {(a) @a (b) @b} + Q = {(identifier) @a (number) @b} "#}; let res = Query::expect_valid_types(input); @@ -393,7 +393,7 @@ fn sequence_merges_fields() { #[test] fn captured_sequence_creates_struct() { let input = indoc! {r#" - Q = {(a) @a (b) @b} @row + Q = {(identifier) @a (number) @b} @row "#}; let res = Query::expect_valid_types(input); @@ -418,7 +418,7 @@ fn captured_sequence_creates_struct() { #[test] fn untagged_alt_same_capture_all_branches() { - let input = "Q = [(a) @x (b) @x]"; + let input = "Q = [(identifier) @x (number) @x]"; let res = Query::expect_valid_types(input); @@ -437,7 +437,7 @@ fn untagged_alt_same_capture_all_branches() { #[test] fn untagged_alt_different_captures() { - let input = "Q = [(a) @a (b) @b]"; + let input = "Q = [(identifier) @a (number) @b]"; let res = Query::expect_valid_types(input); @@ -459,8 +459,8 @@ fn untagged_alt_different_captures() { fn untagged_alt_partial_overlap() { let input = indoc! {r#" Q = [ - {(a) @x (b) @y} - {(a) @x} + {(identifier) @x (number) @y} + {(identifier) @x} ] "#}; @@ -585,7 +585,7 @@ fn nested_captured_group() { let input = indoc! {r#" Q = { (identifier) @name - {(key) @k (value) @v} @pair + {(string) @k (number) @v} @pair } "#}; @@ -613,7 +613,7 @@ fn nested_captured_group() { #[test] fn error_star_with_internal_captures_no_row() { let input = indoc! {r#" - Bad = {(a) @a (b) @b}* + Bad = {(identifier) @a (number) @b}* "#}; let res = Query::expect_invalid(input); @@ -621,8 +621,8 @@ fn error_star_with_internal_captures_no_row() { insta::assert_snapshot!(res, @r" error: quantifier `*` contains captures (`@a`, `@b`) but has no struct capture | - 1 | Bad = {(a) @a (b) @b}* - | ^^^^^^^^^^^^^^^^ + 1 | Bad = {(identifier) @a (number) @b}* + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: add a struct capture: `{...}* @name` "); @@ -631,7 +631,7 @@ fn error_star_with_internal_captures_no_row() { #[test] fn error_plus_with_internal_capture_no_row() { let input = indoc! {r#" - Bad = {(c) @c}+ + Bad = {(identifier) @c}+ "#}; let res = Query::expect_invalid(input); @@ -639,8 +639,8 @@ fn error_plus_with_internal_capture_no_row() { insta::assert_snapshot!(res, @r" error: quantifier `+` contains captures (`@c`) but has no struct capture | - 1 | Bad = {(c) @c}+ - | ^^^^^^^^^ + 1 | Bad = {(identifier) @c}+ + | ^^^^^^^^^^^^^^^^^^ | help: add a struct capture: `{...}+ @name` "); @@ -649,7 +649,7 @@ fn error_plus_with_internal_capture_no_row() { #[test] fn error_named_node_with_capture_quantified() { let input = indoc! {r#" - Bad = (func (identifier) @name)* + Bad = (array (identifier) @name)* "#}; let res = Query::expect_invalid(input); @@ -657,8 +657,8 @@ fn error_named_node_with_capture_quantified() { insta::assert_snapshot!(res, @r" error: quantifier `*` contains captures (`@name`) but has no struct capture | - 1 | Bad = (func (identifier) @name)* - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 1 | Bad = (array (identifier) @name)* + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: add a struct capture: `{...}* @name` "); @@ -722,7 +722,7 @@ fn recursive_type_optional_self_ref() { #[test] fn recursive_type_in_quantified_context() { let input = indoc! {r#" - Item = (item (Item)* @children) + Item = (array (Item)* @children) "#}; let res = Query::expect_valid_types(input); @@ -872,8 +872,8 @@ fn scalar_propagates_through_sequence() { #[test] fn error_multiple_uncaptured_outputs() { let input = indoc! {r#" - A = [X: (x)] - B = [Y: (y)] + A = [X: (identifier)] + B = [Y: (number)] Q = (program (A) (B)) "#}; @@ -892,8 +892,8 @@ fn error_multiple_uncaptured_outputs() { #[test] fn error_uncaptured_output_with_captures() { let input = indoc! {r#" - A = [X: (x)] - Q = (program (A) (identifier) @name) + A = [X: (identifier)] + Q = (program (A) (number) @name) "#}; let res = Query::expect_invalid(input); @@ -901,7 +901,7 @@ fn error_uncaptured_output_with_captures() { insta::assert_snapshot!(res, @r" error: output-producing expression requires capture when siblings have captures | - 2 | Q = (program (A) (identifier) @name) + 2 | Q = (program (A) (number) @name) | ^^^ | help: add `@name` to capture the output @@ -911,8 +911,8 @@ fn error_uncaptured_output_with_captures() { #[test] fn output_captured_with_bubbles_ok() { let input = indoc! {r#" - A = [X: (x) Y: (y)] - Q = (program (A) @a (identifier) @name) + A = [X: (identifier) Y: (number)] + Q = (program (A) @a (string) @name) "#}; let res = Query::expect_valid_types(input); diff --git a/crates/plotnik-lib/src/bytecode/constants.rs b/crates/plotnik-lib/src/bytecode/constants.rs index 9a4088f..e53caa2 100644 --- a/crates/plotnik-lib/src/bytecode/constants.rs +++ b/crates/plotnik-lib/src/bytecode/constants.rs @@ -5,7 +5,8 @@ pub const MAGIC: [u8; 4] = *b"PTKQ"; /// Current bytecode format version. /// v2: Removed explicit offsets (computed from counts), added regex section. -pub const VERSION: u32 = 2; +/// v3: Removed flags field (unlinked mode). +pub const VERSION: u32 = 3; /// Section alignment in bytes. pub const SECTION_ALIGN: usize = 64; diff --git a/crates/plotnik-lib/src/bytecode/dump.rs b/crates/plotnik-lib/src/bytecode/dump.rs index 369b608..7487a2b 100644 --- a/crates/plotnik-lib/src/bytecode/dump.rs +++ b/crates/plotnik-lib/src/bytecode/dump.rs @@ -23,7 +23,6 @@ pub fn dump(module: &Module, colors: Colors) -> String { let mut out = String::new(); let ctx = DumpContext::new(module, colors); - dump_header(&mut out, module, &ctx); dump_strings(&mut out, module, &ctx); dump_types_defs(&mut out, module, &ctx); dump_types_members(&mut out, module, &ctx); @@ -34,25 +33,16 @@ pub fn dump(module: &Module, colors: Colors) -> String { out } -fn dump_header(out: &mut String, module: &Module, ctx: &DumpContext) { - let c = &ctx.colors; - let header = module.header(); - writeln!(out, "{}[flags]{}", c.blue, c.reset).unwrap(); - writeln!(out, "linked = {}", header.is_linked()).unwrap(); - out.push('\n'); -} /// Context for dump formatting, precomputes lookups for O(1) access. struct DumpContext { - /// Whether the bytecode is linked (contains grammar IDs vs StringIds). - is_linked: bool, /// Maps step ID to entrypoint name for labeling. step_labels: BTreeMap, - /// Maps node type ID to name (linked mode only). + /// Maps node type ID to name. node_type_names: BTreeMap, - /// Maps node field ID to name (linked mode only). + /// Maps node field ID to name. node_field_names: BTreeMap, - /// All strings (for unlinked mode lookups). + /// All strings (for predicate values, regex patterns, etc). all_strings: Vec, /// Width for string indices (S#). str_width: usize, @@ -71,7 +61,6 @@ struct DumpContext { impl DumpContext { fn new(module: &Module, colors: Colors) -> Self { let header = module.header(); - let is_linked = header.is_linked(); let strings = module.strings(); let entrypoints = module.entrypoints(); let node_types = module.node_types(); @@ -114,7 +103,6 @@ impl DumpContext { let step_width = width_for_count(header.transitions_count as usize); Self { - is_linked, step_labels, node_type_names, node_field_names, @@ -133,29 +121,13 @@ impl DumpContext { } /// Get the name for a node type ID. - /// - /// In linked mode, this looks up the grammar's node type symbol table. - /// In unlinked mode, this looks up the StringId from the strings table. fn node_type_name(&self, id: u16) -> Option<&str> { - if self.is_linked { - self.node_type_names.get(&id).map(|s| s.as_str()) - } else { - // In unlinked mode, id is a StringId - self.all_strings.get(id as usize).map(|s| s.as_str()) - } + self.node_type_names.get(&id).map(|s| s.as_str()) } /// Get the name for a node field ID. - /// - /// In linked mode, this looks up the grammar's node field symbol table. - /// In unlinked mode, this looks up the StringId from the strings table. fn node_field_name(&self, id: u16) -> Option<&str> { - if self.is_linked { - self.node_field_names.get(&id).map(|s| s.as_str()) - } else { - // In unlinked mode, id is a StringId - self.all_strings.get(id as usize).map(|s| s.as_str()) - } + self.node_field_names.get(&id).map(|s| s.as_str()) } } diff --git a/crates/plotnik-lib/src/bytecode/header.rs b/crates/plotnik-lib/src/bytecode/header.rs index 773dc33..cbdf277 100644 --- a/crates/plotnik-lib/src/bytecode/header.rs +++ b/crates/plotnik-lib/src/bytecode/header.rs @@ -1,32 +1,25 @@ //! Bytecode file header (64 bytes). //! -//! v2 layout: Offsets are computed from counts + SECTION_ALIGN (64 bytes). +//! v3 layout: Offsets are computed from counts + SECTION_ALIGN (64 bytes). //! Section order: Header → StringBlob → RegexBlob → StringTable → RegexTable → //! NodeTypes → NodeFields → Trivia → TypeDefs → TypeMembers → TypeNames → //! Entrypoints → Transitions use super::{MAGIC, SECTION_ALIGN, VERSION}; -/// Header flags (bit field). -pub mod flags { - /// Bit 0: If set, bytecode is linked (instructions contain NodeTypeId/NodeFieldId). - /// If clear, bytecode is unlinked (instructions contain StringId references). - pub const LINKED: u16 = 0x0001; -} - /// File header - first 64 bytes of the bytecode file. /// -/// v2 layout (offsets computed from counts): +/// v3 layout (offsets computed from counts): /// - 0-23: identity and sizes (magic, version, checksum, total_size, str_blob_size, regex_blob_size) -/// - 24-45: counts (11 × u16) — order matches section order -/// - 46-63: reserved +/// - 24-43: counts (10 × u16) — order matches section order +/// - 44-63: reserved #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(C, align(64))] pub struct Header { // Bytes 0-23: Identity and sizes (6 × u32) /// Magic bytes: b"PTKQ" pub magic: [u8; 4], - /// Format version (currently 2) + /// Format version (currently 3) pub version: u32, /// CRC32 checksum of everything after the header pub checksum: u32, @@ -37,7 +30,7 @@ pub struct Header { /// Size of the regex blob in bytes. pub regex_blob_size: u32, - // Bytes 24-45: Element counts (11 × u16) — order matches section order + // Bytes 24-43: Element counts (10 × u16) — order matches section order pub str_table_count: u16, pub regex_table_count: u16, pub node_types_count: u16, @@ -48,11 +41,9 @@ pub struct Header { pub type_names_count: u16, pub entrypoints_count: u16, pub transitions_count: u16, - /// Header flags (see `flags` module for bit definitions). - pub flags: u16, - // Bytes 46-63: Reserved - pub(crate) _reserved: [u8; 18], + // Bytes 44-63: Reserved + pub(crate) _reserved: [u8; 20], } const _: () = assert!(std::mem::size_of::
() == 64); @@ -76,8 +67,7 @@ impl Default for Header { type_names_count: 0, entrypoints_count: 0, transitions_count: 0, - flags: 0, - _reserved: [0; 18], + _reserved: [0; 20], } } } @@ -107,8 +97,8 @@ impl Header { pub fn from_bytes(bytes: &[u8]) -> Self { assert!(bytes.len() >= 64, "header too short"); - let mut reserved = [0u8; 18]; - reserved.copy_from_slice(&bytes[46..64]); + let mut reserved = [0u8; 20]; + reserved.copy_from_slice(&bytes[44..64]); Self { magic: [bytes[0], bytes[1], bytes[2], bytes[3]], @@ -127,7 +117,6 @@ impl Header { type_names_count: u16::from_le_bytes([bytes[38], bytes[39]]), entrypoints_count: u16::from_le_bytes([bytes[40], bytes[41]]), transitions_count: u16::from_le_bytes([bytes[42], bytes[43]]), - flags: u16::from_le_bytes([bytes[44], bytes[45]]), _reserved: reserved, } } @@ -151,8 +140,7 @@ impl Header { bytes[38..40].copy_from_slice(&self.type_names_count.to_le_bytes()); bytes[40..42].copy_from_slice(&self.entrypoints_count.to_le_bytes()); bytes[42..44].copy_from_slice(&self.transitions_count.to_le_bytes()); - bytes[44..46].copy_from_slice(&self.flags.to_le_bytes()); - bytes[46..64].copy_from_slice(&self._reserved); + bytes[44..64].copy_from_slice(&self._reserved); bytes } @@ -164,20 +152,6 @@ impl Header { self.version == VERSION } - /// Returns true if the bytecode is linked (contains resolved grammar IDs). - pub fn is_linked(&self) -> bool { - self.flags & flags::LINKED != 0 - } - - /// Set the linked flag. - pub fn set_linked(&mut self, linked: bool) { - if linked { - self.flags |= flags::LINKED; - } else { - self.flags &= !flags::LINKED; - } - } - /// Compute section offsets from counts and blob sizes. /// /// Section order (all 64-byte aligned): diff --git a/crates/plotnik-lib/src/bytecode/header_tests.rs b/crates/plotnik-lib/src/bytecode/header_tests.rs index a2f90b3..fd88543 100644 --- a/crates/plotnik-lib/src/bytecode/header_tests.rs +++ b/crates/plotnik-lib/src/bytecode/header_tests.rs @@ -32,8 +32,7 @@ fn header_roundtrip() { type_names_count: 4, entrypoints_count: 1, transitions_count: 15, - flags: 0, - _reserved: [0; 18], + _reserved: [0; 20], }; let bytes = h.to_bytes(); @@ -43,32 +42,6 @@ fn header_roundtrip() { assert_eq!(decoded, h); } -#[test] -fn header_linked_flag() { - let mut h = Header::default(); - assert!(!h.is_linked()); - - h.set_linked(true); - assert!(h.is_linked()); - assert_eq!(h.flags, flags::LINKED); - - h.set_linked(false); - assert!(!h.is_linked()); - assert_eq!(h.flags, 0); -} - -#[test] -fn header_flags_roundtrip() { - let mut h = Header::default(); - h.set_linked(true); - - let bytes = h.to_bytes(); - let decoded = Header::from_bytes(&bytes); - - assert!(decoded.is_linked()); - assert_eq!(decoded.flags, flags::LINKED); -} - #[test] fn compute_offsets_empty() { let h = Header::default(); diff --git a/crates/plotnik-lib/src/bytecode/mod.rs b/crates/plotnik-lib/src/bytecode/mod.rs index 0a0f312..430714c 100644 --- a/crates/plotnik-lib/src/bytecode/mod.rs +++ b/crates/plotnik-lib/src/bytecode/mod.rs @@ -25,7 +25,7 @@ pub use constants::{ pub use ids::{StringId, TypeId}; -pub use header::{flags, Header, SectionOffsets}; +pub use header::{Header, SectionOffsets}; pub use sections::{FieldSymbol, NodeSymbol, Slice, TriviaEntry}; diff --git a/crates/plotnik-lib/src/bytecode/module_tests.rs b/crates/plotnik-lib/src/bytecode/module_tests.rs index 56efd4b..e97a48e 100644 --- a/crates/plotnik-lib/src/bytecode/module_tests.rs +++ b/crates/plotnik-lib/src/bytecode/module_tests.rs @@ -9,7 +9,7 @@ use crate::bytecode::{Module, ModuleError}; fn module_from_bytes_valid() { let input = "Test = (identifier) @id"; - let bytes = Query::expect_valid_linked_bytes(input); + let bytes = Query::expect_valid_bytes(input); let module = Module::load(&bytes).unwrap(); assert!(module.header().validate_magic()); @@ -20,7 +20,7 @@ fn module_from_bytes_valid() { fn module_from_bytes_too_small() { let input = "Test = (identifier) @id"; - let bytes = Query::expect_valid_linked_bytes(input); + let bytes = Query::expect_valid_bytes(input); let truncated = bytes[..32].to_vec(); let err = Module::load(&truncated).unwrap_err(); @@ -31,7 +31,7 @@ fn module_from_bytes_too_small() { fn module_from_bytes_invalid_magic() { let input = "Test = (identifier) @id"; - let mut bytes = Query::expect_valid_linked_bytes(input); + let mut bytes = Query::expect_valid_bytes(input); bytes[0] = b'X'; // Corrupt magic let err = Module::load(&bytes).unwrap_err(); @@ -42,7 +42,7 @@ fn module_from_bytes_invalid_magic() { fn module_from_bytes_wrong_version() { let input = "Test = (identifier) @id"; - let mut bytes = Query::expect_valid_linked_bytes(input); + let mut bytes = Query::expect_valid_bytes(input); bytes[4..8].copy_from_slice(&999u32.to_le_bytes()); // Wrong version let err = Module::load(&bytes).unwrap_err(); @@ -53,7 +53,7 @@ fn module_from_bytes_wrong_version() { fn module_from_bytes_size_mismatch() { let input = "Test = (identifier) @id"; - let mut bytes = Query::expect_valid_linked_bytes(input); + let mut bytes = Query::expect_valid_bytes(input); let actual_size = bytes.len() as u32; bytes[12..16].copy_from_slice(&(actual_size + 100).to_le_bytes()); // Wrong total_size @@ -71,7 +71,7 @@ fn module_from_bytes_size_mismatch() { fn module_strings_view() { let input = "Test = (identifier) @id"; - let bytes = Query::expect_valid_linked_bytes(input); + let bytes = Query::expect_valid_bytes(input); let module = Module::load(&bytes).unwrap(); let strings = module.strings(); @@ -85,7 +85,7 @@ fn module_strings_view() { fn module_node_types_view() { let input = "Test = (identifier) @id"; - let bytes = Query::expect_valid_linked_bytes(input); + let bytes = Query::expect_valid_bytes(input); let module = Module::load(&bytes).unwrap(); let node_types = module.node_types(); @@ -102,7 +102,7 @@ fn module_node_types_view() { fn module_node_fields_view() { let input = "Test = (function_declaration name: (identifier) @name)"; - let bytes = Query::expect_valid_linked_bytes(input); + let bytes = Query::expect_valid_bytes(input); let module = Module::load(&bytes).unwrap(); let fields = module.node_fields(); @@ -123,7 +123,7 @@ fn module_types_view() { body: (_) @body) "#}; - let bytes = Query::expect_valid_linked_bytes(input); + let bytes = Query::expect_valid_bytes(input); let module = Module::load(&bytes).unwrap(); let types = module.types(); @@ -139,7 +139,7 @@ fn module_entrypoints_view() { Bar = (string) @str "#}; - let bytes = Query::expect_valid_linked_bytes(input); + let bytes = Query::expect_valid_bytes(input); let module = Module::load(&bytes).unwrap(); let entrypoints = module.entrypoints(); @@ -158,7 +158,7 @@ fn module_entrypoints_view() { fn module_decode_step() { let input = "Test = (identifier) @id"; - let bytes = Query::expect_valid_linked_bytes(input); + let bytes = Query::expect_valid_bytes(input); let module = Module::load(&bytes).unwrap(); let instr = module.decode_step(0); @@ -171,7 +171,7 @@ fn module_from_path_mmap() { let input = "Test = (identifier) @id"; - let bytes = Query::expect_valid_linked_bytes(input); + let bytes = Query::expect_valid_bytes(input); // Write to temp file let mut tmpfile = tempfile::NamedTempFile::new().unwrap(); @@ -218,7 +218,7 @@ fn byte_storage_from_aligned() { fn module_load() { let input = "Test = (identifier) @id"; - let bytes = Query::expect_valid_linked_bytes(input); + let bytes = Query::expect_valid_bytes(input); let module = Module::load(&bytes).unwrap(); assert!(module.header().validate_magic()); diff --git a/crates/plotnik-lib/src/emit/emit_tests.rs b/crates/plotnik-lib/src/emit/emit_tests.rs index 2be5078..dc172e1 100644 --- a/crates/plotnik-lib/src/emit/emit_tests.rs +++ b/crates/plotnik-lib/src/emit/emit_tests.rs @@ -81,14 +81,14 @@ fn captures_multiple() { #[test] fn captures_nested_flat() { snap!(indoc! {r#" - Test = (a (b (c) @c) @b) @a + Test = (array (array (identifier) @c) @b) @a "#}); } #[test] fn captures_deeply_nested() { snap!(indoc! {r#" - Test = (a (b (c (d) @d) @c) @b) @a + Test = (array (array (array (identifier) @d) @c) @b) @a "#}); } @@ -109,7 +109,7 @@ fn captures_with_type_custom() { #[test] fn captures_struct_scope() { snap!(indoc! {r#" - Test = {(a) @a (b) @b} @item + Test = {(identifier) @a (number) @b} @item "#}); } @@ -164,7 +164,7 @@ fn fields_multiple() { #[test] fn fields_negated() { snap!(indoc! {r#" - Test = (function_declaration name: (identifier) @name -type_parameters) + Test = (pair key: (property_identifier) @key -value) "#}); } @@ -250,7 +250,7 @@ fn quantifiers_sequence_in_called_def() { snap!(indoc! {r#" Item = (identifier) @name Collect = {(Item) @item}* @items - Test = (parent (Collect)) + Test = (array (Collect)) "#}); } @@ -259,28 +259,28 @@ fn quantifiers_sequence_in_called_def() { #[test] fn sequences_basic() { snap!(indoc! {r#" - Test = (parent {(a) (b)}) + Test = (array {(identifier) (number)}) "#}); } #[test] fn sequences_with_captures() { snap!(indoc! {r#" - Test = (parent {(a) @a (b) @b}) + Test = (array {(identifier) @a (number) @b}) "#}); } #[test] fn sequences_nested() { snap!(indoc! {r#" - Test = (parent {(a) {(b) (c)} (d)}) + Test = (array {(identifier) {(number) (string)} (null)}) "#}); } #[test] fn sequences_in_quantifier() { snap!(indoc! {r#" - Test = (parent {(a) (b)}* @items) + Test = (array {(identifier) (number)}* @items) "#}); } @@ -352,7 +352,7 @@ fn alternations_tagged_in_field_constraint() { // The capture `@kind` applies to the field expression, but the value determines // whether it's a structured scope (enum in this case). snap!(indoc! {r#" - Test = (foo field: [A: (x) @a B: (y)] @kind) + Test = (pair key: [A: (identifier) @a B: (number)] @kind) "#}); } @@ -361,35 +361,35 @@ fn alternations_tagged_in_field_constraint() { #[test] fn anchors_between_siblings() { snap!(indoc! {r#" - Test = (parent (a) . (b)) + Test = (array (identifier) . (number)) "#}); } #[test] fn anchors_first_child() { snap!(indoc! {r#" - Test = (parent . (first)) + Test = (array . (identifier)) "#}); } #[test] fn anchors_last_child() { snap!(indoc! {r#" - Test = (parent (last) .) + Test = (array (identifier) .) "#}); } #[test] fn anchors_with_anonymous() { snap!(indoc! {r#" - Test = (parent "+" . (next)) + Test = (binary_expression "+" . (identifier)) "#}); } #[test] fn anchors_no_anchor() { snap!(indoc! {r#" - Test = (parent (a) (b)) + Test = (array (identifier) (number)) "#}); } @@ -421,8 +421,8 @@ fn definitions_reference() { #[test] fn definitions_nested_capture() { snap!(indoc! {r#" - Inner = (call (identifier) @name) - Outer = (parent {(Inner) @item}* @items) + Inner = (call_expression (identifier) @name) + Outer = (array {(Inner) @item}* @items) "#}); } diff --git a/crates/plotnik-lib/src/emit/emitter.rs b/crates/plotnik-lib/src/emit/emitter.rs index 6d6976f..d1e2dc0 100644 --- a/crates/plotnik-lib/src/emit/emitter.rs +++ b/crates/plotnik-lib/src/emit/emitter.rs @@ -1,12 +1,8 @@ //! Core bytecode emission logic. -//! -//! Contains the main entry points for emitting bytecode from compiled queries. -use indexmap::IndexMap; -use plotnik_core::{Interner, NodeFieldId, NodeTypeId, Symbol}; +use plotnik_core::Symbol; -use crate::analyze::symbol_table::SymbolTable; -use crate::analyze::type_check::{TypeContext, TypeId}; +use crate::analyze::type_check::TypeId; use crate::bytecode::{ Entrypoint, FieldSymbol, Header, InstructionIR, Label, NodeSymbol, PredicateValueIR, SECTION_ALIGN, TriviaEntry, @@ -20,47 +16,25 @@ use super::regex_table::RegexTableBuilder; use super::string_table::StringTableBuilder; use super::type_table::TypeTableBuilder; -/// Emit bytecode from type context only (no node validation). -pub fn emit( - type_ctx: &TypeContext, - interner: &Interner, - symbol_table: &SymbolTable, -) -> Result, EmitError> { - emit_inner(type_ctx, interner, symbol_table, None, None) -} - -/// Emit bytecode from a LinkedQuery (includes node type/field validation info). -pub fn emit_linked(query: &LinkedQuery) -> Result, EmitError> { - emit_inner( - query.type_context(), - query.interner(), - &query.symbol_table, - Some(query.node_type_ids()), - Some(query.node_field_ids()), - ) -} +/// Emit bytecode from a LinkedQuery. +pub fn emit(query: &LinkedQuery) -> Result, EmitError> { + let type_ctx = query.type_context(); + let interner = query.interner(); + let symbol_table = &query.symbol_table; + let node_type_ids = query.node_type_ids(); + let node_field_ids = query.node_field_ids(); -/// Shared bytecode emission logic. -fn emit_inner( - type_ctx: &TypeContext, - interner: &Interner, - symbol_table: &SymbolTable, - node_type_ids: Option<&IndexMap>, - node_field_ids: Option<&IndexMap>, -) -> Result, EmitError> { - let is_linked = node_type_ids.is_some(); let mut strings = StringTableBuilder::new(); let mut types = TypeTableBuilder::new(); types.build(type_ctx, interner, &mut strings)?; - // Compile transitions (strings are interned here for unlinked mode) let compile_result = Compiler::compile( interner, type_ctx, symbol_table, &mut strings, - node_type_ids, - node_field_ids, + Some(node_type_ids), + Some(node_field_ids), ) .map_err(EmitError::Compile)?; @@ -75,22 +49,18 @@ fn emit_inner( return Err(EmitError::TooManyTransitions(layout.total_steps as usize)); } - // Collect node symbols (empty if not linked) + // Collect node symbols let mut node_symbols: Vec = Vec::new(); - if let Some(ids) = node_type_ids { - for (&sym, &node_id) in ids { - let name = strings.get_or_intern(sym, interner)?; - node_symbols.push(NodeSymbol::new(node_id.get(), name)); - } + for (&sym, &node_id) in node_type_ids { + let name = strings.get_or_intern(sym, interner)?; + node_symbols.push(NodeSymbol::new(node_id.get(), name)); } - // Collect field symbols (empty if not linked) + // Collect field symbols let mut field_symbols: Vec = Vec::new(); - if let Some(ids) = node_field_ids { - for (&sym, &field_id) in ids { - let name = strings.get_or_intern(sym, interner)?; - field_symbols.push(FieldSymbol::new(field_id.get(), name)); - } + for (&sym, &field_id) in node_field_ids { + let name = strings.get_or_intern(sym, interner)?; + field_symbols.push(FieldSymbol::new(field_id.get(), name)); } // Collect entrypoints with actual targets from layout @@ -179,7 +149,6 @@ fn emit_inner( total_size, ..Default::default() }; - header.set_linked(is_linked); header.checksum = crc32fast::hash(&output[64..]); output[..64].copy_from_slice(&header.to_bytes()); diff --git a/crates/plotnik-lib/src/emit/mod.rs b/crates/plotnik-lib/src/emit/mod.rs index 710d2b7..8242d75 100644 --- a/crates/plotnik-lib/src/emit/mod.rs +++ b/crates/plotnik-lib/src/emit/mod.rs @@ -5,10 +5,6 @@ //! - Type table building with field resolution //! - Cache-aligned instruction layout //! - Section assembly and header generation -//! -//! Entry points: -//! - [`emit`]: Emit bytecode without language linking -//! - [`emit_linked`]: Emit bytecode with node type/field validation mod emitter; mod error; @@ -28,7 +24,7 @@ mod regex_table_tests; #[cfg(test)] mod type_table_tests; -pub use emitter::{emit, emit_linked}; +pub use emitter::emit; pub use error::EmitError; pub use regex_table::{deserialize_dfa, RegexTableBuilder}; pub use string_table::StringTableBuilder; diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_captured.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_captured.snap index ea65a0c..5814bb9 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_captured.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_captured.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = [(identifier) (number)] @value --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "value" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_captured_tagged.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_captured_tagged.snap index 632a8b1..a5298c5 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_captured_tagged.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_captured_tagged.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = [A: (identifier) @a B: (number) @b] @item --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "a" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_in_quantifier.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_in_quantifier.snap index ee2b9fa..a819611 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_in_quantifier.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_in_quantifier.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (object { [A: (pair) @a B: (shorthand_property_identifier) @b] @item }* @items) --- -[flags] -linked = false - [strings] S00 "Beauty will save the world" S01 "a" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_labeled.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_labeled.snap index 656a235..cc7374f 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_labeled.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_labeled.snap @@ -6,9 +6,6 @@ Test = [ B: (number) @b ] --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "a" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_no_internal_captures.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_no_internal_captures.snap index 074ebb4..f0c6b51 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_no_internal_captures.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_no_internal_captures.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (program [(identifier) (number)] @x) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "x" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_null_injection.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_null_injection.snap index f957361..74fa3c9 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_null_injection.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_null_injection.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = [(identifier) @x (number) @y] --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "x" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_tagged_in_field_constraint.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_tagged_in_field_constraint.snap index 4ba37aa..fb8277a 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_tagged_in_field_constraint.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_tagged_in_field_constraint.snap @@ -1,11 +1,8 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (foo field: [A: (x) @a B: (y)] @kind) +Test = (pair key: [A: (identifier) @a B: (number)] @kind) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "a" @@ -13,10 +10,10 @@ S2 "A" S3 "B" S4 "kind" S5 "Test" -S6 "foo" -S7 "field" -S8 "x" -S9 "y" +S6 "pair" +S7 "identifier" +S8 "number" +S9 "key" [type_defs] T0 = @@ -46,11 +43,11 @@ _ObjWrap: Test: 06 ε 07 - 07 ! (foo) 08 - 08 ▽ field: _ 09 + 07 ! (pair) 08 + 08 ▽ key: _ 09 09 ε 12, 16 11 ▶ - 12 ! [Enum(M1)] (x) [Node Set(M0) EndEnum Set(M3)] 18 + 12 ! [Enum(M1)] (identifier) [Node Set(M0) EndEnum Set(M3)] 18 15 ... - 16 ! [Enum(M2)] (y) [EndEnum Set(M3)] 18 + 16 ! [Enum(M2)] (number) [EndEnum Set(M3)] 18 18 △ _ 11 diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_tagged_with_definition_ref.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_tagged_with_definition_ref.snap index d32afb6..7e47497 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_tagged_with_definition_ref.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_tagged_with_definition_ref.snap @@ -4,9 +4,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs Inner = (identifier) @name Test = [A: (Inner) B: (number) @b] @item --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "name" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_unlabeled.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_unlabeled.snap index 434a0b5..8f3e34e 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_unlabeled.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__alternations_unlabeled.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = [(identifier) @id (string) @str] --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "id" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_between_siblings.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_between_siblings.snap index 26d120c..4f360fd 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_between_siblings.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_between_siblings.snap @@ -1,17 +1,14 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (parent (a) . (b)) +Test = (array (identifier) . (number)) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "Test" -S2 "parent" -S3 "b" -S4 "a" +S2 "array" +S3 "identifier" +S4 "number" [type_defs] T0 = @@ -33,8 +30,8 @@ _ObjWrap: Test: 06 ε 07 - 07 ! (parent) 08 - 08 ▽ (a) 09 - 09 !▷ (b) 10 + 07 ! (array) 08 + 08 ▽ (identifier) 09 + 09 !▷ (number) 10 10 △ _ 11 11 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_first_child.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_first_child.snap index 32f5e25..ec3c2ac 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_first_child.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_first_child.snap @@ -1,16 +1,13 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (parent . (first)) +Test = (array . (identifier)) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "Test" -S2 "parent" -S3 "first" +S2 "array" +S3 "identifier" [type_defs] T0 = @@ -32,7 +29,7 @@ _ObjWrap: Test: 06 ε 07 - 07 ! (parent) 08 - 08 !▽ (first) 09 + 07 ! (array) 08 + 08 !▽ (identifier) 09 09 △ _ 10 10 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_last_child.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_last_child.snap index bbb7160..e6fd97f 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_last_child.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_last_child.snap @@ -1,16 +1,13 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (parent (last) .) +Test = (array (identifier) .) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "Test" -S2 "parent" -S3 "last" +S2 "array" +S3 "identifier" [type_defs] T0 = @@ -32,10 +29,10 @@ _ObjWrap: Test: 06 ε 07 - 07 ! (parent) 08 + 07 ! (array) 08 08 ▽ _ 13 09 ▶ 10 !△ _ 09 - 11 ! (last) 10 + 11 ! (identifier) 10 12 ▷ _ 13 13 ε 11, 12 diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_no_anchor.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_no_anchor.snap index e4ffd8e..2af5d43 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_no_anchor.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_no_anchor.snap @@ -1,17 +1,14 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (parent (a) (b)) +Test = (array (identifier) (number)) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "Test" -S2 "parent" -S3 "b" -S4 "a" +S2 "array" +S3 "identifier" +S4 "number" [type_defs] T0 = @@ -33,8 +30,8 @@ _ObjWrap: Test: 06 ε 07 - 07 ! (parent) 08 - 08 ▽ (a) 09 - 09 ▷ (b) 10 + 07 ! (array) 08 + 08 ▽ (identifier) 09 + 09 ▷ (number) 10 10 △ _ 11 11 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_with_anonymous.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_with_anonymous.snap index cffb239..f86f7b4 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_with_anonymous.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__anchors_with_anonymous.snap @@ -1,17 +1,14 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (parent "+" . (next)) +Test = (binary_expression "+" . (identifier)) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "Test" -S2 "parent" -S3 "next" -S4 "+" +S2 "binary_expression" +S3 "+" +S4 "identifier" [type_defs] T0 = @@ -33,8 +30,8 @@ _ObjWrap: Test: 06 ε 07 - 07 ! (parent) 08 + 07 ! (binary_expression) 08 08 ▽ "+" 09 - 09 !!▷ (next) 10 + 09 !!▷ (identifier) 10 10 △ _ 11 11 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_basic.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_basic.snap index 34873c5..8ea9e6d 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_basic.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_basic.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (identifier) @name --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "name" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_deeply_nested.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_deeply_nested.snap index f2b4718..616f755 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_deeply_nested.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_deeply_nested.snap @@ -1,11 +1,8 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (a (b (c (d) @d) @c) @b) @a +Test = (array (array (array (identifier) @d) @c) @b) @a --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "a" @@ -13,6 +10,8 @@ S2 "b" S3 "c" S4 "d" S5 "Test" +S6 "array" +S7 "identifier" [type_defs] T0 = @@ -49,10 +48,10 @@ _ObjWrap: Test: 06 ε 08 07 ... - 08 ! (a) [Node Set(M0)] 10 - 10 ▽ (b) [Node Set(M1)] 12 - 12 ▽ (c) [Node Set(M2)] 14 - 14 ▽ (d) [Node Set(M3)] 16 + 08 ! (array) [Node Set(M0)] 10 + 10 ▽ (array) [Node Set(M1)] 12 + 12 ▽ (array) [Node Set(M2)] 14 + 14 ▽ (identifier) [Node Set(M3)] 16 16 △ _ 17 17 △ _ 18 18 △ _ 19 diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_enum_with_type_annotation.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_enum_with_type_annotation.snap index 341bf07..132d41f 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_enum_with_type_annotation.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_enum_with_type_annotation.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = [A: (identifier) @id B: (number) @num] @expr :: Expression --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "id" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_multiple.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_multiple.snap index 7330d93..46c0932 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_multiple.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_multiple.snap @@ -3,17 +3,14 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (binary_expression (identifier) @a (number) @b) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "a" S2 "b" S3 "Test" S4 "binary_expression" -S5 "number" -S6 "identifier" +S5 "identifier" +S6 "number" [type_defs] T0 = diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_nested_flat.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_nested_flat.snap index efdd49b..f364bc5 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_nested_flat.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_nested_flat.snap @@ -1,17 +1,16 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (a (b (c) @c) @b) @a +Test = (array (array (identifier) @c) @b) @a --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "a" S2 "b" S3 "c" S4 "Test" +S5 "array" +S6 "identifier" [type_defs] T0 = @@ -43,9 +42,9 @@ _ObjWrap: Test: 06 ε 08 07 ... - 08 ! (a) [Node Set(M0)] 10 - 10 ▽ (b) [Node Set(M1)] 12 - 12 ▽ (c) [Node Set(M2)] 14 + 08 ! (array) [Node Set(M0)] 10 + 10 ▽ (array) [Node Set(M1)] 12 + 12 ▽ (identifier) [Node Set(M2)] 14 14 △ _ 15 15 △ _ 16 16 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_optional_wrapper_struct.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_optional_wrapper_struct.snap index 3e35672..d59ce08 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_optional_wrapper_struct.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_optional_wrapper_struct.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = {{(identifier) @id} @inner}? @outer --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "id" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_struct_scope.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_struct_scope.snap index bf09c08..15e1237 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_struct_scope.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_struct_scope.snap @@ -1,17 +1,16 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = {(a) @a (b) @b} @item +Test = {(identifier) @a (number) @b} @item --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "a" S2 "b" S3 "item" S4 "Test" +S5 "identifier" +S6 "number" [type_defs] T0 = @@ -44,7 +43,7 @@ Test: 06 ε 08 07 ... 08 ε [Obj] 10 - 10 ! (a) [Node Set(M0)] 12 - 12 ▷ (b) [Node Set(M1)] 14 + 10 ! (identifier) [Node Set(M0)] 12 + 12 ▷ (number) [Node Set(M1)] 14 14 ε [EndObj Set(M2)] 16 16 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_struct_with_type_annotation.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_struct_with_type_annotation.snap index 5cf041d..a980efb 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_struct_with_type_annotation.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_struct_with_type_annotation.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = {(identifier) @fn} @outer :: FunctionInfo --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "fn" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_with_type_custom.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_with_type_custom.snap index 20669db..8cf80bf 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_with_type_custom.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_with_type_custom.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (identifier) @name :: Identifier --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "Identifier" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_with_type_string.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_with_type_string.snap index d8bb868..f9392d5 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_with_type_string.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_with_type_string.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (identifier) @name :: string --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "name" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_wrapper_struct.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_wrapper_struct.snap index 414b443..15a0d1d 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_wrapper_struct.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__captures_wrapper_struct.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = {{(identifier) @id (number) @num} @row}* @rows --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "id" @@ -13,8 +10,8 @@ S2 "num" S3 "row" S4 "rows" S5 "Test" -S6 "number" -S7 "identifier" +S6 "identifier" +S7 "number" [type_defs] T0 = diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__comprehensive_multi_definition.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__comprehensive_multi_definition.snap index de43e9c..a96b059 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__comprehensive_multi_definition.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__comprehensive_multi_definition.snap @@ -10,9 +10,6 @@ Assignment = (assignment_expression left: (identifier) @target right: (Expression) @value) --- -[flags] -linked = false - [strings] S00 "Beauty will save the world" S01 "name" @@ -26,8 +23,8 @@ S08 "Assignment" S09 "identifier" S10 "number" S11 "assignment_expression" -S12 "right" -S13 "left" +S12 "left" +S13 "right" [type_defs] T00 = diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_multiple.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_multiple.snap index 39cdded..a1fbfc2 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_multiple.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_multiple.snap @@ -4,9 +4,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs Foo = (identifier) @id Bar = (string) @str --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "id" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_nested_capture.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_nested_capture.snap index 5156252..6bdce45 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_nested_capture.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_nested_capture.snap @@ -1,12 +1,9 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Inner = (call (identifier) @name) -Outer = (parent {(Inner) @item}* @items) +Inner = (call_expression (identifier) @name) +Outer = (array {(Inner) @item}* @items) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "name" @@ -14,9 +11,9 @@ S2 "item" S3 "items" S4 "Inner" S5 "Outer" -S6 "call" +S6 "call_expression" S7 "identifier" -S8 "parent" +S8 "array" [type_defs] T0 = @@ -47,14 +44,14 @@ _ObjWrap: Inner: 06 ε 07 - 07 ! (call) 08 + 07 ! (call_expression) 08 08 ▽ (identifier) [Node Set(M0)] 10 10 △ _ 11 11 ▶ Outer: 12 ε 13 - 13 ! (parent) 14 + 13 ! (array) 14 14 ε [Arr] 16 16 ε 44, 27 18 ε [EndArr Set(M2)] 20 diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_reference.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_reference.snap index 29175d4..05a0b09 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_reference.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_reference.snap @@ -4,9 +4,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs Expression = [(identifier) @name (number) @value] Root = (function_declaration name: (identifier) @name) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "name" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_single.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_single.snap index 190d54d..4225a3a 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_single.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__definitions_single.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Foo = (identifier) @id --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "id" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_alternation.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_alternation.snap index bfaa39e..ad9f483 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_alternation.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_alternation.snap @@ -3,18 +3,15 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (call_expression function: [(identifier) @fn (number) @num]) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "fn" S2 "num" S3 "Test" S4 "call_expression" -S5 "function" -S6 "identifier" -S7 "number" +S5 "identifier" +S6 "number" +S7 "function" [type_defs] T0 = diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_multiple.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_multiple.snap index c9604a7..134e0aa 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_multiple.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_multiple.snap @@ -5,9 +5,6 @@ Test = (binary_expression left: (_) @left right: (_) @right) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "left" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_negated.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_negated.snap index f5ef3ad..be2688b 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_negated.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_negated.snap @@ -1,25 +1,22 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (function_declaration name: (identifier) @name -type_parameters) +Test = (pair key: (property_identifier) @key -value) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" -S1 "name" +S1 "key" S2 "Test" -S3 "function_declaration" -S4 "type_parameters" -S5 "identifier" +S3 "pair" +S4 "property_identifier" +S5 "value" [type_defs] T0 = -T1 = Struct M0:1 ; { name } +T1 = Struct M0:1 ; { key } [type_members] -M0: S1 → T0 ; name: +M0: S1 → T0 ; key: [type_names] N0: S2 → T1 ; Test @@ -37,7 +34,7 @@ _ObjWrap: Test: 06 ε 08 07 ... - 08 ! -type_parameters (function_declaration) 10 - 10 ▽ name: (identifier) [Node Set(M0)] 12 + 08 ! -value (pair) 10 + 10 ▽ key: (property_identifier) [Node Set(M0)] 12 12 △ _ 13 13 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_single.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_single.snap index 0230b1f..d832684 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_single.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__fields_single.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (function_declaration name: (identifier) @name) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "name" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_anonymous.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_anonymous.snap index 058c27c..cc5a491 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_anonymous.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_anonymous.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (binary_expression "+" @op) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "op" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_error.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_error.snap index 56252bc..7ca6cc1 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_error.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_error.snap @@ -3,14 +3,10 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (ERROR) @err --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "err" S2 "Test" -S3 "ERROR" [type_defs] T0 = @@ -35,5 +31,5 @@ _ObjWrap: Test: 06 ε 08 07 ... - 08 ! (ERROR) [Node Set(M0)] 10 + 08 ! (_) [Node Set(M0)] 10 10 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_missing.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_missing.snap index cbade5f..1d9e969 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_missing.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_missing.snap @@ -3,14 +3,10 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (MISSING) @m --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "m" S2 "Test" -S3 "MISSING" [type_defs] T0 = @@ -35,5 +31,5 @@ _ObjWrap: Test: 06 ε 08 07 ... - 08 ! (MISSING) [Node Set(M0)] 10 + 08 ! (_) [Node Set(M0)] 10 10 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_named.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_named.snap index 5e44bf6..8f33669 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_named.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_named.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (identifier) @id --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "id" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_wildcard_any.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_wildcard_any.snap index 5ae3522..fa856e4 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_wildcard_any.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_wildcard_any.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (pair key: _ @key) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "key" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_wildcard_named.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_wildcard_named.snap index 2e6422e..a02311d 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_wildcard_named.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__nodes_wildcard_named.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (pair key: (_) @key) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "key" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__optional_first_child.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__optional_first_child.snap index 6cd9b8f..e66459e 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__optional_first_child.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__optional_first_child.snap @@ -3,17 +3,14 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (program (identifier)? @id (number) @n) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "id" S2 "n" S3 "Test" S4 "program" -S5 "number" -S6 "identifier" +S5 "identifier" +S6 "number" [type_defs] T0 = diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__optional_null_injection.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__optional_null_injection.snap index 2095a47..b655def 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__optional_null_injection.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__optional_null_injection.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (function_declaration (decorator)? @dec) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "dec" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_first_child_array.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_first_child_array.snap index 721908e..7bdd361 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_first_child_array.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_first_child_array.snap @@ -3,17 +3,14 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (array (identifier)* @ids (number) @n) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "ids" S2 "n" S3 "Test" S4 "array" -S5 "number" -S6 "identifier" +S5 "identifier" +S6 "number" [type_defs] T0 = diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_optional.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_optional.snap index 2095a47..b655def 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_optional.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_optional.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (function_declaration (decorator)? @dec) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "dec" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_optional_nongreedy.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_optional_nongreedy.snap index 83f3457..677ca89 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_optional_nongreedy.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_optional_nongreedy.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (function_declaration (decorator)?? @dec) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "dec" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_plus.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_plus.snap index 09eb7df..eaae60b 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_plus.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_plus.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (identifier)+ @items --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "items" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_plus_nongreedy.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_plus_nongreedy.snap index 53e9f67..1432f2d 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_plus_nongreedy.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_plus_nongreedy.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (identifier)+? @items --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "items" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_repeat_navigation.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_repeat_navigation.snap index 360fdfa..b666fd5 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_repeat_navigation.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_repeat_navigation.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (function_declaration (decorator)* @decs) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "decs" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_sequence_in_called_def.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_sequence_in_called_def.snap index 2f2f101..54ae432 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_sequence_in_called_def.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_sequence_in_called_def.snap @@ -3,11 +3,8 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Item = (identifier) @name Collect = {(Item) @item}* @items -Test = (parent (Collect)) +Test = (array (Collect)) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "name" @@ -17,7 +14,7 @@ S4 "Item" S5 "Collect" S6 "Test" S7 "identifier" -S8 "parent" +S8 "array" [type_defs] T0 = @@ -61,7 +58,7 @@ Collect: Test: 16 ε 17 - 17 ! (parent) 18 + 17 ! (array) 18 18 ▽ (Collect) 11 : 19 19 △ _ 20 20 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_star.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_star.snap index c7b6171..67d6213 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_star.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_star.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (identifier)* @items --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "items" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_star_nongreedy.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_star_nongreedy.snap index f807d3f..4e4aee6 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_star_nongreedy.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_star_nongreedy.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (identifier)*? @items --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "items" diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_struct_array.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_struct_array.snap index ae750b6..2654202 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_struct_array.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__quantifiers_struct_array.snap @@ -3,9 +3,6 @@ source: crates/plotnik-lib/src/emit/emit_tests.rs --- Test = (array {(identifier) @a (number) @b}* @items) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "a" @@ -13,8 +10,8 @@ S2 "b" S3 "items" S4 "Test" S5 "array" -S6 "number" -S7 "identifier" +S6 "identifier" +S7 "number" [type_defs] T0 = diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__recursion_simple.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__recursion_simple.snap index 4c3c6a6..0c038a0 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__recursion_simple.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__recursion_simple.snap @@ -6,9 +6,6 @@ Expr = [ Rec: (call_expression function: (identifier) @fn arguments: (Expr) @inner) ] --- -[flags] -linked = false - [strings] S00 "Beauty will save the world" S01 "value" @@ -19,9 +16,9 @@ S05 "Rec" S06 "Expr" S07 "number" S08 "call_expression" -S09 "arguments" +S09 "identifier" S10 "function" -S11 "identifier" +S11 "arguments" [type_defs] T0 = diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__recursion_with_structured_result.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__recursion_with_structured_result.snap index d1ae05f..a9a7714 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__recursion_with_structured_result.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__recursion_with_structured_result.snap @@ -8,9 +8,6 @@ Expr = [ Test = (program (Expr) @expr) --- -[flags] -linked = false - [strings] S00 "Beauty will save the world" S01 "value" @@ -23,10 +20,10 @@ S07 "Expr" S08 "Test" S09 "number" S10 "call_expression" -S11 "arguments" -S12 "function" -S13 "identifier" -S14 "program" +S11 "identifier" +S12 "program" +S13 "function" +S14 "arguments" [type_defs] T00 = diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_basic.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_basic.snap index 579c894..af9c93f 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_basic.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_basic.snap @@ -1,17 +1,14 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (parent {(a) (b)}) +Test = (array {(identifier) (number)}) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "Test" -S2 "parent" -S3 "b" -S4 "a" +S2 "array" +S3 "identifier" +S4 "number" [type_defs] T0 = @@ -33,8 +30,8 @@ _ObjWrap: Test: 06 ε 07 - 07 ! (parent) 08 - 08 ▽ (a) 09 - 09 ▷ (b) 10 + 07 ! (array) 08 + 08 ▽ (identifier) 09 + 09 ▷ (number) 10 10 △ _ 11 11 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_in_quantifier.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_in_quantifier.snap index 8789d93..69f2933 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_in_quantifier.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_in_quantifier.snap @@ -1,18 +1,15 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (parent {(a) (b)}* @items) +Test = (array {(identifier) (number)}* @items) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "items" S2 "Test" -S3 "parent" -S4 "b" -S5 "a" +S3 "array" +S4 "identifier" +S5 "number" [type_defs] T0 = @@ -37,17 +34,17 @@ _ObjWrap: Test: 06 ε 07 - 07 ! (parent) 08 + 07 ! (array) 08 08 ε [Arr] 10 10 ε 29, 21 12 ε [EndArr Set(M0)] 14 14 △ _ 20 15 ... - 16 ▷ (b) [Node Push] 18 + 16 ▷ (number) [Node Push] 18 18 ε 36, 12 20 ▶ 21 ε [EndArr Set(M0)] 20 - 23 ! (a) 16 + 23 ! (identifier) 16 24 ▷ _ 27 25 ε 24, 12 27 ε 23, 25 diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_nested.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_nested.snap index 6a5e059..531e573 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_nested.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_nested.snap @@ -1,19 +1,16 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (parent {(a) {(b) (c)} (d)}) +Test = (array {(identifier) {(number) (string)} (null)}) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "Test" -S2 "parent" -S3 "d" -S4 "c" -S5 "b" -S6 "a" +S2 "array" +S3 "identifier" +S4 "number" +S5 "string" +S6 "null" [type_defs] T0 = @@ -35,10 +32,10 @@ _ObjWrap: Test: 06 ε 07 - 07 ! (parent) 08 - 08 ▽ (a) 09 - 09 ▷ (b) 10 - 10 ▷ (c) 11 - 11 ▷ (d) 12 + 07 ! (array) 08 + 08 ▽ (identifier) 09 + 09 ▷ (number) 10 + 10 ▷ (string) 11 + 11 ▷ (null) 12 12 △ _ 13 13 ▶ diff --git a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_with_captures.snap b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_with_captures.snap index 61b16d1..4b15cb1 100644 --- a/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_with_captures.snap +++ b/crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__emit_tests__sequences_with_captures.snap @@ -1,17 +1,16 @@ --- source: crates/plotnik-lib/src/emit/emit_tests.rs --- -Test = (parent {(a) @a (b) @b}) +Test = (array {(identifier) @a (number) @b}) --- -[flags] -linked = false - [strings] S0 "Beauty will save the world" S1 "a" S2 "b" S3 "Test" -S4 "parent" +S4 "array" +S5 "identifier" +S6 "number" [type_defs] T0 = @@ -40,8 +39,8 @@ _ObjWrap: Test: 06 ε 07 - 07 ! (parent) 08 - 08 ▽ (a) [Node Set(M0)] 10 - 10 ▷ (b) [Node Set(M1)] 12 + 07 ! (array) 08 + 08 ▽ (identifier) [Node Set(M0)] 10 + 10 ▷ (number) [Node Set(M1)] 12 12 △ _ 13 13 ▶ diff --git a/crates/plotnik-lib/src/engine/engine_tests.rs b/crates/plotnik-lib/src/engine/engine_tests.rs index 2a978d9..0087b6f 100644 --- a/crates/plotnik-lib/src/engine/engine_tests.rs +++ b/crates/plotnik-lib/src/engine/engine_tests.rs @@ -7,7 +7,7 @@ use indoc::indoc; use crate::QueryBuilder; use crate::bytecode::Module; -use crate::emit::emit_linked; +use crate::emit::emit; use super::{Materializer, VM, ValueMaterializer}; @@ -28,7 +28,7 @@ fn execute_with_entry(query: &str, source: &str, entry: Option<&str>) -> String assert!(query_obj.is_valid(), "query should be valid"); - let bytecode = emit_linked(&query_obj).expect("emit failed"); + let bytecode = emit(&query_obj).expect("emit failed"); let module = Module::load(&bytecode).expect("decode failed"); let tree = lang.parse(source); diff --git a/crates/plotnik-lib/src/engine/verify_tests.rs b/crates/plotnik-lib/src/engine/verify_tests.rs index 1f18a71..0e5c21f 100644 --- a/crates/plotnik-lib/src/engine/verify_tests.rs +++ b/crates/plotnik-lib/src/engine/verify_tests.rs @@ -3,7 +3,7 @@ use crate::Colors; use crate::QueryBuilder; use crate::bytecode::{Module, TypeId}; -use crate::emit::emit_linked; +use crate::emit::emit; use crate::engine::value::{NodeHandle, Value}; use super::debug_verify_type; @@ -17,7 +17,7 @@ fn build_module(query: &str) -> (Module, TypeId) { .analyze() .link(&lang); assert!(query_obj.is_valid(), "query should be valid"); - let bytecode = emit_linked(&query_obj).expect("emit failed"); + let bytecode = emit(&query_obj).expect("emit failed"); let module = Module::load(&bytecode).expect("decode failed"); let declared_type = module.entrypoints().get(0).result_type; (module, declared_type) diff --git a/crates/plotnik-lib/src/query/dump.rs b/crates/plotnik-lib/src/query/dump.rs index 9985671..b8f28dd 100644 --- a/crates/plotnik-lib/src/query/dump.rs +++ b/crates/plotnik-lib/src/query/dump.rs @@ -36,12 +36,5 @@ mod test_helpers { pub fn dump_diagnostics_raw(&self) -> String { self.diagnostics().render(self.source_map()) } - - pub fn emit_typescript(&self) -> String { - let bytecode = self.emit().expect("bytecode emission should succeed"); - let module = crate::bytecode::Module::load(&bytecode) - .expect("module loading should succeed"); - crate::typegen::typescript::emit(&module) - } } } diff --git a/crates/plotnik-lib/src/query/query_tests.rs b/crates/plotnik-lib/src/query/query_tests.rs index 82e74b5..0cbf193 100644 --- a/crates/plotnik-lib/src/query/query_tests.rs +++ b/crates/plotnik-lib/src/query/query_tests.rs @@ -93,7 +93,7 @@ impl QueryAnalyzed { #[track_caller] pub fn expect_valid_types(src: &str) -> String { - let query = Self::parse_and_validate(src); + let query = Self::parse_and_validate(src).link(&javascript()); if !query.is_valid() { panic!( "Expected valid types, got error:\n{}", @@ -109,14 +109,6 @@ impl QueryAnalyzed { #[track_caller] pub fn expect_valid_bytecode(src: &str) -> String { - let query = Self::parse_and_validate(src); - let bytecode = query.emit().expect("bytecode emission should succeed"); - let module = Module::load(&bytecode).expect("module loading should succeed"); - crate::bytecode::dump(&module, crate::Colors::OFF) - } - - #[track_caller] - pub fn expect_valid_linked_bytecode(src: &str) -> String { let query = Self::parse_and_validate(src).link(&javascript()); if !query.is_valid() { panic!( @@ -131,12 +123,6 @@ impl QueryAnalyzed { #[track_caller] pub fn expect_valid_bytes(src: &str) -> Vec { - let query = Self::parse_and_validate(src); - query.emit().expect("bytecode emission should succeed") - } - - #[track_caller] - pub fn expect_valid_linked_bytes(src: &str) -> Vec { let query = Self::parse_and_validate(src).link(&javascript()); if !query.is_valid() { panic!( diff --git a/crates/plotnik-lib/src/query/stages.rs b/crates/plotnik-lib/src/query/stages.rs index b409882..af77a75 100644 --- a/crates/plotnik-lib/src/query/stages.rs +++ b/crates/plotnik-lib/src/query/stages.rs @@ -223,16 +223,6 @@ impl QueryAnalyzed { &self.interner } - /// Emit bytecode without language linking (no node type/field validation). - /// - /// Returns `Err(EmitError::InvalidQuery)` if the query has validation errors. - pub fn emit(&self) -> Result, crate::emit::EmitError> { - if !self.is_valid() { - return Err(crate::emit::EmitError::InvalidQuery); - } - crate::emit::emit(&self.type_context, &self.interner, &self.symbol_table) - } - pub fn link(mut self, lang: &Lang) -> LinkedQuery { let mut output = link::LinkOutput::default(); @@ -295,14 +285,12 @@ impl LinkedQuery { &self.linking.node_field_ids } - /// Emit bytecode with node type/field symbols from language linking. - /// - /// Returns `Err(EmitError::InvalidQuery)` if the query has validation errors. + /// Emit bytecode. Returns `Err(EmitError::InvalidQuery)` if the query has errors. pub fn emit(&self) -> Result, crate::emit::EmitError> { if !self.is_valid() { return Err(crate::emit::EmitError::InvalidQuery); } - crate::emit::emit_linked(self) + crate::emit::emit(self) } } diff --git a/docs/binary-format/01-overview.md b/docs/binary-format/01-overview.md index 0c03f3e..d4e9b33 100644 --- a/docs/binary-format/01-overview.md +++ b/docs/binary-format/01-overview.md @@ -67,20 +67,20 @@ Section offsets are not stored in the header. Loaders compute them by: - Section size = count × record size (or explicit size for blobs) 3. Blob sizes come from header: `str_blob_size` and `regex_blob_size` -## Header (v2) +## Header (v3) ```rust #[repr(C, align(64))] struct Header { // Bytes 0-23: Identity and sizes (6 × u32) magic: [u8; 4], // b"PTKQ" - version: u32, // 2 + version: u32, // 3 checksum: u32, // CRC32 of everything after header total_size: u32, str_blob_size: u32, regex_blob_size: u32, - // Bytes 24-45: Element counts (11 × u16) — order matches section order + // Bytes 24-43: Element counts (10 × u16) — order matches section order str_table_count: u16, regex_table_count: u16, node_types_count: u16, @@ -91,20 +91,8 @@ struct Header { type_names_count: u16, entrypoints_count: u16, transitions_count: u16, - flags: u16, - // Bytes 46-63: Reserved - _reserved: [u8; 18], + // Bytes 44-63: Reserved + _reserved: [u8; 20], } ``` - -### Flags - -| Bit | Name | Description | -| --- | ------ | -------------------------------------------------------- | -| 0 | LINKED | If set, bytecode contains resolved NodeTypeId/NodeFieldId | - -**Linked vs Unlinked**: - -- **Linked**: Match instructions store tree-sitter `NodeTypeId` and `NodeFieldId` directly. Executable immediately. -- **Unlinked**: Match instructions store `StringId` references. Requires linking against a grammar before execution.