From 5712d7f4ff93efd9ba627b9143dc739867f6555d Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Sat, 18 Dec 2021 16:12:37 +0100 Subject: [PATCH] Add more parser tests --- src/parser_test.c | 323 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 323 insertions(+) diff --git a/src/parser_test.c b/src/parser_test.c index 8a0e88a..b852b9c 100644 --- a/src/parser_test.c +++ b/src/parser_test.c @@ -173,6 +173,7 @@ MKLISTBUILDER(body, struct apfl_expr_body, struct apfl_expr, items, len) MKLISTBUILDER(dict, struct apfl_expr_dict, struct apfl_expr_dict_pair, items, len) MKLISTBUILDER(complex_func, struct apfl_expr_complex_func, struct apfl_expr_subfunc, subfuncs, len) MKLISTBUILDER(params, struct apfl_expr_params, struct apfl_expr_param, params, len) +MKLISTBUILDER(assignable_list, struct apfl_expr_assignable_list, struct apfl_expr_assignable, children, len) #define POS(l, c) (struct apfl_position) { .line = l, .col = c } @@ -667,6 +668,322 @@ TEST(map, t) { destroy_parser_test(pt); } +TEST(lists, t) { + struct parser_test *pt = new_parser_test(t, + // 123456789 + "[1, 2 3,,# some comment\n" + ",4 ~x ]" + ); + expect_expr(pt, (struct apfl_expr) { + .type = APFL_EXPR_LIST, + .position = POS(1, 1), + .list = LIST_BEGIN(pt, list) + LIST_ADD list_item(false, new_const_expr(pt, 1, 2, num_const(1))), + LIST_ADD list_item(false, new_const_expr(pt, 1, 5, num_const(2))), + LIST_ADD list_item(false, new_const_expr(pt, 1, 7, num_const(3))), + LIST_ADD list_item(false, new_const_expr(pt, 2, 2, num_const(4))), + LIST_ADD list_item(true, new_var(pt, 2, 5, "x")), + LIST_END, + }); + // expect_eof(pt); + destroy_parser_test(pt); +} + +TEST(stringification, t) { + struct parser_test *pt = new_parser_test(t, "'hello"); + expect_expr(pt, const_expr(1, 1, string_const(pt, "hello"))); + expect_eof(pt); + destroy_parser_test(pt); +} + +TEST(line_continuation, t) { + struct parser_test *pt = new_parser_test(t, + "foo \\ # A comment\n" + "bar \\\n" + "\\\n" + "baz\n" + "xyz" + ); + expect_expr(pt, (struct apfl_expr) { + .type = APFL_EXPR_CALL, + .position = POS(1, 1), + .call = (struct apfl_expr_call) { + .callee = new_var(pt, 1, 1, "foo"), + .arguments = LIST_BEGIN(pt, list) + LIST_ADD list_item(false, new_var(pt, 2, 1, "bar")), + LIST_ADD list_item(false, new_var(pt, 4, 1, "baz")), + LIST_END, + }, + }); + expect_expr(pt, var(pt, 5, 1, "xyz")); + expect_eof(pt); + destroy_parser_test(pt); +} + +TEST(dict, t) { + struct parser_test *pt = new_parser_test(t, + // 1 2 3 + // 12345678901234567890123456789012 + "[ a -> b, 'c -> d\n" + "e ->f g ->h\n" + "(i j) -> [1 2 3],, 42 -> [x -> y]\n" + "true -> false]\n" + ); + + expect_expr(pt, (struct apfl_expr) { + .type = APFL_EXPR_DICT, + .position = POS(1, 1), + .dict = LIST_BEGIN(pt, dict) + LIST_ADD (struct apfl_expr_dict_pair) { + .k = new_var(pt, 1, 3, "a"), + .v = new_var(pt, 1, 8, "b"), + }, + LIST_ADD (struct apfl_expr_dict_pair) { + .k = new_const_expr(pt, 1, 11, string_const(pt, "c")), + .v = new_var(pt, 1, 17, "d"), + }, + LIST_ADD (struct apfl_expr_dict_pair) { + .k = new_var(pt, 2, 1, "e"), + .v = new_var(pt, 2, 5, "f"), + }, + LIST_ADD (struct apfl_expr_dict_pair) { + .k = new_var(pt, 2, 7, "g"), + .v = new_var(pt, 2, 11, "h"), + }, + LIST_ADD (struct apfl_expr_dict_pair) { + .k = BEGIN_NEW(pt, struct apfl_expr) { + .type = APFL_EXPR_CALL, + .position = POS(3, 1), + .call = (struct apfl_expr_call) { + .callee = new_var(pt, 3, 2, "i"), + .arguments = LIST_BEGIN(pt, list) + LIST_ADD list_item(false, new_var(pt, 3, 4, "j")), + LIST_END, + }, + } END_NEW, + .v = BEGIN_NEW(pt, struct apfl_expr) { + .type = APFL_EXPR_LIST, + .position = POS(3, 10), + .list = LIST_BEGIN(pt, list) + LIST_ADD list_item(false, new_const_expr(pt, 3, 11, num_const(1))), + LIST_ADD list_item(false, new_const_expr(pt, 3, 13, num_const(2))), + LIST_ADD list_item(false, new_const_expr(pt, 3, 15, num_const(3))), + LIST_END, + } END_NEW, + }, + LIST_ADD (struct apfl_expr_dict_pair) { + .k = new_const_expr(pt, 3, 20, num_const(42)), + .v = BEGIN_NEW(pt, struct apfl_expr) { + .type = APFL_EXPR_DICT, + .position = POS(3, 26), + .dict = LIST_BEGIN(pt, dict) + LIST_ADD (struct apfl_expr_dict_pair) { + .k = new_var(pt, 3, 27, "x"), + .v = new_var(pt, 3, 32, "y"), + }, + LIST_END, + } END_NEW, + }, + LIST_ADD (struct apfl_expr_dict_pair) { + .k = new_const_expr(pt, 4, 1, bool_const(true)), + .v = new_const_expr(pt, 4, 9, bool_const(false)), + }, + LIST_END + }); + expect_eof(pt); + + destroy_parser_test(pt); +} + +TEST(assignment, t) { + struct parser_test *pt = new_parser_test(t, + // 123456 + "a = b\n" + // 1 2 + // 12345678901234567890123456 + "foo.bar := bar?pred = baz\n" + // 1 2 3 + // 12345678901234567890123456789012345 + "[[1 2] ~xs] = bla@(a b) := abc ~xyz\n" + ); + + expect_expr(pt, (struct apfl_expr) { + .type = APFL_EXPR_ASSIGNMENT, + .position = POS(1, 3), + .assignment = (struct apfl_expr_assignment) { + .local = false, + .lhs = (struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_VAR, + .var = new_string(pt, "a"), + }, + .rhs = new_var(pt, 1, 5, "b"), + }, + }); + expect_expr(pt, (struct apfl_expr) { + .type = APFL_EXPR_ASSIGNMENT, + .position = POS(2, 9), + .assignment = (struct apfl_expr_assignment) { + .local = true, + .lhs = (struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_DOT, + .dot = (struct apfl_expr_assignable_dot) { + .lhs = BEGIN_NEW(pt, struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_VAR, + .var = new_string(pt, "foo"), + } END_NEW, + .rhs = new_string(pt, "bar"), + }, + }, + .rhs = BEGIN_NEW(pt, struct apfl_expr) { + .type = APFL_EXPR_ASSIGNMENT, + .position = POS(2, 21), + .assignment = (struct apfl_expr_assignment) { + .local = false, + .lhs = (struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_PREDICATE, + .predicate = (struct apfl_expr_assignable_predicate) { + .lhs = BEGIN_NEW(pt, struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_VAR, + .var = new_string(pt, "bar"), + } END_NEW, + .rhs = new_var(pt, 2, 16, "pred"), + }, + }, + .rhs = new_var(pt, 2, 23, "baz"), + }, + } END_NEW, + }, + }); + expect_expr(pt, (struct apfl_expr) { + .type = APFL_EXPR_ASSIGNMENT, + .position = POS(3, 13), + .assignment = (struct apfl_expr_assignment) { + .local = false, + .lhs = (struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_LIST, + .list = LIST_BEGIN(pt, assignable_list) + LIST_ADD (struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_LIST, + .list = LIST_BEGIN(pt, assignable_list) + LIST_ADD (struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_CONSTANT, + .constant = num_const(1), + }, + LIST_ADD (struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_CONSTANT, + .constant = num_const(2), + }, + LIST_END, + }, + LIST_ADD (struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_EXPAND, + .expand = BEGIN_NEW(pt, struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_VAR, + .var = new_string(pt, "xs"), + } END_NEW, + }, + LIST_END, + }, + .rhs = BEGIN_NEW(pt, struct apfl_expr) { + .type = APFL_EXPR_ASSIGNMENT, + .position = POS(3, 25), + .assignment = (struct apfl_expr_assignment) { + .local = true, + .lhs = (struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_AT, + .at = (struct apfl_expr_assignable_at) { + .lhs = BEGIN_NEW(pt, struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_VAR, + .var = new_string(pt, "bla"), + } END_NEW, + .rhs = BEGIN_NEW(pt, struct apfl_expr) { + .type = APFL_EXPR_CALL, + .position = POS(3, 19), + .call = (struct apfl_expr_call) { + .callee = new_var(pt, 3, 20, "a"), + .arguments = LIST_BEGIN(pt, list) + LIST_ADD list_item(false, new_var(pt, 3, 22, "b")), + LIST_END, + }, + } END_NEW, + }, + }, + .rhs = BEGIN_NEW(pt, struct apfl_expr) { + .type = APFL_EXPR_CALL, + .position = POS(3, 28), + .call = (struct apfl_expr_call) { + .callee = new_var(pt, 3, 28, "abc"), + .arguments = LIST_BEGIN(pt, list) + LIST_ADD list_item(true, new_var(pt, 3, 33, "xyz")), + LIST_END, + }, + } END_NEW, + }, + } END_NEW, + }, + }); + expect_eof(pt); + + destroy_parser_test(pt); +} + +TEST(simple_function, t) { + struct parser_test *pt = new_parser_test(t, + // 12345678901 + "{{\n" + " }; foo \\\n" + "bar { # comment...\n" + " baz = 10\n" + " a\n" + " b\n" + "}; c}\n" + ); + expect_expr(pt, (struct apfl_expr) { + .type = APFL_EXPR_SIMPLE_FUNC, + .position = POS(1, 1), + .simple_func = LIST_BEGIN(pt, body) + LIST_ADD (struct apfl_expr) { + .type = APFL_EXPR_SIMPLE_FUNC, + .position = POS(1, 2), + .simple_func = LIST_BEGIN(pt, body) + LIST_END, + }, + LIST_ADD (struct apfl_expr) { + .type = APFL_EXPR_CALL, + .position = POS(2, 8), + .call = (struct apfl_expr_call) { + .callee = new_var(pt, 2, 8, "foo"), + .arguments = LIST_BEGIN(pt, list) + LIST_ADD list_item(false, new_var(pt, 3, 1, "bar")), + LIST_ADD list_item(false, BEGIN_NEW(pt, struct apfl_expr) { + .type = APFL_EXPR_SIMPLE_FUNC, + .position = POS(3, 5), + .simple_func = LIST_BEGIN(pt, body) + LIST_ADD (struct apfl_expr) { + .type = APFL_EXPR_ASSIGNMENT, + .position = POS(4, 9), + .assignment = (struct apfl_expr_assignment) { + .local = false, + .lhs = (struct apfl_expr_assignable) { + .type = APFL_EXPR_ASSIGNABLE_VAR, + .var = new_string(pt, "baz"), + }, + .rhs = new_const_expr(pt, 4, 11, num_const(10)), + }, + }, + LIST_ADD var(pt, 5, 5, "a"), + LIST_ADD var(pt, 6, 5, "b"), + LIST_END, + } END_NEW), + LIST_END, + }, + }, + LIST_ADD var(pt, 7, 4, "c"), + LIST_END, + }); + destroy_parser_test(pt); +} + TESTS_BEGIN ADDTEST(empty), ADDTEST(hello_world), @@ -679,4 +996,10 @@ TESTS_BEGIN ADDTEST(complex_dot_at_access), ADDTEST(factorial), ADDTEST(map), + ADDTEST(lists), + ADDTEST(stringification), + ADDTEST(line_continuation), + ADDTEST(dict), + ADDTEST(assignment), + ADDTEST(simple_function), TESTS_END