summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-01-27 23:16:20 +0000
committerDamien George <damien.p.george@gmail.com>2014-01-27 23:16:20 +0000
commitc7aa9fcae571a442a50c90409396788dd0b28c24 (patch)
tree8959e333f1d9183fbfb781ed974a17f1e27d71c7 /py
parent4e8dc8c41b6f68269571fe218f7292fc86cf3ddb (diff)
parent9b00dad7bb0125a3459ca4f9c939c7510bd2f77f (diff)
downloadmicropython-c7aa9fcae571a442a50c90409396788dd0b28c24.tar.gz
micropython-c7aa9fcae571a442a50c90409396788dd0b28c24.zip
Merge branch 'master' of github.com:micropython/micropython
Diffstat (limited to 'py')
-rw-r--r--py/objgenerator.c25
-rw-r--r--py/objint.c7
-rw-r--r--py/objint.h1
-rw-r--r--py/objint_longlong.c41
-rw-r--r--py/objlist.c12
5 files changed, 74 insertions, 12 deletions
diff --git a/py/objgenerator.c b/py/objgenerator.c
index 0cac34b09e..91bbbceb2f 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -73,8 +73,11 @@ mp_obj_t gen_instance_getiter(mp_obj_t 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;
+ if (self->ip == 0) {
+ return mp_const_stop_iteration;
+ }
if (self->sp == self->state - 1) {
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"));
@@ -86,6 +89,12 @@ static mp_obj_t gen_send(mp_obj_t self_in, mp_obj_t send_value) {
if (yield) {
return *self->sp;
} 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) {
return mp_const_stop_iteration;
} 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) {
- 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[] = {
- { "send", &gen_send_obj },
+ { "send", &gen_instance_send_obj },
{ NULL, NULL }, // end-of-list sentinel
};
diff --git a/py/objint.c b/py/objint.c
index 1305f1900e..1a04408afd 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -52,6 +52,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
mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
assert(0);
return mp_const_none;
@@ -96,5 +102,6 @@ const mp_obj_type_t int_type = {
"int",
.print = int_print,
.make_new = int_make_new,
+ .unary_op = int_unary_op,
.binary_op = int_binary_op,
};
diff --git a/py/objint.h b/py/objint.h
index 7d43971ec3..6662be1ef3 100644
--- a/py/objint.h
+++ b/py/objint.h
@@ -6,4 +6,5 @@ typedef struct _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);
+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);
diff --git a/py/objint_longlong.c b/py/objint_longlong.c
index 7eaee3bc9d..38a01837e1 100644
--- a/py/objint_longlong.c
+++ b/py/objint_longlong.c
@@ -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_int_t *lhs = lhs_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);
case RT_BINARY_OP_SUBTRACT:
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:
- lhs->val += rhs_val;
- return lhs;
+ lhs->val += rhs_val; return lhs;
case RT_BINARY_OP_INPLACE_SUBTRACT:
- lhs->val -= rhs_val;
- return lhs;
+ lhs->val -= rhs_val; 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:
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:
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:
return mp_obj_new_int_from_ll(lhs->val << (int)rhs_val);
case RT_BINARY_OP_RSHIFT:
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:
return MP_BOOL(lhs->val < rhs_val);
case RT_COMPARE_OP_MORE:
diff --git a/py/objlist.c b/py/objlist.c
index 1e8930eeea..fb68e2c566 100644
--- a/py/objlist.c
+++ b/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_t list_extend(mp_obj_t self_in, mp_obj_t arg_in);
+// TODO: Move to mpconfig.h
+#define LIST_MIN_ALLOC 4
+
/******************************************************************************/
/* 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;
if (self->len >= self->alloc) {
self->items = m_renew(mp_obj_t, self->items, self->alloc, self->alloc * 2);
+ assert(self->items);
self->alloc *= 2;
}
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];
self->len -= 1;
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->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));
mp_obj_list_t *self = self_in;
self->len = 0;
- self->items = m_renew(mp_obj_t, self->items, self->alloc, 4);
- self->alloc = 4;
+ self->items = m_renew(mp_obj_t, self->items, self->alloc, LIST_MIN_ALLOC);
+ self->alloc = LIST_MIN_ALLOC;
return mp_const_none;
}
@@ -412,7 +416,7 @@ const mp_obj_type_t list_type = {
static mp_obj_list_t *list_new(uint n) {
mp_obj_list_t *o = m_new_obj(mp_obj_list_t);
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->items = m_new(mp_obj_t, o->alloc);
return o;