Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

parseNumberLiteral

Assumes that number literals normally rejected by RC's preprocessor are similarly rejected before being parsed.

Relevant RC preprocessor errors: RC2021: expected exponent value, not '<digit>' example that is rejected: 1e1 example that is accepted: 1ea (this function will parse the two examples above the same)

literals.parseNumberLiteral
pub fn parseNumberLiteral(bytes: SourceBytes) Number

File

lib/compiler/resinator/literals.zig:1002

Code

pub fn parseNumberLiteral(bytes: SourceBytes) Number {
    std.debug.assert(bytes.slice.len > 0);
    var result = Number{ .value = 0, .is_long = false };
    var radix: u8 = 10;
    var buf = bytes.slice;

    const Prefix = enum { none, minus, complement };
    var prefix: Prefix = .none;
    switch (buf[0]) {
        '-' => {
            prefix = .minus;
            buf = buf[1..];
        },
        '~' => {
            prefix = .complement;
            buf = buf[1..];
        },
        else => {},
    }

    if (buf.len > 2 and buf[0] == '0') {
        switch (buf[1]) {
            'o' => { // octal radix prefix is case-sensitive
                radix = 8;
                buf = buf[2..];
            },
            'x', 'X' => {
                radix = 16;
                buf = buf[2..];
            },
            else => {},
        }
    }

    var i: usize = 0;
    while (bytes.code_page.codepointAt(i, buf)) |codepoint| : (i += codepoint.byte_len) {
        const c = codepoint.value;
        if (c == 'L' or c == 'l') {
            result.is_long = true;
            break;
        }
        const digit = switch (c) {
            // On invalid digit for the radix, just stop parsing but don't fail
            0x00...0x7F => std.fmt.charToDigit(@intCast(c), radix) catch break,
            else => break,
        };

        if (result.value != 0) {
            result.value *%= radix;
        }
        result.value +%= digit;
    }

    switch (prefix) {
        .none => {},
        .minus => result.value = 0 -% result.value,
        .complement => result.value = ~result.value,
    }

    return result;
}