tiny.smg.tree.runtime.subtree
Defined in tree.runtime.
API (9)
Actions
Public operations.
Types and contracts
Public types and contracts.
Source
Source: tools/smg/src/tree/runtime/root.zig:9
zig
pub const subtree = @import("subtree.zig");Source: tools/smg/src/tree/runtime/subtree.zig
zig
const std = @import("std");const runtime = @import("root.zig");const abi = runtime.abi;const language = runtime.language;const lexer = runtime.lexer;const scanner = @import("scanner.zig");pub const Subtree = struct { symbol: abi.Symbol, children: []const *const Subtree, start: lexer.Position, end: lexer.Position, production_id: u16, dynamic_precedence: i32, parse_state: abi.State, visible_descendant_count: u32, named_descendant_count: u32, visible: bool, named: bool, extra: bool, scanner_state: ?scanner.State,};pub const Tree = struct { allocator: std.mem.Allocator, arena: std.heap.ArenaAllocator, language: language.Language, root: *const Subtree, pub fn init(allocator: std.mem.Allocator, lang: language.Language) !*Tree { const self = try allocator.create(Tree); self.* = .{ .allocator = allocator, .arena = std.heap.ArenaAllocator.init(allocator), .language = lang, .root = undefined, }; return self; } pub fn deinit(self: *Tree) void { const allocator = self.allocator; self.arena.deinit(); allocator.destroy(self); } pub fn leaf( self: *Tree, symbol: abi.Symbol, start: lexer.Position, end: lexer.Position, parse_state: abi.State, extra: bool, scanner_state: ?scanner.State, ) !*const Subtree { const metadata = self.language.symbolMetadata(symbol); const result = try self.arena.allocator().create(Subtree); result.* = .{ .symbol = symbol, .children = &.{}, .start = start, .end = end, .production_id = 0, .dynamic_precedence = 0, .parse_state = parse_state, .visible_descendant_count = 0, .named_descendant_count = 0, .visible = metadata.visible, .named = metadata.named, .extra = extra, .scanner_state = scanner_state, }; return result; } pub fn node( self: *Tree, symbol: abi.Symbol, source_children: []const *const Subtree, production_id: u16, parse_state: abi.State, dynamic_precedence: i32, position: lexer.Position, extra: bool, ) !*const Subtree { const allocator = self.arena.allocator(); const children = try allocator.dupe(*const Subtree, source_children); var total_precedence = dynamic_precedence; for (children) |child| total_precedence += child.dynamic_precedence; const descendant_counts = self.descendantCounts(children, production_id); const metadata = self.language.symbolMetadata(symbol); const result = try allocator.create(Subtree); result.* = .{ .symbol = symbol, .children = children, .start = if (children.len == 0) position else children[0].start, .end = if (children.len == 0) position else children[children.len - 1].end, .production_id = production_id, .dynamic_precedence = total_precedence, .parse_state = parse_state, .visible_descendant_count = descendant_counts.visible, .named_descendant_count = descendant_counts.named, .visible = metadata.visible, .named = metadata.named, .extra = extra, .scanner_state = null, }; return result; } fn descendantCounts(self: *Tree, children: []const *const Subtree, production_id: u16) struct { visible: u32, named: u32 } { const aliases = self.language.aliases(production_id); var visible: u32 = 0; var named: u32 = 0; var structural_index: usize = 0; for (children) |child| { const alias_symbol = if (!child.extra and structural_index < aliases.len) aliases[structural_index] else 0; if (!child.extra) structural_index += 1; if (child.symbol != 0 and alias_symbol != 0) { visible +|= 1; named +|= @intFromBool(self.language.symbolMetadata(alias_symbol).named); } else if (child.visible) { visible +|= 1; named +|= @intFromBool(child.named); } else if (child.children.len > 0) { visible +|= child.visible_descendant_count; named +|= child.named_descendant_count; } } return .{ .visible = visible, .named = named }; } pub fn withExtra(self: *Tree, source: *const Subtree, extra: bool) !*const Subtree { if (source.extra == extra) return source; const result = try self.arena.allocator().create(Subtree); result.* = source.*; result.extra = extra; return result; } pub fn withSpan(self: *Tree, source: *const Subtree, start: lexer.Position, end: lexer.Position) !*const Subtree { if (std.meta.eql(source.start, start) and std.meta.eql(source.end, end)) return source; const result = try self.arena.allocator().create(Subtree); result.* = source.*; result.start = start; result.end = end; return result; }};pub fn order(allocator: std.mem.Allocator, left: *const Subtree, right: *const Subtree) !std.math.Order { const Pair = struct { left: *const Subtree, right: *const Subtree }; var pending: std.ArrayList(Pair) = .empty; defer pending.deinit(allocator); try pending.append(allocator, .{ .left = left, .right = right }); while (pending.pop()) |pair| { if (pair.left.symbol < pair.right.symbol) return .lt; if (pair.left.symbol > pair.right.symbol) return .gt; if (pair.left.children.len < pair.right.children.len) return .lt; if (pair.left.children.len > pair.right.children.len) return .gt; var index = pair.left.children.len; while (index > 0) { index -= 1; try pending.append(allocator, .{ .left = pair.left.children[index], .right = pair.right.children[index], }); } } return .eq;}test "tree owns immutable source spans" { const raw = try std.testing.allocator.create(abi.Language); defer std.testing.allocator.destroy(raw); raw.* = std.mem.zeroes(abi.Language); raw.abi_version = 15; raw.lex_fn = testLex; var actions = [_]abi.ActionEntry{std.mem.zeroes(abi.ActionEntry)}; raw.parse_actions = &actions; var metadata = [_]abi.SymbolMetadata{ .{ .visible = false, .named = false, .supertype = false }, .{ .visible = true, .named = true, .supertype = false }, }; raw.symbol_metadata = &metadata; const lang = try language.Language.init(raw); const tree = try Tree.init(std.testing.allocator, lang); defer tree.deinit(); const leaf = try tree.leaf(1, .{ .byte = 2, .point = .{ .row = 0, .column = 2 } }, .{ .byte = 3, .point = .{ .row = 0, .column = 3 } }, 1, false, null); try std.testing.expectEqual(@as(u32, 2), leaf.start.byte); try std.testing.expect(leaf.visible); try std.testing.expectEqual(@as(u32, 0), leaf.visible_descendant_count);}fn testLex(_: *abi.Lexer, _: abi.State) callconv(.c) bool { return false;}Complete caller list for tree.runtime.subtree.Tree.deinit
7 direct callers.
tiny.smg.tree.runtime.parser.parse[function] attools/smg/src/tree/runtime/parser.zig:50tools.smg.src.tree.runtime.parser.test_focused_active_version_compaction_ranks_precedence_before_stable_identities[function] — test; no exact target attools/smg/src/tree/runtime/parser.zig:472in nearest public ownertiny.smg.tree.runtime.parsertools.smg.src.tree.runtime.parser.test_focused_an_allowed_boundary_merge_frees_the_next_temporary_version[function] — test; no exact target attools/smg/src/tree/runtime/parser.zig:623in nearest public ownertiny.smg.tree.runtime.parsertools.smg.src.tree.runtime.parser.test_focused_equal-precedence_active_version_compaction_retains_the_first_six_identities[function] — test; no exact target attools/smg/src/tree/runtime/parser.zig:428in nearest public ownertiny.smg.tree.runtime.parsertools.smg.src.tree.runtime.parser.test_focused_temporary_overflow_cannot_merge_a_dropped_late_candidate[function] — test; no exact target attools/smg/src/tree/runtime/parser.zig:565in nearest public ownertiny.smg.tree.runtime.parsertools.smg.src.tree.runtime.parser.test_focused_temporary_version_overflow_is_global_and_retains_FIFO_identities[function] — test; no exact target attools/smg/src/tree/runtime/parser.zig:516in nearest public ownertiny.smg.tree.runtime.parsertools.smg.src.tree.runtime.subtree.test_tree_owns_immutable_source_spans[function] — test; no exact target attools/smg/src/tree/runtime/subtree.zig:174in nearest public ownertiny.smg.tree.runtime.subtree
Complete caller list for tree.runtime.subtree.Tree.init
7 direct callers.
tiny.smg.tree.runtime.parser.parse[function] attools/smg/src/tree/runtime/parser.zig:50tools.smg.src.tree.runtime.parser.test_focused_active_version_compaction_ranks_precedence_before_stable_identities[function] — test; no exact target attools/smg/src/tree/runtime/parser.zig:472in nearest public ownertiny.smg.tree.runtime.parsertools.smg.src.tree.runtime.parser.test_focused_an_allowed_boundary_merge_frees_the_next_temporary_version[function] — test; no exact target attools/smg/src/tree/runtime/parser.zig:623in nearest public ownertiny.smg.tree.runtime.parsertools.smg.src.tree.runtime.parser.test_focused_equal-precedence_active_version_compaction_retains_the_first_six_identities[function] — test; no exact target attools/smg/src/tree/runtime/parser.zig:428in nearest public ownertiny.smg.tree.runtime.parsertools.smg.src.tree.runtime.parser.test_focused_temporary_overflow_cannot_merge_a_dropped_late_candidate[function] — test; no exact target attools/smg/src/tree/runtime/parser.zig:565in nearest public ownertiny.smg.tree.runtime.parsertools.smg.src.tree.runtime.parser.test_focused_temporary_version_overflow_is_global_and_retains_FIFO_identities[function] — test; no exact target attools/smg/src/tree/runtime/parser.zig:516in nearest public ownertiny.smg.tree.runtime.parsertools.smg.src.tree.runtime.subtree.test_tree_owns_immutable_source_spans[function] — test; no exact target attools/smg/src/tree/runtime/subtree.zig:174in nearest public ownertiny.smg.tree.runtime.subtree
Audit
| Definitions | 10 |
|---|---|
| Public names | 10 |
| Members | 17 |
| Version | 26.7.0 |
| Revision | daab053ee433 |