Beispiel #1
0
Object obj_add(Object a, Object b) {
    if (TM_TYPE(a) == TM_TYPE(b)) {
        switch (TM_TYPE(a)) {
        case TYPE_NUM:
            GET_NUM(a) += GET_NUM(b);
            return a;
        case TYPE_STR: {
            char* sa = GET_STR(a);
            char* sb = GET_STR(b);
            int la = GET_STR_LEN(a);
            int lb = GET_STR_LEN(b);
            if (la == 0) {return b;    }
            if (lb == 0) {return a;    }
            int len = la + lb;
            Object des = string_alloc(NULL, len);
            char*s = GET_STR(des);
            memcpy(s, sa, la);
            memcpy(s + la, sb, lb);
            return des;
        }
        case TYPE_LIST: {
            return list_add(GET_LIST(a), GET_LIST(b));
        }
        }
    }
    tm_raise("obj_add: can not add %o and %o", (a), (b));
    return NONE_OBJECT;
}
Beispiel #2
0
Object obj_mul(Object a, Object b) {
    if (a.type == b.type && a.type == TYPE_NUM) {
        GET_NUM(a) *= GET_NUM(b);
        return a;
    }
    if (a.type == TYPE_NUM && b.type == TYPE_STR) {
        Object temp = a;
        a = b;
        b = temp;
    }
    if (a.type == TYPE_STR && b.type == TYPE_NUM) {
        int len = GET_STR_LEN(a);
        Object des;
        if (len == 0)
            return a;
        int times = (int) GET_NUM(b);
        if (times <= 0)
            return sz_to_string("");
        if (times == 1)
            return a;
        des = string_alloc(NULL, len * times);
        char* s = GET_STR(des);
        int i;
        for (i = 0; i < times; i++) {
            strncpy(s, GET_STR(a), len);
            s += len;
        }
        return des;
    }
    tm_raise("obj_mul: can not multiply %o and %o", a, b);
    return NONE_OBJECT;
}
Beispiel #3
0
Object obj_get(Object self, Object k) {
    Object v;
    switch (TM_TYPE(self)) {
    case TYPE_STR: {
        DictNode* node;
        if (TM_TYPE(k) == TYPE_NUM) {
            double d = GET_NUM(k);
            int n = d;
            if (n < 0) {
                n += GET_STR_LEN(self);
            }
            if (n >= GET_STR_LEN(self) || n < 0)
                tm_raise("String_get: index overflow ,len=%d,index=%d, str=%o",
                        GET_STR_LEN(self), n, self);
            return string_chr(0xff & GET_STR(self)[n]);
        } else if ((node = dict_get_node(GET_DICT(tm->str_proto), k)) != NULL) {
            return method_new(node->val, self);
        }
        break;
    }
    case TYPE_LIST:{
        DictNode* node;
        if (TM_TYPE(k) == TYPE_NUM) {
            return list_get(GET_LIST(self), GET_NUM(k));
        } else if ((node = dict_get_node(GET_DICT(tm->list_proto), k))!=NULL) {
            return method_new(node->val, self);
        }
        break;
    }
    case TYPE_DICT:{
        DictNode* node;
        node = dict_get_node(GET_DICT(self), k);
        if (node != NULL) {
            return node->val;
        } else if ((node = dict_get_node(GET_DICT(tm->dict_proto), k))!=NULL) {
            return method_new(node->val, self);
        }
        break;
    }
    case TYPE_FUNCTION:
        return get_func_attr(GET_FUNCTION(self), k);
    case TYPE_DATA:
        return GET_DATA(self)->get(GET_DATA(self), k);
    }
    tm_raise("keyError %o", k);
    return NONE_OBJECT;
}
Beispiel #4
0
uint mp_obj_str_get_len(mp_obj_t self_in) {
    if (MP_OBJ_IS_STR(self_in)) {
        GET_STR_LEN(self_in, l);
        return l;
    } else {
        nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly",
                 mp_obj_get_type_str(self_in)));
    }
}
Beispiel #5
0
mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
    assert(MP_OBJ_IS_STR(self_in));

    // get separation string
    GET_STR_DATA_LEN(self_in, sep_str, sep_len);

    // process args
    uint seq_len;
    mp_obj_t *seq_items;
    if (MP_OBJ_IS_TYPE(arg, &tuple_type)) {
        mp_obj_tuple_get(arg, &seq_len, &seq_items);
    } else if (MP_OBJ_IS_TYPE(arg, &list_type)) {
        mp_obj_list_get(arg, &seq_len, &seq_items);
    } else {
        goto bad_arg;
    }

    // count required length
    int required_len = 0;
    for (int i = 0; i < seq_len; i++) {
        if (!MP_OBJ_IS_STR(seq_items[i])) {
            goto bad_arg;
        }
        if (i > 0) {
            required_len += sep_len;
        }
        GET_STR_LEN(seq_items[i], l);
        required_len += l;
    }

    // make joined string
    byte *data;
    mp_obj_t joined_str = mp_obj_str_builder_start(required_len, &data);
    for (int i = 0; i < seq_len; i++) {
        if (i > 0) {
            memcpy(data, sep_str, sep_len);
            data += sep_len;
        }
        GET_STR_DATA_LEN(seq_items[i], s, l);
        memcpy(data, s, l);
        data += l;
    }

    // return joined string
    return mp_obj_str_builder_end(joined_str);

bad_arg:
    nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "?str.join expecting a list of str's"));
}
Beispiel #6
0
int tm_len(Object o) {
    int len = -1;
    switch (TM_TYPE(o)) {
    case TYPE_STR:
        len = GET_STR_LEN(o);
    case TYPE_LIST:
        len = LIST_LEN(o);
    case TYPE_DICT:
        len = DICT_LEN(o);
    }
    if (len < 0) {
        tm_raise("tm_len: %o has no attribute len", o);
    }
    return len;
}
Beispiel #7
0
int is_true_obj(Object v) {
    switch (TM_TYPE(v)) {
    case TYPE_NUM:
        return GET_NUM(v) != 0;
    case TYPE_NONE:
        return 0;
    case TYPE_STR:
        return GET_STR_LEN(v) > 0;
    case TYPE_LIST:
        return LIST_LEN(v) > 0;
    case TYPE_DICT:
        return DICT_LEN(v) > 0;
    case TYPE_FUNCTION:
    case TYPE_DATA:
        return 1;
    }
    return 0;
}
Beispiel #8
0
// may return MP_OBJ_NULL
mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
    if (
#if !MICROPY_PY_BUILTINS_STR_UNICODE
        // It's simple - unicode is slow, non-unicode is fast
        MP_OBJ_IS_STR(o_in) ||
#endif
        MP_OBJ_IS_TYPE(o_in, &mp_type_bytes)) {
        GET_STR_LEN(o_in, l);
        return MP_OBJ_NEW_SMALL_INT(l);
    } else {
        mp_obj_type_t *type = mp_obj_get_type(o_in);
        if (type->unary_op != NULL) {
            return type->unary_op(MP_UNARY_OP_LEN, o_in);
        } else {
            return MP_OBJ_NULL;
        }
    }
}
Beispiel #9
0
/**
 * slice string/list
 * string.slice(a,b) [a,b), b is not included
 * string.slice(0,-1) = string.slice(0,len(string))
 * @since 2016-11-19
 * <code>
 * 'test'.slice(0,1) = 't'
 * 'test'.slice(0,-1) = 'test'
 * </code>
 */
Object obj_slice(Object self, Object first, Object second) {
    int start = GET_NUM(first);
    int end = GET_NUM(second);
    Object ret = NONE_OBJECT;
    
    if (IS_STR(self)) {
        int length = GET_STR_LEN(self);
        start = start >= 0 ? start : start + length + 1;
        end   = end   >= 0 ? end   : end   + length + 1;
        if (start < 0 || start > length) {
            start = 0;
        } 
        if (end < 0 || end > length) {
            end = length; // do not overflow;
        } 
        if (end <= start) {
            return string_alloc("", 0);
        }
        return string_alloc(GET_STR(self) + start, end - start);
    } else if (IS_LIST(self)) {
        int length = LIST_LEN(self);
        start = start > 0 ? start : start + length + 1;
        end   = end   > 0 ? end   : end   + length + 1;
        if (start < 0 || start > length) {
            start = 0;
        } 
        if (end < 0 || end > length) {
            end = length;
        } 
        int i = 0;
        ret = list_new(end - start);
        for (i = start; i < end ; i++) {
            obj_append(ret, LIST_GET(self, i));
        }
    } else {
        tm_raise("slice not implemented for type %s", tm_type(self.type));
    }
    return ret;
}