Exemplo n.º 1
0
//
//  Val_Init_Series_Index_Core: C
// 
// Common function.
//
void Val_Init_Series_Index_Core(
    REBVAL *value,
    enum Reb_Kind type,
    REBSER *series,
    REBCNT index
) {
    assert(series);
    ENSURE_SERIES_MANAGED(series);

    if (type != REB_IMAGE && type != REB_VECTOR) {
        // Code in various places seemed to have different opinions of
        // whether a BINARY needed to be zero terminated.  It doesn't
        // make a lot of sense to zero terminate a binary unless it
        // simplifies the code assumptions somehow--it's in the class
        // "ANY_BINSTR()" so that suggests perhaps it has a bit more
        // obligation to conform.  Also, the original Make_Binary comment
        // from the open source release read:
        //
        //     Make a binary string series. For byte, C, and UTF8 strings.
        //     Add 1 extra for terminator.
        //
        // Until that is consciously overturned, check the REB_BINARY too

        ASSERT_SERIES_TERM(series); // doesn't apply to image/vector
    }

    VAL_RESET_HEADER(value, type);
    INIT_VAL_SERIES(value, series);
    VAL_INDEX(value) = index;
}
Exemplo n.º 2
0
//
//  Make_Vector_Spec: C
// 
// Make a vector from a block spec.
// 
//    make vector! [integer! 32 100]
//    make vector! [decimal! 64 100]
//    make vector! [unsigned integer! 32]
//    Fields:
//         signed:     signed, unsigned
//           datatypes:  integer, decimal
//           dimensions: 1 - N
//           bitsize:    1, 8, 16, 32, 64
//           size:       integer units
//           init:        block of values
//
REBVAL *Make_Vector_Spec(RELVAL *bp, REBCTX *specifier, REBVAL *value)
{
    REBINT type = -1; // 0 = int,    1 = float
    REBINT sign = -1; // 0 = signed, 1 = unsigned
    REBINT dims = 1;
    REBINT bits = 32;
    REBCNT size = 1;
    REBSER *vect;
    REBVAL *iblk = 0;

    // UNSIGNED
    if (IS_WORD(bp) && VAL_WORD_SYM(bp) == SYM_UNSIGNED) {
        sign = 1;
        bp++;
    }

    // INTEGER! or DECIMAL!
    if (IS_WORD(bp)) {
        if (SAME_SYM_NONZERO(VAL_WORD_SYM(bp), SYM_FROM_KIND(REB_INTEGER)))
            type = 0;
        else if (
            SAME_SYM_NONZERO(VAL_WORD_SYM(bp), SYM_FROM_KIND(REB_DECIMAL))
        ){
            type = 1;
            if (sign > 0) return 0;
        }
        else return 0;
        bp++;
    }

    if (type < 0) type = 0;
    if (sign < 0) sign = 0;

    // BITS
    if (IS_INTEGER(bp)) {
        bits = Int32(KNOWN(bp));
        if (
            (bits == 32 || bits == 64)
            ||
            (type == 0 && (bits == 8 || bits == 16))
        ) bp++;
        else return 0;
    } else return 0;

    // SIZE
    if (NOT_END(bp) && IS_INTEGER(bp)) {
        if (Int32(KNOWN(bp)) < 0) return 0;
        size = Int32(KNOWN(bp));
        bp++;
    }

    // Initial data:
    if (NOT_END(bp) && (IS_BLOCK(bp) || IS_BINARY(bp))) {
        REBCNT len = VAL_LEN_AT(bp);
        if (IS_BINARY(bp) && type == 1) return 0;
        if (len > size) size = len;
        iblk = KNOWN(bp);
        bp++;
    }

    VAL_RESET_HEADER(value, REB_VECTOR);

    // Index offset:
    if (NOT_END(bp) && IS_INTEGER(bp)) {
        VAL_INDEX(value) = (Int32s(KNOWN(bp), 1) - 1);
        bp++;
    }
    else VAL_INDEX(value) = 0;

    if (NOT_END(bp)) return 0;

    vect = Make_Vector(type, sign, dims, bits, size);
    if (!vect) return 0;

    if (iblk) Set_Vector_Row(vect, iblk);

    INIT_VAL_SERIES(value, vect);
    MANAGE_SERIES(vect);

    // index set earlier

    return value;
}