@@ -162,9 +162,8 @@ public fn void Parser.parse(Parser* p, i32 file_id, bool is_interface, bool is_g
162162fn void on_tokenizer_error(void* arg, SrcLoc loc) {
163163 Parser* p = arg;
164164 // NOTE: cannot use p.tok.error_msg, because of possible lookahead (changes token)
165- p.tok.loc = loc;
166165 // will longjmp
167- p.error( "%s", p.tokenizer.error_msg);
166+ p.errorAt(loc, "%s", p.tokenizer.error_msg);
168167}
169168
170169fn void on_tokenizer_warning(void* arg, SrcLoc loc) {
@@ -229,18 +228,19 @@ fn void Parser.expect(Parser* p, Kind kind) {
229228}
230229
231230fn void Parser.expectError(Parser* p, Kind kind) {
232- if (p.prev_loc) {
231+ // error position after previous token
232+ SrcLoc loc = p.prev_loc;
233+ if (loc) {
233234 if (kind == Kind.Semicolon) {
234235 // non fatal error to show all such error locations
235- p.diags.error(p.prev_loc , "expected ';'");
236+ p.diags.error(loc , "expected ';'");
236237 return;
237238 }
238- // position after previous token
239- p.tok.loc = p.prev_loc;
240239 } else {
241240 // otherwise position is either first token or end of empty file
241+ loc = p.tok.loc;
242242 }
243- p.error( "expected '%s'", kind.str());
243+ p.errorAt(loc, "expected '%s'", kind.str());
244244}
245245
246246fn void Parser.expectIdentifier(Parser* p) {
@@ -257,6 +257,14 @@ fn void Parser.error(Parser* p, const char* format @(printf_format), ...) @(nore
257257 longjmp(&p.jmpbuf, 1);
258258}
259259
260+ fn void Parser.errorAt(Parser* p, SrcLoc loc, const char* format @(printf_format), ...) @(noreturn) {
261+ va_list args;
262+ va_start(args, format);
263+ p.diags.error2(loc, format, args);
264+ va_end(args);
265+ longjmp(&p.jmpbuf, 1);
266+ }
267+
260268fn void Parser.parseModule(Parser* p, bool is_interface, bool is_generated) {
261269 p.expectAndConsume(Kind.KW_module);
262270 // accept builtin types as module names
@@ -473,8 +481,7 @@ fn void Parser.parseFuncDecl(Parser* p, bool is_public) {
473481 }
474482
475483 if (!p.checkName(func_name, p.is_interface)) {
476- p.tok.loc = func_loc; // reset to correct value for error
477- p.error("a function name must start with a lower case character");
484+ p.errorAt(func_loc, "a function name must start with a lower case character");
478485 }
479486
480487 DeclList params.init();
0 commit comments