Ejemplo n.º 1
0
} END_TEST

START_TEST (test_string_buffer_fillfmt) {
    unsigned int size;
    RFS_PUSH();
    char *buff1;
    char *buff2;
    ck_assert(test_rf_strings_buffer_fillfmt(
                  "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz%d%s",
                  &size,
                  &buff1,
                  42, "ABCD"));
    ck_assert_uint_eq(size, 58);
    ck_assert_nnt_str_eq_cstr(
        buff1,
        "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz42ABCD");
    RFS_PUSH();
    ck_assert(test_rf_strings_buffer_fillfmt(
                  "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ%s",
                  &size,
                  &buff2,
                  "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"));
    ck_assert_uint_eq(size, 104);
    ck_assert_nnt_str_eq_cstr(
        buff2,
        "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
    RFS_POP();
    RFS_POP();
} END_TEST
Ejemplo n.º 2
0
} END_TEST

START_TEST (test_RFS_realloc_vararg_at_second_use) {
    struct RFstring *s1;
    struct RFstring *s2;
    RFS_PUSH();
    s1 = RFS("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz%d%d", 23, 24);
    ck_assert_rf_str_eq_cstr(s1, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz2324");
    RFS_PUSH();
    s2 = RFS("ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ%s%d", "eleos", 124);
    ck_assert_rf_str_eq_cstr(s1, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz2324");
    ck_assert_rf_str_eq_cstr(s2, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZeleos124");
    RFS_POP();
    RFS_POP();
} END_TEST
Ejemplo n.º 3
0
} 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
Ejemplo n.º 4
0
static void test_RFS_in_recursive_functions()
{
    RFS_PUSH();
    struct RFstring *s1;
    s1 = get_str_rec(NULL, 0, true);
    ck_assert_rf_str_eq_cstr(
        s1,
        "0abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
    RFS_POP();
    RFS_PUSH();
    struct RFstring *s2;
    s2 = get_str_rec(NULL, 1, true);
    ck_assert_rf_str_eq_cstr(
        s2,
        "1abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "0abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
    RFS_POP();
}
Ejemplo n.º 5
0
} END_TEST

START_TEST (test_type_op_create_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);
    RFS_PUSH();
    ck_assert_rf_str_eq_cstr(type_op_create_str(t_u32, t_f64, TYPEOP_PRODUCT), "u32,f64");
    ck_assert_rf_str_eq_cstr(type_op_create_str(t_u32, t_f64, TYPEOP_SUM), "u32|f64");
    ck_assert_rf_str_eq_cstr(type_op_create_str(t_u32, t_f64, TYPEOP_IMPLICATION), "u32->f64");
    RFS_POP();
} END_TEST
Ejemplo n.º 6
0
static void test_RFS_in_recursive_functions_with_local()
{
    RFS_PUSH();
    struct RFstring *s1;
    s1 = get_str_rec_with_local(NULL, 0);
    ck_assert_rf_str_eq_cstr(
        s1,
        "pre0abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
    RFS_POP();
    RFS_PUSH();
    struct RFstring *s2;
    s2 = get_str_rec_with_local(NULL, 1);
    ck_assert_rf_str_eq_cstr(
        s2,
        "pre0abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "pre1abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
    );
    RFS_POP();
    RFS_PUSH();
    struct RFstring *s3;
    s3 = get_str_rec_with_local(NULL, 2);
    ck_assert_rf_str_eq_cstr(
        s3,
        "pre0abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "pre1abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "pre2abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
    );
    RFS_POP();
    RFS_PUSH();
    struct RFstring *s4;
    s4 = get_str_rec_with_local(NULL, 3);
    ck_assert_rf_str_eq_cstr(
        s4,
        "pre0abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "pre1abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "pre2abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "pre3abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
    );
    RFS_POP();
}
Ejemplo n.º 7
0
} END_TEST

START_TEST (test_RFS_same_ptr) {
    struct RFstring *s1;
    RFS_PUSH();
    s1 = RFS("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
    ck_assert_rf_str_eq_cstr(s1, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
    s1 = RFS(RFS_PF "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ",
             RFS_PA(s1));
    ck_assert_rf_str_eq_cstr(s1,
        "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ");
    RFS_POP();
} END_TEST
Ejemplo n.º 8
0
} END_TEST

START_TEST (test_RFS_realloc_at_first_use) {
    struct RFstring *s1;
    struct RFstring *s2;
    RFS_PUSH();
    s1 = RFS(
        "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
    ck_assert_rf_str_eq_cstr(
        s1,
        "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
    RFS_PUSH();
    s2 = RFS("ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ");
    ck_assert_rf_str_eq_cstr(
        s1,
        "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
        "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz");
    ck_assert_rf_str_eq_cstr(s2, "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ");
    RFS_POP();
    RFS_POP();
} END_TEST
Ejemplo n.º 9
0
bool rir_binaryop_tostring(struct rirtostr_ctx *ctx, const struct rir_expression *e)
{
    bool ret = false;
    RFS_PUSH();

    const struct RFstring *memtype_s = rir_type_string(e->binaryop.a->type);
    if (e->val.category == RIR_VALUE_NIL) {
        if (!rf_stringx_append(
                ctx->rir->buff,
                RFS(RIRTOSTR_INDENT RF_STR_PF_FMT"(" RF_STR_PF_FMT ", "RF_STR_PF_FMT ", " RF_STR_PF_FMT ")\n",
                    RF_STR_PF_ARG(&rir_bop_type_strings[e->type]),
                    RF_STR_PF_ARG(memtype_s),
                    RF_STR_PF_ARG(rir_value_string(e->binaryop.a)),
                    RF_STR_PF_ARG(rir_value_string(e->binaryop.b)))
            )) {
            goto end;
        }
    } else {
        if (!rf_stringx_append(
                ctx->rir->buff,
                RFS(RIRTOSTR_INDENT RF_STR_PF_FMT" = "RF_STR_PF_FMT"(" RF_STR_PF_FMT ", "RF_STR_PF_FMT ", " RF_STR_PF_FMT ")\n",
                    RF_STR_PF_ARG(rir_value_string(&e->val)),
                    RF_STR_PF_ARG(&rir_bop_type_strings[e->type]),
                    RF_STR_PF_ARG(memtype_s),
                    RF_STR_PF_ARG(rir_value_string(e->binaryop.a)),
                    RF_STR_PF_ARG(rir_value_string(e->binaryop.b)))
            )) {
            goto end;
        }
    }

    ret = true;
end:
    RFS_POP();
    return ret;
}
Ejemplo n.º 10
0
static struct rir_object *rir_convert_init(const struct rir_value *convval,
                                           const struct rir_type *totype,
                                           struct rir_ctx *ctx)
{
    struct rir_object *retobj = NULL;
    // at the moment only conversion to string requires special work
    if (!rir_type_is_specific_elementary(totype, ELEMENTARY_TYPE_STRING)) {
        if ((!(retobj = rir_object_create(RIR_OBJ_EXPRESSION, ctx->rir)))) {
            return NULL;
        }
        retobj->expr.convert.val = convval;
        retobj->expr.convert.type = totype;
        retobj->expr.type = RIR_EXPRESSION_PLACEHOLDER; // to signify we must continue
        return retobj;
    }

    // from here and down it's only about conversion to string
    if (convval->category == RIR_VALUE_CONSTANT) {
        // constant value to string conversion can be done easily here at compile time
        RFS_PUSH();
        const struct RFstring *temps = rir_constant_string(convval);
        if (!(retobj = rir_global_addorget_string(ctx, temps))) {
            RF_ERROR("Failed to add or get a global string literal to the RIR");
        }
        RFS_POP();
        return retobj;
    } else if (rir_type_is_specific_elementary(convval->type, ELEMENTARY_TYPE_BOOL)) {
        struct rir_object *obj;
        // boolean to string conversion requires some branching logic
        retobj = rir_alloca_create_obj(
            rir_type_elem_create(ELEMENTARY_TYPE_STRING, false),
            0,
            ctx
        );
        if (!retobj) {
            return NULL;
        }
        rirctx_block_add(ctx, &retobj->expr);
        struct rir_value *allocv = rir_object_value(retobj);
        // create the blocks
        struct rir_block *prev_block = ctx->current_block;
        struct rir_block *taken_block = rir_block_create(NULL, false, ctx);
        if (!taken_block) {
            return NULL;
        }
        struct rir_block *fallthrough_block = rir_block_create(NULL, false, ctx);
        if (!fallthrough_block) {
            return NULL;
        }
        struct rir_block *after_block = rir_block_create(NULL, false, ctx);
        if (!after_block) {
            return NULL;
        }

        // create the conditional branch to connect to if/else
        if (!rir_block_exit_init_condbranch(
                &prev_block->exit, convval, &taken_block->label, &fallthrough_block->label
            )) {
            return NULL;
        }

        // populate taken block
        ctx->current_block = taken_block;
        if (!(obj = rir_global_addorget_string(ctx, &g_str_true))) {
            RF_ERROR("Failed to add a global string literal to the RIR");
            return NULL;
        }
        struct rir_expression *e = rir_write_create(allocv, rir_object_value(obj), ctx);
        if (!e) {
            return NULL;
        }
        rirctx_block_add(ctx, e);
        if (!rir_block_exit_init_branch(&taken_block->exit, &after_block->label)) {
            return NULL;
        }
        rir_fndef_add_block(ctx->current_fn, taken_block);

        // populate fallthrough block
        ctx->current_block = fallthrough_block;
        if (!(obj = rir_global_addorget_string(ctx, &g_str_false))) {
            RF_ERROR("Failed to add a global string literal to the RIR");
            return NULL;
        }
        if (!(e = rir_write_create(allocv, rir_object_value(obj), ctx))) {
            return NULL;
        }
        rirctx_block_add(ctx, e);
        if (!rir_block_exit_init_branch(&fallthrough_block->exit, &after_block->label)) {
            return NULL;
        }
        rir_fndef_add_block(ctx->current_fn, fallthrough_block);

        // finally let's go to the after block and return the populated alloca which
        // should hold the value of the conversion
        rir_fndef_add_block(ctx->current_fn, after_block);
        ctx->current_block = after_block;
        return retobj;
    } else {
        RF_CRITICAL_FAIL("Unexpected conversion at RIR formation");
        return NULL;
    }
}
Ejemplo n.º 11
0
enum traversal_cb_res typecheck_function_call(
    struct ast_node *n,
    struct analyzer_traversal_ctx *ctx)
{
    const struct RFstring *fn_name;
    const struct type *fn_type;
    const struct type *fn_declared_args_type;
    const struct type *fn_found_args_type;
    struct ast_node *fn_call_args = ast_fncall_args(n);

    // check for existence of function
    fn_name = ast_fncall_name(n);
    fn_type = type_lookup_identifier_string(fn_name, ctx->current_st);

    if (!fn_type || !type_is_callable(fn_type)) {
        analyzer_err(ctx->m, ast_node_startmark(n),
                     ast_node_endmark(n),
                     "Undefined function call \""RFS_PF"\" detected",
                     RFS_PA(fn_name));
        goto fail;
    }

    // create the arguments ast node array
    ast_fncall_arguments(n);

    // also check the ast node of the function declaration to get more
    // information if it's not a conversion
    if (!type_is_explicitly_convertable_elementary(fn_type)) {
        const struct ast_node *fndecl = symbol_table_lookup_node(
            ctx->current_st,
            fn_name,
            NULL
        );
        RF_ASSERT(fndecl, "Since fn_type was found so should fndecl be found here");
        if (fndecl->fndecl.position == FNDECL_PARTOF_FOREIGN_IMPORT) {
            n->fncall.type = AST_FNCALL_FOREIGN;
        }
    }

    fn_found_args_type = (fn_call_args)
        ? ast_node_get_type(fn_call_args)
        : type_elementary_get_type(ELEMENTARY_TYPE_NIL);

    if (!fn_found_args_type) { // argument typechecking failed
        goto fail;
    }

    if (type_is_explicitly_convertable_elementary(fn_type)) {
        // silly way to check if it's only 1 argument. Maybe figure out safer way?
        if (!fn_call_args || fn_found_args_type->category == TYPE_CATEGORY_OPERATOR) {
            analyzer_err(
                ctx->m,
                ast_node_startmark(n),
                ast_node_endmark(n),
                "Invalid arguments for explicit conversion to \""
                RFS_PF"\".",
                RFS_PA(fn_name)
            );
            goto fail;
        }

        // check if the explicit conversion is valid
        if (!type_compare(fn_found_args_type, fn_type, TYPECMP_EXPLICIT_CONVERSION)) {
            analyzer_err(ctx->m, ast_node_startmark(n), ast_node_endmark(n),
                         "Invalid explicit conversion. "RFS_PF".",
                         RFS_PA(typecmp_ctx_get_error()));
            goto fail;
        }
        n->fncall.type = AST_FNCALL_EXPLICIT_CONVERSION;
    } else {
        //check that the types of its arguments do indeed match
        fn_declared_args_type = type_callable_get_argtype(fn_type);
        n->fncall.declared_type = fn_declared_args_type;
        if (type_is_sumop(fn_declared_args_type)) {
            n->fncall.type = AST_FNCALL_SUM;
        }
        typecmp_ctx_set_flags(TYPECMP_FLAG_FUNCTION_CALL);
        if (!type_compare(
                fn_found_args_type,
                fn_declared_args_type,
                n->fncall.type == AST_FNCALL_SUM
                    ? TYPECMP_PATTERN_MATCHING :
                    TYPECMP_IMPLICIT_CONVERSION)) {
            RFS_PUSH();
            analyzer_err(
                ctx->m, ast_node_startmark(n), ast_node_endmark(n),
                RFS_PF" "RFS_PF"() is called with argument type of \""RFS_PF
                "\" which does not match the expected "
                "type of \""RFS_PF"\"%s"RFS_PF".",
                RFS_PA(type_callable_category_str(fn_type)),
                RFS_PA(fn_name),
                RFS_PA(type_str_or_die(fn_found_args_type, TSTR_DEFAULT)),
                RFS_PA(type_str_or_die(fn_declared_args_type, TSTR_DEFINED_ONLY_CONTENTS)),
                typecmp_ctx_have_error() ? ". " : "",
                RFS_PA(typecmp_ctx_get_error())
            );
            RFS_POP();
            goto fail;
        }
        // the function call's matched type should be either a specific sum type
        // that may have matched or the entirety of the called arguments
        if (!(n->fncall.params_type = typemp_ctx_get_matched_type())) {
            n->fncall.params_type = fn_found_args_type;
        }
    }

    traversal_node_set_type(n, type_callable_get_rettype(fn_type), ctx);
    return TRAVERSAL_CB_OK;

fail:
    traversal_node_set_type(n, NULL, ctx);
    return TRAVERSAL_CB_ERROR;
}