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