} END_TEST START_TEST(test_determine_block_type2) { struct ast_node *block; static const struct RFstring s = RF_STRING_STATIC_INIT( "type foo {a:i8, b:string}\n" "{\n" "a:foo\n" "}" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); struct type *t_i8 = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_INT_8); struct type *t_string = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_STRING); struct type *t_prod_1 = testsupport_analyzer_type_create_operator(TYPEOP_PRODUCT, t_i8, t_string); static const struct RFstring id_foo = RF_STRING_STATIC_INIT("foo"); struct type *t_foo = testsupport_analyzer_type_create_defined(&id_foo, t_prod_1); block = ast_node_get_child(front_testdriver_module()->node, 1); ck_assert_msg(block, "Block should be the second child of the root"); const struct type *block_type = ast_node_get_type(block); ck_assert_msg(block_type, "Block should have a type"); ck_assert_msg(type_compare(block_type, t_foo, TYPECMP_IDENTICAL), "Expected the block's type to be an f64"); } END_TEST
} END_TEST START_TEST(test_type_ast_traversal4) { static const struct RFstring s = RF_STRING_STATIC_INIT( "type foo {a:i8, b:string | c:f32, d:u64}\n" ); front_testdriver_new_ast_main_source(&s); testsupport_scan_and_parse(); // go only up to the parsing stage, don't analyze struct type *t_i8 = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_INT_8); struct type *t_string = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_STRING); struct type *t_f32 = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_FLOAT_32); struct type *t_u64 = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_UINT_64); struct type *t_prod1 = testsupport_analyzer_type_create_operator(TYPEOP_PRODUCT, t_i8, t_string); struct type *t_prod2 = testsupport_analyzer_type_create_operator(TYPEOP_PRODUCT, t_f32, t_u64); struct type *t_sum = testsupport_analyzer_type_create_operator(TYPEOP_SUM, t_prod1, t_prod2); struct ast_node *ast_desc = ast_typedecl_typedesc_get(ast_node_get_child(front_testdriver_module()->node, 0)); struct test_traversal_cb_ctx ctx; const struct RFstring expected_names[] = { RF_STRING_STATIC_INIT("a"), RF_STRING_STATIC_INIT("b"), RF_STRING_STATIC_INIT("c"), RF_STRING_STATIC_INIT("d"), }; struct type *expected_types [] = { t_i8, t_string, t_f32, t_u64 }; test_traversal_cb_ctx_init(&ctx, expected_names, expected_types); ck_assert(ast_type_foreach_leaf_arg(ast_desc, t_sum, (ast_type_cb)test_traversal_cb, &ctx)); } END_TEST
}END_TEST START_TEST(test_invalid_stringx_traversal) { static const struct RFstring sub3 = RF_STRING_STATIC_INIT("ain't there"); static const struct RFstring sub4 = RF_STRING_STATIC_INIT("notthere"); struct RFstringx s; struct RFstringx str_buff; struct RFstring res_str_bad; ck_assert(rf_stringx_init_buff(&str_buff, 1024, "")); ck_assert( rf_stringx_init( &s, "中国共産党総書記に習近平氏 新指導部の7人発表") ); ck_assert(RF_FAILURE == rf_stringx_move_after(&s, NULL, &str_buff, RF_STRINGX_ARGUMENT)); ck_assert(RF_FAILURE == rf_stringx_move_after(&s, &sub3, &str_buff, RF_STRINGX_ARGUMENT)); ck_assert(!rf_stringx_move_afterv(&s, NULL, 0, 2, &sub3, &sub4)); ck_assert(!rf_stringx_move_after_pair(&s, NULL, &sub3, &res_str_bad, 0, 2)); ck_assert(!rf_stringx_move_after_pair(&s, &sub4, NULL, &res_str_bad, 0, 2)); rf_stringx_deinit(&s); rf_stringx_deinit(&str_buff); }END_TEST
}END_TEST START_TEST(test_stringx_move_after_pair) { struct RFstringx s; struct RFstring res_str_good; struct RFstring res_str_bad; struct RFstring dependent_s; static const struct RFstring sub1 = RF_STRING_STATIC_INIT("「"); static const struct RFstring sub2 = RF_STRING_STATIC_INIT("」"); static const struct RFstring sub3 = RF_STRING_STATIC_INIT("eleos"); static const struct RFstring sub4 = RF_STRING_STATIC_INIT("notthere"); ck_assert( rf_stringx_init( &s, "これがMoveAfterPairのテストですね!「Δεν θα επιστραφω εγω" "」 Γεμιζουμε το στρινγκ " "με διαφορα 「ブラケットの中のテ" "キストは結果になる」Let's see if the function will work " "as expected." ) ); ck_assert( rf_stringx_move_after_pair(&s, &sub1, &sub2, &res_str_good, 0, 2) ); ck_assert_rf_str_eq_cstr( &s, "Let's see if the function will work as expected." ); ck_assert_rf_str_eq_cstr( &res_str_good, "ブラケットの中のテキストは結果になる" ); /* dependent string */ rf_stringx_reset(&s); ck_assert( rf_stringx_move_after_pair(&s, &sub1, &sub2, &dependent_s, RF_STRING_DEPENDENT, 2) ); ck_assert_rf_str_eq_cstr( &s, "Let's see if the function will work as expected." ); ck_assert_rf_str_eq_cstr( &dependent_s, "ブラケットの中のテキストは結果になる" ); /* non existing substrings */ ck_assert(!rf_stringx_move_after_pair(&s, &sub3, &sub4, &res_str_bad, 0, 2)); rf_stringx_deinit(&s); rf_string_deinit(&res_str_good); rf_string_deinit(&dependent_s); }END_TEST
} END_TEST START_TEST(test_typecheck_invalid_custom_type_constructor) { static const struct RFstring s = RF_STRING_STATIC_INIT( "type person { name:string, age:u32 }\n" "fn do_something() -> string\n" "{\n" "a:person = person(\"Celina\")\n" "return a.name" "}\n" ); front_testdriver_new_ast_main_source(&s); struct info_msg messages[] = { TESTSUPPORT_INFOMSG_INIT_BOTH( MESSAGE_SEMANTIC_ERROR, "constructor person() is called with argument type of " "\"string\" which does not match the expected type of \"string,u32\".", 3, 11, 3, 26), TESTSUPPORT_INFOMSG_INIT_BOTH( MESSAGE_SEMANTIC_ERROR, "Type of right side of \"=\" can not be determined", 3, 11, 3, 26), }; ck_assert_typecheck_with_messages(false, messages); } END_TEST
} END_TEST START_TEST(test_typecheck_valid_custom_sum_type_constructor) { static const struct RFstring s = RF_STRING_STATIC_INIT( "type person { name:string | id:u32 }" "fn do_something()\n" "{\n" "a:person = person(\"Celina\")\n" "b:person = person(13)\n" "}\n" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); struct ast_node *fn_impl = ast_node_get_child(front_testdriver_root(), 1); ck_assert(fn_impl->type == AST_FUNCTION_IMPLEMENTATION); struct ast_node *block = ast_fnimpl_body_get(fn_impl); struct ast_node *bop1 = ast_node_get_child(block, 0); struct ast_node *bop2 = ast_node_get_child(block, 1); ck_assert(ast_node_is_specific_binaryop(bop1, BINARYOP_ASSIGN)); ck_assert(ast_node_is_specific_binaryop(bop2, BINARYOP_ASSIGN)); struct ast_node *ctor1 = ast_binaryop_right(bop1); struct ast_node *ctor2 = ast_binaryop_right(bop2); ck_assert(ctor1->type = AST_FUNCTION_CALL); ck_assert(ctor2->type = AST_FUNCTION_CALL); struct type *t_string = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_STRING); struct type *t_u32 = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_UINT_32); ck_assert(type_compare(ctor1->fncall.params_type, t_string, TYPECMP_IDENTICAL)); ck_assert(type_compare(ctor2->fncall.params_type, t_u32, TYPECMP_IDENTICAL)); } END_TEST
} END_TEST START_TEST(test_array_type4) { static const struct RFstring s = RF_STRING_STATIC_INIT( "{\n" "a:u64[] = [1, 2, 3]\n" "}" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); int64_t dims[] = {3}; struct type *t_u64 = testsupport_analyzer_type_create_elemarray( ELEMENTARY_TYPE_UINT_64, dims ); struct ast_node *block = ast_node_get_child(front_testdriver_module()->node, 0); struct ast_node *blist = ast_binaryop_right(ast_node_get_child(block, 0)); const struct type *blist_type = ast_node_get_type(blist); ck_assert_msg(blist_type, "bracket type should not be NULL"); ck_assert_msg( type_compare(blist_type, t_u64, TYPECMP_GENERIC), "Bracket type comparison failure" ); struct ast_node *vardecl = ast_binaryop_left(ast_node_get_child(block, 0)); const struct type *vardecl_type = ast_node_get_type(vardecl); ck_assert_msg(vardecl_type, "bracket type should not be NULL"); ck_assert_msg( type_compare(vardecl_type, t_u64, TYPECMP_IDENTICAL), "Bracket type comparison failure" ); } END_TEST
}END_TEST START_TEST(test_acc_ifexpr_ambiguous_less_than_or_generic) { struct ast_node *n; static const struct RFstring s = RF_STRING_STATIC_INIT( "if a < 42 {\n" "}" ); front_testdriver_new_main_source(&s); struct ast_node *id1 = testsupport_parser_identifier_create(0, 3, 0, 3); testsupport_parser_constant_create(cnum, 0, 7, 0, 8, integer, 42); testsupport_parser_node_create(cmp_exp, binaryop, 0, 3, 0, 8, BINARYOP_CMP_LT, id1, cnum); testsupport_parser_block_create(bnode, 0, 10, 1, 0); testsupport_parser_node_create(cond, condbranch, 0, 3, 1, 0, cmp_exp, bnode); testsupport_parser_node_create(ifx, ifexpr, 0, 0, 1, 0, cond, NULL); ck_test_parse_as(n, ifexpr, "if_expression", ifx, TOKEN_KW_IF); ast_node_destroy(n); ast_node_destroy(ifx); }END_TEST
} END_TEST START_TEST (test_type_to_str) { struct type *t_u32 = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_UINT_32); struct type *t_f64 = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_FLOAT_64); struct type *t_string = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_STRING); struct type *t_prod_1 = testsupport_analyzer_type_create_operator(TYPEOP_PRODUCT, t_u32, t_f64); struct type *t_sum_1 = testsupport_analyzer_type_create_operator(TYPEOP_SUM, t_f64, t_string); static const struct RFstring id_person = RF_STRING_STATIC_INIT("person"); struct type *t_defined_1 = testsupport_analyzer_type_create_defined(&id_person, t_sum_1); struct RFstring *ts; RFS_PUSH(); ck_assert((ts = type_str(t_u32, TSTR_DEFAULT))); ck_assert_rf_str_eq_cstr(ts, "u32"); ck_assert((ts = type_str(t_prod_1, TSTR_DEFAULT))); ck_assert_rf_str_eq_cstr(ts, "u32,f64"); ck_assert((ts = type_str(t_defined_1, TSTR_DEFAULT))); ck_assert_rf_str_eq_cstr(ts, "person"); RFS_POP(); } END_TEST
} END_TEST START_TEST (test_type_get_uid) { static const struct RFstring s = RF_STRING_STATIC_INIT( "type foo {a:i8, b:string}\n" "fn do_something()\n" "{\n" "a:foo = foo(15, \"name\")\n" "b:u32 = 15\n" "}" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); struct ast_node *fn_impl = ast_node_get_child(front_testdriver_root(), 1); ck_assert(fn_impl->type == AST_FUNCTION_IMPLEMENTATION); struct ast_node *block = ast_fnimpl_body_get(fn_impl); struct ast_node *bop1 = ast_node_get_child(block, 0); ck_assert(ast_node_is_specific_binaryop(bop1, BINARYOP_ASSIGN)); struct ast_node *a_foo = ast_binaryop_left(bop1); ck_assert(a_foo); const struct type *t1 = ast_node_get_type_or_die(a_foo); size_t s1 = type_get_uid(t1); ck_assert_uint_eq(s1, 590239457); struct ast_node *bop2 = ast_node_get_child(block, 1); ck_assert(ast_node_is_specific_binaryop(bop2, BINARYOP_ASSIGN)); struct ast_node *b_u32 = ast_binaryop_left(bop2); ck_assert(b_u32); const struct type *t2 = ast_node_get_type_or_die(b_u32); size_t s2 = type_get_uid(t2); ck_assert_uint_eq(s2, 3813314396); } END_TEST
}END_TEST START_TEST(test_stringx_reset) { struct RFstringx s; static const struct RFstring sub1 = RF_STRING_STATIC_INIT("に"); ck_assert( rf_stringx_init( &s, "中国共産党総書記に習近平氏 新指導部の7人発表" ) ); /* resetting an unmoved string has no effect */ rf_stringx_reset(&s); ck_assert_rf_str_eq_cstr( &s, "中国共産党総書記に習近平氏 新指導部の7人発表" ); /* move and reset */ ck_assert(RF_FAILURE != rf_stringx_move_after(&s, &sub1, NULL, 0)); ck_assert_rf_str_eq_cstr(&s, "習近平氏 新指導部の7人発表"); rf_stringx_reset(&s); ck_assert_rf_str_eq_cstr( &s, "中国共産党総書記に習近平氏 新指導部の7人発表" ); rf_stringx_deinit(&s); }END_TEST
}END_TEST START_TEST(test_textfile_replace) { struct RFtextfile f; static const char *s; static struct RFstring str = RF_STRING_STATIC_INIT("Line Replacement"); ck_assert(rf_stringx_assign_unsafe_nnt( &g_fname, CLIB_TESTS_PATH"temp_file", strlen(CLIB_TESTS_PATH"temp_file"))); ck_assert(rf_textfile_init(&f, &g_fname, RF_FILE_NEW, RF_ENDIANESS_UNKNOWN, RF_UTF8, RF_EOL_LF)); /* write line 1 */ s = get_line(RF_UTF8, RF_ENDIANESS_UNKNOWN, true, line_scenario1); ck_assert(rf_stringx_assign_unsafe_nnt( &g_buff, s, strlen(s))); ck_assert(rf_textfile_write(&f, RF_STRX2STR(&g_buff))); /* write line 2 */ ck_assert(rf_stringx_assign_unsafe_nnt( &g_buff, SECOND_LINE_UTF8"\n", strlen(SECOND_LINE_UTF8"\n"))); ck_assert(rf_textfile_write(&f, RF_STRX2STR(&g_buff))); /* write line 3 */ s = get_line(RF_UTF8, RF_ENDIANESS_UNKNOWN, true, line_scenario3); ck_assert(rf_stringx_assign_unsafe_nnt( &g_buff, THIRD_LINE_UTF8"\n", strlen(THIRD_LINE_UTF8"\n"))); ck_assert(rf_textfile_write(&f, RF_STRX2STR(&g_buff))); /* replace the 2nd line */ ck_assert(rf_textfile_replace(&f, 2, &str)); /* go to the starting position and switch to reading */ ck_assert(RF_SUCCESS == rf_textfile_go_to_line(&f, 1)); ck_assert(rf_textfile_set_mode(&f, RF_FILE_READ)); /* read 1st line */ ck_assert(RF_SUCCESS == rf_textfile_read_line(&f, &g_buff)); ck_assert_rf_str_eq_cstr( &g_buff, get_line(RF_UTF8, RF_ENDIANESS_UNKNOWN, false, line_scenario1)); /* read 2nd line */ ck_assert(RF_SUCCESS == rf_textfile_read_line(&f, &g_buff)); ck_assert(rf_string_equal(&str, RF_STRX2STR(&g_buff))); /* read 3rd line */ ck_assert(RF_SUCCESS == rf_textfile_read_line(&f, &g_buff)); ck_assert_rf_str_eq_cstr(&g_buff, THIRD_LINE_UTF8); /* check for empty line and EOF */ ck_assert(RE_FILE_EOF == rf_textfile_read_line(&f, &g_buff)); ck_assert(rf_system_delete_file(&g_fname)); rf_textfile_deinit(&f); }END_TEST
}END_TEST START_TEST(test_invalid_textfile_replace) { struct RFtextfile f; static const char *s; static struct RFstring str = RF_STRING_STATIC_INIT("Line Replacement"); ck_assert(rf_stringx_assign_unsafe_nnt( &g_fname, CLIB_TESTS_PATH"temp_file", strlen(CLIB_TESTS_PATH"temp_file"))); ck_assert(rf_textfile_init(&f, &g_fname, RF_FILE_NEW, RF_ENDIANESS_UNKNOWN, RF_UTF8, RF_EOL_LF)); /* write line 1 */ s = get_line(RF_UTF8, RF_ENDIANESS_UNKNOWN, true, line_scenario1); ck_assert(rf_stringx_assign_unsafe_nnt( &g_buff, s, strlen(s))); ck_assert(rf_textfile_write(&f, RF_STRX2STR(&g_buff))); /* illegal input */ ck_assert(!rf_textfile_replace(&f, 0, &str)); ck_assert(!rf_textfile_replace(&f, 9999, &str)); ck_assert(!rf_textfile_replace(&f, 2, NULL)); ck_assert(rf_system_delete_file(&g_fname)); rf_textfile_deinit(&f); }END_TEST
}END_TEST START_TEST(test_textfile_read_lines) { struct RFtextfile f; static const struct RFstring fname = RF_STRING_STATIC_INIT( CLIB_TESTS_PATH"utf8stringfile" ); uint32_t buff_arr[64]; struct RFarray line_arr = RF_ARRAY_SHALLOW_INIT(buff_arr); ck_assert(rf_textfile_init(&f, &fname, RF_FILE_READ, RF_ENDIANESS_UNKNOWN, RF_UTF8, RF_EOL_LF)); rf_stringx_reset(&g_buff); /* read all lines (3 + 1 empty line) */ ck_assert_int_eq(4, rf_textfile_read_lines(&f, 0, &g_buff, &line_arr)); ck_assert_rf_str_eq_cstr(&g_buff, FIRST_LINE_UTF8"\n" SECOND_LINE_UTF8"\n" THIRD_LINE_UTF8"\n\n" ); ck_assert_int_eq(rf_array_at_unsafe(&line_arr, 0, uint32_t), 0); ck_assert_int_eq(rf_array_at_unsafe(&line_arr, 1, uint32_t), 11); ck_assert_int_eq(rf_array_at_unsafe(&line_arr, 2, uint32_t), 366); ck_assert_int_eq(rf_array_at_unsafe(&line_arr, 3, uint32_t), 1166); ck_assert(RF_SUCCESS == rf_textfile_go_to_line(&f, 1)); /* read 3 lines */ ck_assert(3 == rf_textfile_read_lines(&f, 3, &g_buff, 0)); ck_assert_rf_str_eq_cstr(&g_buff, FIRST_LINE_UTF8"\n" SECOND_LINE_UTF8"\n" THIRD_LINE_UTF8"\n" ); ck_assert(RF_SUCCESS == rf_textfile_go_to_line(&f, 1)); /* read 2 lines */ ck_assert(2 == rf_textfile_read_lines(&f, 2, &g_buff, 0)); ck_assert_rf_str_eq_cstr(&g_buff, FIRST_LINE_UTF8"\n" SECOND_LINE_UTF8"\n" ); ck_assert(RF_SUCCESS == rf_textfile_go_to_line(&f, 1)); /* read 1 line */ ck_assert(1 == rf_textfile_read_lines(&f, 1, &g_buff, 0)); ck_assert_rf_str_eq_cstr(&g_buff, FIRST_LINE_UTF8"\n"); rf_textfile_deinit(&f); }END_TEST
} END_TEST START_TEST(test_array_index_access1) { static const struct RFstring s = RF_STRING_STATIC_INIT( "{\n" "a:u64[2] = [1, 2]\n" "b:u64 = a[0]\n" "}" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
} END_TEST START_TEST(test_typecheck_negative_int_variable_declarations) { static const struct RFstring s = RF_STRING_STATIC_INIT( "{\n" "a:i32 = -23432\n" "}" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
} END_TEST START_TEST(test_array_index_access3) { static const struct RFstring s = RF_STRING_STATIC_INIT( "{\n" "idx:u32 = 3" "a:u16[3] = [1, 2, 3]\n" "b:u32 = 15 + a[idx]\n" "}" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
} END_TEST START_TEST(test_array_index_access2) { static const struct RFstring s = RF_STRING_STATIC_INIT( "{\n" "idx:u32 = 3" "a:string[3] = [\"foo\", \"boo\", \"bar\"]\n" "b:string = a[idx]\n" "}" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
} END_TEST START_TEST(test_typecheck_complex_type_in_variable_declaration) { static const struct RFstring s = RF_STRING_STATIC_INIT( "{\n" "a:(b:int | c:string)\n" "}" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
} END_TEST START_TEST (test_typecheck_valid_if_stmt) { static const struct RFstring s = RF_STRING_STATIC_INIT( "{\n" " a:u64 = 1453\n" " b:u64" " if a == 1453 { b = 1 } else { b = 0 }\n" "}\n" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
} END_TEST START_TEST(test_typecheck_valid_custom_type_and_fncall2) { static const struct RFstring s = RF_STRING_STATIC_INIT( "type person { name:string, age:u32 }" "fn do_something(a:person, b:u64) -> string\n" "{\n" "return \"something\" + a.name" "}\n" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
} END_TEST START_TEST(test_typecheck_valid_custom_type_constructor) { static const struct RFstring s = RF_STRING_STATIC_INIT( "type person { name:string, age:u32 }" "fn do_something() -> string\n" "{\n" "a:person = person(\"Celina\", 18)\n" "return a.name" "}\n" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
} END_TEST START_TEST(test_typecheck_foreign_import) { static const struct RFstring s = RF_STRING_STATIC_INIT( "foreign_import rf_stdlib_print_int64(i64), rf_stdlib_print_string(string)\n" "{\n" "rf_stdlib_print_int64(3)\n" "rf_stdlib_print_string(\"hello\")\n" "}" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
} END_TEST START_TEST (test_typecheck_valid_assignment_from_block1) { static const struct RFstring s = RF_STRING_STATIC_INIT( "{\n" " a:string = \n" " {\n" " b:u32 = 13 + 25\n" " \"a_string_literal\"\n" " }\n" "}\n" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
} END_TEST START_TEST (test_typecheck_valid_assignment_from_block2) { static const struct RFstring s = RF_STRING_STATIC_INIT( "type foo { a:u64, b:string }\n" "{\n" " a:foo = \n" " {\n" " b:u32 = 13 + 25\n" " c:foo = foo(565, \"Berlin\")\n" " }\n" "}\n" ); front_testdriver_new_ast_main_source(&s); ck_assert_typecheck_ok(); } END_TEST
}END_TEST START_TEST(test_acc_ifexpr_errors_1) { static const struct RFstring s = RF_STRING_STATIC_INIT( "if " ); front_testdriver_new_main_source(&s); ck_test_fail_parse_as(ifexpr, TOKEN_KW_IF); struct info_msg errors[] = { TESTSUPPORT_INFOMSG_INIT_START( MESSAGE_SYNTAX_ERROR, "Expected an expression after 'if'", 0, 1), }; ck_assert_parser_errors(errors); }END_TEST
}END_TEST START_TEST(test_acc_ifexpr_2) { struct ast_node *n; static const struct RFstring s = RF_STRING_STATIC_INIT( "if a == 42 {\n" " do_sth()\n" "} else { \n" " 55 + 2.31\n" "}" ); front_testdriver_new_main_source(&s); struct ast_node *id1 = testsupport_parser_identifier_create(0, 3, 0, 3); testsupport_parser_constant_create(cnum1, 0, 8, 0, 9, integer, 42); testsupport_parser_node_create(cmp_exp, binaryop, 0, 3, 0, 9, BINARYOP_CMP_EQ, id1, cnum1); testsupport_parser_block_create(bnode1, 0, 11, 2, 0); struct ast_node *fn_name = testsupport_parser_identifier_create( 1, 4, 1, 9); testsupport_parser_node_create(fc, fncall, 1, 4, 1, 11, fn_name, NULL, NULL); ast_node_add_child(bnode1, fc); testsupport_parser_node_create(cond1, condbranch, 0, 3, 2, 0, cmp_exp, bnode1); testsupport_parser_block_create(bnode2, 2, 7, 4, 0); testsupport_parser_constant_create(cnum2, 3, 4, 3, 5, integer, 55); testsupport_parser_constant_create(cnum3, 3, 9, 3, 12, float, 2.31); testsupport_parser_node_create(op1, binaryop, 3, 4, 3, 12, BINARYOP_ADD, cnum2, cnum3); ast_node_add_child(bnode2, op1); testsupport_parser_node_create(ifx, ifexpr, 0, 0, 4, 0, cond1, bnode2); ck_test_parse_as(n, ifexpr, "if_expression", ifx, TOKEN_KW_IF); ast_node_destroy(n); ast_node_destroy(ifx); }END_TEST
} END_TEST START_TEST(test_typecheck_invalid_type_in_typedecl) { static const struct RFstring s = RF_STRING_STATIC_INIT( "type person { name:string, age:if32 }\n" ); front_testdriver_new_ast_main_source(&s); struct info_msg messages[] = { TESTSUPPORT_INFOMSG_INIT_BOTH( MESSAGE_SEMANTIC_ERROR, "Type \"if32\" is not defined", 0, 31, 0, 34) }; ck_assert_typecheck_with_messages(false, messages); } END_TEST
} END_TEST START_TEST(test_acc_ws_full) { struct inpfile *f; struct front_ctx *front; struct inpoffset *off; struct RFstringx *str; static const struct RFstring s = RF_STRING_STATIC_INIT(" \n \r \t \n \n "); front = front_testdriver_new_main_source(&s); f = front->file; ck_assert_msg(f, "Failed to assign string to file "); inpfile_acc_ws(f); off = inpfile_offset(f); ck_assert_inpoffset_eq(off, 12, 12, 3); str = inpfile_str(f); ck_assert_rf_str_eq_cstr(str, ""); } END_TEST
}END_TEST START_TEST(test_acc_ifexpr_errors_2) { static const struct RFstring s = RF_STRING_STATIC_INIT( "if a > 25 \n" " do_sth()\n" "}" ); front_testdriver_new_main_source(&s); ck_test_fail_parse_as(ifexpr, TOKEN_KW_IF); struct info_msg errors[] = { TESTSUPPORT_INFOMSG_INIT_START( MESSAGE_SYNTAX_ERROR, "Expected a block after \"if\"'s conditional expression", 0, 8), }; ck_assert_parser_errors(errors); }END_TEST