Skip to documentation
SLOP

tiny.zen.math.token

Reference tiny.zen math token

Defined in math.

API (4)

Actions

Public operations.

Types and contracts

Public types and contracts.

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

Source

Called byCallsprivate sourcelib.zen.src.math.parse.Parseradvanceprivate sourcelib.zen.src.math.token.Tokenizerfailprivate sourcelib.zen.src.math.token.TokenizerisSpacemath.token.Tokenizernext
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/zen/src/math/root.zig:6

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

Source: lib/zen/src/math/token.zig

zig
const std = @import("std");pub const Error = error{InvalidEquation};pub const Token = union(enum) {    char: u21,    command: []const u8,    open,    close,    caret,    underscore,    prime,    end,};pub const Tokenizer = struct {    source: []const u8,    index: usize = 0,    start: usize = 0,    reason: []const u8 = "",    pub fn next(self: *Tokenizer) Error!Token {        while (self.index < self.source.len and isSpace(self.source[self.index])) self.index += 1;        self.start = self.index;        if (self.index >= self.source.len) return .end;        const byte = self.source[self.index];        switch (byte) {            '{' => {                self.index += 1;                return .open;            },            '}' => {                self.index += 1;                return .close;            },            '^' => {                self.index += 1;                return .caret;            },            '_' => {                self.index += 1;                return .underscore;            },            '\'' => {                self.index += 1;                return .prime;            },            '\\' => {                self.index += 1;                if (self.index >= self.source.len) return self.fail("incomplete command");                if (!std.ascii.isAlphabetic(self.source[self.index])) {                    self.index += 1;                    return .{ .command = self.source[self.index - 1 .. self.index] };                }                const start = self.index;                while (self.index < self.source.len and std.ascii.isAlphabetic(self.source[self.index])) self.index += 1;                return .{ .command = self.source[start..self.index] };            },            else => {                if (byte < 0x80) {                    self.index += 1;                    return .{ .char = byte };                }                const len = std.unicode.utf8ByteSequenceLength(byte) catch return self.fail("invalid utf-8");                if (self.index + len > self.source.len) return self.fail("invalid utf-8");                const decoded = std.unicode.utf8Decode(self.source[self.index .. self.index + len]) catch return self.fail("invalid utf-8");                self.index += len;                return .{ .char = decoded };            },        }    }    fn fail(self: *Tokenizer, reason: []const u8) Error {        self.reason = reason;        return error.InvalidEquation;    }    fn isSpace(byte: u8) bool {        return byte == ' ' or byte == '\t' or byte == '\n' or byte == '\r';    }};test "tokenizer splits commands scripts and characters" {    var tokens = Tokenizer{ .source = "\\frac{a}{2} ^ x_\\pi \\, ω'" };    try std.testing.expectEqualStrings("frac", (try tokens.next()).command);    try std.testing.expect((try tokens.next()) == .open);    try std.testing.expectEqual(@as(u21, 'a'), (try tokens.next()).char);    try std.testing.expect((try tokens.next()) == .close);    try std.testing.expect((try tokens.next()) == .open);    try std.testing.expectEqual(@as(u21, '2'), (try tokens.next()).char);    try std.testing.expect((try tokens.next()) == .close);    try std.testing.expect((try tokens.next()) == .caret);    try std.testing.expectEqual(@as(u21, 'x'), (try tokens.next()).char);    try std.testing.expect((try tokens.next()) == .underscore);    try std.testing.expectEqualStrings("pi", (try tokens.next()).command);    try std.testing.expectEqualStrings(",", (try tokens.next()).command);    try std.testing.expectEqual(@as(u21, 'ω'), (try tokens.next()).char);    try std.testing.expect((try tokens.next()) == .prime);    try std.testing.expect((try tokens.next()) == .end);}test "tokenizer records token starts" {    var tokens = Tokenizer{ .source = "  x \\pi" };    _ = try tokens.next();    try std.testing.expectEqual(@as(usize, 2), tokens.start);    _ = try tokens.next();    try std.testing.expectEqual(@as(usize, 4), tokens.start);    _ = try tokens.next();    try std.testing.expectEqual(@as(usize, 7), tokens.start);}test "tokenizer rejects trailing backslash and bad utf8" {    var trailing = Tokenizer{ .source = "x\\" };    _ = try trailing.next();    try std.testing.expectError(error.InvalidEquation, trailing.next());    try std.testing.expectEqualStrings("incomplete command", trailing.reason);    try std.testing.expectEqual(@as(usize, 1), trailing.start);    var bad = Tokenizer{ .source = &.{ 0xFF, 0x20 } };    try std.testing.expectError(error.InvalidEquation, bad.next());    try std.testing.expectEqualStrings("invalid utf-8", bad.reason);    try std.testing.expectEqual(@as(usize, 0), bad.start);}

Audit

Definitions5
Public names5
Members13
Version26.7.0
Revisiondaab053ee433