Skip to documentation
SLOP

tiny.smg.tree.runtime.subtree

Reference tiny.smg tree runtime subtree

Defined in tree.runtime.

API (9)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callstree.runtimesubtree
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callstree.runtime.parserparsetest; no linktools.smg.src.tree.runtime.parsertest: focused active version compacti...test; no linktools.smg.src.tree.runtime.parsertest: focused an allowed boundary mer...test; no linktools.smg.src.tree.runtime.parsertest: focused equal-precedence active...test; no linktools.smg.src.tree.runtime.parsertest: focused temporary overflow cann...+2 moretree.runtime.subtree.Treedeinit
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callstree.runtime.parserparsetest; no linktools.smg.src.tree.runtime.parsertest: focused active version compacti...test; no linktools.smg.src.tree.runtime.parsertest: focused an allowed boundary mer...test; no linktools.smg.src.tree.runtime.parsertest: focused equal-precedence active...test; no linktools.smg.src.tree.runtime.parsertest: focused temporary overflow cann...+2 moretree.runtime.subtree.Treeinit
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest; no linktools.smg.src.tree.runtime.parsertest: focused temporary version overf...test; no linktools.smg.src.tree.runtime.subtreetest: tree owns immutable source spanstree.runtime.language.LanguagesymbolMetadatatree.runtime.subtree.Treeleaf
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest; no linktools.smg.src.tree.runtime.parsertest: focused active version compacti...test; no linktools.smg.src.tree.runtime.parsertest: focused an allowed boundary mer...test; no linktools.smg.src.tree.runtime.parsertest: focused equal-precedence active...test; no linktools.smg.src.tree.runtime.parsertest: focused temporary overflow cann...tree.runtime.language.LanguagesymbolMetadataprivate; no linktools.smg.src.tree.runtime.subtree.TreedescendantCountstree.runtime.subtree.Treenode
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallstree.runtime.selectionconsiderprivate; no linktools.smg.src.tree.runtime.stackpreferredprivate sourcelib.quic.src.properties.tls.Pairdeinittree.runtime.subtreeorder
Static calls · unresolved targets: 2 · external targets: 0.

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.

Complete caller list for tree.runtime.subtree.Tree.init

7 direct callers.

Audit

Definitions10
Public names10
Members17
Version26.7.0
Revisiondaab053ee433