unionstd.zon.parse.Error[src]

Fields

Functions

FunctionfmtMessage[src]

pub fn fmtMessage(self: @This(), status: *const Status) std.fmt.Formatter(formatMessage)

Parameters

self: @This()
status: *const Status

Source Code

Source code
pub fn fmtMessage(self: @This(), status: *const Status) std.fmt.Formatter(formatMessage) {
    return .{ .data = .{
        .err = self,
        .status = status,
    } };
}

FunctiongetLocation[src]

pub fn getLocation(self: @This(), status: *const Status) Ast.Location

Parameters

self: @This()
status: *const Status

Source Code

Source code
pub fn getLocation(self: @This(), status: *const Status) Ast.Location {
    const ast = status.ast.?;
    return switch (self) {
        .zoir => |err| return zoirErrorLocation(
            status.ast.?,
            err.token,
            err.node_or_offset,
        ),
        .type_check => |err| return ast.tokenLocation(err.offset, err.token),
    };
}

FunctioniterateNotes[src]

pub fn iterateNotes(self: @This(), status: *const Status) Note.Iterator

Parameters

self: @This()
status: *const Status

Source Code

Source code
pub fn iterateNotes(self: @This(), status: *const Status) Note.Iterator {
    return .{ .err = self, .status = status };
}

Source Code

Source code
pub const Error = union(enum) {
    zoir: Zoir.CompileError,
    type_check: Error.TypeCheckFailure,

    pub const Note = union(enum) {
        zoir: Zoir.CompileError.Note,
        type_check: TypeCheckFailure.Note,

        pub const Iterator = struct {
            index: usize = 0,
            err: Error,
            status: *const Status,

            pub fn next(self: *@This()) ?Note {
                switch (self.err) {
                    .zoir => |err| {
                        if (self.index >= err.note_count) return null;
                        const zoir = self.status.zoir.?;
                        const note = err.getNotes(zoir)[self.index];
                        self.index += 1;
                        return .{ .zoir = note };
                    },
                    .type_check => |err| {
                        if (self.index >= err.getNoteCount()) return null;
                        const note = err.getNote(self.index);
                        self.index += 1;
                        return .{ .type_check = note };
                    },
                }
            }
        };

        fn formatMessage(
            self: []const u8,
            comptime f: []const u8,
            options: std.fmt.FormatOptions,
            writer: anytype,
        ) !void {
            _ = f;
            _ = options;

            // Just writes the string for now, but we're keeping this behind a formatter so we have
            // the option to extend it in the future to print more advanced messages (like `Error`
            // does) without breaking the API.
            try writer.writeAll(self);
        }

        pub fn fmtMessage(self: Note, status: *const Status) std.fmt.Formatter(Note.formatMessage) {
            return .{ .data = switch (self) {
                .zoir => |note| note.msg.get(status.zoir.?),
                .type_check => |note| note.msg,
            } };
        }

        pub fn getLocation(self: Note, status: *const Status) Ast.Location {
            const ast = status.ast.?;
            switch (self) {
                .zoir => |note| return zoirErrorLocation(ast, note.token, note.node_or_offset),
                .type_check => |note| return ast.tokenLocation(note.offset, note.token),
            }
        }
    };

    pub const Iterator = struct {
        index: usize = 0,
        status: *const Status,

        pub fn next(self: *@This()) ?Error {
            const zoir = self.status.zoir orelse return null;

            if (self.index < zoir.compile_errors.len) {
                const result: Error = .{ .zoir = zoir.compile_errors[self.index] };
                self.index += 1;
                return result;
            }

            if (self.status.type_check) |err| {
                if (self.index == zoir.compile_errors.len) {
                    const result: Error = .{ .type_check = err };
                    self.index += 1;
                    return result;
                }
            }

            return null;
        }
    };

    const TypeCheckFailure = struct {
        const Note = struct {
            token: Ast.TokenIndex,
            offset: u32,
            msg: []const u8,
            owned: bool,

            fn deinit(self: @This(), gpa: Allocator) void {
                if (self.owned) gpa.free(self.msg);
            }
        };

        message: []const u8,
        owned: bool,
        token: Ast.TokenIndex,
        offset: u32,
        note: ?@This().Note,

        fn deinit(self: @This(), gpa: Allocator) void {
            if (self.note) |note| note.deinit(gpa);
            if (self.owned) gpa.free(self.message);
        }

        fn getNoteCount(self: @This()) usize {
            return @intFromBool(self.note != null);
        }

        fn getNote(self: @This(), index: usize) @This().Note {
            assert(index == 0);
            return self.note.?;
        }
    };

    const FormatMessage = struct {
        err: Error,
        status: *const Status,
    };

    fn formatMessage(
        self: FormatMessage,
        comptime f: []const u8,
        options: std.fmt.FormatOptions,
        writer: anytype,
    ) !void {
        _ = f;
        _ = options;
        switch (self.err) {
            .zoir => |err| try writer.writeAll(err.msg.get(self.status.zoir.?)),
            .type_check => |tc| try writer.writeAll(tc.message),
        }
    }

    pub fn fmtMessage(self: @This(), status: *const Status) std.fmt.Formatter(formatMessage) {
        return .{ .data = .{
            .err = self,
            .status = status,
        } };
    }

    pub fn getLocation(self: @This(), status: *const Status) Ast.Location {
        const ast = status.ast.?;
        return switch (self) {
            .zoir => |err| return zoirErrorLocation(
                status.ast.?,
                err.token,
                err.node_or_offset,
            ),
            .type_check => |err| return ast.tokenLocation(err.offset, err.token),
        };
    }

    pub fn iterateNotes(self: @This(), status: *const Status) Note.Iterator {
        return .{ .err = self, .status = status };
    }

    fn zoirErrorLocation(ast: Ast, maybe_token: Ast.TokenIndex, node_or_offset: u32) Ast.Location {
        if (maybe_token == Zoir.CompileError.invalid_token) {
            const main_tokens = ast.nodes.items(.main_token);
            const ast_node = node_or_offset;
            const token = main_tokens[ast_node];
            return ast.tokenLocation(0, token);
        } else {
            var location = ast.tokenLocation(0, maybe_token);
            location.column += node_or_offset;
            return location;
        }
    }
}