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::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::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 */ }
/* ::cortex::ic::program::add(node n) */ cx_void ic_program_add(ic_program _this, ic_node n) { /* $begin(::cortex::ic::program::add) */ if (n->kind == IC_OP) { if (!ic_op_validate(ic_op(n))) { _this->errors++; } } if (cx_instanceof(cx_type(ic_storage_o), n)) { ic_node_list__append(_this->scope->storages, n); } else { ic_node_list__append(_this->scope->program, n); } /* $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 */ }
/* ::cortex::web::SockJsServer::poll() */ cx_void web_SockJsServer_poll(web_SockJsServer _this) { /* $begin(::cortex::web::SockJsServer::poll) */ struct mg_server *server = (struct mg_server *)_this->server; mg_poll_server(server, _this->pollTimemoutMillis); _this->timeElapsed += _this->pollTimemoutMillis; /* Send heartbeats for all live connections every n seconds */ if (_this->timeElapsed >= (WEB_SOCKJSSERVER_DEFAULT_HEARTBEAT_TIMEOUT * 1000)) { cx_ll scope = cx_scopeClaim(_this); cx_iter iter = cx_llIter(scope); while (cx_iterHasNext(&iter)) { cx_object o = cx_iterNext(&iter); if (cx_instanceof(cx_type(web_SockJsServer_Connection_o), o)) { web_SockJsServer_Connection c = web_SockJsServer_Connection(o); mg_websocket_printf((struct mg_connection *)c->conn, WEBSOCKET_OPCODE_TEXT, "h"); } } cx_scopeRelease(scope); _this->timeElapsed = 0; } /* $end */ }
/* ::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 */ }
/* ::cortex::Fast::Expression::cast(type type,bool isReference) */ Fast_Expression Fast_Expression_cast(Fast_Expression _this, cx_type type, cx_bool isReference) { /* $begin(::cortex::Fast::Expression::cast) */ cx_type exprType, refType; Fast_Expression result = NULL; cx_bool castRequired = TRUE; cx_assert(type != NULL, "cannot cast to unknown type NULL"); exprType = Fast_Expression_getType(_this); if((_this->deref == Fast_ByReference) && !isReference && !exprType->reference) { refType = cx_object_o; } else { refType = exprType; } /* If types are different, cast */ if (refType != type) { if (!exprType) { /* If expression is an untyped initializer, create an anonymous variable of the destination type * and assign it to the initializer. */ if(Fast_Node(_this)->kind == Fast_InitializerExpr) { Fast_Expression local = Fast_Expression(Fast_Temporary__create(type, FALSE)); Fast_InitializerExpression_insert(Fast_InitializerExpression(_this), local); result = local; castRequired = TRUE; }else { castRequired = FALSE; } } else if (cx_type_castable(type, refType)) { void *value = NULL; /* If expression is a literal or constant create new literal of right type */ value = (void*)Fast_Expression_getValue(_this); if (value) { if (type->reference && (Fast_Node(_this)->kind == Fast_LiteralExpr)) { /* If destination type is a reference and the literal is a string this results * in a resolve at run-time. */ switch(Fast_Literal(_this)->kind) { case Fast_Text: break; case Fast_Nothing: /* No cast required */ break; default: { cx_id id1, id2; /* Invalid cast */ Fast_Parser_error(yparser(), "cannot cast from '%s' to '%s'", Fast_Parser_id(exprType, id1), Fast_Parser_id(type, id2)); break; } } } /* Create literal expressions based on destination type */ switch(cx_primitive(type)->kind) { case CX_BOOLEAN: { cx_bool dstValue = FALSE; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_bool_o), &dstValue); result = Fast_Expression(Fast_Boolean__create(dstValue)); break; } case CX_CHARACTER: { cx_char dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_char_o), &dstValue); result = Fast_Expression(Fast_Character__create(dstValue)); break; } case CX_BINARY: case CX_UINTEGER: { cx_uint64 dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_uint64_o), &dstValue); result = Fast_Expression(Fast_Integer__create(dstValue)); break; } case CX_INTEGER: { cx_int64 dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_int64_o), &dstValue); result = Fast_Expression(Fast_SignedInteger__create(dstValue)); break; } case CX_FLOAT: { cx_float64 dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_float64_o), &dstValue); result = Fast_Expression(Fast_FloatingPoint__create(dstValue)); break; } case CX_TEXT: { cx_string dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_string_o), &dstValue); result = Fast_Expression(Fast_String__create(dstValue)); break; } case CX_ENUM: case CX_BITMASK: { cx_int32 dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_int32_o), &dstValue); result = Fast_Expression(Fast_SignedInteger__create(dstValue)); break; } case CX_ALIAS: { cx_int32 dstValue; cx_convert(cx_primitive(exprType), value, cx_primitive(cx_word_o), &dstValue); result = Fast_Expression(Fast_SignedInteger__create(dstValue)); break; } } if (result){ cx_set_ext(result, &Fast_Expression(result)->type, type, "Set correct type after cast"); } } else { /* TODO: This functionality must be pushed down to the assembler. For all this function is concerned a cast should only be required when a type is a) castable and b) not compatible. */ /* If both types are primitive make sure that no cast is inserted for primitives * of the same kind or 'score' to the same width */ if ((refType->kind == CX_PRIMITIVE) && (type->kind == CX_PRIMITIVE) && (Fast_Expression_getCastScore(cx_primitive(refType)) == Fast_Expression_getCastScore(cx_primitive(type)))) { if (cx_primitive(exprType)->width != cx_primitive(type)->width) { result = Fast_Expression(Fast_Cast__create(type, _this, isReference)); } else { /* Types have the same width, so no cast required */ castRequired = FALSE; } /* Interface-downcasting doesn't require an explicit cast */ } else if (!cx_instanceof(cx_type(cx_interface_o), type)) { result = Fast_Expression(Fast_Cast__create(type, _this, isReference)); } else { castRequired = FALSE; } } /* If object is a reference and targetType is string, insert toString operation */ } else /*if (_this->isReference || Fast_Expression_getType(_this)->reference)*/ { if ((type->kind == CX_PRIMITIVE) && (cx_primitive(type)->kind == CX_TEXT)) { /* Create call-expression */ result = Fast_Expression(Fast_createCallWithArguments(_this, "toString", NULL)); if (!result) { goto error; } cx_keep(result); /* If type is of a generic reference type, accept any reference without cast */ } else if (type->kind == CX_VOID && type->reference) { castRequired = FALSE; /* If assigning to a generic reference, insert cast */ } else if (exprType->kind == CX_VOID && exprType->reference && isReference) { result = Fast_Expression(Fast_Cast__create(type, _this, isReference)); } } } else { castRequired = FALSE; } if (result && castRequired) { Fast_Parser_collect(yparser(), result); } else { if (castRequired) { cx_id id1, id2; Fast_Parser_error(yparser(), "no conversion from '%s' to '%s'", Fast_Parser_id(exprType, id1), Fast_Parser_id(type, id2)); } } return result; error: return NULL; /* $end */ }
/* ::cortex::lang::type::instanceof(type type) */ cx_bool cx_type_instanceof(cx_any _this, cx_type type) { /* $begin(::cortex::lang::type::instanceof) */ return cx_instanceof(type, _this.value); /* $end */ }