Ejemplo n.º 1
0
cx_int16 cx_type_bindMetaprocedure(cx_type _this, cx_metaprocedure procedure) {
    cx_function* f;
    cx_int32 d = 0;

    /* Check if function is overloaded */
    if ((f = cx_vtableLookup(&_this->metaprocedures, cx_nameof(procedure), NULL, &d))) {
        if (d) {
            cx_function(*f)->overloaded = TRUE; /* Flag found and passed function as overloaded. */
            cx_function(procedure)->overloaded = TRUE;
        } else {
            if (*f != cx_function(procedure)) {
                /* Overriding metaprocedures is not allowed. */
                cx_id id, id2;
                cx_error("definition of metaprocedure '%s' conflicts with existing metaprocedure '%s'", cx_fullname(*f, id), cx_fullname(procedure, id2));
                goto error;
            }
        }
    }

    if (cx_vtableInsert(&_this->metaprocedures, cx_function(procedure))) {
        cx_keep_ext(_this, procedure, "Bind metaprocedure to type.");
    }
    return 0;
error:
    return -1;
}
Ejemplo n.º 2
0
cx_int16 Fast_Member_resolveMember(Fast_Member _this, cx_type type, cx_string member) {
    cx_object o = NULL;

    if (cx_instanceof(cx_type(cx_interface_o), type) && !strcmp(member, "super")) {
        if (cx_interface(type)->base) {
            _this->member = NULL;
            cx_set(&Fast_Expression(_this)->type, cx_interface(type)->base);
        } else {
            cx_id id;
            Fast_Parser_error(yparser(), "type '%s' has no base", Fast_Parser_id(type, id));
            goto error;
        }
    } else {
        if (cx_instanceof(cx_type(cx_interface_o), type)) {
            o = cx_interface_resolveMember(cx_interface(type), member);
        }
        if (!o) {
            /* If no members are found for name, look for methods */
            o = cx_type_resolveProcedure(type, member);
            if (!o) {
                cx_id id;
                Fast_Parser_error(yparser(), "unresolved member '%s' for type '%s'", member, Fast_Parser_id(type, id));
                goto error;
            }
            cx_set(&Fast_Expression(_this)->type, cx_function(o)->returnType);
        } else {
            cx_set(&Fast_Expression(_this)->type, cx_member(o)->type);
        }
        _this->member = o; cx_keep_ext(_this, o, "Keep object for member-expression");
    }

    return 0;
error:
    return -1;
}
Ejemplo n.º 3
0
static int cx_functionLookupWalk(cx_object o, void* userData) {
    cx_functionLookup_t* data;
    cx_int32 d;

    data = userData;

    if (o != data->f) {
        if ((cx_class_instanceof(cx_procedure_o, cx_typeof(o)))) {
            if (cx_overload(o, cx_nameof(data->f), &d, FALSE)) {
                data->error = TRUE;
                goto finish;
            }

            /* Check if function matches */
            if (!d) {
                cx_id id, id2;
                cx_error("function '%s' conflicts with existing declaration '%s'", cx_fullname(data->f, id), cx_fullname(o, id2));
                data->error = TRUE;
                goto finish;
            } else {
                cx_id id;

                /* Get name of function */
                cx_signatureName(cx_nameof(o), id);

                /* Set overloading flags if a function with same name is found. */
                if (!strcmp(data->name, id)) {
                    cx_function(o)->overloaded = TRUE;
                    data->f->overloaded = TRUE;
                }
            }
        }
    }

    return 1;
finish:
    return 0;
}
Ejemplo n.º 4
0
/* Build dependency-administration for object */
int cx_genDepBuildAction(cx_object o, void* userData) {
    g_itemWalk_t data;
    struct g_depWalk_t walkData;
    struct cx_serializer_s s;
    int result;
    cx_object parent = NULL;

    if (cx_checkAttr(o, CX_ATTR_SCOPED)) {
        parent = cx_parentof(o);
    }

    data = userData;

    /* If object is cortex_lang_o, signal that a bootstrap is found, indicating
     * that dependencies should be disregarded. */
    if (o == cortex_lang_o) {
        data->bootstrap = TRUE;
        result = 0;
    } else {
        /* Insert type-dependency: object can be declared only after it's type is defined. */
        if (g_mustParse(data->g, cx_typeof(o))) {
            cx_depresolver_depend(data->resolver, o, CX_DECLARED, cx_typeof(o), CX_DEFINED);
        }

        /* TODO: this is not nice */
        if (cx_class_instanceof(cx_procedure_o, cx_typeof(o))) {
            /* Insert base-dependency: methods may only be declared after the base of a class has been defined. */
            if (cx_typeof(o) != cx_type(cx_function_o)) {
                if (cx_class_instanceof(cx_class_o, parent) && cx_interface(parent)->base) {
                    if (g_mustParse(data->g, cx_interface(parent)->base)) {
                        cx_depresolver_depend(data->resolver, o, CX_DECLARED, cx_interface(parent)->base, CX_DEFINED);
                    }
                }
            }

            /* Add dependencies on function parameters - types must be declared before function is declared. */
            if (cx_genDepBuildProc(cx_function(o), data)) {
                goto error;
            }
        }

        /* Insert dependency on parent */
        if (cx_checkAttr(o, CX_ATTR_SCOPED)) {
            if (parent != root_o) { /* Root is always available */
                cx_int8 parentState = cx_type(cx_typeof(o))->parentState;

                cx_depresolver_depend(data->resolver, o, CX_DECLARED, parent, parentState);
                if (parentState == CX_DECLARED) {
                    cx_depresolver_depend(data->resolver, parent, CX_DEFINED, o, CX_DEFINED);
                }
            }
        }

        /* Insert dependencies on references in the object-value */
        walkData.o = o;
        walkData.data = data;
        s = cx_genDepSerializer();
        if (cx_serialize(&s, o, &walkData)) {
            goto error;
        }

        result = 1;
    }

    return result;
error:
    return 0;
}