Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
b95d90b2
Commit
b95d90b2
authored
Jan 03, 2014
by
Damien George
Browse files
Merge pull request #59 from pfalcon/slice
Implement basic slice object and string slicing
parents
9ba9589e
f8b9d3c4
Changes
9
Hide whitespace changes
Inline
Side-by-side
py/mpconfig.h
View file @
b95d90b2
...
...
@@ -25,3 +25,9 @@
#ifndef MICROPY_MEM_STATS
#define MICROPY_MEM_STATS (1)
#endif
// Whether to support slice object and correspondingly
// slice subscript operators
#ifndef MICROPY_ENABLE_SLICE
#define MICROPY_ENABLE_SLICE (1)
#endif
py/obj.h
View file @
b95d90b2
...
...
@@ -144,6 +144,7 @@ mp_obj_t mp_obj_new_list(uint n, mp_obj_t *items);
mp_obj_t
mp_obj_new_list_reverse
(
uint
n
,
mp_obj_t
*
items
);
mp_obj_t
mp_obj_new_dict
(
int
n_args
);
mp_obj_t
mp_obj_new_set
(
int
n_args
,
mp_obj_t
*
items
);
mp_obj_t
mp_obj_new_slice
(
mp_obj_t
start
,
mp_obj_t
stop
,
mp_obj_t
step
);
mp_obj_t
mp_obj_new_bound_meth
(
mp_obj_t
self
,
mp_obj_t
meth
);
mp_obj_t
mp_obj_new_class
(
struct
_mp_map_t
*
class_locals
);
mp_obj_t
mp_obj_new_instance
(
mp_obj_t
clas
);
...
...
@@ -214,6 +215,10 @@ mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value);
// set
void
mp_obj_set_store
(
mp_obj_t
self_in
,
mp_obj_t
item
);
// slice
extern
const
mp_obj_type_t
slice_type
;
void
mp_obj_slice_get
(
mp_obj_t
self_in
,
machine_int_t
*
start
,
machine_int_t
*
stop
,
machine_int_t
*
step
);
// functions
typedef
struct
_mp_obj_fun_native_t
{
// need this so we can define const objects (to go in ROM)
mp_obj_base_t
base
;
...
...
py/objslice.c
0 → 100644
View file @
b95d90b2
#include
<stdlib.h>
#include
<stdint.h>
#include
<string.h>
#include
<assert.h>
#include
"nlr.h"
#include
"misc.h"
#include
"mpconfig.h"
#include
"obj.h"
#include
"runtime0.h"
#if MICROPY_ENABLE_SLICE
// TODO: This implements only variant of slice with 2 integer args only.
// CPython supports 3rd arg (step), plus args can be arbitrary Python objects.
typedef
struct
_mp_obj_slice_t
{
mp_obj_base_t
base
;
machine_int_t
start
;
machine_int_t
stop
;
}
mp_obj_slice_t
;
void
slice_print
(
void
(
*
print
)(
void
*
env
,
const
char
*
fmt
,
...),
void
*
env
,
mp_obj_t
o_in
)
{
mp_obj_slice_t
*
o
=
o_in
;
print
(
env
,
"slice("
INT_FMT
", "
INT_FMT
")"
,
o
->
start
,
o
->
stop
);
}
const
mp_obj_type_t
slice_type
=
{
{
&
mp_const_type
},
"slice"
,
slice_print
,
NULL
,
// call_n
NULL
,
// unary_op
NULL
,
// binary_op
NULL
,
// getiter
NULL
,
// iternext
{
{
NULL
,
NULL
},
},
// method list
};
// TODO: Make sure to handle "empty" values, which are signified by None in CPython
mp_obj_t
mp_obj_new_slice
(
mp_obj_t
ostart
,
mp_obj_t
ostop
,
mp_obj_t
ostep
)
{
assert
(
ostep
==
NULL
);
machine_int_t
start
=
0
,
stop
=
0
;
if
(
ostart
!=
mp_const_none
)
{
start
=
mp_obj_get_int
(
ostart
);
}
if
(
ostop
!=
mp_const_none
)
{
stop
=
mp_obj_get_int
(
ostop
);
if
(
stop
==
0
)
{
// [x:0] is a special case - in our slice object, stop = 0 means
// "end of sequence". Fortunately, [x:0] is an empty seqence for
// any x (including negative). [x:x] is also always empty sequence.
// but x also can be 0. But note that b""[x:x] is b"" for any x (i.e.
// no IndexError, at least in Python 3.3.3). So, we just use -1's to
// signify that. -1 is catchy "special" number in case someone will
// try to print [x:0] slice ever.
start
=
stop
=
-
1
;
}
}
mp_obj_slice_t
*
o
=
m_new
(
mp_obj_slice_t
,
1
);
o
->
base
.
type
=
&
slice_type
;
o
->
start
=
start
;
o
->
stop
=
stop
;
return
(
mp_obj_t
)
o
;
}
void
mp_obj_slice_get
(
mp_obj_t
self_in
,
machine_int_t
*
start
,
machine_int_t
*
stop
,
machine_int_t
*
step
)
{
assert
(
MP_OBJ_IS_TYPE
(
self_in
,
&
slice_type
));
mp_obj_slice_t
*
self
=
self_in
;
*
start
=
self
->
start
;
*
stop
=
self
->
stop
;
*
step
=
1
;
}
#endif
py/objstr.c
View file @
b95d90b2
...
...
@@ -27,9 +27,31 @@ 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!
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
// 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
))
{
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
));
#endif
}
else
{
// 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
:
case
RT_BINARY_OP_INPLACE_ADD
:
...
...
py/vm.c
View file @
b95d90b2
...
...
@@ -410,6 +410,20 @@ 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
)
{
obj2
=
POP
();
obj1
=
TOP
();
SET_TOP
(
mp_obj_new_slice
(
obj1
,
obj2
,
NULL
));
}
else
{
printf
(
"3-argument slice is not supported
\n
"
);
assert
(
0
);
}
break
;
#endif
case
MP_BC_UNPACK_SEQUENCE
:
DECODE_UINT
;
rt_unpack_sequence
(
sp
[
0
],
unum
,
sp
-
unum
+
1
);
...
...
stm/Makefile
View file @
b95d90b2
...
...
@@ -78,6 +78,7 @@ PY_O = \
objnone.o
\
objrange.o
\
objset.o
\
objslice.o
\
objstr.o
\
objtuple.o
\
objtype.o
\
...
...
tests/basics/tests/slice-bstr1.py
0 → 100644
View file @
b95d90b2
b
"123"
[
0
:
1
]
b
"123"
[
0
:
2
]
b
"123"
[:
1
]
b
"123"
[
1
:]
# Idiom for copying sequence
b
"123"
[:]
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
]
# No IndexError!
b
""
[
1
:
1
]
b
""
[
-
1
:
-
1
]
unix-cpy/Makefile
View file @
b95d90b2
...
...
@@ -43,6 +43,7 @@ PY_O = \
objnone.o
\
objrange.o
\
objset.o
\
objslice.o
\
objstr.o
\
objtuple.o
\
objtype.o
\
...
...
unix/Makefile
View file @
b95d90b2
...
...
@@ -50,6 +50,7 @@ PY_O = \
objnone.o
\
objrange.o
\
objset.o
\
objslice.o
\
objstr.o
\
objtuple.o
\
objtype.o
\
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment