} 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_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_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_comparison_for_sum_fncall) { // test for a bug concerning subtypes of sum types // make type a:i64 | b:u64 | c:f64 | d:string // just like the typechecking for function calls // check that comparing a subtype gives the correct matched type struct type *t_i64 = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_INT_64); struct type *t_u64 = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_UINT_64); 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_sum = testsupport_analyzer_type_create_operator(TYPEOP_SUM, t_i64, t_u64, t_f64, t_string); typecmp_ctx_set_flags(TYPECMP_FLAG_FUNCTION_CALL); ck_assert(type_compare(t_u64, t_sum, TYPECMP_PATTERN_MATCHING)); const struct type *matched_type = typemp_ctx_get_matched_type(); ck_assert_msg( matched_type == t_u64, "Unexpected match type "RFS_PF" found", RFS_PA(type_str_or_die(matched_type, TSTR_DEFAULT)) ); typecmp_ctx_set_flags(TYPECMP_FLAG_FUNCTION_CALL); ck_assert(type_compare(t_i64, t_sum, TYPECMP_PATTERN_MATCHING)); matched_type = typemp_ctx_get_matched_type(); ck_assert_msg( matched_type == t_i64, "Unexpected match type "RFS_PF" found", RFS_PA(type_str_or_die(matched_type, TSTR_DEFAULT)) ); typecmp_ctx_set_flags(TYPECMP_FLAG_FUNCTION_CALL); ck_assert(type_compare(t_f64, t_sum, TYPECMP_PATTERN_MATCHING)); matched_type = typemp_ctx_get_matched_type(); ck_assert_msg( matched_type == t_f64, "Unexpected match type "RFS_PF" found", RFS_PA(type_str_or_die(matched_type, TSTR_DEFAULT)) ); typecmp_ctx_set_flags(TYPECMP_FLAG_FUNCTION_CALL); ck_assert(type_compare(t_string, t_sum, TYPECMP_PATTERN_MATCHING)); matched_type = typemp_ctx_get_matched_type(); ck_assert_msg( matched_type == t_string, "Unexpected match type "RFS_PF" found", RFS_PA(type_str_or_die(matched_type, TSTR_DEFAULT)) ); } END_TEST
} END_TEST START_TEST(test_typecheck_valid_custom_sum_type_constructor2) { static const struct RFstring s = RF_STRING_STATIC_INIT( "type person { name:string, b:u64 | id:u32, foo:f64}" "fn do_something()\n" "{\n" "a:person = person(\"Celina\", 53342)\n" "b:person = person(13, 54.231)\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_u64 = testsupport_analyzer_type_create_simple_elementary(ELEMENTARY_TYPE_UINT_64); 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_prod_1 = testsupport_analyzer_type_create_operator(TYPEOP_PRODUCT, t_string, t_u64); struct type *t_prod_2 = testsupport_analyzer_type_create_operator(TYPEOP_PRODUCT, t_u32, t_f64); ck_assert(type_compare(ctor1->fncall.params_type, t_prod_1, TYPECMP_IDENTICAL)); ck_assert(type_compare(ctor2->fncall.params_type, t_prod_2, TYPECMP_IDENTICAL)); } END_TEST
} END_TEST START_TEST (test_type_comparison_for_sum_fncall_with_conversion) { struct type *t_i8 = testsupport_analyzer_type_create_elementary(ELEMENTARY_TYPE_INT_8, false); struct type *t_i64 = testsupport_analyzer_type_create_elementary(ELEMENTARY_TYPE_INT_64, false); struct type *t_f64 = testsupport_analyzer_type_create_elementary(ELEMENTARY_TYPE_FLOAT_64, false); struct type *t_string = testsupport_analyzer_type_create_elementary(ELEMENTARY_TYPE_STRING, false); struct type *t_sum = testsupport_analyzer_type_create_operator(TYPEOP_SUM, t_i64, t_f64, t_string); typecmp_ctx_set_flags(TYPECMP_FLAG_FUNCTION_CALL); ck_assert(type_compare(t_i8, t_sum, TYPECMP_PATTERN_MATCHING)); const struct type *matched_type = typemp_ctx_get_matched_type(); ck_assert_msg(matched_type == t_i64, "Unexpected match type "RF_STR_PF_FMT" found", RF_STR_PF_ARG(type_str_or_die(matched_type, TSTR_DEFAULT))); } END_TEST