Merge branch 'master' of github.com:micropython/micropython
This commit is contained in:
commit
c7aa9fcae5
@ -73,8 +73,11 @@ mp_obj_t gen_instance_getiter(mp_obj_t self_in) {
|
|||||||
return self_in;
|
return self_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
static mp_obj_t gen_send(mp_obj_t self_in, mp_obj_t send_value) {
|
static mp_obj_t gen_next_send(mp_obj_t self_in, mp_obj_t send_value) {
|
||||||
mp_obj_gen_instance_t *self = self_in;
|
mp_obj_gen_instance_t *self = self_in;
|
||||||
|
if (self->ip == 0) {
|
||||||
|
return mp_const_stop_iteration;
|
||||||
|
}
|
||||||
if (self->sp == self->state - 1) {
|
if (self->sp == self->state - 1) {
|
||||||
if (send_value != mp_const_none) {
|
if (send_value != mp_const_none) {
|
||||||
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "can't send non-None value to a just-started generator"));
|
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "can't send non-None value to a just-started generator"));
|
||||||
@ -86,6 +89,12 @@ static mp_obj_t gen_send(mp_obj_t self_in, mp_obj_t send_value) {
|
|||||||
if (yield) {
|
if (yield) {
|
||||||
return *self->sp;
|
return *self->sp;
|
||||||
} else {
|
} else {
|
||||||
|
// Explicitly mark generator as completed. If we don't do this,
|
||||||
|
// subsequent next() may re-execute statements after last yield
|
||||||
|
// again and again, leading to side effects.
|
||||||
|
// TODO: check how return with value behaves under such conditions
|
||||||
|
// in CPython.
|
||||||
|
self->ip = 0;
|
||||||
if (*self->sp == mp_const_none) {
|
if (*self->sp == mp_const_none) {
|
||||||
return mp_const_stop_iteration;
|
return mp_const_stop_iteration;
|
||||||
} else {
|
} else {
|
||||||
@ -94,14 +103,22 @@ static mp_obj_t gen_send(mp_obj_t self_in, mp_obj_t send_value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static MP_DEFINE_CONST_FUN_OBJ_2(gen_send_obj, gen_send);
|
|
||||||
|
|
||||||
mp_obj_t gen_instance_iternext(mp_obj_t self_in) {
|
mp_obj_t gen_instance_iternext(mp_obj_t self_in) {
|
||||||
return gen_send(self_in, mp_const_none);
|
return gen_next_send(self_in, mp_const_none);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mp_obj_t gen_instance_send(mp_obj_t self_in, mp_obj_t send_value) {
|
||||||
|
mp_obj_t ret = gen_next_send(self_in, send_value);
|
||||||
|
if (ret == mp_const_stop_iteration) {
|
||||||
|
nlr_jump(mp_obj_new_exception(MP_QSTR_StopIteration));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
static MP_DEFINE_CONST_FUN_OBJ_2(gen_instance_send_obj, gen_instance_send);
|
||||||
|
|
||||||
static const mp_method_t gen_type_methods[] = {
|
static const mp_method_t gen_type_methods[] = {
|
||||||
{ "send", &gen_send_obj },
|
{ "send", &gen_instance_send_obj },
|
||||||
{ NULL, NULL }, // end-of-list sentinel
|
{ NULL, NULL }, // end-of-list sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,6 +51,12 @@ void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is called only for non-SMALL_INT
|
||||||
|
mp_obj_t int_unary_op(int op, mp_obj_t o_in) {
|
||||||
|
assert(0);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
// This is called only for non-SMALL_INT
|
// This is called only for non-SMALL_INT
|
||||||
mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||||
assert(0);
|
assert(0);
|
||||||
@ -96,5 +102,6 @@ const mp_obj_type_t int_type = {
|
|||||||
"int",
|
"int",
|
||||||
.print = int_print,
|
.print = int_print,
|
||||||
.make_new = int_make_new,
|
.make_new = int_make_new,
|
||||||
|
.unary_op = int_unary_op,
|
||||||
.binary_op = int_binary_op,
|
.binary_op = int_binary_op,
|
||||||
};
|
};
|
||||||
|
@ -6,4 +6,5 @@ typedef struct _mp_obj_int_t {
|
|||||||
} mp_obj_int_t;
|
} mp_obj_int_t;
|
||||||
|
|
||||||
void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind);
|
void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind);
|
||||||
|
mp_obj_t int_unary_op(int op, mp_obj_t o_in);
|
||||||
mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in);
|
mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in);
|
||||||
|
@ -32,6 +32,17 @@ 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_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);
|
||||||
|
default: return NULL; // op not supported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
||||||
mp_obj_int_t *lhs = lhs_in;
|
mp_obj_int_t *lhs = lhs_in;
|
||||||
mp_obj_int_t *rhs = rhs_in;
|
mp_obj_int_t *rhs = rhs_in;
|
||||||
@ -50,13 +61,23 @@ mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
|||||||
return mp_obj_new_int_from_ll(lhs->val + rhs_val);
|
return mp_obj_new_int_from_ll(lhs->val + rhs_val);
|
||||||
case RT_BINARY_OP_SUBTRACT:
|
case RT_BINARY_OP_SUBTRACT:
|
||||||
return mp_obj_new_int_from_ll(lhs->val - rhs_val);
|
return mp_obj_new_int_from_ll(lhs->val - rhs_val);
|
||||||
|
case RT_BINARY_OP_MULTIPLY:
|
||||||
|
return mp_obj_new_int_from_ll(lhs->val * rhs_val);
|
||||||
|
case RT_BINARY_OP_FLOOR_DIVIDE:
|
||||||
|
return mp_obj_new_int_from_ll(lhs->val / rhs_val);
|
||||||
|
case RT_BINARY_OP_MODULO:
|
||||||
|
return mp_obj_new_int_from_ll(lhs->val % rhs_val);
|
||||||
|
|
||||||
case RT_BINARY_OP_INPLACE_ADD:
|
case RT_BINARY_OP_INPLACE_ADD:
|
||||||
lhs->val += rhs_val;
|
lhs->val += rhs_val; return lhs;
|
||||||
return lhs;
|
|
||||||
case RT_BINARY_OP_INPLACE_SUBTRACT:
|
case RT_BINARY_OP_INPLACE_SUBTRACT:
|
||||||
lhs->val -= rhs_val;
|
lhs->val -= rhs_val; return lhs;
|
||||||
return lhs;
|
case RT_BINARY_OP_INPLACE_MULTIPLY:
|
||||||
|
lhs->val *= rhs_val; return lhs;
|
||||||
|
case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE:
|
||||||
|
lhs->val /= rhs_val; return lhs;
|
||||||
|
case RT_BINARY_OP_INPLACE_MODULO:
|
||||||
|
lhs->val %= rhs_val; return lhs;
|
||||||
|
|
||||||
case RT_BINARY_OP_AND:
|
case RT_BINARY_OP_AND:
|
||||||
return mp_obj_new_int_from_ll(lhs->val & rhs_val);
|
return mp_obj_new_int_from_ll(lhs->val & rhs_val);
|
||||||
@ -65,11 +86,23 @@ mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
|||||||
case RT_BINARY_OP_XOR:
|
case RT_BINARY_OP_XOR:
|
||||||
return mp_obj_new_int_from_ll(lhs->val ^ rhs_val);
|
return mp_obj_new_int_from_ll(lhs->val ^ rhs_val);
|
||||||
|
|
||||||
|
case RT_BINARY_OP_INPLACE_AND:
|
||||||
|
lhs->val &= rhs_val; return lhs;
|
||||||
|
case RT_BINARY_OP_INPLACE_OR:
|
||||||
|
lhs->val |= rhs_val; return lhs;
|
||||||
|
case RT_BINARY_OP_INPLACE_XOR:
|
||||||
|
lhs->val ^= rhs_val; return lhs;
|
||||||
|
|
||||||
case RT_BINARY_OP_LSHIFT:
|
case RT_BINARY_OP_LSHIFT:
|
||||||
return mp_obj_new_int_from_ll(lhs->val << (int)rhs_val);
|
return mp_obj_new_int_from_ll(lhs->val << (int)rhs_val);
|
||||||
case RT_BINARY_OP_RSHIFT:
|
case RT_BINARY_OP_RSHIFT:
|
||||||
return mp_obj_new_int_from_ll(lhs->val >> (int)rhs_val);
|
return mp_obj_new_int_from_ll(lhs->val >> (int)rhs_val);
|
||||||
|
|
||||||
|
case RT_BINARY_OP_INPLACE_LSHIFT:
|
||||||
|
lhs->val <<= (int)rhs_val; return lhs;
|
||||||
|
case RT_BINARY_OP_INPLACE_RSHIFT:
|
||||||
|
lhs->val >>= (int)rhs_val; return lhs;
|
||||||
|
|
||||||
case RT_COMPARE_OP_LESS:
|
case RT_COMPARE_OP_LESS:
|
||||||
return MP_BOOL(lhs->val < rhs_val);
|
return MP_BOOL(lhs->val < rhs_val);
|
||||||
case RT_COMPARE_OP_MORE:
|
case RT_COMPARE_OP_MORE:
|
||||||
|
12
py/objlist.c
12
py/objlist.c
@ -23,6 +23,9 @@ static mp_obj_t mp_obj_new_list_iterator(mp_obj_list_t *list, int cur);
|
|||||||
static mp_obj_list_t *list_new(uint n);
|
static mp_obj_list_t *list_new(uint n);
|
||||||
static mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in);
|
static mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in);
|
||||||
|
|
||||||
|
// TODO: Move to mpconfig.h
|
||||||
|
#define LIST_MIN_ALLOC 4
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* list */
|
/* list */
|
||||||
|
|
||||||
@ -189,6 +192,7 @@ mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg) {
|
|||||||
mp_obj_list_t *self = self_in;
|
mp_obj_list_t *self = self_in;
|
||||||
if (self->len >= self->alloc) {
|
if (self->len >= self->alloc) {
|
||||||
self->items = m_renew(mp_obj_t, self->items, self->alloc, self->alloc * 2);
|
self->items = m_renew(mp_obj_t, self->items, self->alloc, self->alloc * 2);
|
||||||
|
assert(self->items);
|
||||||
self->alloc *= 2;
|
self->alloc *= 2;
|
||||||
}
|
}
|
||||||
self->items[self->len++] = arg;
|
self->items[self->len++] = arg;
|
||||||
@ -223,7 +227,7 @@ static mp_obj_t list_pop(uint n_args, const mp_obj_t *args) {
|
|||||||
mp_obj_t ret = self->items[index];
|
mp_obj_t ret = self->items[index];
|
||||||
self->len -= 1;
|
self->len -= 1;
|
||||||
memcpy(self->items + index, self->items + index + 1, (self->len - index) * sizeof(mp_obj_t));
|
memcpy(self->items + index, self->items + index + 1, (self->len - index) * sizeof(mp_obj_t));
|
||||||
if (self->alloc > 2 * self->len) {
|
if (self->alloc > LIST_MIN_ALLOC && self->alloc > 2 * self->len) {
|
||||||
self->items = m_renew(mp_obj_t, self->items, self->alloc, self->alloc/2);
|
self->items = m_renew(mp_obj_t, self->items, self->alloc, self->alloc/2);
|
||||||
self->alloc /= 2;
|
self->alloc /= 2;
|
||||||
}
|
}
|
||||||
@ -275,8 +279,8 @@ static mp_obj_t list_clear(mp_obj_t self_in) {
|
|||||||
assert(MP_OBJ_IS_TYPE(self_in, &list_type));
|
assert(MP_OBJ_IS_TYPE(self_in, &list_type));
|
||||||
mp_obj_list_t *self = self_in;
|
mp_obj_list_t *self = self_in;
|
||||||
self->len = 0;
|
self->len = 0;
|
||||||
self->items = m_renew(mp_obj_t, self->items, self->alloc, 4);
|
self->items = m_renew(mp_obj_t, self->items, self->alloc, LIST_MIN_ALLOC);
|
||||||
self->alloc = 4;
|
self->alloc = LIST_MIN_ALLOC;
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,7 +416,7 @@ const mp_obj_type_t list_type = {
|
|||||||
static mp_obj_list_t *list_new(uint n) {
|
static mp_obj_list_t *list_new(uint n) {
|
||||||
mp_obj_list_t *o = m_new_obj(mp_obj_list_t);
|
mp_obj_list_t *o = m_new_obj(mp_obj_list_t);
|
||||||
o->base.type = &list_type;
|
o->base.type = &list_type;
|
||||||
o->alloc = n < 4 ? 4 : n;
|
o->alloc = n < LIST_MIN_ALLOC ? LIST_MIN_ALLOC : n;
|
||||||
o->len = n;
|
o->len = n;
|
||||||
o->items = m_new(mp_obj_t, o->alloc);
|
o->items = m_new(mp_obj_t, o->alloc);
|
||||||
return o;
|
return o;
|
||||||
|
@ -13,3 +13,25 @@ except TypeError:
|
|||||||
print(g.send(None))
|
print(g.send(None))
|
||||||
print(g.send(100))
|
print(g.send(100))
|
||||||
print(g.send(200))
|
print(g.send(200))
|
||||||
|
|
||||||
|
|
||||||
|
def f2():
|
||||||
|
print("entering")
|
||||||
|
for i in range(3):
|
||||||
|
print(i)
|
||||||
|
yield
|
||||||
|
print("returning 1")
|
||||||
|
print("returning 2")
|
||||||
|
|
||||||
|
g = f2()
|
||||||
|
g.send(None)
|
||||||
|
g.send(1)
|
||||||
|
g.send(1)
|
||||||
|
try:
|
||||||
|
g.send(1)
|
||||||
|
except StopIteration:
|
||||||
|
print("caught")
|
||||||
|
try:
|
||||||
|
g.send(1)
|
||||||
|
except StopIteration:
|
||||||
|
print("caught")
|
||||||
|
39
tests/basics/int-long.py
Normal file
39
tests/basics/int-long.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# This tests long ints for 32-bit machine
|
||||||
|
|
||||||
|
a = 0x1ffffffff
|
||||||
|
b = 0x100000000
|
||||||
|
print(a)
|
||||||
|
print(b)
|
||||||
|
print(a + b)
|
||||||
|
print(a - b)
|
||||||
|
print(b - a)
|
||||||
|
# overflows long long implementation
|
||||||
|
#print(a * b)
|
||||||
|
print(a // b)
|
||||||
|
print(a % b)
|
||||||
|
print(a & b)
|
||||||
|
print(a | b)
|
||||||
|
print(a ^ b)
|
||||||
|
print(a << 3)
|
||||||
|
print(a >> 1)
|
||||||
|
|
||||||
|
a += b
|
||||||
|
print(a)
|
||||||
|
a -= 123456
|
||||||
|
print(a)
|
||||||
|
a *= 257
|
||||||
|
print(a)
|
||||||
|
a //= 257
|
||||||
|
print(a)
|
||||||
|
a %= b
|
||||||
|
print(a)
|
||||||
|
a ^= b
|
||||||
|
print(a)
|
||||||
|
a |= b
|
||||||
|
print(a)
|
||||||
|
a &= b
|
||||||
|
print(a)
|
||||||
|
a <<= 5
|
||||||
|
print(a)
|
||||||
|
a >>= 1
|
||||||
|
print(a)
|
Loading…
x
Reference in New Issue
Block a user