Ejemplo n.º 1
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.º 2
0
/* ::cortex::lang::struct::compatible(type type) */
cx_bool cx_struct_compatible_v(cx_struct _this, cx_type type) {
/* $begin(::cortex::lang::struct::compatible) */
    cx_bool result;

    cx_assert(cx_class_instanceof(cx_struct_o, _this), "struct::compatible called on non-struct object.");
    result = FALSE;

    /* Call overloaded type::compatible function first to check for generic compatibility. */
    if (!cx_type_compatible_v(cx_type(_this), type)) {
        /* Type must be at least struct for it to be compatible. */
        if (cx_class_instanceof(cx_struct_o, type)) {
            cx_interface e;

            /* Check if '_this' is superclass of 'type' */
            e = cx_interface(type);
            do {
                e = cx_interface(e)->base;
            }while(e && (e != cx_interface(_this)));
            result = (e == (cx_interface)_this);
        }
    } else {
        result = TRUE;
    }

    return result;
/* $end */
}
Ejemplo n.º 3
0
/* ::cortex::lang::type::resolveProcedure(string name) */
cx_function cx_type_resolveProcedure(cx_type _this, cx_string name) {
/* $begin(::cortex::lang::type::resolveProcedure) */
    cx_function result = NULL;

    /* If type is an interface, try first to resolve a method on the interface */
    if (cx_instanceof((cx_type)cx_interface_o, _this)) {
        result = (cx_function)cx_interface_resolveMethod(cx_interface(_this), name);
    }

    /* If no method is found or type is not an interface, resolve metaprocedure */
    if (!result) {
        cx_function *f;
        cx_int32 d = 0, prevD = 9999;
        cx_class metaclass = cx_class(cx_typeof(_this));

        /* Walk inheritance of metaclass to find metaprocedure */
        do {
            if ((f = cx_vtableLookup(&cx_type(metaclass)->metaprocedures, name, NULL, &d))) {
                if (d < prevD) {
                    result = *f;
                    prevD = d;
                }
            }
            metaclass = cx_class(cx_interface(metaclass)->base);
        }while(metaclass && !result);
    }

    return result;
/* $end */
}
Ejemplo n.º 4
0
/* ::cortex::lang::struct::resolveMember(string name) */
cx_member cx_struct_resolveMember_v(cx_struct _this, cx_string name) {
/* $begin(::cortex::lang::struct::resolveMember) */
    cx_interface base;
    cx_member m;

    m = NULL;
    base = cx_interface(_this);
    do {
        m = cx_interface_resolveMember_v(cx_interface(base), name);
    }while(!m && (base=cx_interface(base)->base));

    return m;
/* $end */
}
Ejemplo n.º 5
0
/* ::cortex::lang::struct::init() */
cx_int16 cx_struct_init(cx_struct _this) {
/* $begin(::cortex::lang::struct::init) */
    /* If not bootstrapping, set baseAccess to GLOBAL | PUBLIC */
    if (cx_checkState(cx_type_o, CX_DEFINED)) {
        _this->baseAccess = CX_GLOBAL;
    }

    if (cx_interface_init(cx_interface(_this))) {
        goto error;
    }

    cx_interface(_this)->kind = CX_STRUCT;
    cx_type(_this)->reference = FALSE;

    return 0;
error:
    return -1;
/* $end */
}
Ejemplo n.º 6
0
/* ::cortex::Fast::Member::toIc(ic::program program,ic::storage storage,bool stored) */
ic_node Fast_Member_toIc_v(Fast_Member _this, ic_program program, ic_storage storage, cx_bool stored) {
/* $begin(::cortex::Fast::Member::toIc) */
    ic_member result = NULL;
    cx_member member;
    ic_node lvalue;
    CX_UNUSED(stored);
    CX_UNUSED(storage);

    /* Get lvalue & rvalue */
    lvalue = Fast_Node_toIc(Fast_Node(_this->lvalue), program, NULL, FALSE);

    if (Fast_Node(_this->rvalue)->kind == Fast_LiteralExpr) {
        if (Fast_Literal(_this->rvalue)->kind == Fast_Text) {
            cx_type t = Fast_Expression_getType(_this->lvalue);
            if (cx_instanceof(cx_type(cx_interface_o), t)) {
                cx_interface baseType = cx_interface(t);
                member = cx_interface_resolveMember(baseType, Fast_String(_this->rvalue)->value);
            } else {
                cx_id id;
                Fast_Parser_error(yparser(), "cannot resolve members on non-interface type '%s'", Fast_Parser_id(t, id));
                goto error;
            }
        } else {
            Fast_Parser_error(yparser(), "dynamic resolving of members not yet supported.");
            goto error;
        }
    } else {
        Fast_Parser_error(yparser(), "dynamic resolving of members not yet supported.");
        goto error;
    }

    if (member) {
        result = ic_program_getMember(program, ic_storage(lvalue), member);
    }

    return (ic_node)result;
error:
    return NULL;
/* $end */
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
/* ::cortex::lang::struct::construct() */
cx_int16 cx_struct_construct(cx_struct _this) {
/* $begin(::cortex::lang::struct::construct) */
    cx_struct base;
    cx_uint16 alignment;
    cx_uint32 size;

    size = 0;
    alignment = 0;

    /* Insert members */
    if (cx__interface_insertMembers(cx_interface(_this))) {
        goto error;
    }

    /* Calculate alignment of self */
    if (cx_interface(_this)->members.length) {
        alignment = cx__interface_calculateAlignment(cx_interface(_this));
        if (!alignment) {
            cx_id id;
            cx_error("error in definition of '%s'", cx_fullname(_this, id));
            goto error;            
        }
    }

    /* Check if struct inherits from another struct */
    base = (cx_struct)cx_interface(_this)->base;

    /* Get maximum alignment from self and base-class and copy template parameters */
    if (base) {
        if (!cx_instanceof(cx_type(cx_struct_o), base)) {
            cx_id id, id2;
            cx_error("struct '%s' inherits from non-struct type '%s'", cx_fullname(_this, id), cx_fullname(base, id2));
            goto error;
        }

        if (cx_type(base)->alignment) {
            if (alignment < cx_type(base)->alignment) {
                alignment = cx_type(base)->alignment;
            }
        }
    }

    /* Set alignment of self */
    cx_type(_this)->alignment = alignment;

    /* Get size of base-class */
    if (base) {
        size = cx_type(base)->size;

        if (cx_type(base)->hasResources) {
            cx_type(_this)->hasResources = TRUE;
        }
    }

    /* Calculate size of self */
    if (cx_interface(_this)->members.length) {
        size = cx__interface_calculateSize(cx_interface(_this), size);
        if (!size) {
            cx_id id;
            cx_error("error in definition of '%s'", cx_fullname(_this, id));
            goto error;
        }
    }

    /* Set size of self */
    cx_type(_this)->size = size;

    return cx_interface_construct(cx_interface(_this));
error:
    return -1;
/* $end */
}