#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"); } 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); } #endif