add 'error contexts' to parser error reports
This commit is contained in:
parent
7ddd37b725
commit
3ad0859bc9
3 changed files with 39 additions and 8 deletions
|
@ -1,4 +1,4 @@
|
|||
import std;
|
||||
// import std;
|
||||
|
||||
fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
|
|
|
@ -1,15 +1,24 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn report(line: usize, where: []const u8, message: []const u8) void {
|
||||
pub fn report(line: usize, where: []const u8, ctx_opt: ?[]const u8, message: []const u8) void {
|
||||
if (ctx_opt) |ctx| {
|
||||
std.debug.warn("[line {}] Error{} on {}: {}", line, where, ctx, message);
|
||||
} else {
|
||||
std.debug.warn("[line {}] Error{}: {}", line, where, message);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reportN(line: usize, message: []const u8) void {
|
||||
report(line, "", message);
|
||||
}
|
||||
|
||||
pub fn reportFmt(line: usize, comptime fmt: []const u8, args: ...) void {
|
||||
pub fn reportFmt(line: usize, ctx_opt: ?[]const u8, comptime fmt: []const u8, args: ...) void {
|
||||
if (ctx_opt) |ctx| {
|
||||
std.debug.warn("[line {}] Error on {}", line, ctx);
|
||||
} else {
|
||||
std.debug.warn("[line {}] Error", line);
|
||||
}
|
||||
|
||||
std.debug.warn(fmt, args);
|
||||
std.debug.warn("\n");
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ pub const Parser = struct {
|
|||
tokens: TokenList,
|
||||
|
||||
hadError: bool = false,
|
||||
err_ctx: ?[]const u8 = null,
|
||||
|
||||
pub fn init(allocator: *Allocator, scanner: *Scanner) Parser {
|
||||
return Parser{
|
||||
|
@ -44,10 +45,26 @@ pub const Parser = struct {
|
|||
self.tokens.deinit();
|
||||
}
|
||||
|
||||
fn setErrContext(self: *Parser, comptime fmt: ?[]const u8, args: ...) void {
|
||||
if (fmt == null) {
|
||||
self.err_ctx = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var buf = self.allocator.alloc(u8, 256) catch unreachable;
|
||||
self.err_ctx = std.fmt.bufPrint(buf, fmt.?, args) catch unreachable;
|
||||
}
|
||||
|
||||
fn doError(self: *Parser, comptime fmt: []const u8, args: ...) ParseError {
|
||||
self.hadError = true;
|
||||
|
||||
std.debug.warn("parser error at line {}\n\t", self.scanner.line);
|
||||
std.debug.warn("parser error at line {}", self.scanner.line);
|
||||
if (self.err_ctx) |ctx| {
|
||||
std.debug.warn(" on {}", ctx);
|
||||
}
|
||||
|
||||
std.debug.warn("\n\t");
|
||||
|
||||
std.debug.warn(fmt, args);
|
||||
std.debug.warn("\n");
|
||||
|
||||
|
@ -80,10 +97,11 @@ pub const Parser = struct {
|
|||
}
|
||||
|
||||
fn tokenError(self: *Parser, token: Token, msg: []const u8) ParseError {
|
||||
std.debug.warn("ctx: '{}'\n", self.err_ctx);
|
||||
if (token.typ == .EOF) {
|
||||
ereport.report(token.line, " at end", msg);
|
||||
ereport.report(token.line, " at end", self.err_ctx, msg);
|
||||
} else {
|
||||
ereport.reportFmt(token.line, " at '{}': {}", token.lexeme, msg);
|
||||
ereport.reportFmt(token.line, self.err_ctx, " at '{}': {}", token.lexeme, msg);
|
||||
}
|
||||
|
||||
return ParseError.CompileError;
|
||||
|
@ -439,6 +457,8 @@ pub const Parser = struct {
|
|||
|
||||
const name = try self.consumeSingle(.Identifier);
|
||||
|
||||
self.setErrContext("function {}", name.lexeme);
|
||||
|
||||
_ = try self.consumeSingle(.LeftParen);
|
||||
|
||||
while (self.peek().typ != .RightParen) {
|
||||
|
@ -623,6 +643,8 @@ pub const Parser = struct {
|
|||
}
|
||||
|
||||
fn parseTopDecl(self: *@This()) !*Node {
|
||||
self.setErrContext(null);
|
||||
|
||||
return switch (self.peek().typ) {
|
||||
.Fn => try self.parseFnDecl(),
|
||||
.Const => try self.parseConstDecl(),
|
||||
|
|
Loading…
Reference in a new issue