From 5b4ac67de9ea4674624a8507511e16ee30d75149 Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Thu, 8 Dec 2022 21:35:41 +0100 Subject: [PATCH] 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. --- src/apfl.h | 1 + src/error.c | 1 - src/eval.c | 31 ++++++++++++++++++++++++------- src/functional-test-runner.c | 5 +++++ src/main.c | 8 ++++++-- webpage/playground/playground.c | 5 +++++ 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/apfl.h b/src/apfl.h index 7efe706..ebca6ea 100644 --- a/src/apfl.h +++ b/src/apfl.h @@ -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); diff --git a/src/error.c b/src/error.c index 759a4f5..875d7a1 100644 --- a/src/error.c +++ b/src/error.c @@ -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; diff --git a/src/eval.c b/src/eval.c index 73c5975..134b5b4 100644 --- a/src/eval.c +++ b/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) { diff --git a/src/functional-test-runner.c b/src/functional-test-runner.c index 736c406..3f46a5b 100644 --- a/src/functional-test-runner.c +++ b/src/functional-test-runner.c @@ -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); diff --git a/src/main.c b/src/main.c index e41fbb5..4620039 100644 --- a/src/main.c +++ b/src/main.c @@ -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); diff --git a/webpage/playground/playground.c b/webpage/playground/playground.c index 899b5c4..d3513b0 100644 --- a/webpage/playground/playground.c +++ b/webpage/playground/playground.c @@ -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);