예제 #1
0
파일: backend_c.c 프로젝트: wm4/boringlang
static void write_fn_type(CTX *ctx, struct ir_fn_type *fnt, bool as_ptr,
                          char *name)
{
    fprintf(ctx->f, "%s ", ret_type(ctx, fnt->ret_type));
    if (as_ptr) {
        fprintf(ctx->f, "(*%s)", name);
    } else {
        fprintf(ctx->f, "%s", name);
    }
    fprintf(ctx->f, "(");
    for (int n = 0; n < fnt->args->members_count; n++) {
        struct ir_struct_member *m = fnt->args->members[n];
        if (n > 0)
            fprintf(ctx->f, ", ");
        P(ctx, "%s A%d", def_type(ctx, m->type), n);
    }
    if (fnt->vararg == IR_VARARG_C) {
        if (fnt->args->members_count)
            fprintf(ctx->f, ", ");
        fprintf(ctx->f, "...");
    } else if (fnt->args->members_count == 0) {
        fprintf(ctx->f, "void");
    }
    fprintf(ctx->f, ")");
}
예제 #2
0
파일: backend_c.c 프로젝트: wm4/boringlang
static char *def_tuple(CTX *ctx, struct ir_struct_type *st, bool add_names)
{
    // NOTE: we use the same C type for empty tuples and compounds; should be ok
    if (st->members_count == 0)
        return VOID_MANGLE;
    char *m = get_mangle(ctx, st);
    if (m)
        return m;
    assert(ctx->writing_types);
    m = talloc_strdup(ctx, MANGLE_PREFIX "tuple_");
    for (int n = 0; n < st->members_count; n++) {
        struct ir_struct_member *sm = st->members[n];
        mangle_append_sub(&m, def_type(ctx, sm->type));
        assert(add_names == (sm->name[0]));
        if (sm->name)
            m = talloc_asprintf_append_buffer(m, "n%zd_%s_", strlen(sm->name),
                                              sm->name);
    }
    if (use_anon_mangle_for_tuples) {
        char *new_mangle = HT_GET_DEF(dstr, dstr, ctx->tuple_abbrev, m, NULL);
        if (!new_mangle) {
            new_mangle = gen_anon_mangle(ctx, "tuple");
            HT_INSERT(dstr, dstr, ctx->tuple_abbrev, m, new_mangle);
        }
        m = new_mangle;
    }
    add_mangle(ctx, st, m);
    if (!check_redef(ctx, m))
        write_struct(ctx, st, m);
    return m;
}
예제 #3
0
파일: backend_c.c 프로젝트: wm4/boringlang
static char *def_array_type(CTX *ctx, struct ir_array_type *at)
{
    char *m = get_mangle(ctx, at);
    if (m)
        return m;
    assert(ctx->writing_types);
    m = talloc_strdup(ctx, MANGLE_PREFIX "arr_");
    m = talloc_asprintf_append_buffer(m, "%d_", at->dimension);
    mangle_append_sub(&m, def_type(ctx, at->item_type));
    add_mangle(ctx, at, m);
    if (!check_redef(ctx, m)) {
        wf(ctx, "typedef struct %s {", m);
        indent_in(ctx);
        wf(ctx, "%s a[%d];", def_type(ctx, at->item_type), at->dimension);
        indent_out(ctx);
        wf(ctx, "} %s;", m);
    }
    return m;
}
예제 #4
0
파일: backend_c.c 프로젝트: wm4/boringlang
static void write_struct(CTX *ctx, struct ir_struct_type *st, char *name)
{
    assert(ctx->writing_types);
    wf(ctx, "struct %s;", name);
    wf(ctx, "typedef struct %s %s;", name, name);
    // Make sure all types are written out first.
    for (int n = 0; n < st->members_count; n++) {
        struct ir_struct_member *m = st->members[n];
        def_type(ctx, m->type);
    }
    set_loc(ctx, st->loc);
    wf(ctx, "struct %s {", name);
    indent_in(ctx);
    for (int n = 0; n < st->members_count; n++) {
        struct ir_struct_member *m = st->members[n];
        struct name_temp t;
        char *mname = member_name(m, &t);
        set_loc(ctx, m->loc);
        wf(ctx, "%s %s;", def_type(ctx, m->type), mname);
    }
    indent_out(ctx);
    wf(ctx, "};");
    set_no_loc(ctx);
}
예제 #5
0
파일: backend_c.c 프로젝트: wm4/boringlang
static char *def_fn_type(CTX *ctx, struct ir_fn_type *fnt)
{
    char *m = get_mangle(ctx, fnt);
    if (m)
        return m;
    assert(ctx->writing_types);
    m = talloc_strdup(ctx, MANGLE_PREFIX "fn_");
    mangle_append_sub(&m, def_type(ctx, fnt->ret_type));
    for (int n = 0; n < fnt->args->members_count; n++) {
        struct ir_struct_member *sm = fnt->args->members[n];
        mangle_append_sub(&m, def_type(ctx, sm->type));
    }
    switch (fnt->vararg) {
        case IR_VARARG_NONE: break;
        case IR_VARARG_NATIVE: mangle_append_sub(&m, "vararg"); break;
        case IR_VARARG_C: mangle_append_sub(&m, "cvararg"); break;
        default: assert(false);
    }
    add_mangle(ctx, fnt, m);
    fprintf(ctx->f, "typedef ");
    write_fn_type(ctx, fnt, true, m);
    fprintf(ctx->f, ";\n");
    return m;
}
예제 #6
0
파일: tok.c 프로젝트: litcave/neateqn
/* return the type of a token */
static int char_type(char *s)
{
	int c = (unsigned char) s[0];
	int t;
	if (isdigit(c))
		return T_NUMBER;
	if (c == '"')
		return T_STRING;
	if ((t = def_type(s)) >= 0)
		return t;
	if (c == '~' || c == '^')
		return T_GAP;
	if (ispunct(c) && (c != '\\' || !s[1]))
		return T_ORD;
	return T_LETTER;
}
예제 #7
0
파일: backend_c.c 프로젝트: wm4/boringlang
static char *def_ptr(CTX *ctx, struct ir_type *pt)
{
    if (type_is_untyped(*pt))
        return VPTR_MANGLE;
    char *m = get_mangle(ctx, pt);
    if (m)
        return m;
    assert(ctx->writing_types);
    char *sub = def_type(ctx, *pt);
    m = talloc_strdup(ctx, MANGLE_PREFIX "p_");
    mangle_append_sub(&m, sub);
    add_mangle(ctx, pt, m);
    if (!check_redef(ctx, m))
        wf(ctx, "typedef %s *%s;", sub, m);
    return m;
}
예제 #8
0
파일: backend_c.c 프로젝트: wm4/boringlang
static void gen_fn(CTX *ctx, struct ir_function *fn, char *name, bool visible)
{
    assert(!ctx->writing_types);

    if (!fn->parent)
        fn_complete_nested_calls(fn);

    for (int n = 0; n < fn->nested_functions_count; n++) {
        struct ir_function *nfn = fn->nested_functions[n];
        ctx->writing_types = true;
        char *nname = def_nested_fn(ctx, nfn);
        ctx->writing_types = false;
        gen_fn(ctx, nfn, nname, false);
    }

    fn_remove_global_ssa(fn);
    fn_verify(fn);
    //dump_fn(stderr, fn);

    for (int b = 0; b < fn->blocks_count; b++) {
        for (struct ir_inst *in = fn->blocks[b]->first; in; in = in->next)
            in->scratch1_i = -1;
    }

    // add all C types and function declarations needed for this function
    ctx->writing_types = true;
    do_fn_types(ctx, fn->type);
    for (int n = 0; n < fn->vars_count; n++)
        def_type(ctx, fn->vars[n]->type);
    for (int b = 0; b < fn->blocks_count; b++) {
        struct ir_bb *bb = fn->blocks[b];
        for (struct ir_inst *in = bb->first; in; in = in->next) {
            def_type(ctx, in->result_type);
            if (in->op == IR_OP_CALL || in->op == IR_OP_FN_PTR) {
                def_fn(ctx, in->fn);
            }
        }
    }
    ctx->writing_types = false;

    set_loc(ctx, fn->loc);
    if (!visible)
        fprintf(ctx->f, "static ");
    write_fn_type(ctx, fn->type, false, name);
    wf(ctx, " {");
    indent_in(ctx);
    for (int n = 0; n < fn->vars_count; n++) {
        struct ir_var *v = fn->vars[n];
        set_loc(ctx, v->loc);
        indent(ctx);
        P(ctx, "%s V%d", type(ctx, v->type), n);
        // void values are never assigned to (to avoid clashes with C's void);
        // since they have only one value, there's no need to. Initialize them
        // to avoid C warnings, though.
        if (type_is_void(v->type))
            P(ctx, " = {0}");
        P(ctx, ";\n");
    }
    indent(ctx);
    P(ctx, "goto B%d;\n", fn->entry->index);
    for (int b = 0; b < fn->blocks_count; b++) {
        struct ir_bb *bb = fn->blocks[b];
        indent(ctx);
        P(ctx, "B%d: {\n", b);
        indent_in(ctx);
        ctx->reg = 0;
        for (struct ir_inst *in = bb->first; in; in = in->next)
            gen_inst(ctx, in);
        indent_out(ctx);
        wf(ctx, "}");
    }
    indent_out(ctx);
    wf(ctx, "}");
}
예제 #9
0
파일: backend_c.c 프로젝트: wm4/boringlang
// Define all referenced function types.
static void do_fn_types(CTX *ctx, struct ir_fn_type *fnt)
{
    def_type(ctx, fnt->ret_type);
    for (int n = 0; n < fnt->args->members_count; n++)
        def_type(ctx, fnt->args->members[n]->type);
}
예제 #10
0
파일: backend_c.c 프로젝트: wm4/boringlang
static char *ret_type(CTX *ctx, struct ir_type t)
{
    // for C ABI compatibility
    return type_is_void(t) ? "void" : def_type(ctx, t);
}
예제 #11
0
파일: backend_c.c 프로젝트: wm4/boringlang
static char *type(CTX *ctx, struct ir_type t)
{
    return def_type(ctx, t);
}