| ... | @@ -157,7 +157,8 @@ pub const Parser = struct { | ... | @@ -157,7 +157,8 @@ pub const Parser = struct { |
| 157 | max_codepoint: u21, | 157 | max_codepoint: u21, |
| 158 | /// We only want to issue a max of 1 error per char literal | 158 | /// We only want to issue a max of 1 error per char literal |
| 159 | errored: bool = false, | 159 | errored: bool = false, |
| 160 | errors: std.BoundedArray(CharDiagnostic, 4) = .{}, | 160 | errors_buffer: [4]CharDiagnostic, |
| | 161 | errors_len: usize, |
| 161 | comp: *const Compilation, | 162 | comp: *const Compilation, |
| 162 | | 163 | |
| 163 | pub fn init(literal: []const u8, kind: Kind, max_codepoint: u21, comp: *const Compilation) Parser { | 164 | pub fn init(literal: []const u8, kind: Kind, max_codepoint: u21, comp: *const Compilation) Parser { |
| ... | @@ -166,6 +167,8 @@ pub const Parser = struct { | ... | @@ -166,6 +167,8 @@ pub const Parser = struct { |
| 166 | .comp = comp, | 167 | .comp = comp, |
| 167 | .kind = kind, | 168 | .kind = kind, |
| 168 | .max_codepoint = max_codepoint, | 169 | .max_codepoint = max_codepoint, |
| | 170 | .errors_buffer = undefined, |
| | 171 | .errors_len = 0, |
| 169 | }; | 172 | }; |
| 170 | } | 173 | } |
| 171 | | 174 | |
| ... | @@ -178,19 +181,28 @@ pub const Parser = struct { | ... | @@ -178,19 +181,28 @@ pub const Parser = struct { |
| 178 | }; | 181 | }; |
| 179 | } | 182 | } |
| 180 | | 183 | |
| | 184 | pub fn errors(p: *Parser) []CharDiagnostic { |
| | 185 | return p.errors_buffer[0..p.errors_len]; |
| | 186 | } |
| | 187 | |
| 181 | pub fn err(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void { | 188 | pub fn err(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void { |
| 182 | if (self.errored) return; | 189 | if (self.errored) return; |
| 183 | self.errored = true; | 190 | self.errored = true; |
| 184 | const diagnostic = .{ .tag = tag, .extra = extra }; | 191 | const diagnostic = .{ .tag = tag, .extra = extra }; |
| 185 | self.errors.append(diagnostic) catch { | 192 | if (self.errors_len == self.errors_buffer.len) { |
| 186 | _ = self.errors.pop(); | 193 | self.errors_buffer[self.errors_buffer.len - 1] = diagnostic; |
| 187 | self.errors.append(diagnostic) catch unreachable; | 194 | } else { |
| 188 | }; | 195 | self.errors_buffer[self.errors_len] = diagnostic; |
| | 196 | self.errors_len += 1; |
| | 197 | } |
| 189 | } | 198 | } |
| 190 | | 199 | |
| 191 | pub fn warn(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void { | 200 | pub fn warn(self: *Parser, tag: Diagnostics.Tag, extra: Diagnostics.Message.Extra) void { |
| 192 | if (self.errored) return; | 201 | if (self.errored) return; |
| 193 | self.errors.append(.{ .tag = tag, .extra = extra }) catch {}; | 202 | if (self.errors_len < self.errors_buffer.len) { |
| | 203 | self.errors_buffer[self.errors_len] = .{ .tag = tag, .extra = extra }; |
| | 204 | self.errors_len += 1; |
| | 205 | } |
| 194 | } | 206 | } |
| 195 | | 207 | |
| 196 | pub fn next(self: *Parser) ?Item { | 208 | pub fn next(self: *Parser) ?Item { |