Make APFL_ERR_INPUT_ERROR non fatal

For two reasons:

- We'll later want apfl code to load other apfl code. If an IO error
  happens in that case, we don't want that to be a fatal error, only a
  regular error that can be catched in apfl (once we have something like
  `try`).
- I want to get rid of fatal errors as a generic category completely.
  Instead the error reporting functions themselves should tell you the type
  of error directly, if it was something fatal.
This commit is contained in:
Laria 2022-12-08 21:35:41 +01:00
parent 57cd32dfa5
commit 5b4ac67de9
6 changed files with 41 additions and 10 deletions

View file

@ -647,6 +647,7 @@ apfl_iterative_runner apfl_iterative_runner_new(apfl_ctx, struct apfl_source_rea
bool apfl_iterative_runner_next(apfl_iterative_runner);
enum apfl_result apfl_iterative_runner_get_result(apfl_iterative_runner);
bool apfl_iterative_runner_has_error_on_stack(apfl_iterative_runner);
bool apfl_iterative_runner_stopped_because_of_error(apfl_iterative_runner);
void apfl_iterative_runner_destroy(apfl_iterative_runner);
typedef void (*apfl_cfunc)(apfl_ctx);

View file

@ -218,7 +218,6 @@ apfl_error_is_fatal_type(enum apfl_error_type type)
{
switch (type) {
case APFL_ERR_MALLOC_FAILED:
case APFL_ERR_INPUT_ERROR:
return true;
default:
return false;

View file

@ -1325,13 +1325,19 @@ dispatch(apfl_ctx ctx, struct call_stack_entry *cse)
);
}
enum interative_runner_state {
IRUNNER_OK,
IRUNNER_EOF,
IRUNNER_ERR,
};
struct apfl_iterative_runner_data {
apfl_ctx ctx;
apfl_tokenizer_ptr tokenizer;
apfl_parser_ptr parser;
enum apfl_result result;
bool with_error_on_stack;
bool end;
enum interative_runner_state state;
struct scope *scope;
};
@ -1427,7 +1433,7 @@ apfl_iterative_runner_new(apfl_ctx ctx, struct apfl_source_reader reader)
.tokenizer = tokenizer,
.parser = parser,
.result = APFL_RESULT_OK,
.end = false,
.state = IRUNNER_OK,
.scope = scope,
};
@ -1455,11 +1461,16 @@ iterative_runner_next_protected(apfl_ctx ctx, void *opaque)
case APFL_PARSE_OK:
iterative_runner_eval_expr(runner, apfl_parser_get_expr(runner->parser));
return;
case APFL_PARSE_ERROR:
apfl_raise_error_object(runner->ctx, apfl_parser_get_error(runner->parser));
case APFL_PARSE_ERROR: {
struct apfl_error err = apfl_parser_get_error(runner->parser);
if (err.type == APFL_ERR_INPUT_ERROR) {
runner->state = IRUNNER_ERR;
}
apfl_raise_error_object(runner->ctx, err);
return;
}
case APFL_PARSE_EOF:
runner->end = true;
runner->state = IRUNNER_EOF;
return;
}
@ -1469,7 +1480,7 @@ iterative_runner_next_protected(apfl_ctx ctx, void *opaque)
bool
apfl_iterative_runner_next(apfl_iterative_runner runner)
{
if (runner->end) {
if (runner->state != IRUNNER_OK) {
return false;
}
@ -1477,7 +1488,7 @@ apfl_iterative_runner_next(apfl_iterative_runner runner)
runner->result = apfl_do_protected(runner->ctx, iterative_runner_next_protected, runner, &runner->with_error_on_stack);
return !runner->end;
return runner->state == IRUNNER_OK;
}
enum apfl_result
@ -1492,6 +1503,12 @@ apfl_iterative_runner_has_error_on_stack(apfl_iterative_runner runner)
return runner->with_error_on_stack;
}
bool
apfl_iterative_runner_stopped_because_of_error(apfl_iterative_runner runner)
{
return runner->state == IRUNNER_ERR;
}
void
apfl_iterative_runner_destroy(apfl_iterative_runner runner)
{

View file

@ -182,6 +182,11 @@ runtest(const char *filename)
}
}
if (apfl_iterative_runner_stopped_because_of_error(runner)) {
fprintf(stderr, "Runner stopped due to error.\n");
return T_FATAL;
}
apfl_iterative_runner_destroy(runner);
apfl_ctx_destroy(ctx);

View file

@ -64,7 +64,7 @@ repl_tokenizer(struct apfl_allocator allocator, apfl_tokenizer_ptr tokenizer)
err = apfl_tokenizer_get_error(tokenizer);
apfl_error_print(err, stderr);
if (APFL_ERROR_IS_FATAL(err)) {
if (err.type == APFL_ERR_INPUT_ERROR || APFL_ERROR_IS_FATAL(err)) {
return 1;
}
break;
@ -91,7 +91,7 @@ repl_parser(struct apfl_allocator allocator, apfl_parser_ptr parser)
err = apfl_parser_get_error(parser);
apfl_error_print(err, stderr);
if (APFL_ERROR_IS_FATAL(err)) {
if (err.type == APFL_ERR_INPUT_ERROR || APFL_ERROR_IS_FATAL(err)) {
return 1;
}
break;
@ -188,6 +188,10 @@ repl_eval(void)
}
}
if (apfl_iterative_runner_stopped_because_of_error(runner)) {
rv = 1;
}
exit:
apfl_iterative_runner_destroy(runner);
apfl_ctx_destroy(ctx);

View file

@ -125,6 +125,11 @@ main(void)
}
}
if (apfl_iterative_runner_stopped_because_of_error(runner)) {
assert(apfl_format_put_string(w_err, "Runner stopped due to error.\n"));
rv = 1;
}
exit:
free(source_reader_data.str);
apfl_iterative_runner_destroy(runner);