Example #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;
}
Example #2
0
/* Create if statement based on ternary operator expressions */
ast_If ast_Ternary_createIf(ast_Expression condition, ast_Node ifTrue, ast_Node ifFalse) {
    ast_Block trueBlock;
    ast_Block falseBlock;
    ast_If falseIf;
    ast_If result;
    
    if (corto_instanceof(corto_type(ast_Block_o), ifTrue)) {
        trueBlock = ast_BlockCreate(yparser()->block);
        falseBlock = ast_BlockCreate(yparser()->block);
        ast_Block_addStatement(trueBlock, ast_Node(ifTrue));
        ast_Block_addStatement(falseBlock, ast_Node(ifFalse));
        ast_Parser_collect(yparser(), trueBlock);
        ast_Parser_collect(yparser(), falseBlock);
    } else {
        trueBlock = ast_Block(ifTrue);
        falseBlock = ast_Block(ifFalse);
    }
    
    falseIf = ast_IfCreate(NULL, falseBlock, NULL);
    result = ast_IfCreate(condition, trueBlock, falseIf);
    
    /* Because a ternary operator always has a true and false branch it there is not much use
     * in reporting unreachable code. If a ternary operator has a compile-time resolvable
     * condition, it is probably intended. */
    ast_If_noWarnUnreachable(result);

    ast_Parser_collect(yparser(), falseIf);
    
    return result;
}
/* ::cortex::Fast::StaticInitializer::value(Expression v) */
cx_int16 Fast_StaticInitializer_value(Fast_StaticInitializer _this, Fast_Expression v) {
/* $begin(::cortex::Fast::StaticInitializer::value) */
    cx_word offset;
    cx_uint32 variable;
    cx_uint32 fp = Fast_Initializer(_this)->fp;
    cx_type type = Fast_Initializer_currentType(Fast_Initializer(_this));
    cx_type vType = Fast_Expression_getType_type(v, type);
    
    if (!type) {
        cx_id id;
        Fast_Parser_error(yparser(), "excess elements in initializer of type '%s'", 
            Fast_Parser_id(Fast_Object(Fast_Expression(_this)->type)->value, id));
        goto error;
    }

    if (!vType) {
        goto error;
    }

    /* Validate whether expression type matches current type of initializer */
    if (vType && !cx_type_castable(type, vType)) {
        cx_id id, id2;
        Fast_Parser_error(yparser(), "type '%s' invalid here (expected '%s')", 
            Fast_Parser_id(vType, id), Fast_Parser_id(type, id2));
        goto error;
    }

    /* Validate whether value has no side-effects - which are not allowed in a static initializer */
    if (Fast_Expression_hasSideEffects(v)) {
        Fast_Parser_error(yparser(), "expressions with side-effects are not allowed in static initializers.");
        goto error;
    }

    /* Serialize value to all variables being initialized */
    for(variable=0; variable<Fast_Initializer(_this)->variableCount; variable++) {
        /* Calculate the offset for the current value */
        _this->frames[fp].ptr[variable] = Fast_Initializer_offset(_this, variable);
        offset = _this->frames[fp].ptr[variable];

        if (!offset) {
            goto error;
        }
        
        if (Fast_Expression_serialize(v, type, offset)) {
            goto error;
        }
    }

    return Fast_Initializer_next(Fast_Initializer(_this));
error:
    return -1;
/* $end */
}
Example #4
0
/* Walk embedded expressions in string */
cx_int16 Fast_String_parse(Fast_String _this) {
    cx_char *ptr, ch, *str;
    Fast_String element;

    ptr = _this->value;
    str = ptr; /* Keep track of beginning of string-element */
    
    if (ptr) {
        /* Walk string, split embedded expressions */
        while((ch = *ptr)) {
            switch(ch) {
            case '$':
                /* Insert string-element */
                if (str != ptr) {
                    *ptr = '\0';

                    element = Fast_String__create(str);
                    cx_llAppend(_this->elements, element);

                    *ptr = ch;
                }

                /* Parse embedded expression */
                str = ptr = Fast_String_parseEmbedded(_this, ptr+1);
                if (!ptr) {
                    yparser()->line = Fast_Node(_this)->line;
                    yparser()->column = Fast_Node(_this)->column;
                    Fast_Parser_error(yparser(), "parsing string '%s' failed", _this->value);
                    goto error;
                }
                break;
            default:
                ptr++;
                break;
            }
        }

        /* If string contains embedded expressions, add last bit of remaining
         * string to elements list */
        if ((str != _this->value) && *str) {
            element = Fast_String__create(str);
            cx_llAppend(_this->elements, element);
        }
    } else {
        element = Fast_String__create("null");
        cx_llAppend(_this->elements, element);
    }

    return 0;
error:
    return -1;
}
Example #5
0
/* ::cortex::Fast::String::construct() */
cx_int16 Fast_String_construct(Fast_String _this) {
/* $begin(::cortex::Fast::String::construct) */
    
    if (!yparser()->block || !yparser()->scope) {
        goto error;
    }

    _this->block = yparser()->block; cx_keep_ext(_this, _this->block, "_this->block (keep block for string-expression)");
    _this->scope = yparser()->scope; cx_keep_ext(_this, _this->scope, "_this->scope (keep scope for string-expression)");
    
    return 0;
error:
    return -1;
/* $end */
}
Example #6
0
/* ::cortex::Fast::Expression::fromList(list{Expression} list) */
Fast_Expression Fast_Expression_fromList(Fast_Expression_list list) {
/* $begin(::cortex::Fast::Expression::fromList) */
    Fast_Expression result = NULL;

    /* Convert list to comma expression */
    if (list) {
        if (cx_llSize(list) == 1) {
            result = cx_llGet(list, 0);
        } else {
            cx_ll toList = cx_llNew(); /* Copy list */
            cx_iter iter;
            Fast_Expression expr;
            
            result = Fast_Expression(Fast_Comma__create());

            iter = cx_llIter(list);
            while(cx_iterHasNext(&iter)) {
                expr = cx_iterNext(&iter);
                cx_llAppend(toList, expr); cx_keep_ext(result, expr, "add expression from list to comma-expression");
            }
            Fast_Comma(result)->expressions = toList;
            Fast_Parser_collect(yparser(), result);
        }
    }
    
    return result;
/* $end */
}
Example #7
0
/* ::cortex::Fast::String::serialize(type dstType,word dst) */
cx_int16 Fast_String_serialize(Fast_String _this, cx_type dstType, cx_word dst) {
/* $begin(::cortex::Fast::String::serialize) */
    Fast_valueKind kind;

    kind = Fast_valueKindFromType(dstType);

    switch(kind) {
    case Fast_Bool:
    case Fast_Int:
    case Fast_SignedInt:
    case Fast_Text:
        cx_convert(cx_primitive(cx_string_o), &_this->value, cx_primitive(dstType), (void*)dst);
        break;
    case Fast_Ref: {
        cx_object o = cx_resolve_ext(NULL, NULL, _this->value, FALSE, "Serialize reference from string");
        cx_set_ext(NULL, &dst, o, "serialize string to reference");
        break;
    }
    default: {
        cx_id id;
        Fast_Parser_error(yparser(), "cannot serialize string value to storage of type '%s'", Fast_Parser_id(dstType, id));
        goto error;
        break;
    }
    }

    return 0;
error:
    return -1;
/* $end */
}
Example #8
0
/* Create a call-expression */
Fast_Call Fast_createCallWithArguments(Fast_Expression instance, cx_string function, Fast_Expression arguments) {
    Fast_Call result;
    Fast_CallBuilder builder;

    /* Initialize builder */
    Fast_CallBuilder__init(&builder, 
        function, 
        arguments, 
        instance, 
        yparser()->scope, 
        yparser()->block);
    result = Fast_CallBuilder_build(&builder);
    Fast_CallBuilder__deinit(&builder);

    return result;
}
Example #9
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;  
}
Example #10
0
/* ::cortex::Fast::SignedInteger::serialize(type dstType,word dst) */
cx_int16 Fast_SignedInteger_serialize(Fast_SignedInteger _this, cx_type dstType, cx_word dst) {
/* $begin(::cortex::Fast::SignedInteger::serialize) */
    Fast_valueKind kind;

    kind = Fast_valueKindFromType(dstType);
    
    memset((void*)dst, 0, cx_type_sizeof(dstType));

    switch(kind) {
    case Fast_Bool:
        *(cx_bool*)dst = _this->value ? TRUE : FALSE;
        break;
    case Fast_Int:
    case Fast_SignedInt:
    case Fast_Enum:
    case Fast_Text:
        cx_convert(cx_primitive(cx_int64_o), &_this->value, cx_primitive(dstType), (void*)dst);
        break;
    default: {
        cx_id id;
        Fast_Parser_error(yparser(), "cannot serialize signed integer value to storage of type '%s'", Fast_Parser_id(dstType, id));
        goto error;
        break;
    }
    }

    return 0;
error:
    return -1;
/* $end */
}
Example #11
0
Fast_Call Fast_createCallFromExpr(Fast_Expression f, Fast_Expression arguments) {
    Fast_Call result = NULL;
    Fast_Expression instance = NULL;
    cx_id name;
    cx_object scope = yparser()->scope;
    Fast_CallBuilder builder;

    if (Fast_Node(f)->kind == Fast_StorageExpr) {
        switch(Fast_Storage(f)->kind) {

        case Fast_ObjectStorage: {
            cx_object o = Fast_Object(f)->value;
            cx_signatureName(cx_nameof(o), name);
            scope = cx_parentof(o);
            break;
        }

        case Fast_LocalStorage:
            strcpy(name, Fast_Local(f)->name);
            break;

        case Fast_MemberStorage:
            instance = Fast_Member(f)->lvalue;
            strcpy(name, Fast_String(Fast_Member(f)->rvalue)->value);
            break;

        case Fast_ElementStorage:
            result = Fast_Call(Fast_DelegateCall__create(NULL, arguments, f));
            break;

        default:
            Fast_Parser_error(yparser(), "'%s' expression is not callable",
                cx_nameof(cx_enum_constant(Fast_storageKind_o, Fast_Storage(f)->kind)));
            goto error;
        }
    }

    if (!result) {
        Fast_CallBuilder__init(&builder, name, arguments, instance, scope, yparser()->block);
        result = Fast_CallBuilder_build(&builder);
        Fast_CallBuilder__deinit(&builder);
    }

    return result;
error:
    return NULL;
}
Example #12
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 */
}
Example #13
0
/* ::cortex::Fast::Member::construct() */
cx_int16 Fast_Member_construct(Fast_Member _this) {
/* $begin(::cortex::Fast::Member::construct) */

    Fast_Storage(_this)->kind = Fast_MemberStorage;
    
    if (!(_this->lvalue && _this->rvalue)) {
        goto error;
    }

    /* If member-_this can be determined at compile-time, resolve it */
    if (_this->lvalue->type) { /* Type must be a known _this at compile-time */
        if (Fast_Node(_this->rvalue)->kind == Fast_LiteralExpr) { /* Member-expression must be a literal */
            switch(Fast_Literal(_this->rvalue)->kind) {
            case Fast_Int: /* Resolve the nth member of a type */
                Fast_Parser_error(yparser(), "resolving members by index not yet supported");
                goto error;
                break;
            case Fast_Text: /* Resolve member by name */
                /* Validate that string does not exceed 512 characters */
                if (strlen(Fast_String(_this->rvalue)->value) >= 512) {
                    Fast_Parser_error(yparser(), "identifiers longer than 511 characters are not supported");
                    goto error;
                }

                if (Fast_Member_resolveMember(_this, _this->lvalue->type, Fast_String(_this->rvalue)->value)) {
                    goto error;
                }
                break;
            default:
                Fast_Parser_error(yparser(), "invalid member expression");
                goto error;
                break;
            }
        }
    }

    Fast_Expression(_this)->isReference = Fast_Expression(_this)->type->reference;

    return Fast_Storage_construct(Fast_Storage(_this));
error:
    return -1;
/* $end */
}
Example #14
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 */
}
/* ::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 */
}
Example #16
0
/* ::cortex::Fast::DelegateCall::construct() */
cx_int16 Fast_DelegateCall_construct(Fast_DelegateCall _this) {
/* $begin(::cortex::Fast::DelegateCall::construct) */
    if (!_this->expr) {
        Fast_Parser_error(yparser(), "no expression provided for delegate call");
        goto error;
    } else {
        cx_uint32 i;
        cx_delegate type = cx_delegate(Fast_Expression_getType(_this->expr));

        /* Create expression to obtain pointer to the instance */
        Fast_String instanceString = Fast_String__create("instance");
        Fast_Member iExpr = Fast_Member__create(_this->expr, Fast_Expression(instanceString));
        cx_set(&Fast_Call(_this)->instanceExpr, iExpr);
        Fast_Parser_collect(yparser(), iExpr);
        Fast_Parser_collect(yparser(), instanceString);

        /* Set function expression to delegate */
        cx_set(&Fast_Call(_this)->functionExpr, _this->expr);

        /* Set parameters */
        cx_set(&Fast_Call(_this)->returnType, type->returnType);
        Fast_Call(_this)->returnsReference = type->returnsReference;

        cx_parameter_seq__size(&Fast_Call(_this)->parameters, type->parameters.length);

        for (i = 0; i < type->parameters.length; i++) {
            cx_set(&Fast_Call(_this)->parameters.buffer[i].type, type->parameters.buffer[i].type);
            Fast_Call(_this)->parameters.buffer[i].passByReference = type->parameters.buffer[i].passByReference;
        }
    }

    return Fast_Call_construct(Fast_Call(_this));
error:
    return -1;
/* $end */
}
/* ::cortex::Fast::StaticInitializer::construct() */
cx_int16 Fast_StaticInitializer_construct(Fast_StaticInitializer _this) {
/* $begin(::cortex::Fast::StaticInitializer::construct) */
    cx_int8 variable;
    
    /* Copy offsets of variables into frames */
    for(variable=0; variable<Fast_Initializer(_this)->variableCount; variable++) {
         _this->frames[0].ptr[variable] =
                (cx_word)Fast_Object(Fast_Initializer(_this)->variables[variable].object)->value;
        if (!_this->frames[0].ptr[variable]) {
            Fast_Parser_error(yparser(), "non-static variable in static initializer");
            goto error;
        }
    }
    
    return Fast_Initializer_construct(Fast_Initializer(_this));
error:
    return -1;
/* $end */
}
Example #18
0
/* Create a call-expression */
Fast_Call Fast_createCall(Fast_Expression instance, cx_string function, cx_uint32 numArgs, ...) {
    Fast_Expression args = NULL, arg = NULL;
    va_list arglist;
    cx_uint32 i;
    
    /* Create comma-expression if there is more than one argument */
    va_start(arglist, numArgs);
    if (numArgs > 1) {
        args = Fast_Expression(Fast_Comma__create());
        for(i=0; i<numArgs; i++) {
            arg = va_arg(arglist, Fast_Expression);
            Fast_Comma_addExpression(Fast_Comma(args), arg);
        }
    } else if (numArgs) {
        args = va_arg(arglist, Fast_Expression);
    }
    va_end(arglist);

    if (args) {
        Fast_Parser_collect(yparser(), args);
    }

    return Fast_createCallWithArguments(instance, function, args);
}
Example #19
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 */
}
Example #20
0

/* $end */

corto_int16 _ast_Ternary_construct(
    ast_Ternary this)
{
/* $begin(corto/ast/Ternary/construct) */
    ast_Node trueBranch=NULL, falseBranch=NULL;
    ast_Expression trueExpr, falseExpr;
    corto_type resultType = ast_Expression_getType(this->result);

    ast_Node(this)->kind = Ast_TernaryExpr;
    
    /* Create true statement */
    trueBranch = ast_Node(ast_Parser_blockPush(yparser(), FALSE));
    trueExpr = ast_Expression(ast_Parser_binaryExpr(yparser(), this->result, this->ifTrue, CORTO_ASSIGN));
    ast_Block_addStatement(ast_Block(trueBranch), ast_Node(trueExpr));
    ast_Parser_blockPop(yparser());
    
    /* Create false statement */
    falseBranch = ast_Node(ast_Parser_blockPush(yparser(), FALSE));
    falseExpr = ast_Expression(ast_Parser_binaryExpr(yparser(), this->result, this->ifFalse, CORTO_ASSIGN));
    ast_Block_addStatement(ast_Block(falseBranch), ast_Node(falseExpr));
    ast_Parser_blockPop(yparser());

    /* Store both expressions in this */
    corto_setref(&this->ifTrueExpr, trueExpr);
    corto_setref(&this->ifFalseExpr, falseExpr);
    
    /* Create condition */
Example #21
0
/* Parse embedded expression */
cx_char *Fast_String_parseEmbedded(Fast_String _this, cx_char *expr) {
    cx_char ch, *ptr;
    cx_uint32 nesting;
    Fast_Expression element;
    cx_bool bracketExpr = FALSE;

    if (!maskSet) {
        cx_tokenMaskSet(alphaMask, ":abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_");
        cx_tokenMaskSet(numericMask, "0123456789");
    }

    ptr = expr;
    if (*ptr == '{') {
        bracketExpr = TRUE;
        expr = ++ptr; /* Progress expression as well to skip the initial '{' */
        nesting = 1;
        while((ch = *ptr) && nesting) {
            switch(ch) {
            case '{':
                nesting++;
                break;
            case '}':
                nesting--;
                break;
            }
            ptr++;
        }
        ptr--; /* Skip the last '{' */
    } else {
        /* If character is not a '{' parse a variable-name which is
         * delimited by a non-alphanumeric character. Additionally
         * variable names cannot start with a number. */
        if (!alphaMask[(int)*ptr]) {
            yparser()->line = Fast_Node(_this)->line;
            yparser()->column = Fast_Node(_this)->column;
            Fast_Parser_error(yparser(), "invalid embedded expression at '%s'", expr);
            goto error;
        }
        ptr++;
        while((ch = *ptr) && (alphaMask[(int)ch] || numericMask[(int)ch])) {
            if (ch == ':') {
                ptr++;
                if (*ptr != ':') {
                    ptr--;
                    break;
                }
            }
            ptr++;
        }
    }

    ch = *ptr;
    *ptr = '\0';

    element = Fast_Parser_parseExpression(yparser(), expr, _this->block, _this->scope, Fast_Node(_this)->line, Fast_Node(_this)->column);
    if (element) {
        cx_llAppend(_this->elements, element);
        cx_keep(element);
    } else {
        goto error;
    }

    *ptr = ch;
    if (bracketExpr) {
        ptr++;
    }

    return ptr;
error:
    return NULL;
}
Example #22
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 */
}
 * Only code written between the begin and end tags will be preserved
 * when the file is regenerated.
 */

#include <corto/ast/ast.h>

/* $header() */
#include "ast__private.h"
/* $end */

corto_int16 _ast_DelegateCall_construct(
    ast_DelegateCall this)
{
/* $begin(corto/ast/DelegateCall/construct) */
    if (!this->expr) {
        ast_Parser_error(yparser(), "no expression provided for delegate call");
        goto error;
    } else {
        corto_uint32 i;
        corto_delegate type = corto_delegate(ast_Expression_getType(this->expr));

        /* Create expression to obtain pointer to the instance */
        ast_String instanceString = ast_StringCreate("instance");
        ast_Member iExpr = ast_MemberCreate(this->expr, ast_Expression(instanceString));
        corto_setref(&ast_Call(this)->instanceExpr, iExpr);
        ast_Parser_collect(yparser(), iExpr);
        ast_Parser_collect(yparser(), instanceString);

        /* Set function expression to delegate */
        corto_setref(&ast_Call(this)->functionExpr, this->expr);
cx_word Fast_Initializer_offset(Fast_StaticInitializer _this, cx_uint32 variable) {
    cx_word result, base;
    cx_uint16 fp = Fast_Initializer(_this)->fp;
    Fast_InitializerFrame *frame = &Fast_Initializer(_this)->frames[fp?fp-1:0];
    Fast_StaticInitializerFrame *baseFrame = &(_this->frames[fp?fp-1:0]);
    Fast_InitializerFrame *thisFrame = &Fast_Initializer(_this)->frames[fp];
    result = 0;

    base = baseFrame->ptr[variable];
    if (!base) {
        Fast_Parser_error(yparser(), "parser error: base is zero in offset calculation");
        goto error;
    }

    /* Switch on current type */
    switch(frame->type->kind) {
    case CX_PRIMITIVE:
        result = base;
        break;
    case CX_COMPOSITE:
        if (fp) {
            result = base + thisFrame->member->offset;
        } else {
            result = base;
        }
        break;
    case CX_ITERATOR:
        result = base;
        break;
    case CX_COLLECTION: {
        if (fp) {
            cx_uint32 elementSize = cx_type_sizeof(cx_collection(frame->type)->elementType);
            switch(cx_collection(frame->type)->kind) {
            case CX_SEQUENCE:
                ((cx_objectSeq*)base)->length++;
                ((cx_objectSeq*)base)->buffer = cx_realloc(((cx_objectSeq*)base)->buffer, ((cx_objectSeq*)base)->length * elementSize);
                base = (cx_word)((cx_objectSeq*)base)->buffer;
            case CX_ARRAY:
                result = base + thisFrame->location * cx_type_sizeof(cx_collection(frame->type)->elementType);
                memset((void*)result, 0, elementSize);
                break;
            case CX_LIST: {
                if (cx_collection_elementRequiresAlloc(cx_collection(frame->type))) {
                    result = (cx_word)cx_calloc(elementSize);
                }
                if (!*(cx_ll*)base) {
                    *(cx_ll*)base = cx_llNew();
                }
                cx_llAppend(*(cx_ll*)base, (void*)result);
                if (!result) {
                    result = (cx_word)cx_llGetPtr(*(cx_ll*)base, cx_llSize(*(cx_ll*)base)-1);
                }
                break;
            }
            case CX_MAP: {
                cx_type keyType = cx_map(frame->type)->keyType;
                if (!thisFrame->isKey) {
                    if (cx_collection_elementRequiresAlloc(cx_collection(frame->type))) {
                        result = (cx_word)cx_calloc(elementSize);
                    }
                    if (!*(cx_rbtree*)base) {
                        *(cx_rbtree*)base = cx_rbtreeNew(frame->type);
                    }
                    cx_rbtreeSet(*(cx_rbtree*)base, (void*)_this->frames[fp].keyPtr[variable], (void*)result);
                    if (!result) {
                        if (_this->frames[fp].keyPtr[variable]) {
                            result = (cx_word)cx_rbtreeGetPtr(*(cx_rbtree*)base, (void*)_this->frames[fp].keyPtr[variable]);
                        } else {
                            Fast_Parser_error(yparser(), "cannot set element without keyvalue");
                            goto error;
                        }
                    }
                } else {
                    result = (cx_word)cx_calloc(cx_type_sizeof(keyType));
                    _this->frames[fp].keyPtr[variable] = result;
                    thisFrame->isKey = FALSE;
                }
                break;
            }
            }
        } else {
            result = base;
        }
        break;
    }
    default: {
        cx_id id;
        Fast_Parser_error(yparser(), "invalid initializer type '%s'", Fast_Parser_id(frame->type, id));
        break;
    }
    }

    return result;
error:
    return 0;
}