#ifndef SK_TEST_PARSER_H #define SK_TEST_PARSER_H #include #include "node.h" #include static void test_parser(char const* oracle, char const* source) { struct parser parser; parser_init(&parser, source); struct node* node = parser_try_parse(&parser); CU_ASSERT_FATAL(node != NULL); struct str str; str_init(&str); node_str(node, &str); if (strcmp(oracle, str.value) != 0) { fprintf(stderr, "\n%s <> %s\n", oracle, str.value); } CU_ASSERT_STRING_EQUAL_FATAL(oracle, str.value); str_free(&str); node_free(node); free(node); parser_free(&parser); } static void test_parser_int() { test_parser("ROOT(INT[32])", " 32 "); test_parser("ROOT(INT[32],INT[2],INT[24])", " 32 2 24"); test_parser("ROOT(ADD(INT[1],MUL(INT[2],INT[3])))", " 1 + 2 * 3 "); test_parser("ROOT(DIV(SUB(INT[1],INT[2]),INT[3]))", " (1 - 2) / 3 "); test_parser("ROOT(USUB(INT[32]))", " -(32) "); } static void test_parser_assert() { test_parser("ROOT(ASSERT_EQ(INT[32],INT[12]))", " assert 32 eq 12 "); } static void test_parser_bool() { test_parser("ROOT(BOOL[true])", "true"); test_parser("ROOT(NOT(BOOL[false]))", "not false"); test_parser("ROOT(OR(AND(NOT(BOOL[false]),BOOL[true])," "BOOL[false]))", "not false and true or false"); test_parser("ROOT(AND(NOT(BOOL[false]),OR(BOOL[true]," "BOOL[false])))", "not false and (true or false)"); } static void test_parser_string() { test_parser("ROOT(STRING[ok pizza NOW])", "\"ok pizza NOW\""); } static void test_parser_cmp() { test_parser("ROOT(LT(INT[5],INT[3]))", "5<3"); test_parser("ROOT(LE(INT[5],INT[3]))", "5<=3"); test_parser("ROOT(GT(INT[5],INT[3]))", "5>3"); test_parser("ROOT(GE(INT[5],INT[3]))", "5>=3"); test_parser("ROOT(EQUAL(INT[5],INT[3]))", "5==3"); test_parser("ROOT(NOT_EQUAL(INT[5],INT[3]))", "5<>3"); } static void test_parser_decl() { test_parser("ROOT(IDENT[bim!])", "bim!"); test_parser("ROOT(VAR_DECL(IDENT[x],INT[37]))", "var x = 37"); test_parser("ROOT(CONST_DECL(IDENT[x],MUL(FLOAT[2.2],INT[3])))", "const x = 2.2 * 3"); } static void test_parser_assign() { test_parser("ROOT(ASSIGN(IDENT[hello],BOOL[false]))", "hello = false"); } static void test_parser_block() { test_parser("ROOT(BLOCK)", "begin end"); test_parser("ROOT(BLOCK(INT[1],INT[2]))", "begin 1 2 end"); } static void test_parser_if() { test_parser("ROOT(IF(BOOL[true],BLOCK(INT[0])))", "if true 0 end"); test_parser("ROOT(IF(BOOL[true],BLOCK(INT[0]),BLOCK(INT[1])))", "if true 0 else 1 end"); test_parser("ROOT(IF(BOOL[true],BLOCK(INT[0])," "IF(BOOL[false],BLOCK(INT[1]),BLOCK(INT[2]))))", "if true 0 else if false 1 else 2 end"); } static void test_parser_function() { test_parser("ROOT(FUN(PARAMS(IDENT[x],IDENT[y])," "BLOCK(INT[0],INT[1])))", "fun (x, y) 0 1 end"); test_parser("ROOT(FUN(PARAMS," "BLOCK(INT[0],INT[1])))", "fun () 0 1 end"); test_parser("ROOT(FUN(PARAMS,BLOCK))", "fun () end"); test_parser("ROOT(CONST_DECL(IDENT[hello]" ",FUN(PARAMS(IDENT[x],IDENT[y])," "BLOCK(INT[0],INT[1]))))", "fun hello (x, y) 0 1 end"); test_parser("ROOT(CALL(IDENT[hello],ARGS))", "hello()"); test_parser("ROOT(CALL(IDENT[hello],ARGS(IDENT[x],INT[2])))", "hello(x, 2)"); } static void test_parser_module() { test_parser("ROOT(MODULE(INT[4],STRING[5],BOOL[true]))", "module 4 \"5\" true end"); test_parser("ROOT(ASSIGN(MOD_ACCESS(IDENT[x],IDENT[hello])" ",INT[3]))", "x::hello = 3"); test_parser("ROOT(CALL(MOD_ACCESS(IDENT[x],IDENT[hello]),ARGS))", "x::hello()"); } static void test_parser_import() { test_parser("ROOT(IMPORT(STRING[./hello]))", "import \"./hello\""); } void register_parser() { CU_pSuite suite = CU_add_suite("Parser", 0, 0); CU_add_test(suite, "Integers", test_parser_int); CU_add_test(suite, "Assertions", test_parser_assert); CU_add_test(suite, "Booleans", test_parser_bool); CU_add_test(suite, "Strings", test_parser_string); CU_add_test(suite, "Comparisons", test_parser_cmp); CU_add_test(suite, "Declarations", test_parser_decl); CU_add_test(suite, "Assignments", test_parser_assign); CU_add_test(suite, "Blocks", test_parser_block); CU_add_test(suite, "IfExpression", test_parser_if); CU_add_test(suite, "Functions", test_parser_function); CU_add_test(suite, "Modules", test_parser_module); CU_add_test(suite, "Imports", test_parser_import); } #endif