/* Initialization of objects */ static void cx_initObject(cx_object o) { cx_newObject(o); cx_delegateInit(cx_typeof(o), o); if (cx_typeof(o)->kind == CX_VOID) { cx__setState(o, CX_DEFINED); } }
static int cx_genDefineAction(cx_object o, void* userData) { g_itemWalk_t data; data = userData; if ((cx_typeof(o)->kind != CX_VOID) || (cx_typeof(o)->reference)) { if (data->onDefine) { data->onDefine(o, data->userData); } } return 1; }
/* ::cortex::lang::function::bind() */ cx_int16 cx_function_bind(cx_function _this) { /* $begin(::cortex::lang::function::bind) */ /* Count the size based on the parameters and store parameters in slots */ if (!_this->size) { cx_uint32 i; for(i=0; i<_this->parameters.length; i++) { if (_this->parameters.buffer[i].passByReference) { _this->size += sizeof(cx_word); } else { cx_type paramType = _this->parameters.buffer[i].type; switch(paramType->kind) { case CX_ANY: _this->size += sizeof(cx_any); break; case CX_PRIMITIVE: _this->size += cx_type_sizeof(paramType); break; default: _this->size += sizeof(void*); break; } } } /* Add size of this-pointer - this must be moved to impl of methods, delegates and callbacks. */ if (!(cx_typeof(_this) == cx_type(cx_function_o))) { if (cx_typeof(_this) == cx_type(cx_metaprocedure_o)) { _this->size += sizeof(cx_any); } else { _this->size += sizeof(cx_object); } } } /* If no returntype is set, make it void */ if (!_this->returnType) { cx_set(&_this->returnType, cx_void_o); } /* Bind with interface if possible */ if (cx_delegate_bind(_this)) { goto error; } return 0; error: return -1; /* $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::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 */ }
/* Add dependencies for function arguments */ static int cx_genDepBuildProc(cx_function f, g_itemWalk_t data) { cx_uint32 i; cx_type t; if (cx_procedure(cx_typeof(f))->kind != CX_OBSERVER) { for(i=0; i<f->parameters.length; i++) { t = f->parameters.buffer[i].type; if (g_mustParse(data->g, t)) { cx_depresolver_depend(data->resolver, f, CX_DECLARED, t, CX_DECLARED | CX_DEFINED); /* The type must be at least declared when the function is declared. */ } } } return 0; }
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 */ }
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; }
/* ::cortex::Fast::StaticInitializer::define() */ cx_int16 Fast_StaticInitializer_define(Fast_StaticInitializer _this) { /* $begin(::cortex::Fast::StaticInitializer::define) */ cx_uint32 variable; cx_object o; /* Types are defined during 1st pass. All other objects are defined when a program starts. Defining types * at compile-time is required to do validity checking while parsing. On the other hand, objects cannot be * defined at compile-time because class constructors\destructors are not yet defined at that point. This * would cause object creation\destruction without calling the appropriate constructors\destructors. */ for(variable=0; variable<Fast_Initializer(_this)->variableCount; variable++) { o = (cx_object)Fast_Object(Fast_Initializer(_this)->variables[variable].object)->value; if (cx_instanceof(cx_type(cx_type_o), o) || (cx_checkAttr(o, CX_ATTR_SCOPED) && cx_instanceof(cx_type(cx_type_o), cx_parentof(o)))) { if (cx_define(o)) { cx_id id1, id2; Fast_Parser_error(yparser(), "define of variable '%s' of type '%s' failed", Fast_Parser_id(o, id1), Fast_Parser_id(cx_typeof(o), id2)); goto error; } } else { Fast_Expression refVar = Fast_Expression(Fast_Object__create(o)); refVar->isReference = TRUE; /* Always treat object as reference */ Fast_Define defineStmt = Fast_Define__create(refVar); Fast_Parser_addStatement(yparser(), Fast_Node(defineStmt)); Fast_Parser_collect(yparser(), defineStmt); Fast_Parser_collect(yparser(), refVar); } } Fast_Initializer_define_v(Fast_Initializer(_this)); return 0; error: return -1; /* $end */ }
/* Serve a Cortex object */ static int web_serveObject(struct mg_connection *conn) { cx_object o = NULL; /* Resolve object based on URI */ o = cx_resolve(NULL, (cx_string)conn->uri + 2); if (!o) { mg_send_status(conn, 404); mg_printf_data(conn, "404: resource '%s' not found\n", conn->uri); } else { char option[6]; cx_bool value = 0; cx_bool meta = 0; cx_bool scope = 0; /* Set correct content type */ mg_send_header(conn, "Content-Type", "application/json; charset=utf-8"); /* Determine what to show */ mg_get_var(conn, "value", option, sizeof(option)); if (!strcmp(option, "true")) { value = TRUE; } mg_get_var(conn, "meta", option, sizeof(option)); if (!strcmp(option, "true")) { meta = TRUE; } mg_get_var(conn, "scope", option, sizeof(option)); if (!strcmp(option, "true")) { scope = TRUE; } if (!(value || meta || scope)) { value = TRUE; } { /* Serialize object-value to JSON */ struct cx_serializer_s serializer = cx_json_ser(CX_PRIVATE, CX_NOT, CX_SERIALIZER_TRACE_NEVER); if ((cx_typeof(o)->kind == CX_VOID) && (!meta && !scope)) { mg_printf_data(conn, "\n"); } else { mg_printf_data(conn, "["); /* Serialize metadata of parents */ if (meta) { if (web_printParents(conn, cx_parentof(o))) { mg_printf_data(conn, ","); } } /* Serialize value */ { cx_json_ser_t jsonData = {NULL, NULL, 0, 0, 0, meta, value, scope, TRUE}; cx_serialize(&serializer, o, &jsonData); mg_printf_data(conn, "%s", jsonData.buffer); cx_dealloc(jsonData.buffer); } mg_printf_data(conn, "]\n"); } } cx_free(o); } return MG_TRUE; }
/* 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; }
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; }