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
b25711ea
Commit
b25711ea
authored
Jan 30, 2014
by
Damien George
Browse files
Merge pull request #238 from pfalcon/bool_len
Implement __bool__ and __len__ via unary_op virtual method for all types.
parents
cdd2c62e
c1d9bbc3
Changes
13
Hide whitespace changes
Inline
Side-by-side
py/obj.c
View file @
b25711ea
...
...
@@ -251,9 +251,15 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
len
=
seq_len
;
}
else
if
(
MP_OBJ_IS_TYPE
(
o_in
,
&
dict_type
))
{
len
=
mp_obj_dict_len
(
o_in
);
}
else
if
(
MP_OBJ_IS_TYPE
(
o_in
,
&
array_type
))
{
len
=
mp_obj_array_len
(
o_in
);
}
else
{
mp_obj_type_t
*
type
=
mp_obj_get_type
(
o_in
);
if
(
type
->
unary_op
!=
NULL
)
{
mp_obj_t
result
=
type
->
unary_op
(
RT_UNARY_OP_LEN
,
o_in
);
if
(
result
!=
MP_OBJ_NULL
)
{
return
result
;
}
}
return
MP_OBJ_NULL
;
}
return
MP_OBJ_NEW_SMALL_INT
(
len
);
...
...
py/objarray.c
View file @
b25711ea
...
...
@@ -189,6 +189,15 @@ static mp_obj_t mp_builtin_bytearray(mp_obj_t arg) {
}
MP_DEFINE_CONST_FUN_OBJ_1
(
mp_builtin_bytearray_obj
,
mp_builtin_bytearray
);
static
mp_obj_t
array_unary_op
(
int
op
,
mp_obj_t
o_in
)
{
mp_obj_array_t
*
o
=
o_in
;
switch
(
op
)
{
case
RT_UNARY_OP_BOOL
:
return
MP_BOOL
(
o
->
len
!=
0
);
case
RT_UNARY_OP_LEN
:
return
MP_OBJ_NEW_SMALL_INT
(
o
->
len
);
default:
return
MP_OBJ_NULL
;
// op not supported
}
}
static
mp_obj_t
array_binary_op
(
int
op
,
mp_obj_t
lhs
,
mp_obj_t
rhs
)
{
mp_obj_array_t
*
o
=
lhs
;
switch
(
op
)
{
...
...
@@ -245,6 +254,7 @@ const mp_obj_type_t array_type = {
.
print
=
array_print
,
.
make_new
=
array_make_new
,
.
getiter
=
array_iterator_new
,
.
unary_op
=
array_unary_op
,
.
binary_op
=
array_binary_op
,
.
store_item
=
array_store_item
,
.
methods
=
array_type_methods
,
...
...
py/objbool.c
View file @
b25711ea
...
...
@@ -36,7 +36,7 @@ static mp_obj_t bool_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp
static
mp_obj_t
bool_unary_op
(
int
op
,
mp_obj_t
o_in
)
{
machine_int_t
value
=
((
mp_obj_bool_t
*
)
o_in
)
->
value
;
switch
(
op
)
{
case
RT_UNARY_OP_
NOT
:
if
(
value
)
{
return
mp_const_false
;
}
else
{
return
mp_const_true
;
}
case
RT_UNARY_OP_
BOOL
:
return
o_in
;
case
RT_UNARY_OP_POSITIVE
:
return
MP_OBJ_NEW_SMALL_INT
(
value
);
case
RT_UNARY_OP_NEGATIVE
:
return
MP_OBJ_NEW_SMALL_INT
(
-
value
);
case
RT_UNARY_OP_INVERT
:
...
...
py/objcomplex.c
View file @
b25711ea
...
...
@@ -73,7 +73,7 @@ static mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
static
mp_obj_t
complex_unary_op
(
int
op
,
mp_obj_t
o_in
)
{
mp_obj_complex_t
*
o
=
o_in
;
switch
(
op
)
{
case
RT_UNARY_OP_
NOT
:
if
(
o
->
real
!=
0
||
o
->
imag
!=
0
)
{
return
mp_const_true
;}
else
{
return
mp_const_false
;
}
case
RT_UNARY_OP_
BOOL
:
return
MP_BOOL
(
o
->
real
!=
0
||
o
->
imag
!=
0
)
;
case
RT_UNARY_OP_POSITIVE
:
return
o_in
;
case
RT_UNARY_OP_NEGATIVE
:
return
mp_obj_new_complex
(
-
o
->
real
,
-
o
->
imag
);
default:
return
MP_OBJ_NULL
;
// op not supported
...
...
py/objdict.c
View file @
b25711ea
...
...
@@ -46,7 +46,8 @@ static mp_obj_t dict_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp
static
mp_obj_t
dict_unary_op
(
int
op
,
mp_obj_t
self_in
)
{
mp_obj_dict_t
*
self
=
self_in
;
switch
(
op
)
{
case
RT_UNARY_OP_NOT
:
if
(
self
->
map
.
used
==
0
)
{
return
mp_const_true
;
}
else
{
return
mp_const_false
;
}
case
RT_UNARY_OP_BOOL
:
return
MP_BOOL
(
self
->
map
.
used
!=
0
);
case
RT_UNARY_OP_LEN
:
return
MP_OBJ_NEW_SMALL_INT
(
self
->
map
.
used
);
default:
return
MP_OBJ_NULL
;
// op not supported for None
}
}
...
...
py/objfloat.c
View file @
b25711ea
...
...
@@ -47,7 +47,7 @@ static mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
static
mp_obj_t
float_unary_op
(
int
op
,
mp_obj_t
o_in
)
{
mp_obj_float_t
*
o
=
o_in
;
switch
(
op
)
{
case
RT_UNARY_OP_
NOT
:
if
(
o
->
value
!=
0
)
{
return
mp_const_true
;}
else
{
return
mp_const_false
;
}
case
RT_UNARY_OP_
BOOL
:
return
MP_BOOL
(
o
->
value
!=
0
);
case
RT_UNARY_OP_POSITIVE
:
return
o_in
;
case
RT_UNARY_OP_NEGATIVE
:
return
mp_obj_new_float
(
-
o
->
value
);
default:
return
NULL
;
// op not supported
...
...
py/objint_longlong.c
View file @
b25711ea
...
...
@@ -35,7 +35,7 @@ void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj
mp_obj_t
int_unary_op
(
int
op
,
mp_obj_t
o_in
)
{
mp_obj_int_t
*
o
=
o_in
;
switch
(
op
)
{
case
RT_UNARY_OP_
NOT
:
return
MP_BOOL
(
o
->
val
!=
0
);
// TODO: implements RT_UNARY_OP_BOOL
case
RT_UNARY_OP_
BOOL
:
return
MP_BOOL
(
o
->
val
!=
0
);
case
RT_UNARY_OP_POSITIVE
:
return
o_in
;
case
RT_UNARY_OP_NEGATIVE
:
return
mp_obj_new_int_from_ll
(
-
o
->
val
);
case
RT_UNARY_OP_INVERT
:
return
mp_obj_new_int_from_ll
(
~
o
->
val
);
...
...
py/objlist.c
View file @
b25711ea
...
...
@@ -125,7 +125,8 @@ static bool list_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) {
static
mp_obj_t
list_unary_op
(
int
op
,
mp_obj_t
self_in
)
{
mp_obj_list_t
*
self
=
self_in
;
switch
(
op
)
{
case
RT_UNARY_OP_NOT
:
if
(
self
->
len
==
0
)
{
return
mp_const_true
;
}
else
{
return
mp_const_false
;
}
case
RT_UNARY_OP_BOOL
:
return
MP_BOOL
(
self
->
len
!=
0
);
case
RT_UNARY_OP_LEN
:
return
MP_OBJ_NEW_SMALL_INT
(
self
->
len
);
default:
return
MP_OBJ_NULL
;
// op not supported for None
}
}
...
...
py/objnone.c
View file @
b25711ea
...
...
@@ -18,7 +18,7 @@ static void none_print(void (*print)(void *env, const char *fmt, ...), void *env
static
mp_obj_t
none_unary_op
(
int
op
,
mp_obj_t
o_in
)
{
switch
(
op
)
{
case
RT_UNARY_OP_
NOT
:
return
mp_const_
tru
e
;
case
RT_UNARY_OP_
BOOL
:
return
mp_const_
fals
e
;
default:
return
MP_OBJ_NULL
;
// op not supported for None
}
}
...
...
py/objtuple.c
View file @
b25711ea
...
...
@@ -76,7 +76,8 @@ static mp_obj_t tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
static
mp_obj_t
tuple_unary_op
(
int
op
,
mp_obj_t
self_in
)
{
mp_obj_tuple_t
*
self
=
self_in
;
switch
(
op
)
{
case
RT_UNARY_OP_NOT
:
if
(
self
->
len
==
0
)
{
return
mp_const_true
;
}
else
{
return
mp_const_false
;
}
case
RT_UNARY_OP_BOOL
:
return
MP_BOOL
(
self
->
len
!=
0
);
case
RT_UNARY_OP_LEN
:
return
MP_OBJ_NEW_SMALL_INT
(
self
->
len
);
default:
return
MP_OBJ_NULL
;
// op not supported for None
}
}
...
...
py/runtime.c
View file @
b25711ea
...
...
@@ -317,15 +317,20 @@ int rt_is_true(mp_obj_t arg) {
}
else
if
(
arg
==
mp_const_true
)
{
return
1
;
}
else
{
mp_obj_type_t
*
type
=
mp_obj_get_type
(
arg
);
if
(
type
->
unary_op
!=
NULL
)
{
mp_obj_t
result
=
type
->
unary_op
(
RT_UNARY_OP_BOOL
,
arg
);
if
(
result
!=
NULL
)
{
return
result
==
mp_const_true
;
}
}
mp_obj_t
len
=
mp_obj_len_maybe
(
arg
);
if
(
len
!=
MP_OBJ_NULL
)
{
// obj has a length, truth determined if len != 0
return
len
!=
MP_OBJ_NEW_SMALL_INT
(
0
);
}
else
{
// TODO check for __bool__ method
// TODO check floats and complex numbers
// any other obj is true (TODO is that correct?)
// any other obj is true per Python semantics
return
1
;
}
}
...
...
@@ -476,7 +481,7 @@ mp_obj_t rt_unary_op(int op, mp_obj_t arg) {
if
(
MP_OBJ_IS_SMALL_INT
(
arg
))
{
mp_small_int_t
val
=
MP_OBJ_SMALL_INT_VALUE
(
arg
);
switch
(
op
)
{
case
RT_UNARY_OP_
NOT
:
if
(
val
==
0
)
{
return
mp_const_true
;}
else
{
return
mp_const_false
;
}
case
RT_UNARY_OP_
BOOL
:
return
MP_BOOL
(
val
!=
0
);
case
RT_UNARY_OP_POSITIVE
:
break
;
case
RT_UNARY_OP_NEGATIVE
:
val
=
-
val
;
break
;
case
RT_UNARY_OP_INVERT
:
val
=
~
val
;
break
;
...
...
py/runtime0.h
View file @
b25711ea
typedef
enum
{
RT_UNARY_OP_NOT
,
// TODO remove this op since it's no longer needed
RT_UNARY_OP_BOOL
,
// __bool__
RT_UNARY_OP_LEN
,
// __len__
RT_UNARY_OP_POSITIVE
,
RT_UNARY_OP_NEGATIVE
,
RT_UNARY_OP_INVERT
,
// Used only for CPython-compatible codegeneration
RT_UNARY_OP_NOT
,
}
rt_unary_op_t
;
typedef
enum
{
...
...
tests/basics/true-value.py
View file @
b25711ea
...
...
@@ -3,9 +3,18 @@
if
not
False
:
print
(
"False"
)
if
not
None
:
print
(
"None"
)
if
not
0
:
print
(
"0"
)
if
not
0.0
:
print
(
"float 0"
)
if
not
0
+
0j
:
print
(
"complex 0"
)
if
not
""
:
print
(
"Empty string"
)
if
"foo"
:
...
...
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