From 158b8fffeb17fe19b3630d4d3e0ea0c3f8d59033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Fri, 19 May 2017 20:35:32 +0200 Subject: Rethink the parse() function Now the parser should handle memory allocation failures properly. --- ell.c | 57 +++++++++++++++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/ell.c b/ell.c index 043fad5..8ad5468 100755 --- a/ell.c +++ b/ell.c @@ -620,35 +620,22 @@ parse_line (struct parser *self, jmp_buf out) { #undef CHECK static struct item * -parse (const char *s, size_t len, char **e) { - struct parser parser; - parser_init (&parser, s, len); - +parser_run (struct parser *self, const char **e) { jmp_buf err; struct item *volatile result = NULL, *volatile *tail = &result; if (setjmp (err)) { item_free_list (result); - *e = parser.error; - lexer_free (&parser.lexer); - - // TODO: figure out how to handle this, since the return value - // may be null and we may not be able to allocate an error message - if (parser.memory_failure) - abort (); - + if (e) { + *e = self->error; + if (self->memory_failure) + *e = "memory allocation failure"; + } return NULL; } - while ((*tail = parse_line (&parser, err))) + while ((*tail = parse_line (self, err))) tail = &(*tail)->next; - parser_expect (&parser, T_ABORT, err); - - parser_free (&parser); -#ifndef NDEBUG - printf ("\x1b[1m%s\x1b[0m\n", s); - print_tree (result, 0); - printf ("\n\n"); -#endif + parser_expect (self, T_ABORT, err); return result; } @@ -929,17 +916,18 @@ init_runtime_library_scripts (struct context *ctx) { }; for (size_t i = 0; i < N_ELEMENTS (functions); i++) { - char *e = NULL; - struct item *body = parse (functions[i].definition, - strlen (functions[i].definition), &e); - // TODO: also handle memory allocation errors + struct parser parser; + parser_init (&parser, + functions[i].definition, strlen (functions[i].definition)); + const char *e = NULL; + struct item *body = parser_run (&parser, &e); if (e) { printf ("error parsing internal function `%s': %s\n", - functions[i].definition, e); - free (e); + functions[i].name, e); ok = false; } else ok &= set (ctx, functions[i].name, body); + parser_free (&parser); } return ok; } @@ -1025,15 +1013,24 @@ main (int argc, char *argv[]) { buffer_append_c (&buf, 0); fclose (fp); - char *e = NULL; - struct item *program = parse (buf.s, buf.len, &e); + struct parser parser; + parser_init (&parser, buf.s, buf.len - 1); + const char *e = NULL; + struct item *program = parser_run (&parser, &e); free (buf.s); + if (e) { printf ("%s: %s\n", "parse error", e); - free (e); return 1; } +#ifndef NDEBUG + printf ("\x1b[1m%s\x1b[0m\n", buf.s); + print_tree (program, 0); + printf ("\n\n"); +#endif + parser_free (&parser); + struct context ctx; context_init (&ctx); if (!init_runtime_library () -- cgit v1.2.3