Skip to content

Commit bc33c60

Browse files
committed
enhance
1 parent 7986ba2 commit bc33c60

File tree

5 files changed

+36
-32
lines changed

5 files changed

+36
-32
lines changed

include/interpreter/parser.h

+5
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,13 @@
2525

2626

2727
/* types */
28+
/*
29+
* NOTE: I have not categorized the other errors as we never use that information.
30+
* TODO: One possible optimization is to store the error msg for each error type in a static table
31+
*/
2832
typedef enum {
2933
PET_EXPECTED_RBRACE,
34+
PET_CUSTOME,
3035
} ParseErrorType;
3136

3237
typedef struct parse_error_t ParseError;

src/interactive/prompt.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,10 @@ void prompt_run(Prompt *prompt, bool continuation)
176176
handle_arrow(prompt);
177177
break;
178178

179-
case KEY_TAB:
180-
for (size_t i = 0; i < 4; i++)
181-
prompt_buf_insert_at_cursor(prompt, ' ');
182-
break;
179+
case KEY_TAB:
180+
for (size_t i = 0; i < 4; i++)
181+
prompt_buf_insert_at_cursor(prompt, ' ');
182+
break;
183183

184184
default:
185185
if (PROMPT_ABS_POS(prompt) == prompt->buf_len)

src/interpreter/error.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,14 @@ void report_parse_err(ParseError *error, char *full_input)
130130
REPORT_IMPL("%s[line %zu]%s: Error during parsing: %s\n", ANSI_BOLD_START,
131131
error->failed->line + 1, ANSI_BOLD_END, error->msg);
132132

133-
char *line = offending_line(full_input, error->failed->line);
133+
Token *failed = error->failed;
134+
char *line = offending_line(full_input, failed->line);
134135
if (line == NULL) {
135136
REPORT_IMPL("Internal error: could not find line where parse error occured");
136137
return;
137138
}
138139

139-
ErrBuf bf = offending_line_from_offset(line, error->failed->start);
140-
err_buf_print(bf, error->failed->end - error->failed->start);
140+
ErrBuf bf = offending_line_from_offset(line, failed->start);
141+
err_buf_print(bf, error->failed->end - failed->start);
141142
free(bf.alloced_buffer);
142143
}

src/interpreter/parser.c

+20-16
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ static Expr *grouping(Parser *parser);
7676
static Expr *func_def(Parser *parser);
7777
static ArenaLL arguments(Parser *parser);
7878

79-
static void handle_parse_err(Parser *parser, char *msg);
79+
static void handle_parse_err(Parser *parser, char *msg, ParseErrorType pet);
8080

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)
8282
{
8383
ParseError *error = m_arena_alloc_struct(arena, ParseError);
84-
error->err_type = PET_EXPECTED_RBRACE;
84+
error->err_type = pet;
8585
size_t msg_len = strlen(msg); // TODO: could we avoid strlen somehow?
8686
char *msg_arena = m_arena_alloc(arena, msg_len + 1);
8787
memcpy(msg_arena, msg, msg_len + 1);
@@ -121,7 +121,7 @@ static Token *advance(Parser *parser)
121121
static void backup(Parser *parser)
122122
{
123123
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);
125125
parser->token_pos--;
126126
}
127127

@@ -163,7 +163,7 @@ static bool check_either(Parser *parser, int step, unsigned int n, ...)
163163
static Token *consume(Parser *parser, TokenType expected, char *err_msg)
164164
{
165165
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);
167167
/* we need to "unconsume" the token before we later advance again */
168168
backup(parser);
169169
}
@@ -208,20 +208,24 @@ static bool match_either(Parser *parser, unsigned int n, ...)
208208
#define match(parser, ...) match_either(parser, VA_NUMBER_OF_ARGS(__VA_ARGS__), __VA_ARGS__)
209209

210210

211-
static void handle_parse_err(Parser *parser, char *msg)
211+
static void handle_parse_err(Parser *parser, char *msg, ParseErrorType pet)
212212
{
213213
parser->n_errors++;
214214
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)
217225
parser->perr_head = error;
218-
parser->perr_tail = error;
219-
} else {
226+
else
220227
parser->perr_tail->next = error;
221-
parser->perr_tail = error;
222-
}
223-
224-
// report_parse_err(parser, msg);
228+
parser->perr_tail = error;
225229

226230
if (parser->n_errors >= MAX_PARSE_ERRORS) {
227231
REPORT_IMPL("TOO MANY PARSE ERRORS. Quitting now ...\n");
@@ -690,7 +694,7 @@ static Expr *single(Parser *parser)
690694
CastExpr *expr = (CastExpr *)expr_alloc(parser->ast_arena, EXPR_CAST, parser->source_line);
691695
expr->expr = left;
692696
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);
694698
/* move past token and continue as normal */
695699
parser->token_pos++;
696700
return NULL;
@@ -786,7 +790,7 @@ static Expr *primary(Parser *parser)
786790
return func_def(parser);
787791

788792
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);
790794
return NULL;
791795
}
792796

src/main.c

+3-9
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,11 @@ void interactive(int argc, char **argv)
5959
interpreter_run(&interpreter, &parse_result.stmts);
6060
} else if ((parse_result.n_errors == 1 || inside_block) &&
6161
parse_result.perr_tail->err_type == PET_EXPECTED_RBRACE) {
62-
/* */
62+
/* Change the PS1 to signify we are inside a block */
6363
prompt_set_ps1(&prompt, ".. ");
6464
inside_block = true;
6565
prompt.buf[--prompt.buf_len] = 0; /* Pop EOF. We are continuing. */
66-
67-
arraylist_free(&lex_result.tokens);
68-
arraylist_free(&parse_result.stmts);
69-
m_arena_clear(&ast_arena);
70-
71-
continue;
66+
goto continue_repl;
7267
} else {
7368
report_all_parse_errors(parse_result.perr_head, prompt.buf);
7469
}
@@ -78,7 +73,7 @@ void interactive(int argc, char **argv)
7873
inside_block = false;
7974
}
8075

81-
// TODO: these should maybe be reset (e.i. set size to 0), not freed
76+
continue_repl:
8277
arraylist_free(&lex_result.tokens);
8378
arraylist_free(&parse_result.stmts);
8479
m_arena_clear(&ast_arena);
@@ -89,7 +84,6 @@ void interactive(int argc, char **argv)
8984
prompt_free(&prompt);
9085
}
9186

92-
9387
int main(int argc, char **argv)
9488
{
9589
if (argc == 1) {

0 commit comments

Comments
 (0)