From ebc42d57ccc9de614e5b9bba3a6bfc1ec33ef05d Mon Sep 17 00:00:00 2001 From: Jay Pratt Date: Mon, 27 Jan 2025 18:54:31 +1100 Subject: [PATCH] Support mode node types --- Cargo.lock | 1 + takolib/Cargo.toml | 1 + takolib/src/ast/mod.rs | 142 +++++++++++++++++++++----------------- takolib/src/ast/nodes.rs | 60 ++++++++++++++++ takolib/src/parser/mod.rs | 3 +- 5 files changed, 144 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75b32b3c..78ae14d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2797,6 +2797,7 @@ dependencies = [ "log", "melior", "num-traits", + "paste", "pretty_assertions", "rand 0.9.0-alpha.2", "short-typed-index", diff --git a/takolib/Cargo.toml b/takolib/Cargo.toml index e5e52b4e..ff4a26ec 100644 --- a/takolib/Cargo.toml +++ b/takolib/Cargo.toml @@ -57,6 +57,7 @@ tree-sitter-tako = { path = "../tree-sitter-tako", features = [ ] } tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter" } entity-component-slab = { path = "../entity-component-slab", features = [ ] } test_each_file = "0.3.2" +paste = "1.0.15" [dev-dependencies] strum = "0.26.2" diff --git a/takolib/src/ast/mod.rs b/takolib/src/ast/mod.rs index 654952fe..94d294d3 100644 --- a/takolib/src/ast/mod.rs +++ b/takolib/src/ast/mod.rs @@ -1,3 +1,4 @@ +pub use paste::paste; mod nodes; use entity_component_slab::{ChildSlab, Slab}; pub use nodes::*; @@ -38,74 +39,91 @@ pub struct Ast { pub atoms: ChildSlab, pub string_interner: StringInterner, + pub node_types: NodeTypes, +} + +macro_rules! construct_lang { + ($start_value: expr, $( $name: ident ),*) => { + { + let _lang: &Language = &tree_sitter_tako::LANGUAGE.into(); - // TS Node Ids - // TODO: generated from - // ../../../tree_sitter_tako/src/node-types.json - pub add_node_id: TsNodeId, - pub and_node_id: TsNodeId, - pub assign_node_id: TsNodeId, - pub binding_node_id: TsNodeId, - pub bit_and_node_id: TsNodeId, - pub bit_not_node_id: TsNodeId, - pub bit_or_node_id: TsNodeId, - pub bit_xor_node_id: TsNodeId, - pub block_node_id: TsNodeId, - pub call_node_id: TsNodeId, - pub color_node_id: TsNodeId, - pub container_node_id: TsNodeId, - pub div_node_id: TsNodeId, - pub equals_node_id: TsNodeId, - pub exp_node_id: TsNodeId, - pub field_node_id: TsNodeId, - pub format_expression_node_id: TsNodeId, - pub greater_than_node_id: TsNodeId, - pub greater_than_equals_node_id: TsNodeId, - pub has_type_node_id: TsNodeId, - pub hex_literal_node_id: TsNodeId, - pub index_node_id: TsNodeId, - pub left_shift_node_id: TsNodeId, - pub less_than_node_id: TsNodeId, - pub less_than_equals_node_id: TsNodeId, - pub mod_node_id: TsNodeId, - pub mul_node_id: TsNodeId, - pub neg_node_id: TsNodeId, - pub nesting_comment_node_id: TsNodeId, - pub not_node_id: TsNodeId, - pub not_equals_node_id: TsNodeId, - pub or_node_id: TsNodeId, - pub parens_node_id: TsNodeId, - pub range_node_id: TsNodeId, - pub right_shift_node_id: TsNodeId, - pub sequence_node_id: TsNodeId, - pub set_node_id: TsNodeId, - pub shebang_node_id: TsNodeId, - pub single_line_comment_node_id: TsNodeId, - pub source_file_node_id: TsNodeId, - pub spread_node_id: TsNodeId, - pub string_literal_node_id: TsNodeId, - pub sub_node_id: TsNodeId, - pub try_node_id: TsNodeId, - pub escape_sequence_node_id: TsNodeId, - pub exists_node_id: TsNodeId, - pub float_literal_node_id: TsNodeId, - pub forall_node_id: TsNodeId, - pub given_node_id: TsNodeId, - pub heading_node_id: TsNodeId, - pub ident_node_id: TsNodeId, - pub int_literal_node_id: TsNodeId, + paste!{ + Ast { + node_types: NodeTypes { + $( + [< _ $name>]: _lang.id_for_node_kind(stringify!($name), /*named*/ true), + )* + }, + ..$start_value + } + } + } + } } impl Ast { #[must_use] pub fn new(filepath: PathBuf) -> Self { - let tako_lang: &Language = &tree_sitter_tako::LANGUAGE.into(); - let int_literal_node_id = tako_lang.id_for_node_kind("int_literal", /*named*/ true); - Self { - filepath, - int_literal_node_id, - ..Self::default() - } + construct_lang!( + Self { + filepath, + ..Self::default() + }, + // TODO: generate from + // ./tree_sitter_tako/src/node-types.json | jq "map(.type)" + add, + and, + assign, + binding, + bit_and, + bit_not, + bit_or, + bit_xor, + block, + call, + color, + container, + div, + equals, + exp, + field, + format_expression, + greater_than, + greater_than_equals, + has_type, + hex_literal, + index, + left_shift, + less_than, + less_than_equals, + mod, + mul, + neg, + nesting_comment, + not, + not_equals, + or, + parens, + range, + right_shift, + sequence, + set, + shebang, + single_line_comment, + source_file, + spread, + string_literal, + sub, + try, + escape_sequence, + exists, + float_literal, + forall, + given, + heading, + ident, + int_literal + ) } #[must_use] diff --git a/takolib/src/ast/nodes.rs b/takolib/src/ast/nodes.rs index be53959b..722064f4 100644 --- a/takolib/src/ast/nodes.rs +++ b/takolib/src/ast/nodes.rs @@ -4,6 +4,66 @@ use crate::ast::string_interner::Identifier; use crate::parser::semantics::BindingMode; use smallvec::SmallVec; +#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)] +pub struct NodeTypes { + // TS Node Ids + // TODO: generate from + // ./tree_sitter_tako/src/node-types.json | jq "map(.type)" + pub _add: TsNodeId, + pub _and: TsNodeId, + pub _assign: TsNodeId, + pub _binding: TsNodeId, + pub _bit_and: TsNodeId, + pub _bit_not: TsNodeId, + pub _bit_or: TsNodeId, + pub _bit_xor: TsNodeId, + pub _block: TsNodeId, + pub _call: TsNodeId, + pub _color: TsNodeId, + pub _container: TsNodeId, + pub _div: TsNodeId, + pub _equals: TsNodeId, + pub _exp: TsNodeId, + pub _field: TsNodeId, + pub _format_expression: TsNodeId, + pub _greater_than: TsNodeId, + pub _greater_than_equals: TsNodeId, + pub _has_type: TsNodeId, + pub _hex_literal: TsNodeId, + pub _index: TsNodeId, + pub _left_shift: TsNodeId, + pub _less_than: TsNodeId, + pub _less_than_equals: TsNodeId, + pub _mod: TsNodeId, + pub _mul: TsNodeId, + pub _neg: TsNodeId, + pub _nesting_comment: TsNodeId, + pub _not: TsNodeId, + pub _not_equals: TsNodeId, + pub _or: TsNodeId, + pub _parens: TsNodeId, + pub _range: TsNodeId, + pub _right_shift: TsNodeId, + pub _sequence: TsNodeId, + pub _set: TsNodeId, + pub _shebang: TsNodeId, + pub _single_line_comment: TsNodeId, + pub _source_file: TsNodeId, + pub _spread: TsNodeId, + pub _string_literal: TsNodeId, + pub _sub: TsNodeId, + pub _try: TsNodeId, + pub _escape_sequence: TsNodeId, + pub _exists: TsNodeId, + pub _float_literal: TsNodeId, + pub _forall: TsNodeId, + pub _given: TsNodeId, + pub _heading: TsNodeId, + pub _ident: TsNodeId, + pub _int_literal: TsNodeId, +} + + #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct Node { pub id: NodeData, diff --git a/takolib/src/parser/mod.rs b/takolib/src/parser/mod.rs index 2b0ff8ea..b66bbd74 100644 --- a/takolib/src/parser/mod.rs +++ b/takolib/src/parser/mod.rs @@ -314,8 +314,9 @@ fn handle_subtree<'a>( } // TODO: Handle merging // TODO: Handle constructing this kind of node from it's children + let nt = &ast.node_types; - if ts_node.kind_id() == ast.int_literal_node_id { + if ts_node.kind_id() == nt._int_literal { println!("INT_LITERAL"); } let info = (