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; }
/* ::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 */ }
/* ::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 */ }
/* ::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 */ }
/* ::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 */ }
/* ::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 */ }
/* 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; }
/* ::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 */ }