Skip to content

Commit 4c7b09c

Browse files
committed
Parser: add Parser.errorAt with specific error location
1 parent 76fb5a7 commit 4c7b09c

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

parser/c2_parser.c2

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,8 @@ public fn void Parser.parse(Parser* p, i32 file_id, bool is_interface, bool is_g
162162
fn 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

170169
fn void on_tokenizer_warning(void* arg, SrcLoc loc) {
@@ -229,18 +228,19 @@ fn void Parser.expect(Parser* p, Kind kind) {
229228
}
230229

231230
fn 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

246246
fn 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+
260268
fn 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();

parser/c2_parser_stmt.c2

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fn Stmt* Parser.parseStmt(Parser* p) {
3131
case LBrace:
3232
return (Stmt*)p.parseCompoundStmt();
3333
case RBrace:
34-
p.error("expected stmt");
34+
p.error("expected statement");
3535
break;
3636
case KW_asm:
3737
return p.parseAsmStmt();
@@ -167,22 +167,19 @@ fn u32 Parser.skipArray(Parser* p, u32 ahead, Kind endKind) {
167167
break;
168168
case RParen:
169169
if (closeKind[--depth] != RParen) {
170-
p.tok.loc = next.loc;
171-
p.error("expected ']'");
170+
p.errorAt(next.loc, "expected ']'");
172171
}
173172
break;
174173
case LSquare:
175174
closeKind[depth++] = RSquare;
176175
break;
177176
case RSquare:
178177
if (closeKind[--depth] != RSquare) {
179-
p.tok.loc = next.loc;
180-
p.error("expected ')'");
178+
p.errorAt(next.loc, "expected ')'");
181179
}
182180
break;
183181
case Eof:
184-
p.tok.loc = next.loc;
185-
p.error("unexpected end-of-file");
182+
p.errorAt(next.loc, "unexpected end-of-file");
186183
break;
187184
default:
188185
break;

0 commit comments

Comments
 (0)