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:
parent
57cd32dfa5
commit
5b4ac67de9
6 changed files with 41 additions and 10 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
31
src/eval.c
31
src/eval.c
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue