#ifndef MK_TEST_PARSER_H #define MK_TEST_PARSER_H #include #include #include #include void test_parser(char const* oracle, char const* source) { struct status status; status_init(&status); struct lexer lex; lexer_init(&lex, source, &status); struct parser parser; parser_init(&parser, &lex); struct node* ast = parser_try_new_parse(&parser); ck_assert(ast); struct str my_node_str; str_init(&my_node_str); node_str(ast, &my_node_str); ck_assert_str_eq(oracle, my_node_str.value); bool ok = status_is_ok(&status); if (!ok) { status_dump(&status); } ck_assert(ok); str_free(&my_node_str); node_free(ast); free(ast); parser_free(&parser); lexer_free(&lex); status_free(&status); } START_TEST(parser_atom) { test_parser("ROOT(INT[34])", " 34 "); test_parser("ROOT(FLOAT[0.8])", " 0.8 "); test_parser("ROOT(BOOL[true],BOOL[false])", " true false "); test_parser("ROOT(STRING[pizza!])", " \"pizza!\" "); test_parser("ROOT(SYMBOL[tea])", " 'tea "); } END_TEST START_TEST(parser_call) { test_parser("ROOT(CALL(IDENT[hello-noparam]))", " (hello-noparam) "); test_parser("ROOT(CALL(IDENT[hello],SYMBOL[world]))", " (hello 'world) "); test_parser("ROOT(CALL(IDENT[is-ok?],BOOL[true],INT[4]))", " (is-ok? true 4) "); } END_TEST START_TEST(parser_array) { test_parser("ROOT(CALL(IDENT[quote],CALL(INT[1],INT[2],INT[3])))", " [1 2 3] "); test_parser("ROOT(CALL(IDENT[quote],CALL(INT[1])))", " [1] "); } END_TEST void register_parser(Suite* suite) { TCase* tcase = tcase_create("Parser"); tcase_add_test(tcase, parser_atom); tcase_add_test(tcase, parser_call); tcase_add_test(tcase, parser_array); suite_add_tcase(suite, tcase); } #endif