add 'error contexts' to parser error reports

This commit is contained in:
Luna 2019-09-20 13:16:55 -03:00
parent 7ddd37b725
commit 3ad0859bc9
3 changed files with 39 additions and 8 deletions

View File

@ -1,4 +1,4 @@
import std;
// import std;
fn add(a: i32, b: i32) i32 {
return a + b;

View File

@ -1,15 +1,24 @@
const std = @import("std");
pub fn report(line: usize, where: []const u8, message: []const u8) void {
std.debug.warn("[line {}] Error{}: {}", line, where, message);
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 {
std.debug.warn("[line {}] Error", line);
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");
}

View File

@ -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(),