Пример #1
0
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;
}
Пример #2
0
/* ::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 */
}
Пример #3
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 */
}
Пример #4
0
/* ::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 */
}
Пример #5
0
/* ::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 */
}
Пример #6
0
/* ::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 */
}
Пример #7
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 */
}
Пример #8
0
/* ::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 */
}
Пример #9
0
/* ::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 */
}