Esempio n. 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;
}
Esempio n. 2
0
/* ::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 */
}
Esempio n. 3
0
/* Obtain inttype from value */
cx_type Fast_Expression_getIntTypeFromValue(cx_int64 v, cx_primitive t) {
    cx_type result = NULL;

    if (v < 0) {
        if(t->kind == CX_UINTEGER) {
            /* Overflow */
            if (((cx_uint64)v) <= 4294967295) {
                result = cx_type(cx_uint32_o);
            } else {
                result = cx_type(cx_uint64_o);
            }
        } else if (v >= -128) {
            result = cx_type(cx_int8_o);
        } else if (v >= -32768) {
            result = cx_type(cx_int16_o);
        } else if (v >= -2147483648) {
            result = cx_type(cx_int32_o);
        } else {
            result = cx_type(cx_int64_o);
        }
    } else {
        if (v <= 255) {
            result = cx_type(cx_uint8_o);
        } else if (v <= 65535) {
            result = cx_type(cx_uint16_o);
        } else {
            result = cx_type(cx_uint32_o);
        }
    }

    return result;
}
Esempio n. 4
0
/* ::cortex::lang::list::construct() */
cx_int16 cx_list_construct(cx_list _this) {
/* $begin(::cortex::lang::list::construct) */
    cx_type(_this)->hasResources = TRUE;
    cx_type(_this)->size = sizeof(cx_ll);
    cx_type(_this)->alignment = CX_ALIGNMENT(cx_ll);
    if (!cx_collection(_this)->elementType) {
        cx_error("no elementtype provided for list");
        goto error;
    }
    return cx_type_construct(cx_type(_this));
error:
    return -1;
/* $end */
}
Esempio n. 5
0
/* ::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 */
}
Esempio n. 6
0
/* ::cortex::lang::struct::compatible(type type) */
cx_bool cx_struct_compatible_v(cx_struct _this, cx_type type) {
/* $begin(::cortex::lang::struct::compatible) */
    cx_bool result;

    cx_assert(cx_class_instanceof(cx_struct_o, _this), "struct::compatible called on non-struct object.");
    result = FALSE;

    /* Call overloaded type::compatible function first to check for generic compatibility. */
    if (!cx_type_compatible_v(cx_type(_this), type)) {
        /* Type must be at least struct for it to be compatible. */
        if (cx_class_instanceof(cx_struct_o, type)) {
            cx_interface e;

            /* Check if '_this' is superclass of 'type' */
            e = cx_interface(type);
            do {
                e = cx_interface(e)->base;
            }while(e && (e != cx_interface(_this)));
            result = (e == (cx_interface)_this);
        }
    } else {
        result = TRUE;
    }

    return result;
/* $end */
}
Esempio n. 7
0
/* $header(::cortex::Fast::Expression::getType_expr) */
cx_type Fast_Expression_getType_intern(Fast_Expression _this, cx_type target, Fast_Expression targetExpr) {
    cx_type result = Fast_Expression_getType(_this);

    if (!result) {
        if ((Fast_Node(_this)->kind == Fast_LiteralExpr) && (Fast_Literal(_this)->kind == Fast_Nothing)) {
            if (target) {
                if (target->reference) {
                    result = target;
                } else if ((target->kind == CX_PRIMITIVE) && (cx_primitive(target)->kind == CX_TEXT)) {
                    result = cx_type(cx_string_o);
                } else {
                    if (targetExpr && targetExpr->isReference) {
                        result = target;
                    } else {
                        goto error;
                    }
                }
            } else {
                goto error;
            }
        } else if (Fast_Node(_this)->kind == Fast_InitializerExpr) {
            result = target;
        } else {
            goto error;
        }
    } else if ((target && (target->kind == CX_VOID) && target->reference)) {
        result = cx_object_o;
    }

    return result;
error: 
    Fast_Parser_error(yparser(), "inconsistent usage of references");
    return NULL;  
}
Esempio n. 8
0
/* ::cortex::lang::type::compare(any value) */
cx_equalityKind cx_type_compare(cx_any _this, cx_any value) {
/* $begin(::cortex::lang::type::compare) */
    cx_compare_ser_t data;
    struct cx_serializer_s s;
    cx_value v1;
    
    cx_valueValueInit(&v1, NULL, cx_type(_this.type), _this.value);
    cx_valueValueInit(&data.value, NULL, cx_type(value.type), value.value);
    
    s = cx_compare_ser(CX_PRIVATE, CX_NOT, CX_SERIALIZER_TRACE_NEVER);

    cx_serializeValue(&s, &v1, &data);

    return data.result;
/* $end */
}
Esempio n. 9
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 */
}
Esempio n. 10
0
/* ::cortex::lang::text::init() */
cx_int16 cx_text_init(cx_text _this) {
/* $begin(::cortex::lang::text::init) */
    cx_type(_this)->hasResources = TRUE;
    cx_primitive(_this)->kind = CX_TEXT;
    cx_primitive(_this)->width = CX_WIDTH_WORD;
    return cx_primitive_init((cx_primitive)_this);
/* $end */
}
Esempio n. 11
0
/* ::cortex::lang::bitmask::init() */
cx_int16 cx_bitmask_init(cx_bitmask _this) {
/* $begin(::cortex::lang::bitmask::init) */
    cx_primitive(_this)->kind = CX_BITMASK;
    cx_primitive(_this)->width = CX_WIDTH_32;
    cx_set(&cx_type(_this)->defaultType, cx_constant_o);
    return cx_primitive_init((cx_primitive)_this);
/* $end */
}
Esempio n. 12
0
/* 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);
    }
}
Esempio n. 13
0
/* ::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 */
}
Esempio n. 14
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 */
}
Esempio n. 15
0
/* Do metawalk on type */
cx_int16 cx_metaWalk(cx_serializer s, cx_type type, void* userData) {
    cx__object* o;
    cx_int16 result;

    /* Instantiate dummy-object */
    o = cx_malloc(sizeof(cx__object) + type->size); /* alloca is dangerous here because objects can get large, causing stack overflows. */
    memset(o, 0, sizeof(cx__object) + type->size);
    o->type = cx_type(type);
    o->refcount = 1;

    result = cx_serialize(s, CX_OFFSET(o, sizeof(cx__object)), userData);
    cx_dealloc(o);

    return result;
}
Esempio n. 16
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 */
}
Esempio n. 17
0
/* ::cortex::Fast::Element::construct() */
cx_int16 Fast_Element_construct(Fast_Element _this) {
/* $begin(::cortex::Fast::Element::construct) */
    cx_type lvalueType, rvalueType;

    Fast_Storage(_this)->kind = Fast_ElementStorage;

    lvalueType = Fast_Expression_getType(_this->lvalue);

    if (lvalueType) {
        if (lvalueType->kind == CX_COLLECTION) {
            rvalueType = Fast_Expression_getType(_this->rvalue);
            if (rvalueType) {
                if (cx_collection(lvalueType)->kind != CX_MAP) {
                    if (!cx_type_castable(cx_type(cx_uint32_o), rvalueType)) {
                        cx_id id;
                        Fast_Parser_error(yparser(), "expected integer expression for index, got '%s'", Fast_Parser_id(rvalueType, id));
                        goto error;
                    }
                } else {
                    if (!cx_type_castable(cx_map(lvalueType)->keyType, rvalueType)) {
                        cx_id id, id2;
                        Fast_Parser_error(yparser(), "expected expression of type '%s' for key, got '%s'",
                                Fast_Parser_id(cx_map(lvalueType)->keyType, id), Fast_Parser_id(rvalueType, id2));
                        goto error;
                    }
                }
            }
            /* Set type of expression */
            cx_set(&Fast_Expression(_this)->type, cx_collection(lvalueType)->elementType);
        } else {
            cx_id id;
            Fast_Parser_error(yparser(), "cannot obtain element from _this of non-collection type '%s'", Fast_Parser_id(lvalueType, id));
            goto error;
        }
    } else {
        Fast_Parser_error(yparser(), "dynamic expressions are not yet supported");
        goto error;
    }

    Fast_Expression(_this)->isReference = cx_collection(lvalueType)->elementType->reference;

    return Fast_Storage_construct(Fast_Storage(_this));
error:
    return -1;
/* $end */
}
Esempio n. 18
0
cx_type Fast_Expression_narrowType(Fast_Expression expr) {
    cx_int64 v;
    cx_type t = Fast_Expression_getType(expr);
    if (Fast_Node(expr)->kind == Fast_LiteralExpr) {
        if (t && (t->kind == CX_PRIMITIVE)) {
            switch(cx_primitive(t)->kind) {
            case CX_INTEGER:
            case CX_UINTEGER:
                Fast_Expression_serialize(expr, cx_type(cx_int64_o), (cx_word)&v);
                t = Fast_Expression_getIntTypeFromValue(v, cx_primitive(t));
                break;
            default:
                break;
            }
        }
    }

    return t;
}
Esempio n. 19
0
/* ::cortex::lang::struct::init() */
cx_int16 cx_struct_init(cx_struct _this) {
/* $begin(::cortex::lang::struct::init) */
    /* If not bootstrapping, set baseAccess to GLOBAL | PUBLIC */
    if (cx_checkState(cx_type_o, CX_DEFINED)) {
        _this->baseAccess = CX_GLOBAL;
    }

    if (cx_interface_init(cx_interface(_this))) {
        goto error;
    }

    cx_interface(_this)->kind = CX_STRUCT;
    cx_type(_this)->reference = FALSE;

    return 0;
error:
    return -1;
/* $end */
}
Esempio n. 20
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 */
}
Esempio n. 21
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 */
}
Esempio n. 22
0
cx_type cx_rbtreeKeyType(cx_rbtree tree) {
    return cx_type(jsw_rbtype((jsw_rbtree_t*)tree));
}
Esempio n. 23
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 */
}
Esempio n. 24
0
/* ::cortex::Fast::String::toIc(ic::program program,ic::storage storage,bool stored) */
ic_node Fast_String_toIc_v(Fast_String _this, ic_program program, ic_storage storage, cx_bool stored) {
/* $begin(::cortex::Fast::String::toIc) */
    ic_node result = NULL;
    CX_UNUSED(storage);
    CX_UNUSED(stored);

    /* Parse string after parsing script and thus not interfere with parser */
    if (Fast_String_parse(_this)) {
        goto error;
    }

    if (!cx_llSize(_this->elements)) {
        result = (ic_node)ic_literal__create((cx_any){cx_type(cx_string_o), &_this->value, FALSE});
    } else {
        if (stored) {
            cx_iter elementIter;
            Fast_Expression element;
            ic_node icElement1, icElement2;
            cx_uint32 elementCount = cx_llSize(_this->elements);
            cx_bool stored = FALSE;
            ic_node dummy;
            cx_uint32 accPushCount = 0;
            cx_type elementType;

            if (storage && (storage->type != cx_type(cx_string_o))) {
                Fast_Parser_error(yparser(),
                        "storage for string-expression '%s' has invalid type (%s)",
                        _this->value,
                        cx_nameof(storage->type));
                goto error;
            }

            dummy = (ic_node)ic_literal__create((cx_any){cx_type(cx_string_o), NULL, FALSE});

            result = (ic_node)storage;
            elementIter = cx_llIter(_this->elements);
            while(cx_iterHasNext(&elementIter)) {
                ic_accumulator acc = ic_program_pushAccumulator(program, (cx_type)cx_string_o, FALSE, FALSE);
                accPushCount++;
                element = cx_iterNext(&elementIter);

                elementType = Fast_Expression_getType(element);
                if (!elementType) {
                    element = Fast_Expression(Fast_String__create(CX_NULL_STRING));
                } else if (elementType != cx_type(cx_string_o)) {
                    element = Fast_Expression_cast(element, cx_type(cx_string_o), FALSE);
                    if(!element) {
                        goto error;
                    }
                }

                icElement1 = Fast_Node_toIc(Fast_Node(element), program, (ic_storage)acc, TRUE);
                if (!icElement1) {
                    goto error;
                }
                if (elementCount == 1) {
                    if (storage) {
                        IC_2(program, Fast_Node(_this)->line, ic_strcpy, storage, icElement1, IC_DEREF_VALUE, IC_DEREF_VALUE);
                    } else {
                        result = (ic_node)icElement1;
                    }
                    stored = TRUE;
                } else {
                    if (elementCount) {
                        if (cx_iterHasNext(&elementIter)) {
                            ic_accumulator acc = ic_program_pushAccumulator(program, (cx_type)cx_string_o, FALSE, FALSE);
                            accPushCount++;
                            element = cx_iterNext(&elementIter);
                            elementType = Fast_Expression_getType(element);

                            if (!elementType) {
                                element = Fast_Expression(Fast_String__create(CX_NULL_STRING));
                            } else if (elementType && (Fast_Expression_getType(element) != cx_type(cx_string_o))) {
                                element = Fast_Expression_cast(element, cx_type(cx_string_o), FALSE);
                                if (!element) {
                                    goto error;
                                }
                            }

                            icElement2 = Fast_Node_toIc(Fast_Node(element), program, (ic_storage)acc, TRUE);
                            if (!icElement2) {
                                goto error;
                            }
                            IC_2(program, Fast_Node(_this)->line, ic_strcat, icElement1, icElement2, IC_DEREF_VALUE, IC_DEREF_VALUE);
                            elementCount--;
                        }
                    } else {
                        IC_2(program, Fast_Node(_this)->line, ic_strcat, icElement1, dummy, IC_DEREF_VALUE, IC_DEREF_VALUE);
                    }
                }
                elementCount--;
            }

            /* If string is not yet copied, insert copy instruction */
            if (!stored) {
                IC_2(program, Fast_Node(_this)->line, ic_strcpy, storage, dummy, IC_DEREF_VALUE, IC_DEREF_VALUE);
                stored = TRUE;
            }

            while(accPushCount) {
                ic_program_popAccumulator(program);
                accPushCount--;
            }
        }
    }

    return result;
error:
    return NULL;
/* $end */
}
Esempio n. 25
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;
}
Esempio n. 26
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 */
}
Esempio n. 27
0
int cx_start(void) {

    /* Initialize threadkeys */
    cx_threadTlsKey(&CX_KEY_OBSERVER_ADMIN, NULL);
    cx_threadTlsKey(&CX_KEY_WAIT_ADMIN, NULL);

    /* Init admin-lock */
    cx_mutexNew(&cx_adminLock);

    /* Bootstrap sizes of types used in parameters, these are used to determine
     * argument-stack sizes for functions during function::bind. */
    cx_type(cx_string_o)->size = sizeof(cx_string);
    cx_type(cx_int32_o)->size = sizeof(cx_int32);
    cx_type(cx_uint32_o)->size = sizeof(cx_uint32);
    cx_type(cx_any_o)->size = sizeof(cx_any);
    cx_type(cx_state_o)->size = sizeof(cx_state);
    cx_type(cx_attr_o)->size = sizeof(cx_attr);

    /* Initialize builtin scopes */
    cx_initObject(root_o);
    cx_initObject(cortex_o);
    cx_initObject(cortex_lang_o);

    /* Define builtin scopes */
    cx_defineObject(root_o);
    cx_defineObject(cortex_o);
    cx_defineObject(cortex_lang_o);

    /* Init objects */
    SSO_OP_TYPE(cx_initType);
    SSO_OP_OBJECT(cx_initObject);
    SSO_OP_OBJECT_2ND(cx_initObject);

    /* Construct objects */
    SSO_OP_OBJECT_2ND(cx_defineObject);
    SSO_OP_OBJECT(cx_defineObject);
    SSO_OP_TYPE(cx_defineType);

    /* Update refcounts of public members */
    SSO_OP_TYPE(cx_updateRefType);
    SSO_OP_OBJECT(cx_updateRef);
    SSO_OP_OBJECT_2ND(cx_updateRef);

    /* Initialize conversions and operators */
    cx_convertInit();
    cx_operatorInit();

    /* Register C-binding and vm-binding */
    {
        cx_uint32 id;
        id = cx_callRegisterBinding(NULL, NULL, NULL, NULL);
        cx_assert(id == 1, "C-binding did not receive binding-id 1.");

        id = cx_callRegisterBinding(cx_call_vm, NULL, NULL, (cx_callDestructHandler)cx_callDestruct_vm);
        cx_assert(id == 2, "Vm-binding did not receive binding-id 2.");
    }

    /* Always randomize seed */
    srand (time(NULL));

    /* Init CRC table */
    cx_crcInit();

    return 0;
}