@@ -76,12 +76,12 @@ static Expr *grouping(Parser *parser);
76
76
static Expr * func_def (Parser * parser );
77
77
static ArenaLL arguments (Parser * parser );
78
78
79
- static void handle_parse_err (Parser * parser , char * msg );
79
+ static void handle_parse_err (Parser * parser , char * msg , ParseErrorType pet );
80
80
81
- static ParseError * new_parse_error (Arena * arena , char * msg , Token * failed )
81
+ static ParseError * new_parse_error (Arena * arena , char * msg , Token * failed , ParseErrorType pet )
82
82
{
83
83
ParseError * error = m_arena_alloc_struct (arena , ParseError );
84
- error -> err_type = PET_EXPECTED_RBRACE ;
84
+ error -> err_type = pet ;
85
85
size_t msg_len = strlen (msg ); // TODO: could we avoid strlen somehow?
86
86
char * msg_arena = m_arena_alloc (arena , msg_len + 1 );
87
87
memcpy (msg_arena , msg , msg_len + 1 );
@@ -121,7 +121,7 @@ static Token *advance(Parser *parser)
121
121
static void backup (Parser * parser )
122
122
{
123
123
if (parser -> token_pos == 0 )
124
- handle_parse_err (parser , "Internal error: attempted to backup() at pos = 0" );
124
+ handle_parse_err (parser , "Internal error: attempted to backup() at pos = 0" , PET_CUSTOME );
125
125
parser -> token_pos -- ;
126
126
}
127
127
@@ -163,7 +163,7 @@ static bool check_either(Parser *parser, int step, unsigned int n, ...)
163
163
static Token * consume (Parser * parser , TokenType expected , char * err_msg )
164
164
{
165
165
if (!check_single (parser , expected , 0 )) {
166
- handle_parse_err (parser , err_msg );
166
+ handle_parse_err (parser , err_msg , expected == t_rbrace ? PET_EXPECTED_RBRACE : PET_CUSTOME );
167
167
/* we need to "unconsume" the token before we later advance again */
168
168
backup (parser );
169
169
}
@@ -208,20 +208,24 @@ static bool match_either(Parser *parser, unsigned int n, ...)
208
208
#define match (parser , ...) match_either(parser, VA_NUMBER_OF_ARGS(__VA_ARGS__), __VA_ARGS__)
209
209
210
210
211
- static void handle_parse_err (Parser * parser , char * msg )
211
+ static void handle_parse_err (Parser * parser , char * msg , ParseErrorType pet )
212
212
{
213
213
parser -> n_errors ++ ;
214
214
Token * failed = arraylist_get (parser -> tokens , parser -> token_pos );
215
- ParseError * error = new_parse_error (parser -> ast_arena , msg , failed );
216
- if (parser -> perr_head == NULL ) {
215
+ /*
216
+ * Edge case where we failed on a newline or the eof.
217
+ * This ensures the error reporting system is not tripped up because the character
218
+ * is not found on the expected line.
219
+ */
220
+ if ((failed -> type == t_eof || failed -> type == t_newline ) && parser -> token_pos != 0 )
221
+ failed = arraylist_get (parser -> tokens , parser -> token_pos - 1 );
222
+
223
+ ParseError * error = new_parse_error (parser -> ast_arena , msg , failed , pet );
224
+ if (parser -> perr_head == NULL )
217
225
parser -> perr_head = error ;
218
- parser -> perr_tail = error ;
219
- } else {
226
+ else
220
227
parser -> perr_tail -> next = error ;
221
- parser -> perr_tail = error ;
222
- }
223
-
224
- // report_parse_err(parser, msg);
228
+ parser -> perr_tail = error ;
225
229
226
230
if (parser -> n_errors >= MAX_PARSE_ERRORS ) {
227
231
REPORT_IMPL ("TOO MANY PARSE ERRORS. Quitting now ...\n" );
@@ -690,7 +694,7 @@ static Expr *single(Parser *parser)
690
694
CastExpr * expr = (CastExpr * )expr_alloc (parser -> ast_arena , EXPR_CAST , parser -> source_line );
691
695
expr -> expr = left ;
692
696
if (!match (parser , t_ident )) {
693
- handle_parse_err (parser , "Expected identifier after cast" );
697
+ handle_parse_err (parser , "Expected identifier after cast" , PET_CUSTOME );
694
698
/* move past token and continue as normal */
695
699
parser -> token_pos ++ ;
696
700
return NULL ;
@@ -786,7 +790,7 @@ static Expr *primary(Parser *parser)
786
790
return func_def (parser );
787
791
788
792
if (!match (parser , t_dt_str , t_dt_text_lit )) {
789
- handle_parse_err (parser , "Not a valid primary type" );
793
+ handle_parse_err (parser , "Not a valid primary type" , PET_CUSTOME );
790
794
return NULL ;
791
795
}
792
796
0 commit comments