diff options
-rw-r--r-- | examples/mandel.py | 14 | ||||
-rw-r--r-- | py/asmx64.c | 2 | ||||
-rw-r--r-- | py/emit.h | 2 | ||||
-rw-r--r-- | py/obj.h | 2 | ||||
-rw-r--r-- | py/objcomplex.c | 70 | ||||
-rw-r--r-- | py/objfloat.c | 43 | ||||
-rw-r--r-- | py/runtime.c | 100 | ||||
-rw-r--r-- | py/vm.c | 2 | ||||
-rw-r--r-- | stm/led.c | 12 | ||||
-rw-r--r-- | stm/led.h | 16 |
10 files changed, 147 insertions, 116 deletions
diff --git a/examples/mandel.py b/examples/mandel.py new file mode 100644 index 0000000000..b13b7d87f8 --- /dev/null +++ b/examples/mandel.py @@ -0,0 +1,14 @@ +@micropython.native +def in_set(c): + z = 0 + for i in range(40): + z = z*z + c + if abs(z) > 60: + return False + return True + +for v in range(31): + line = [] + for u in range(91): + line.append('*' if in_set((u / 30 - 2) + (v / 15 - 1) * 1j) else ' ') + print(''.join(line)) diff --git a/py/asmx64.c b/py/asmx64.c index ed9ca80f5c..226d4efee8 100644 --- a/py/asmx64.c +++ b/py/asmx64.c @@ -155,7 +155,7 @@ void asm_x64_end_pass(asm_x64_t *as) { //as->code_base = m_new(byte, as->code_size); need to allocale executable memory uint actual_alloc; as->code_base = alloc_mem(as->code_size, &actual_alloc, true); - printf("code_size: %u\n", as->code_size); + //printf("code_size: %u\n", as->code_size); } /* @@ -5,7 +5,7 @@ * is not known until the end of pass 1. * As a consequence, we don't know the maximum stack size until the end of pass 2. * This is problematic for some emitters (x64) since they need to know the maximum - * stack size to compile the entry to the function, and this effects code size. + * stack size to compile the entry to the function, and this affects code size. */ typedef enum { @@ -200,10 +200,12 @@ qstr mp_obj_str_get(mp_obj_t self_in); // float extern const mp_obj_type_t float_type; mp_float_t mp_obj_float_get(mp_obj_t self_in); +mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs); // complex extern const mp_obj_type_t complex_type; void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag); +mp_obj_t mp_obj_complex_binary_op(int op, mp_float_t lhs_real, mp_float_t lhs_imag, mp_obj_t rhs_in); #endif // tuple diff --git a/py/objcomplex.c b/py/objcomplex.c index fc32f96674..46f43b54b5 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -48,14 +48,14 @@ static mp_obj_t complex_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *a { mp_float_t real, imag; if (MP_OBJ_IS_TYPE(args[1], &complex_type)) { - mp_obj_get_complex(args[1], &real, &imag); + mp_obj_complex_get(args[1], &real, &imag); } else { real = mp_obj_get_float(args[1]); imag = 0; } if (MP_OBJ_IS_TYPE(args[0], &complex_type)) { mp_float_t real2, imag2; - mp_obj_get_complex(args[0], &real2, &imag2); + mp_obj_complex_get(args[0], &real2, &imag2); real -= imag2; imag += real2; } else { @@ -80,9 +80,41 @@ static mp_obj_t complex_unary_op(int op, mp_obj_t o_in) { } static mp_obj_t complex_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { - mp_float_t lhs_real, lhs_imag, rhs_real, rhs_imag; - mp_obj_complex_get(lhs_in, &lhs_real, &lhs_imag); - mp_obj_complex_get(rhs_in, &rhs_real, &rhs_imag); + mp_obj_complex_t *lhs = lhs_in; + return mp_obj_complex_binary_op(op, lhs->real, lhs->imag, rhs_in); +} + +const mp_obj_type_t complex_type = { + { &mp_const_type }, + "complex", + complex_print, // print + complex_make_new, // make_new + NULL, // call_n + complex_unary_op, // unary_op + complex_binary_op, // binary_op + NULL, // getiter + NULL, // iternext + .methods = { { NULL, NULL }, }, +}; + +mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag) { + mp_obj_complex_t *o = m_new_obj(mp_obj_complex_t); + o->base.type = &complex_type; + o->real = real; + o->imag = imag; + return o; +} + +void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag) { + assert(MP_OBJ_IS_TYPE(self_in, &complex_type)); + mp_obj_complex_t *self = self_in; + *real = self->real; + *imag = self->imag; +} + +mp_obj_t mp_obj_complex_binary_op(int op, mp_float_t lhs_real, mp_float_t lhs_imag, mp_obj_t rhs_in) { + mp_float_t rhs_real, rhs_imag; + mp_obj_get_complex(rhs_in, &rhs_real, &rhs_imag); // can be any type, this function will convert to float (if possible) switch (op) { case RT_BINARY_OP_ADD: case RT_BINARY_OP_INPLACE_ADD: @@ -115,32 +147,4 @@ static mp_obj_t complex_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { return mp_obj_new_complex(lhs_real, lhs_imag); } -const mp_obj_type_t complex_type = { - { &mp_const_type }, - "complex", - complex_print, // print - complex_make_new, // make_new - NULL, // call_n - complex_unary_op, // unary_op - complex_binary_op, // binary_op - NULL, // getiter - NULL, // iternext - .methods = { { NULL, NULL }, }, -}; - -mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag) { - mp_obj_complex_t *o = m_new_obj(mp_obj_complex_t); - o->base.type = &complex_type; - o->real = real; - o->imag = imag; - return o; -} - -void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag) { - assert(MP_OBJ_IS_TYPE(self_in, &complex_type)); - mp_obj_complex_t *self = self_in; - *real = self->real; - *imag = self->imag; -} - #endif diff --git a/py/objfloat.c b/py/objfloat.c index 0250172ad3..336ae597fc 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -53,27 +53,12 @@ static mp_obj_t float_unary_op(int op, mp_obj_t o_in) { } static mp_obj_t float_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + mp_obj_float_t *lhs = lhs_in; if (MP_OBJ_IS_TYPE(rhs_in, &complex_type)) { - return complex_type.binary_op(op, lhs_in, rhs_in); + return mp_obj_complex_binary_op(op, lhs->value, 0, rhs_in); + } else { + return mp_obj_float_binary_op(op, lhs->value, rhs_in); } - mp_float_t lhs_val = mp_obj_get_float(lhs_in); - mp_float_t rhs_val = mp_obj_get_float(rhs_in); - switch (op) { - case RT_BINARY_OP_ADD: - case RT_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break; - case RT_BINARY_OP_SUBTRACT: - case RT_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break; - case RT_BINARY_OP_MULTIPLY: - case RT_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break; - /* TODO floor(?) the value - case RT_BINARY_OP_FLOOR_DIVIDE: - case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: val = lhs_val / rhs_val; break; - */ - case RT_BINARY_OP_TRUE_DIVIDE: - case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: lhs_val /= rhs_val; break; - return NULL; // op not supported - } - return mp_obj_new_float(lhs_val); } const mp_obj_type_t float_type = { @@ -99,4 +84,24 @@ mp_float_t mp_obj_float_get(mp_obj_t self_in) { return self->value; } +mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs_in) { + mp_float_t rhs_val = mp_obj_get_float(rhs_in); // can be any type, this function will convert to float (if possible) + switch (op) { + case RT_BINARY_OP_ADD: + case RT_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break; + case RT_BINARY_OP_SUBTRACT: + case RT_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break; + case RT_BINARY_OP_MULTIPLY: + case RT_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break; + /* TODO floor(?) the value + case RT_BINARY_OP_FLOOR_DIVIDE: + case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: val = lhs_val / rhs_val; break; + */ + case RT_BINARY_OP_TRUE_DIVIDE: + case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: lhs_val /= rhs_val; break; + return NULL; // op not supported + } + return mp_obj_new_float(lhs_val); +} + #endif diff --git a/py/runtime.c b/py/runtime.c index 197c08b55a..6bc71abff7 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -452,57 +452,63 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { // then fail // note that list does not implement + or +=, so that inplace_concat is reached first for += - if (MP_OBJ_IS_SMALL_INT(lhs) && MP_OBJ_IS_SMALL_INT(rhs)) { + if (MP_OBJ_IS_SMALL_INT(lhs)) { mp_small_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs); - mp_small_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs); - switch (op) { - case RT_BINARY_OP_OR: - case RT_BINARY_OP_INPLACE_OR: lhs_val |= rhs_val; break; - case RT_BINARY_OP_XOR: - case RT_BINARY_OP_INPLACE_XOR: lhs_val ^= rhs_val; break; - case RT_BINARY_OP_AND: - case RT_BINARY_OP_INPLACE_AND: lhs_val &= rhs_val; break; - case RT_BINARY_OP_LSHIFT: - case RT_BINARY_OP_INPLACE_LSHIFT: lhs_val <<= rhs_val; break; - case RT_BINARY_OP_RSHIFT: - case RT_BINARY_OP_INPLACE_RSHIFT: lhs_val >>= rhs_val; break; - case RT_BINARY_OP_ADD: - case RT_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break; - case RT_BINARY_OP_SUBTRACT: - case RT_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break; - case RT_BINARY_OP_MULTIPLY: - case RT_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break; - case RT_BINARY_OP_FLOOR_DIVIDE: - case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: lhs_val /= rhs_val; break; -#if MICROPY_ENABLE_FLOAT - case RT_BINARY_OP_TRUE_DIVIDE: - case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: return mp_obj_new_float((mp_float_t)lhs_val / (mp_float_t)rhs_val); -#endif - - // TODO implement modulo as specified by Python - case RT_BINARY_OP_MODULO: - case RT_BINARY_OP_INPLACE_MODULO: lhs_val %= rhs_val; break; - - // TODO check for negative power, and overflow - case RT_BINARY_OP_POWER: - case RT_BINARY_OP_INPLACE_POWER: - { - int ans = 1; - while (rhs_val > 0) { - if (rhs_val & 1) { - ans *= lhs_val; + if (MP_OBJ_IS_SMALL_INT(rhs)) { + mp_small_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs); + switch (op) { + case RT_BINARY_OP_OR: + case RT_BINARY_OP_INPLACE_OR: lhs_val |= rhs_val; break; + case RT_BINARY_OP_XOR: + case RT_BINARY_OP_INPLACE_XOR: lhs_val ^= rhs_val; break; + case RT_BINARY_OP_AND: + case RT_BINARY_OP_INPLACE_AND: lhs_val &= rhs_val; break; + case RT_BINARY_OP_LSHIFT: + case RT_BINARY_OP_INPLACE_LSHIFT: lhs_val <<= rhs_val; break; + case RT_BINARY_OP_RSHIFT: + case RT_BINARY_OP_INPLACE_RSHIFT: lhs_val >>= rhs_val; break; + case RT_BINARY_OP_ADD: + case RT_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break; + case RT_BINARY_OP_SUBTRACT: + case RT_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break; + case RT_BINARY_OP_MULTIPLY: + case RT_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break; + case RT_BINARY_OP_FLOOR_DIVIDE: + case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: lhs_val /= rhs_val; break; + #if MICROPY_ENABLE_FLOAT + case RT_BINARY_OP_TRUE_DIVIDE: + case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: return mp_obj_new_float((mp_float_t)lhs_val / (mp_float_t)rhs_val); + #endif + + // TODO implement modulo as specified by Python + case RT_BINARY_OP_MODULO: + case RT_BINARY_OP_INPLACE_MODULO: lhs_val %= rhs_val; break; + + // TODO check for negative power, and overflow + case RT_BINARY_OP_POWER: + case RT_BINARY_OP_INPLACE_POWER: + { + int ans = 1; + while (rhs_val > 0) { + if (rhs_val & 1) { + ans *= lhs_val; + } + lhs_val *= lhs_val; + rhs_val /= 2; } - lhs_val *= lhs_val; - rhs_val /= 2; + lhs_val = ans; + break; } - lhs_val = ans; - break; - } - default: assert(0); - } - if (fit_small_int(lhs_val)) { - return MP_OBJ_NEW_SMALL_INT(lhs_val); + default: assert(0); + } + if (fit_small_int(lhs_val)) { + return MP_OBJ_NEW_SMALL_INT(lhs_val); + } + } else if (MP_OBJ_IS_TYPE(rhs, &float_type)) { + return mp_obj_float_binary_op(op, lhs_val, rhs); + } else if (MP_OBJ_IS_TYPE(rhs, &complex_type)) { + return mp_obj_complex_binary_op(op, lhs_val, 0, rhs); } } else if (MP_OBJ_IS_OBJ(lhs)) { mp_obj_base_t *o = lhs; @@ -106,7 +106,7 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t ** case MP_BC_LOAD_CONST_SMALL_INT: unum = (ip[0] | (ip[1] << 8) | (ip[2] << 16)) - 0x800000; ip += 3; - PUSH((mp_obj_t)(unum << 1 | 1)); + PUSH(MP_OBJ_NEW_SMALL_INT(unum)); break; case MP_BC_LOAD_CONST_DEC: @@ -8,10 +8,10 @@ #include "led.h" /* LED numbers, used internally */ -#define PYB_LED_1 (0) -#define PYB_LED_2 (1) -#define PYB_LED_3 (2) -#define PYB_LED_4 (3) +#define PYB_LED_1 (1) +#define PYB_LED_2 (2) +#define PYB_LED_3 (3) +#define PYB_LED_4 (4) #if defined(PYBOARD) #define PYB_LED1_PORT (GPIOA) @@ -63,8 +63,8 @@ void led_init(void) { /* Turn off LEDs */ PYB_LED_OFF(PYB_LED1_PORT, PYB_LED1_PIN); PYB_LED_OFF(PYB_LED2_PORT, PYB_LED2_PIN); - PYB_LED_OFF(PYB_LED3_PORT, PYB_LED1_PIN); - PYB_LED_OFF(PYB_LED4_PORT, PYB_LED2_PIN); + PYB_LED_OFF(PYB_LED3_PORT, PYB_LED3_PIN); + PYB_LED_OFF(PYB_LED4_PORT, PYB_LED4_PIN); /* Initialize LEDs */ GPIO_InitStructure.GPIO_Pin = PYB_LED1_PIN; @@ -1,13 +1,13 @@ typedef enum { - PYB_LED_R1 = 0, - PYB_LED_R2 = 1, - PYB_LED_G1 = 2, - PYB_LED_G2 = 3, + PYB_LED_R1 = 1, + PYB_LED_R2 = 2, + PYB_LED_G1 = 3, + PYB_LED_G2 = 4, //STM32F4DISC - PYB_LED_R = 0, - PYB_LED_G = 1, - PYB_LED_B = 2, - PYB_LED_O = 3, + PYB_LED_R = 1, + PYB_LED_G = 2, + PYB_LED_B = 3, + PYB_LED_O = 4, } pyb_led_t; void led_init(void); |