/* ::cortex::lang::type::copy(any value) */ cx_int16 cx_type_copy(cx_any _this, cx_any value) { /* $begin(::cortex::lang::type::copy) */ cx_copy_ser_t data; struct cx_serializer_s s; cx_value v1; cx_int16 result; if (_this.type->reference || value.type->reference) { cx_valueObjectInit(&data.value, _this.value); cx_valueObjectInit(&v1, value.value); } else { cx_valueValueInit(&data.value, NULL, cx_type(_this.type), _this.value); cx_valueValueInit(&v1, NULL, cx_type(value.type), value.value); } s = cx_copy_ser(CX_PRIVATE, CX_NOT, CX_SERIALIZER_TRACE_ON_FAIL); result = cx_serializeValue(&s, &v1, &data); if (result) { cx_id id, id2; cx_error("type::copy: failed to copy value of type '%s' to value of type '%s'", cx_fullname(_this.type, id), cx_fullname(value.type, id2)); } return result; /* $end */ }
/* ::cortex::lang::type::fullname() */ cx_string cx_type_fullname(cx_any _this) { /* $begin(::cortex::lang::type::fullname) */ cx_string result = NULL; if (_this.value) { cx_id id; result = cx_strdup(cx_fullname(_this.value, id)); } else { result = cx_strdup("null"); } return result; /* $end */ }
static cx_int16 serializeBase(cx_serializer s, cx_value* v, void* userData) { cx_json_ser_t *data = userData; cx_id id; if (!cx_ser_appendstr(data, "\"@%s\":", cx_fullname(cx_valueType(v), id))) { goto finished; } if (cx_serializeValue(s, v, userData)) { goto error; } data->itemCount += 1; return 0; error: return -1; finished: return 1; }
/* ::cortex::ic::program::getObject(object o) */ ic_object ic_program_getObject(ic_program _this, cx_object o) { /* $begin(::cortex::ic::program::getObject) */ cx_id id; ic_scope root = _this->scope; ic_object result = NULL; while(root->parent) { root = root->parent; } result = ic_object(ic_scope_lookupStorage(root, cx_fullname(o, id), FALSE)); if (!result) { result = ic_object__create(o); ic_scope_addStorage(root, ic_storage(result)); } return result; /* $end */ }
static int serializeMetaWalkScopeAction(cx_object o, void* userData) { if (!cx_ser_appendstr(userData, "{")) { goto finished; } cx_string name = cx_nameof(o); if (name) { if (!cx_appendStringAttr("name", name, userData)) { goto finished; } } else { if (!cx_ser_appendstr(userData, "\"name\":\"::\",")) { goto finished; } } cx_id type_fullname; cx_fullname(cx_typeof(o), type_fullname); if (!cx_appendStringAttr("type", type_fullname, userData)) { goto finished; } char states[sizeof("V|DCL|DEF")]; dbsh_stateStr(o, states); if (!cx_ser_appendstr(userData, "\"states\":\"%s\",", states)) { goto finished; } char attributes[sizeof("S|W|O|P")]; dbsh_attrStr(o, attributes); if (!cx_ser_appendstr(userData, "\"attributes\":\"%s\",", attributes)) { goto finished; } cx_uint32 scopeSize = cx_scopeSize(o); if (!cx_ser_appendstr(userData, "\"childCount\":%"PRId32"", scopeSize)) { goto finished; } if (!cx_ser_appendstr(userData, "},")) { goto finished; } return 1; finished: return 0; }
/* ::cortex::lang::type::parentof() */ cx_object cx_type_parentof(cx_any _this) { /* $begin(::cortex::lang::type::parentof) */ cx_string result = NULL; if (cx_checkAttr(_this.value, CX_ATTR_SCOPED)) { result = cx_parentof(_this.value); } else { cx_id id; cx_error("cannot get parent from non-scoped object of type '%s'", cx_fullname(cx_typeof(_this.value), id)); } if (result) { cx_keep(result); } return result; /* $end */ }
/* ::cortex::lang::constant::init() */ cx_int16 cx_constant_init(cx_constant *_this) { /* $begin(::cortex::lang::constant::init) */ cx_object parent; parent = cx_parentof(_this); /* Parent must be an enum */ if (cx_typeof(parent) == cx_type(cx_enum_o)) { cx__enum_bindConstant(parent, _this); } else if (cx_typeof(parent) == cx_type(cx_bitmask_o)) { cx__bitmask_bindConstant(parent, _this); } else { cx_id id; cx_error("::constant::init: parent of constant '%s' is not an enum.", cx_fullname(_this, id)); goto error; } return 0; error: return -1;/* $end */ }
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; }
static cx_int16 serializeReference(cx_serializer s, cx_value *v, void *userData) { CX_UNUSED(s); cx_json_ser_t *data; void *o; cx_object object; cx_id id; data = userData; o = cx_valueValue(v); object = *(cx_object*)o; if (object) { if (cx_checkAttr(object, CX_ATTR_SCOPED) || (cx_valueObject(v) == object)) { cx_uint32 length; cx_fullname(object, id); /* Escape value */ cx_string escapedValue = cx_malloc((length = stresc(NULL, 0, id)) + 1); stresc(escapedValue, length, id); if (!cx_ser_appendstr(data, "\"@R %s\"", escapedValue)) { cx_dealloc(escapedValue); goto finished; } cx_dealloc(escapedValue); } else { cx_ser_appendstr(data, "\"anonymous\""); } } else { if (!cx_ser_appendstrbuff(data, "null")) { goto finished; } } return 0; finished: return 1; }
/* ::cortex::lang::function::stringToParameterSeq(string name,object scope) */ cx_parameterSeq cx_function_stringToParameterSeq(cx_string name, cx_object scope) { /* $begin(::cortex::lang::function::stringToParameterSeq) */ cx_parameterSeq result = {0, NULL}; cx_char* ptr; ptr = strchr(name, '('); if (!ptr) { cx_error("missing argumentlist in name for signature '%s'", name); goto error; } ptr++; /* Check if function has arguments */ if (*ptr != ')') { cx_int32 count = 0, i = 0; cx_id id; int flags = 0; /* Count number of parameters for function */ count = cx_signatureParamCount(name); if (count == -1) { goto error; } /* Allocate size for parameters */ result.length = count; result.buffer = cx_malloc(sizeof(cx_parameter) * count); memset(result.buffer, 0, sizeof(cx_parameter) * count); /* Parse arguments */ for(i=0; i<count; i++) { if (cx_signatureParamType(name, i, id, &flags)) { cx_error("error occurred while parsing type of parameter '%d' for signature '%s'", i, name); goto error; } /* Set reference */ result.buffer[i].passByReference = (flags & CX_PARAMETER_REFERENCE) != 0; /* Assign type */ result.buffer[i].type = cx_resolve_ext(NULL, scope, id, FALSE, "Resolve parameter-type for function"); if (!result.buffer[i].type) { cx_error("type '%s' of parameter %d in signature %s not found", id, i, name); goto error; } /* Validate whether reference is not redundantly applied */ if (result.buffer[i].passByReference && result.buffer[i].type->reference) { cx_id id; cx_error("redundant '&' qualifier for parameter %d, type '%s' is already a reference", i, cx_fullname(result.buffer[i].type, id)); goto error; } /* Parse name */ if (cx_signatureParamName(name, i, id)) { cx_error("error occurred while parsing name of argument '%s' for signature '%s'", name); goto error; } result.buffer[i].name = cx_strdup(id); } } return result; error: result.length = -1; cx_dealloc(result.buffer); result.buffer = NULL; return result; /* $end */ }
/* Define type */ static void cx_defineType(cx_object o, cx_uint32 size) { cx_defineObject(o); /* Size validation */ if (cx_type(o)->size != size) { cx_id id; cx_error("bootstrap: size validation failed for type '%s' - metatype = %d, c-type = %d.", cx_fullname(o, id), cx_type(o)->size, size); } }
static cx_int16 serializeMeta(cx_serializer s, cx_value* v, void* userData) { CX_UNUSED(s); cx_json_ser_t *data = userData; cx_object o = cx_valueValue(v); if (!data->serializeMeta) { goto error; } if (!cx_ser_appendstr(userData, "{")) { goto finished; } cx_string name = cx_nameof(o); if (name) { if (!cx_appendStringAttr("name", name, userData)) { goto finished; } } else { if (!cx_ser_appendstr(userData, "\"name\":\"::\",")) { goto finished; } } cx_id type_fullname; cx_fullname(cx_typeof(o), type_fullname); if (!cx_appendStringAttr("type", type_fullname, userData)) { goto finished; } if (cx_checkAttr(o, CX_ATTR_PERSISTENT)) { cx_time t = cx_timestampof(o); if (!cx_ser_appendstr(data, "\"timestamp\":\"%d.%.9d\",", t.tv_sec, t.tv_nsec)) { goto finished; } } char states[sizeof("V|DCL|DEF")]; dbsh_stateStr(o, states); if (!cx_ser_appendstr(data, "\"states\":\"%s\",", states)) { goto finished; } char attributes[sizeof("S|W|O|P")]; dbsh_attrStr(o, attributes); if (!cx_ser_appendstr(data, "\"attributes\":\"%s\",", attributes)) { goto finished; } cx_id parent_fullname; cx_fullname(cx_parentof(o), parent_fullname); if (!cx_ser_appendstr(data, "\"parent\":\"%s\",", parent_fullname)) { goto finished; } cx_uint32 scopeSize = cx_scopeSize(o); if (!cx_ser_appendstr(data, "\"childCount\":%"PRId32"", scopeSize)) { goto finished; } if (!cx_ser_appendstr(data, "}")) { goto finished; } return 0; error: return -1; finished: return 1; }
/* ::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 */ }
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; }