From 31ba60f8364a4009ddc3d45fee90c84b43d88d2c Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 3 Jan 2014 02:51:16 +0200 Subject: str: Initial implementation of string slicing. Only step=1 and non-negative indexes are supported so far. --- py/objstr.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'py/objstr.c') diff --git a/py/objstr.c b/py/objstr.c index 48abf4951d..46adabcec9 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -29,7 +29,21 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { case RT_BINARY_OP_SUBSCR: // string access // XXX a massive hack! - return mp_obj_new_int(lhs_str[mp_obj_get_int(rhs_in)]); + + // TODO: need predicate to check for int-like type (bools are such for example) + // ["no", "yes"][1 == 2] is common idiom + if (MP_OBJ_IS_SMALL_INT(rhs_in)) { + // TODO: This implements byte string access for single index so far + return mp_obj_new_int(lhs_str[mp_obj_get_int(rhs_in)]); + } else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) { + int start, stop, step; + mp_obj_slice_get(rhs_in, &start, &stop, &step); + assert(step == 1); + return mp_obj_new_str(qstr_from_strn_copy(lhs_str + start, stop - start)); + } else { + // Throw TypeError here + assert(0); + } case RT_BINARY_OP_ADD: case RT_BINARY_OP_INPLACE_ADD: -- cgit v1.2.3 From decad08ef57aa3cf3960ce65e29b194cb97c6d22 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 3 Jan 2014 23:36:56 +0200 Subject: str: Handle non-positive slice indexes. --- py/objstr.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'py/objstr.c') diff --git a/py/objstr.c b/py/objstr.c index 46adabcec9..54dd087a45 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -39,6 +39,13 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { int start, stop, step; mp_obj_slice_get(rhs_in, &start, &stop, &step); assert(step == 1); + int len = strlen(lhs_str); + if (start < 0) { + start = len + start; + } + if (stop <= 0) { + stop = len + stop; + } return mp_obj_new_str(qstr_from_strn_copy(lhs_str + start, stop - start)); } else { // Throw TypeError here -- cgit v1.2.3 From e606cb656165aff2424fb6ca45f09d606246d073 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 4 Jan 2014 01:34:23 +0200 Subject: slice: Allow building with MICROPY_ENABLE_SLICE=0. --- py/objstr.c | 2 ++ py/vm.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'py/objstr.c') diff --git a/py/objstr.c b/py/objstr.c index 54dd087a45..8e3e9d9025 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -35,6 +35,7 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { if (MP_OBJ_IS_SMALL_INT(rhs_in)) { // TODO: This implements byte string access for single index so far return mp_obj_new_int(lhs_str[mp_obj_get_int(rhs_in)]); +#if MICROPY_ENABLE_SLICE } else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) { int start, stop, step; mp_obj_slice_get(rhs_in, &start, &stop, &step); @@ -47,6 +48,7 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { stop = len + stop; } return mp_obj_new_str(qstr_from_strn_copy(lhs_str + start, stop - start)); +#endif } else { // Throw TypeError here assert(0); diff --git a/py/vm.c b/py/vm.c index 35dcbea523..382780640b 100644 --- a/py/vm.c +++ b/py/vm.c @@ -410,6 +410,7 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t ** sp++; break; +#if MICROPY_ENABLE_SLICE case MP_BC_BUILD_SLICE: DECODE_UINT; if (unum == 2) { @@ -421,6 +422,7 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t ** assert(0); } break; +#endif case MP_BC_UNPACK_SEQUENCE: DECODE_UINT; -- cgit v1.2.3 From f8b9d3c41addea79851c355f014db9f0f256cdaf Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 4 Jan 2014 01:38:26 +0200 Subject: str: Throw TypeError for invalid index type and clean up comments. --- py/objstr.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'py/objstr.c') diff --git a/py/objstr.c b/py/objstr.c index 8e3e9d9025..6a0721d45f 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -27,13 +27,11 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { const char *lhs_str = qstr_str(lhs->qstr); switch (op) { case RT_BINARY_OP_SUBSCR: - // string access - // XXX a massive hack! - // TODO: need predicate to check for int-like type (bools are such for example) // ["no", "yes"][1 == 2] is common idiom if (MP_OBJ_IS_SMALL_INT(rhs_in)) { // TODO: This implements byte string access for single index so far + // TODO: Handle negative indexes. return mp_obj_new_int(lhs_str[mp_obj_get_int(rhs_in)]); #if MICROPY_ENABLE_SLICE } else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) { @@ -50,8 +48,9 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { return mp_obj_new_str(qstr_from_strn_copy(lhs_str + start, stop - start)); #endif } else { - // Throw TypeError here - assert(0); + // Message doesn't match CPython, but we don't have so much bytes as they + // to spend them on verbose wording + nlr_jump(mp_obj_new_exception_msg(rt_q_TypeError, "index must be int")); } case RT_BINARY_OP_ADD: -- cgit v1.2.3 From c8d1384fc0c7aafa5dee3445ece20f4e43dfa9c1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 4 Jan 2014 01:06:10 +0000 Subject: Fix int -> machine_int_t; add print to slice test. --- py/objstr.c | 2 +- tests/basics/tests/slice-bstr1.py | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'py/objstr.c') diff --git a/py/objstr.c b/py/objstr.c index 6a0721d45f..59547e3cd6 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -35,7 +35,7 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { return mp_obj_new_int(lhs_str[mp_obj_get_int(rhs_in)]); #if MICROPY_ENABLE_SLICE } else if (MP_OBJ_IS_TYPE(rhs_in, &slice_type)) { - int start, stop, step; + machine_int_t start, stop, step; mp_obj_slice_get(rhs_in, &start, &stop, &step); assert(step == 1); int len = strlen(lhs_str); diff --git a/tests/basics/tests/slice-bstr1.py b/tests/basics/tests/slice-bstr1.py index 8b492b35cc..0bed959141 100644 --- a/tests/basics/tests/slice-bstr1.py +++ b/tests/basics/tests/slice-bstr1.py @@ -1,27 +1,27 @@ -b"123"[0:1] +print(b"123"[0:1]) -b"123"[0:2] +print(b"123"[0:2]) -b"123"[:1] +print(b"123"[:1]) -b"123"[1:] +print(b"123"[1:]) # Idiom for copying sequence -b"123"[:] +print(b"123"[:]) -b"123"[:-1] +print(b"123"[:-1]) # Weird cases -b"123"[0:0] -b"123"[1:0] -b"123"[1:1] -b"123"[-1:-1] -b"123"[-3:] -b"123"[-3:3] -b"123"[0:] -b"123"[:0] -b"123"[:-3] -b"123"[:-4] +print(b"123"[0:0]) +print(b"123"[1:0]) +print(b"123"[1:1]) +print(b"123"[-1:-1]) +print(b"123"[-3:]) +print(b"123"[-3:3]) +print(b"123"[0:]) +print(b"123"[:0]) +print(b"123"[:-3]) +print(b"123"[:-4]) # No IndexError! -b""[1:1] -b""[-1:-1] +print(b""[1:1]) +print(b""[-1:-1]) -- cgit v1.2.3