Skip to documentation
SLOP

tiny.smg.tree.runtime.lexer

Reference tiny.smg tree runtime lexer

Defined in tree.runtime.

API (12)

Actions

Public operations.

Types and contracts

Public types and contracts.

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

Source

Called byCallstree.runtime.lexer.Lexerstarttest; no linktools.smg.src.tree.runtime.lexertest: lexer exposes generated and nat...test; no linktools.smg.src.tree.scanner.witness.testtest: focused witness lexer matches r...private; no linktools.smg.src.tree.runtime.lexer.LexercodepointLengthprivate; no linktools.smg.src.tree.runtime.lexer.Lexerrefreshtree.runtime.lexer.Lexeradvance
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate; no linktools.smg.src.tree.runtime.lexer.Lexerrefreshtest; no linktools.smg.src.tree.scanner.witness.testtest: focused witness lexer matches r...tree.runtime.lexer.Lexereof
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest; no linktools.smg.src.tree.runtime.lexertest: lexer exposes generated and nat...private; no linktools.smg.src.tree.runtime.parserlextree.runtime.lexer.LexermarkEndtree.runtime.lexer.Lexerfinish
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest; no linktools.smg.src.tree.runtime.lexertest: lexer exposes generated and nat...private; no linktools.smg.src.tree.runtime.parserlextest; no linktools.smg.src.tree.runtime.scannertest: runtime scanner dispatch never ...test; no linktools.smg.src.tree.scanner.witness.testtest: focused witness lexer matches r...tree.runtime.lexer.Lexerinit
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest; no linktools.smg.src.tree.runtime.lexertest: lexer exposes generated and nat...test; no linktools.smg.src.tree.scanner.witness.testtest: focused witness lexer matches r...tree.runtime.lexer.Lexerlookahead
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstree.runtime.lexer.Lexerfinishtree.runtime.lexer.LexermarkEnd
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest; no linktools.smg.src.tree.runtime.lexertest: lexer exposes generated and nat...tree.runtime.lexer.LexersetResult
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest; no linktools.smg.src.tree.runtime.lexertest: lexer exposes generated and nat...private; no linktools.smg.src.tree.runtime.parserlextest; no linktools.smg.src.tree.runtime.scannertest: runtime scanner dispatch never ...tree.runtime.lexer.Lexeradvancetree.runtime.lexer.Lexerstart
Static calls · unresolved targets: 0 · external targets: 0.

Source: tools/smg/src/tree/runtime/lexer.zig

zig
const std = @import("std");const runtime = @import("root.zig");const abi = runtime.abi;pub const Position = struct {    byte: u32,    point: abi.Point,};pub const Token = struct {    symbol: abi.Symbol,    start: Position,    end: Position,};pub const Lexer = struct {    abi: abi.Lexer,    source: []const u8,    current: Position,    token_start: Position,    token_end: Position,    marked: bool,    pub fn init(source: []const u8, initial: Position) Lexer {        var self = Lexer{            .abi = .{                .lookahead = 0,                .result_symbol = 0,                .advance = advanceAbi,                .mark_end = markEndAbi,                .get_column = columnAbi,                .is_at_included_range_start = rangeStartAbi,                .eof = eofAbi,                .log = null,            },            .source = source,            .current = initial,            .token_start = initial,            .token_end = initial,            .marked = false,        };        self.refresh();        return self;    }    pub fn start(self: *Lexer) void {        self.token_start = self.current;        self.token_end = self.current;        self.marked = false;        self.abi.result_symbol = 0;        if (self.current.byte == 0 and self.abi.lookahead == 0xfeff) self.advance(true);    }    pub fn finish(self: *Lexer) Token {        if (!self.marked) self.markEnd();        if (self.token_end.byte < self.token_start.byte) self.token_start = self.token_end;        return .{            .symbol = self.abi.result_symbol,            .start = self.token_start,            .end = self.token_end,        };    }    pub fn lookahead(self: *const Lexer) i32 {        return self.abi.lookahead;    }    pub fn setResult(self: *Lexer, symbol: abi.Symbol) void {        self.abi.result_symbol = symbol;    }    pub fn advance(self: *Lexer, skip: bool) void {        if (self.current.byte < self.source.len) {            const length = codepointLength(self.source[self.current.byte..]);            if (self.abi.lookahead == '\n') {                self.current.point.row += 1;                self.current.point.column = 0;            } else {                self.current.point.column += @intCast(length);            }            self.current.byte += @intCast(length);        }        if (skip) self.token_start = self.current;        self.refresh();    }    pub fn markEnd(self: *Lexer) void {        self.token_end = self.current;        self.marked = true;    }    pub fn includedRangeStart(_: *const Lexer) bool {        return false;    }    pub fn eof(self: *const Lexer) bool {        return self.current.byte == self.source.len;    }    fn refresh(self: *Lexer) void {        if (self.eof()) {            self.abi.lookahead = 0;            return;        }        const remaining = self.source[self.current.byte..];        const length = codepointLength(remaining);        if (length == 1 and remaining[0] >= 0x80) return self.setDecodeError();        self.abi.lookahead = @intCast(std.unicode.utf8Decode(remaining[0..length]) catch {            return self.setDecodeError();        });    }    fn setDecodeError(self: *Lexer) void {        self.abi.lookahead = -1;    }    fn codepointLength(source: []const u8) usize {        const length = std.unicode.utf8ByteSequenceLength(source[0]) catch return 1;        if (length > source.len) return 1;        _ = std.unicode.utf8Decode(source[0..length]) catch return 1;        return length;    }    fn parent(pointer: anytype) if (@TypeOf(pointer) == *abi.Lexer) *Lexer else *const Lexer {        return @fieldParentPtr("abi", pointer);    }    fn advanceAbi(pointer: *abi.Lexer, skip: bool) callconv(.c) void {        parent(pointer).advance(skip);    }    fn markEndAbi(pointer: *abi.Lexer) callconv(.c) void {        parent(pointer).markEnd();    }    fn columnAbi(pointer: *abi.Lexer) callconv(.c) u32 {        return parent(pointer).current.point.column;    }    fn rangeStartAbi(pointer: *const abi.Lexer) callconv(.c) bool {        return parent(pointer).includedRangeStart();    }    fn eofAbi(pointer: *const abi.Lexer) callconv(.c) bool {        return parent(pointer).eof();    }};test "lexer exposes generated and native scanner semantics" {    var value = Lexer.init("a\n\xe2\x82\xac", .{ .byte = 0, .point = .{ .row = 0, .column = 0 } });    value.start();    try std.testing.expectEqual(@as(i32, 'a'), value.lookahead());    value.advance(true);    try std.testing.expectEqual(@as(u32, 1), value.token_start.byte);    value.advance(false);    try std.testing.expectEqual(@as(u32, 1), value.current.point.row);    try std.testing.expectEqual(@as(i32, 0x20ac), value.lookahead());    value.setResult(7);    value.advance(false);    const token = value.finish();    try std.testing.expectEqual(@as(abi.Symbol, 7), token.symbol);    try std.testing.expectEqual(@as(u32, 1), token.start.byte);    try std.testing.expectEqual(@as(u32, 5), token.end.byte);}

Source: tools/smg/src/tree/runtime/root.zig:3

zig
pub const lexer = @import("lexer.zig");

Audit

Definitions13
Public names13
Members11
Version26.7.0
Revisiondaab053ee433