summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorCarlos Maniero <carlosmaniero@gmail.com>2023-04-20 13:32:36 -0300
committerJohnny Richard <johnny@johnnyrichard.com>2023-04-20 18:31:55 +0200
commit3ceb85bd93fa87a5be3682ab8995abea82a63ea3 (patch)
tree9512c4255bd87967dfd42a8ca68abd18e34e7407 /test
parenta47e5ceb6eefdac9c5f5473e1fee0d33a5f4646e (diff)
parser: Stop exiting on parser error
Previously, when an error occurred during parsing, the application would exit, making it difficult to test the parser and limiting the compiler's extensibility. This commit improves the parser's error handling by allowing for continued execution after an error, enabling easier testing and increased flexibility. The parser is prepared to handle multiples errors, although the current implementation always returns a single error, it may be useful given multiples functions where we can show errors by context. Signed-off-by: Carlos Maniero <carlosmaniero@gmail.com> Reviwed-by: Johnny Richard <johnny@johnnyrichard.com>
Diffstat (limited to 'test')
-rw-r--r--test/parser_test.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/test/parser_test.c b/test/parser_test.c
index 30aa285..d0d36ca 100644
--- a/test/parser_test.c
+++ b/test/parser_test.c
@@ -23,6 +23,7 @@
void
make_lexer_from_static_src(lexer_t *lexer, char *src)
{
+ lexer->filepath = "test.pipa";
lexer->srclen = 0;
lexer->cur = 0;
lexer->row = 0;
@@ -31,6 +32,22 @@ make_lexer_from_static_src(lexer_t *lexer, char *src)
lexer->srclen = strlen(src);
}
+void
+assert_parser_error(char* src, char* error_msg) {
+ parser_t parser;
+ lexer_t lexer;
+
+ make_lexer_from_static_src(&lexer, src);
+ parser_init(&parser, &lexer);
+
+ ast_node_t *ast_function = ast_node_new();
+
+ bool parsed = parser_parse_function_declaration(&parser, ast_function);
+ assert_false(parsed);
+ assert_int(1, ==, parser.errors_len);
+ assert_string_equal(error_msg, parser.errors[0].message);
+}
+
static MunitResult
test_parse_function(const MunitParameter params[],
void *user_data_or_fixture)
@@ -41,7 +58,9 @@ test_parse_function(const MunitParameter params[],
make_lexer_from_static_src(&lexer, "main(): i32 { return 42; }");
parser_init(&parser, &lexer);
ast_node_t *ast_function = ast_node_new();
- parser_parse_function_declaration(&parser, ast_function);
+
+ bool parsed = parser_parse_function_declaration(&parser, ast_function);
+ assert_true(parsed);
char actual[5];
@@ -59,8 +78,28 @@ test_parse_function(const MunitParameter params[],
return MUNIT_OK;
}
+static MunitResult
+test_parse_basic_syntax_errors(const MunitParameter params[],
+ void *user_data_or_fixture)
+{
+ assert_parser_error("(): i32 { return 42; }" , "expected 'TOKEN_NAME' but got '('");
+ assert_parser_error("main): i32 { return 42; }" , "expected '(' but got ')'");
+ assert_parser_error("main(: i32 { return 42; }" , "expected ')' but got ':'");
+ assert_parser_error("main() i32 { return 42; }" , "expected ':' but got 'TOKEN_NAME'");
+ assert_parser_error("main(): { return 42; }" , "expected 'TOKEN_NAME' but got '{'");
+ assert_parser_error("main(): i32 return 42; }" , "expected '{' but got 'TOKEN_NAME'");
+ assert_parser_error("main(): i32 { 42; }" , "expected 'TOKEN_NAME' but got 'TOKEN_NUMBER'");
+ assert_parser_error("main(): i32 { return; }" , "expected 'TOKEN_NUMBER' but got ';'");
+ assert_parser_error("main(): i32 { return 42;" , "expected '}' but got end of file");
+ assert_parser_error("main(): beff { return 42; }" , "type 'beff' is not defined");
+ assert_parser_error("main(): i32 { oxi 42; }" , "expected 'return' keyword but got 'oxi'");
+
+ return MUNIT_OK;
+}
+
static MunitTest tests[] = {
{ "/test_parse_function", test_parse_function, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
+ { "/test_parse_basic_syntax_errors", test_parse_basic_syntax_errors, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};