Port of MicroPython to the mbed platform. See micropython-repl for an interactive program.

Dependents:   micropython-repl

This a port of MicroPython to the mbed Classic platform.

This provides an interpreter running on the board's USB serial connection.

Getting Started

Import the micropython-repl program into your IDE workspace on developer.mbed.org. Compile and download to your board. Connect to the USB serial port in your usual manner. You should get a startup message similar to the following:

  MicroPython v1.7-155-gdddcdd8 on 2016-04-23; K64F with ARM
  Type "help()" for more information.
  >>>

Then you can start using micropython. For example:

  >>> from mbed import DigitalOut
  >>> from pins import LED1
  >>> led = DigitalOut(LED1)
  >>> led.write(1)

Requirements

You need approximately 100K of flash memory, so this will be no good for boards with smaller amounts of storage.

Caveats

This can be considered an alpha release of the port; things may not work; APIs may change in later releases. It is NOT an official part part the micropython project, so if anything doesn't work, blame me. If it does work, most of the credit is due to micropython.

  • Only a few of the mbed classes are available in micropython so far, and not all methods of those that are.
  • Only a few boards have their full range of pin names available; for others, only a few standard ones (USBTX, USBRX, LED1) are implemented.
  • The garbage collector is not yet implemented. The interpreter will gradually consume memory and then fail.
  • Exceptions from the mbed classes are not yet handled.
  • Asynchronous processing (e.g. events on inputs) is not supported.

Credits

  • Damien P. George and other contributors who created micropython.
  • Colin Hogben, author of this port.
Committer:
Colin Hogben
Date:
Wed Apr 27 22:11:29 2016 +0100
Revision:
10:33521d742af1
Parent:
0:5868e8752d44
Update README and version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pythontech 0:5868e8752d44 1 /*
pythontech 0:5868e8752d44 2 * This file is part of the Micro Python project, http://micropython.org/
pythontech 0:5868e8752d44 3 *
pythontech 0:5868e8752d44 4 * The MIT License (MIT)
pythontech 0:5868e8752d44 5 *
pythontech 0:5868e8752d44 6 * Copyright (c) 2013, 2014 Damien P. George
pythontech 0:5868e8752d44 7 * Copyright (c) 2014 Paul Sokolovsky
pythontech 0:5868e8752d44 8 *
pythontech 0:5868e8752d44 9 * Permission is hereby granted, free of charge, to any person obtaining a copy
pythontech 0:5868e8752d44 10 * of this software and associated documentation files (the "Software"), to deal
pythontech 0:5868e8752d44 11 * in the Software without restriction, including without limitation the rights
pythontech 0:5868e8752d44 12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
pythontech 0:5868e8752d44 13 * copies of the Software, and to permit persons to whom the Software is
pythontech 0:5868e8752d44 14 * furnished to do so, subject to the following conditions:
pythontech 0:5868e8752d44 15 *
pythontech 0:5868e8752d44 16 * The above copyright notice and this permission notice shall be included in
pythontech 0:5868e8752d44 17 * all copies or substantial portions of the Software.
pythontech 0:5868e8752d44 18 *
pythontech 0:5868e8752d44 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pythontech 0:5868e8752d44 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pythontech 0:5868e8752d44 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pythontech 0:5868e8752d44 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pythontech 0:5868e8752d44 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pythontech 0:5868e8752d44 24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pythontech 0:5868e8752d44 25 * THE SOFTWARE.
pythontech 0:5868e8752d44 26 */
pythontech 0:5868e8752d44 27
pythontech 0:5868e8752d44 28 #include <string.h>
pythontech 0:5868e8752d44 29 #include <assert.h>
pythontech 0:5868e8752d44 30 #include <stdint.h>
pythontech 0:5868e8752d44 31
pythontech 0:5868e8752d44 32 #include "py/nlr.h"
pythontech 0:5868e8752d44 33 #include "py/runtime0.h"
pythontech 0:5868e8752d44 34 #include "py/runtime.h"
pythontech 0:5868e8752d44 35 #include "py/binary.h"
pythontech 0:5868e8752d44 36 #include "py/objstr.h"
pythontech 0:5868e8752d44 37
pythontech 0:5868e8752d44 38 #if MICROPY_PY_ARRAY || MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 39
pythontech 0:5868e8752d44 40 // About memoryview object: We want to reuse as much code as possible from
pythontech 0:5868e8752d44 41 // array, and keep the memoryview object 4 words in size so it fits in 1 GC
pythontech 0:5868e8752d44 42 // block. Also, memoryview must keep a pointer to the base of the buffer so
pythontech 0:5868e8752d44 43 // that the buffer is not GC'd if the original parent object is no longer
pythontech 0:5868e8752d44 44 // around (we are assuming that all memoryview'able objects return a pointer
pythontech 0:5868e8752d44 45 // which points to the start of a GC chunk). Given the above constraints we
pythontech 0:5868e8752d44 46 // do the following:
pythontech 0:5868e8752d44 47 // - typecode high bit is set if the buffer is read-write (else read-only)
pythontech 0:5868e8752d44 48 // - free is the offset in elements to the first item in the memoryview
pythontech 0:5868e8752d44 49 // - len is the length in elements
pythontech 0:5868e8752d44 50 // - items points to the start of the original buffer
pythontech 0:5868e8752d44 51 // Note that we don't handle the case where the original buffer might change
pythontech 0:5868e8752d44 52 // size due to a resize of the original parent object.
pythontech 0:5868e8752d44 53
pythontech 0:5868e8752d44 54 // make (& TYPECODE_MASK) a null operation if memorview not enabled
pythontech 0:5868e8752d44 55 #if MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 56 #define TYPECODE_MASK (0x7f)
pythontech 0:5868e8752d44 57 #else
pythontech 0:5868e8752d44 58 #define TYPECODE_MASK (~(mp_uint_t)0)
pythontech 0:5868e8752d44 59 #endif
pythontech 0:5868e8752d44 60
pythontech 0:5868e8752d44 61 typedef struct _mp_obj_array_t {
pythontech 0:5868e8752d44 62 mp_obj_base_t base;
pythontech 0:5868e8752d44 63 mp_uint_t typecode : 8;
pythontech 0:5868e8752d44 64 // free is number of unused elements after len used elements
pythontech 0:5868e8752d44 65 // alloc size = len + free
pythontech 0:5868e8752d44 66 mp_uint_t free : (8 * sizeof(mp_uint_t) - 8);
pythontech 0:5868e8752d44 67 mp_uint_t len; // in elements
pythontech 0:5868e8752d44 68 void *items;
pythontech 0:5868e8752d44 69 } mp_obj_array_t;
pythontech 0:5868e8752d44 70
pythontech 0:5868e8752d44 71 STATIC mp_obj_t array_iterator_new(mp_obj_t array_in);
pythontech 0:5868e8752d44 72 STATIC mp_obj_t array_append(mp_obj_t self_in, mp_obj_t arg);
pythontech 0:5868e8752d44 73 STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in);
pythontech 0:5868e8752d44 74 STATIC mp_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, mp_uint_t flags);
pythontech 0:5868e8752d44 75
pythontech 0:5868e8752d44 76 /******************************************************************************/
pythontech 0:5868e8752d44 77 // array
pythontech 0:5868e8752d44 78
pythontech 0:5868e8752d44 79 #if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY
pythontech 0:5868e8752d44 80 STATIC void array_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) {
pythontech 0:5868e8752d44 81 (void)kind;
pythontech 0:5868e8752d44 82 mp_obj_array_t *o = MP_OBJ_TO_PTR(o_in);
pythontech 0:5868e8752d44 83 if (o->typecode == BYTEARRAY_TYPECODE) {
pythontech 0:5868e8752d44 84 mp_print_str(print, "bytearray(b");
pythontech 0:5868e8752d44 85 mp_str_print_quoted(print, o->items, o->len, true);
pythontech 0:5868e8752d44 86 } else {
pythontech 0:5868e8752d44 87 mp_printf(print, "array('%c'", o->typecode);
pythontech 0:5868e8752d44 88 if (o->len > 0) {
pythontech 0:5868e8752d44 89 mp_print_str(print, ", [");
pythontech 0:5868e8752d44 90 for (mp_uint_t i = 0; i < o->len; i++) {
pythontech 0:5868e8752d44 91 if (i > 0) {
pythontech 0:5868e8752d44 92 mp_print_str(print, ", ");
pythontech 0:5868e8752d44 93 }
pythontech 0:5868e8752d44 94 mp_obj_print_helper(print, mp_binary_get_val_array(o->typecode, o->items, i), PRINT_REPR);
pythontech 0:5868e8752d44 95 }
pythontech 0:5868e8752d44 96 mp_print_str(print, "]");
pythontech 0:5868e8752d44 97 }
pythontech 0:5868e8752d44 98 }
pythontech 0:5868e8752d44 99 mp_print_str(print, ")");
pythontech 0:5868e8752d44 100 }
pythontech 0:5868e8752d44 101 #endif
pythontech 0:5868e8752d44 102
pythontech 0:5868e8752d44 103 #if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY
pythontech 0:5868e8752d44 104 STATIC mp_obj_array_t *array_new(char typecode, mp_uint_t n) {
pythontech 0:5868e8752d44 105 int typecode_size = mp_binary_get_size('@', typecode, NULL);
pythontech 0:5868e8752d44 106 if (typecode_size == 0) {
pythontech 0:5868e8752d44 107 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "bad typecode"));
pythontech 0:5868e8752d44 108 }
pythontech 0:5868e8752d44 109 mp_obj_array_t *o = m_new_obj(mp_obj_array_t);
pythontech 0:5868e8752d44 110 #if MICROPY_PY_BUILTINS_BYTEARRAY && MICROPY_PY_ARRAY
pythontech 0:5868e8752d44 111 o->base.type = (typecode == BYTEARRAY_TYPECODE) ? &mp_type_bytearray : &mp_type_array;
pythontech 0:5868e8752d44 112 #elif MICROPY_PY_BUILTINS_BYTEARRAY
pythontech 0:5868e8752d44 113 o->base.type = &mp_type_bytearray;
pythontech 0:5868e8752d44 114 #else
pythontech 0:5868e8752d44 115 o->base.type = &mp_type_array;
pythontech 0:5868e8752d44 116 #endif
pythontech 0:5868e8752d44 117 o->typecode = typecode;
pythontech 0:5868e8752d44 118 o->free = 0;
pythontech 0:5868e8752d44 119 o->len = n;
pythontech 0:5868e8752d44 120 o->items = m_new(byte, typecode_size * o->len);
pythontech 0:5868e8752d44 121 return o;
pythontech 0:5868e8752d44 122 }
pythontech 0:5868e8752d44 123 #endif
pythontech 0:5868e8752d44 124
pythontech 0:5868e8752d44 125 #if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY
pythontech 0:5868e8752d44 126 STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) {
pythontech 0:5868e8752d44 127 // bytearrays can be raw-initialised from anything with the buffer protocol
pythontech 0:5868e8752d44 128 // other arrays can only be raw-initialised from bytes and bytearray objects
pythontech 0:5868e8752d44 129 mp_buffer_info_t bufinfo;
pythontech 0:5868e8752d44 130 if (((MICROPY_PY_BUILTINS_BYTEARRAY
pythontech 0:5868e8752d44 131 && typecode == BYTEARRAY_TYPECODE)
pythontech 0:5868e8752d44 132 || (MICROPY_PY_ARRAY
pythontech 0:5868e8752d44 133 && (MP_OBJ_IS_TYPE(initializer, &mp_type_bytes)
pythontech 0:5868e8752d44 134 || (MICROPY_PY_BUILTINS_BYTEARRAY && MP_OBJ_IS_TYPE(initializer, &mp_type_bytearray)))))
pythontech 0:5868e8752d44 135 && mp_get_buffer(initializer, &bufinfo, MP_BUFFER_READ)) {
pythontech 0:5868e8752d44 136 // construct array from raw bytes
pythontech 0:5868e8752d44 137 // we round-down the len to make it a multiple of sz (CPython raises error)
pythontech 0:5868e8752d44 138 size_t sz = mp_binary_get_size('@', typecode, NULL);
pythontech 0:5868e8752d44 139 mp_uint_t len = bufinfo.len / sz;
pythontech 0:5868e8752d44 140 mp_obj_array_t *o = array_new(typecode, len);
pythontech 0:5868e8752d44 141 memcpy(o->items, bufinfo.buf, len * sz);
pythontech 0:5868e8752d44 142 return MP_OBJ_FROM_PTR(o);
pythontech 0:5868e8752d44 143 }
pythontech 0:5868e8752d44 144
pythontech 0:5868e8752d44 145 mp_uint_t len;
pythontech 0:5868e8752d44 146 // Try to create array of exact len if initializer len is known
pythontech 0:5868e8752d44 147 mp_obj_t len_in = mp_obj_len_maybe(initializer);
pythontech 0:5868e8752d44 148 if (len_in == MP_OBJ_NULL) {
pythontech 0:5868e8752d44 149 len = 0;
pythontech 0:5868e8752d44 150 } else {
pythontech 0:5868e8752d44 151 len = MP_OBJ_SMALL_INT_VALUE(len_in);
pythontech 0:5868e8752d44 152 }
pythontech 0:5868e8752d44 153
pythontech 0:5868e8752d44 154 mp_obj_array_t *array = array_new(typecode, len);
pythontech 0:5868e8752d44 155
pythontech 0:5868e8752d44 156 mp_obj_t iterable = mp_getiter(initializer);
pythontech 0:5868e8752d44 157 mp_obj_t item;
pythontech 0:5868e8752d44 158 mp_uint_t i = 0;
pythontech 0:5868e8752d44 159 while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
pythontech 0:5868e8752d44 160 if (len == 0) {
pythontech 0:5868e8752d44 161 array_append(MP_OBJ_FROM_PTR(array), item);
pythontech 0:5868e8752d44 162 } else {
pythontech 0:5868e8752d44 163 mp_binary_set_val_array(typecode, array->items, i++, item);
pythontech 0:5868e8752d44 164 }
pythontech 0:5868e8752d44 165 }
pythontech 0:5868e8752d44 166
pythontech 0:5868e8752d44 167 return MP_OBJ_FROM_PTR(array);
pythontech 0:5868e8752d44 168 }
pythontech 0:5868e8752d44 169 #endif
pythontech 0:5868e8752d44 170
pythontech 0:5868e8752d44 171 #if MICROPY_PY_ARRAY
pythontech 0:5868e8752d44 172 STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
pythontech 0:5868e8752d44 173 (void)type_in;
pythontech 0:5868e8752d44 174 mp_arg_check_num(n_args, n_kw, 1, 2, false);
pythontech 0:5868e8752d44 175
pythontech 0:5868e8752d44 176 // get typecode
pythontech 0:5868e8752d44 177 mp_uint_t l;
pythontech 0:5868e8752d44 178 const char *typecode = mp_obj_str_get_data(args[0], &l);
pythontech 0:5868e8752d44 179
pythontech 0:5868e8752d44 180 if (n_args == 1) {
pythontech 0:5868e8752d44 181 // 1 arg: make an empty array
pythontech 0:5868e8752d44 182 return MP_OBJ_FROM_PTR(array_new(*typecode, 0));
pythontech 0:5868e8752d44 183 } else {
pythontech 0:5868e8752d44 184 // 2 args: construct the array from the given object
pythontech 0:5868e8752d44 185 return array_construct(*typecode, args[1]);
pythontech 0:5868e8752d44 186 }
pythontech 0:5868e8752d44 187 }
pythontech 0:5868e8752d44 188 #endif
pythontech 0:5868e8752d44 189
pythontech 0:5868e8752d44 190 #if MICROPY_PY_BUILTINS_BYTEARRAY
pythontech 0:5868e8752d44 191 STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
pythontech 0:5868e8752d44 192 (void)type_in;
pythontech 0:5868e8752d44 193 mp_arg_check_num(n_args, n_kw, 0, 1, false);
pythontech 0:5868e8752d44 194
pythontech 0:5868e8752d44 195 if (n_args == 0) {
pythontech 0:5868e8752d44 196 // no args: construct an empty bytearray
pythontech 0:5868e8752d44 197 return MP_OBJ_FROM_PTR(array_new(BYTEARRAY_TYPECODE, 0));
pythontech 0:5868e8752d44 198 } else if (MP_OBJ_IS_INT(args[0])) {
pythontech 0:5868e8752d44 199 // 1 arg, an integer: construct a blank bytearray of that length
pythontech 0:5868e8752d44 200 mp_uint_t len = mp_obj_get_int(args[0]);
pythontech 0:5868e8752d44 201 mp_obj_array_t *o = array_new(BYTEARRAY_TYPECODE, len);
pythontech 0:5868e8752d44 202 memset(o->items, 0, len);
pythontech 0:5868e8752d44 203 return MP_OBJ_FROM_PTR(o);
pythontech 0:5868e8752d44 204 } else {
pythontech 0:5868e8752d44 205 // 1 arg: construct the bytearray from that
pythontech 0:5868e8752d44 206 return array_construct(BYTEARRAY_TYPECODE, args[0]);
pythontech 0:5868e8752d44 207 }
pythontech 0:5868e8752d44 208 }
pythontech 0:5868e8752d44 209 #endif
pythontech 0:5868e8752d44 210
pythontech 0:5868e8752d44 211 #if MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 212
pythontech 0:5868e8752d44 213 mp_obj_t mp_obj_new_memoryview(byte typecode, mp_uint_t nitems, void *items) {
pythontech 0:5868e8752d44 214 mp_obj_array_t *self = m_new_obj(mp_obj_array_t);
pythontech 0:5868e8752d44 215 self->base.type = &mp_type_memoryview;
pythontech 0:5868e8752d44 216 self->typecode = typecode;
pythontech 0:5868e8752d44 217 self->free = 0;
pythontech 0:5868e8752d44 218 self->len = nitems;
pythontech 0:5868e8752d44 219 self->items = items;
pythontech 0:5868e8752d44 220 return MP_OBJ_FROM_PTR(self);
pythontech 0:5868e8752d44 221 }
pythontech 0:5868e8752d44 222
pythontech 0:5868e8752d44 223 STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
pythontech 0:5868e8752d44 224 (void)type_in;
pythontech 0:5868e8752d44 225
pythontech 0:5868e8752d44 226 // TODO possibly allow memoryview constructor to take start/stop so that one
pythontech 0:5868e8752d44 227 // can do memoryview(b, 4, 8) instead of memoryview(b)[4:8] (uses less RAM)
pythontech 0:5868e8752d44 228
pythontech 0:5868e8752d44 229 mp_arg_check_num(n_args, n_kw, 1, 1, false);
pythontech 0:5868e8752d44 230
pythontech 0:5868e8752d44 231 mp_buffer_info_t bufinfo;
pythontech 0:5868e8752d44 232 mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
pythontech 0:5868e8752d44 233
pythontech 0:5868e8752d44 234 mp_obj_array_t *self = MP_OBJ_TO_PTR(mp_obj_new_memoryview(bufinfo.typecode,
pythontech 0:5868e8752d44 235 bufinfo.len / mp_binary_get_size('@', bufinfo.typecode, NULL),
pythontech 0:5868e8752d44 236 bufinfo.buf));
pythontech 0:5868e8752d44 237
pythontech 0:5868e8752d44 238 // test if the object can be written to
pythontech 0:5868e8752d44 239 if (mp_get_buffer(args[0], &bufinfo, MP_BUFFER_RW)) {
pythontech 0:5868e8752d44 240 self->typecode |= 0x80; // used to indicate writable buffer
pythontech 0:5868e8752d44 241 }
pythontech 0:5868e8752d44 242
pythontech 0:5868e8752d44 243 return MP_OBJ_FROM_PTR(self);
pythontech 0:5868e8752d44 244 }
pythontech 0:5868e8752d44 245 #endif
pythontech 0:5868e8752d44 246
pythontech 0:5868e8752d44 247 STATIC mp_obj_t array_unary_op(mp_uint_t op, mp_obj_t o_in) {
pythontech 0:5868e8752d44 248 mp_obj_array_t *o = MP_OBJ_TO_PTR(o_in);
pythontech 0:5868e8752d44 249 switch (op) {
pythontech 0:5868e8752d44 250 case MP_UNARY_OP_BOOL: return mp_obj_new_bool(o->len != 0);
pythontech 0:5868e8752d44 251 case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(o->len);
pythontech 0:5868e8752d44 252 default: return MP_OBJ_NULL; // op not supported
pythontech 0:5868e8752d44 253 }
pythontech 0:5868e8752d44 254 }
pythontech 0:5868e8752d44 255
pythontech 0:5868e8752d44 256 STATIC mp_obj_t array_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
pythontech 0:5868e8752d44 257 mp_obj_array_t *lhs = MP_OBJ_TO_PTR(lhs_in);
pythontech 0:5868e8752d44 258 switch (op) {
pythontech 0:5868e8752d44 259 case MP_BINARY_OP_ADD: {
pythontech 0:5868e8752d44 260 // allow to add anything that has the buffer protocol (extension to CPython)
pythontech 0:5868e8752d44 261 mp_buffer_info_t lhs_bufinfo;
pythontech 0:5868e8752d44 262 mp_buffer_info_t rhs_bufinfo;
pythontech 0:5868e8752d44 263 array_get_buffer(lhs_in, &lhs_bufinfo, MP_BUFFER_READ);
pythontech 0:5868e8752d44 264 mp_get_buffer_raise(rhs_in, &rhs_bufinfo, MP_BUFFER_READ);
pythontech 0:5868e8752d44 265
pythontech 0:5868e8752d44 266 size_t sz = mp_binary_get_size('@', lhs_bufinfo.typecode, NULL);
pythontech 0:5868e8752d44 267
pythontech 0:5868e8752d44 268 // convert byte count to element count (in case rhs is not multiple of sz)
pythontech 0:5868e8752d44 269 mp_uint_t rhs_len = rhs_bufinfo.len / sz;
pythontech 0:5868e8752d44 270
pythontech 0:5868e8752d44 271 // note: lhs->len is element count of lhs, lhs_bufinfo.len is byte count
pythontech 0:5868e8752d44 272 mp_obj_array_t *res = array_new(lhs_bufinfo.typecode, lhs->len + rhs_len);
pythontech 0:5868e8752d44 273 mp_seq_cat((byte*)res->items, lhs_bufinfo.buf, lhs_bufinfo.len, rhs_bufinfo.buf, rhs_len * sz, byte);
pythontech 0:5868e8752d44 274 return MP_OBJ_FROM_PTR(res);
pythontech 0:5868e8752d44 275 }
pythontech 0:5868e8752d44 276
pythontech 0:5868e8752d44 277 case MP_BINARY_OP_INPLACE_ADD: {
pythontech 0:5868e8752d44 278 #if MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 279 if (lhs->base.type == &mp_type_memoryview) {
pythontech 0:5868e8752d44 280 return MP_OBJ_NULL; // op not supported
pythontech 0:5868e8752d44 281 }
pythontech 0:5868e8752d44 282 #endif
pythontech 0:5868e8752d44 283 array_extend(lhs_in, rhs_in);
pythontech 0:5868e8752d44 284 return lhs_in;
pythontech 0:5868e8752d44 285 }
pythontech 0:5868e8752d44 286
pythontech 0:5868e8752d44 287 case MP_BINARY_OP_IN: {
pythontech 0:5868e8752d44 288 /* NOTE `a in b` is `b.__contains__(a)` */
pythontech 0:5868e8752d44 289 mp_buffer_info_t lhs_bufinfo;
pythontech 0:5868e8752d44 290 mp_buffer_info_t rhs_bufinfo;
pythontech 0:5868e8752d44 291
pythontech 0:5868e8752d44 292 // Can search string only in bytearray
pythontech 0:5868e8752d44 293 if (mp_get_buffer(rhs_in, &rhs_bufinfo, MP_BUFFER_READ)) {
pythontech 0:5868e8752d44 294 if (!MP_OBJ_IS_TYPE(lhs_in, &mp_type_bytearray)) {
pythontech 0:5868e8752d44 295 return mp_const_false;
pythontech 0:5868e8752d44 296 }
pythontech 0:5868e8752d44 297 array_get_buffer(lhs_in, &lhs_bufinfo, MP_BUFFER_READ);
pythontech 0:5868e8752d44 298 return mp_obj_new_bool(
pythontech 0:5868e8752d44 299 find_subbytes(lhs_bufinfo.buf, lhs_bufinfo.len, rhs_bufinfo.buf, rhs_bufinfo.len, 1) != NULL);
pythontech 0:5868e8752d44 300 }
pythontech 0:5868e8752d44 301
pythontech 0:5868e8752d44 302 // Otherwise, can only look for a scalar numeric value in an array
pythontech 0:5868e8752d44 303 if (MP_OBJ_IS_INT(rhs_in) || mp_obj_is_float(rhs_in)) {
pythontech 0:5868e8752d44 304 mp_not_implemented("");
pythontech 0:5868e8752d44 305 }
pythontech 0:5868e8752d44 306
pythontech 0:5868e8752d44 307 return mp_const_false;
pythontech 0:5868e8752d44 308 }
pythontech 0:5868e8752d44 309
pythontech 0:5868e8752d44 310 case MP_BINARY_OP_EQUAL: {
pythontech 0:5868e8752d44 311 mp_buffer_info_t lhs_bufinfo;
pythontech 0:5868e8752d44 312 mp_buffer_info_t rhs_bufinfo;
pythontech 0:5868e8752d44 313 array_get_buffer(lhs_in, &lhs_bufinfo, MP_BUFFER_READ);
pythontech 0:5868e8752d44 314 if (!mp_get_buffer(rhs_in, &rhs_bufinfo, MP_BUFFER_READ)) {
pythontech 0:5868e8752d44 315 return mp_const_false;
pythontech 0:5868e8752d44 316 }
pythontech 0:5868e8752d44 317 return mp_obj_new_bool(mp_seq_cmp_bytes(op, lhs_bufinfo.buf, lhs_bufinfo.len, rhs_bufinfo.buf, rhs_bufinfo.len));
pythontech 0:5868e8752d44 318 }
pythontech 0:5868e8752d44 319
pythontech 0:5868e8752d44 320 default:
pythontech 0:5868e8752d44 321 return MP_OBJ_NULL; // op not supported
pythontech 0:5868e8752d44 322 }
pythontech 0:5868e8752d44 323 }
pythontech 0:5868e8752d44 324
pythontech 0:5868e8752d44 325 #if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY
pythontech 0:5868e8752d44 326 STATIC mp_obj_t array_append(mp_obj_t self_in, mp_obj_t arg) {
pythontech 0:5868e8752d44 327 // self is not a memoryview, so we don't need to use (& TYPECODE_MASK)
pythontech 0:5868e8752d44 328 assert((MICROPY_PY_BUILTINS_BYTEARRAY && MP_OBJ_IS_TYPE(self_in, &mp_type_bytearray))
pythontech 0:5868e8752d44 329 || (MICROPY_PY_ARRAY && MP_OBJ_IS_TYPE(self_in, &mp_type_array)));
pythontech 0:5868e8752d44 330 mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in);
pythontech 0:5868e8752d44 331
pythontech 0:5868e8752d44 332 if (self->free == 0) {
pythontech 0:5868e8752d44 333 size_t item_sz = mp_binary_get_size('@', self->typecode, NULL);
pythontech 0:5868e8752d44 334 // TODO: alloc policy
pythontech 0:5868e8752d44 335 self->free = 8;
pythontech 0:5868e8752d44 336 self->items = m_renew(byte, self->items, item_sz * self->len, item_sz * (self->len + self->free));
pythontech 0:5868e8752d44 337 mp_seq_clear(self->items, self->len + 1, self->len + self->free, item_sz);
pythontech 0:5868e8752d44 338 }
pythontech 0:5868e8752d44 339 mp_binary_set_val_array(self->typecode, self->items, self->len, arg);
pythontech 0:5868e8752d44 340 // only update length/free if set succeeded
pythontech 0:5868e8752d44 341 self->len++;
pythontech 0:5868e8752d44 342 self->free--;
pythontech 0:5868e8752d44 343 return mp_const_none; // return None, as per CPython
pythontech 0:5868e8752d44 344 }
pythontech 0:5868e8752d44 345 STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_append_obj, array_append);
pythontech 0:5868e8752d44 346
pythontech 0:5868e8752d44 347 STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) {
pythontech 0:5868e8752d44 348 // self is not a memoryview, so we don't need to use (& TYPECODE_MASK)
pythontech 0:5868e8752d44 349 assert((MICROPY_PY_BUILTINS_BYTEARRAY && MP_OBJ_IS_TYPE(self_in, &mp_type_bytearray))
pythontech 0:5868e8752d44 350 || (MICROPY_PY_ARRAY && MP_OBJ_IS_TYPE(self_in, &mp_type_array)));
pythontech 0:5868e8752d44 351 mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in);
pythontech 0:5868e8752d44 352
pythontech 0:5868e8752d44 353 // allow to extend by anything that has the buffer protocol (extension to CPython)
pythontech 0:5868e8752d44 354 mp_buffer_info_t arg_bufinfo;
pythontech 0:5868e8752d44 355 mp_get_buffer_raise(arg_in, &arg_bufinfo, MP_BUFFER_READ);
pythontech 0:5868e8752d44 356
pythontech 0:5868e8752d44 357 size_t sz = mp_binary_get_size('@', self->typecode, NULL);
pythontech 0:5868e8752d44 358
pythontech 0:5868e8752d44 359 // convert byte count to element count
pythontech 0:5868e8752d44 360 mp_uint_t len = arg_bufinfo.len / sz;
pythontech 0:5868e8752d44 361
pythontech 0:5868e8752d44 362 // make sure we have enough room to extend
pythontech 0:5868e8752d44 363 // TODO: alloc policy; at the moment we go conservative
pythontech 0:5868e8752d44 364 if (self->free < len) {
pythontech 0:5868e8752d44 365 self->items = m_renew(byte, self->items, (self->len + self->free) * sz, (self->len + len) * sz);
pythontech 0:5868e8752d44 366 self->free = 0;
pythontech 0:5868e8752d44 367 } else {
pythontech 0:5868e8752d44 368 self->free -= len;
pythontech 0:5868e8752d44 369 }
pythontech 0:5868e8752d44 370
pythontech 0:5868e8752d44 371 // extend
pythontech 0:5868e8752d44 372 mp_seq_copy((byte*)self->items + self->len * sz, arg_bufinfo.buf, len * sz, byte);
pythontech 0:5868e8752d44 373 self->len += len;
pythontech 0:5868e8752d44 374
pythontech 0:5868e8752d44 375 return mp_const_none;
pythontech 0:5868e8752d44 376 }
pythontech 0:5868e8752d44 377 STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_extend_obj, array_extend);
pythontech 0:5868e8752d44 378 #endif
pythontech 0:5868e8752d44 379
pythontech 0:5868e8752d44 380 STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
pythontech 0:5868e8752d44 381 if (value == MP_OBJ_NULL) {
pythontech 0:5868e8752d44 382 // delete item
pythontech 0:5868e8752d44 383 // TODO implement
pythontech 0:5868e8752d44 384 // TODO: confirmed that both bytearray and array.array support
pythontech 0:5868e8752d44 385 // slice deletion
pythontech 0:5868e8752d44 386 return MP_OBJ_NULL; // op not supported
pythontech 0:5868e8752d44 387 } else {
pythontech 0:5868e8752d44 388 mp_obj_array_t *o = MP_OBJ_TO_PTR(self_in);
pythontech 0:5868e8752d44 389 if (0) {
pythontech 0:5868e8752d44 390 #if MICROPY_PY_BUILTINS_SLICE
pythontech 0:5868e8752d44 391 } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) {
pythontech 0:5868e8752d44 392 mp_bound_slice_t slice;
pythontech 0:5868e8752d44 393 if (!mp_seq_get_fast_slice_indexes(o->len, index_in, &slice)) {
pythontech 0:5868e8752d44 394 mp_not_implemented("only slices with step=1 (aka None) are supported");
pythontech 0:5868e8752d44 395 }
pythontech 0:5868e8752d44 396 if (value != MP_OBJ_SENTINEL) {
pythontech 0:5868e8752d44 397 #if MICROPY_PY_ARRAY_SLICE_ASSIGN
pythontech 0:5868e8752d44 398 // Assign
pythontech 0:5868e8752d44 399 mp_uint_t src_len;
pythontech 0:5868e8752d44 400 void *src_items;
pythontech 0:5868e8752d44 401 size_t item_sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL);
pythontech 0:5868e8752d44 402 if (MP_OBJ_IS_OBJ(value) && ((mp_obj_base_t*)MP_OBJ_TO_PTR(value))->type->subscr == array_subscr) {
pythontech 0:5868e8752d44 403 // value is array, bytearray or memoryview
pythontech 0:5868e8752d44 404 mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value);
pythontech 0:5868e8752d44 405 if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) {
pythontech 0:5868e8752d44 406 compat_error:
pythontech 0:5868e8752d44 407 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "lhs and rhs should be compatible"));
pythontech 0:5868e8752d44 408 }
pythontech 0:5868e8752d44 409 src_len = src_slice->len;
pythontech 0:5868e8752d44 410 src_items = src_slice->items;
pythontech 0:5868e8752d44 411 #if MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 412 if (MP_OBJ_IS_TYPE(value, &mp_type_memoryview)) {
pythontech 0:5868e8752d44 413 src_items = (uint8_t*)src_items + (src_slice->free * item_sz);
pythontech 0:5868e8752d44 414 }
pythontech 0:5868e8752d44 415 #endif
pythontech 0:5868e8752d44 416 } else if (MP_OBJ_IS_TYPE(value, &mp_type_bytes)) {
pythontech 0:5868e8752d44 417 if (item_sz != 1) {
pythontech 0:5868e8752d44 418 goto compat_error;
pythontech 0:5868e8752d44 419 }
pythontech 0:5868e8752d44 420 mp_buffer_info_t bufinfo;
pythontech 0:5868e8752d44 421 mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_READ);
pythontech 0:5868e8752d44 422 src_len = bufinfo.len;
pythontech 0:5868e8752d44 423 src_items = bufinfo.buf;
pythontech 0:5868e8752d44 424 } else {
pythontech 0:5868e8752d44 425 mp_not_implemented("array/bytes required on right side");
pythontech 0:5868e8752d44 426 }
pythontech 0:5868e8752d44 427
pythontech 0:5868e8752d44 428 // TODO: check src/dst compat
pythontech 0:5868e8752d44 429 mp_int_t len_adj = src_len - (slice.stop - slice.start);
pythontech 0:5868e8752d44 430 uint8_t* dest_items = o->items;
pythontech 0:5868e8752d44 431 #if MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 432 if (o->base.type == &mp_type_memoryview) {
pythontech 0:5868e8752d44 433 if (len_adj != 0) {
pythontech 0:5868e8752d44 434 goto compat_error;
pythontech 0:5868e8752d44 435 }
pythontech 0:5868e8752d44 436 dest_items += o->free * item_sz;
pythontech 0:5868e8752d44 437 }
pythontech 0:5868e8752d44 438 #endif
pythontech 0:5868e8752d44 439 if (len_adj > 0) {
pythontech 0:5868e8752d44 440 if (len_adj > o->free) {
pythontech 0:5868e8752d44 441 // TODO: alloc policy; at the moment we go conservative
pythontech 0:5868e8752d44 442 o->items = m_renew(byte, o->items, (o->len + o->free) * item_sz, (o->len + len_adj) * item_sz);
pythontech 0:5868e8752d44 443 o->free = 0;
pythontech 0:5868e8752d44 444 dest_items = o->items;
pythontech 0:5868e8752d44 445 }
pythontech 0:5868e8752d44 446 mp_seq_replace_slice_grow_inplace(dest_items, o->len,
pythontech 0:5868e8752d44 447 slice.start, slice.stop, src_items, src_len, len_adj, item_sz);
pythontech 0:5868e8752d44 448 } else {
pythontech 0:5868e8752d44 449 mp_seq_replace_slice_no_grow(dest_items, o->len,
pythontech 0:5868e8752d44 450 slice.start, slice.stop, src_items, src_len, item_sz);
pythontech 0:5868e8752d44 451 // Clear "freed" elements at the end of list
pythontech 0:5868e8752d44 452 // TODO: This is actually only needed for typecode=='O'
pythontech 0:5868e8752d44 453 mp_seq_clear(dest_items, o->len + len_adj, o->len, item_sz);
pythontech 0:5868e8752d44 454 // TODO: alloc policy after shrinking
pythontech 0:5868e8752d44 455 }
pythontech 0:5868e8752d44 456 o->len += len_adj;
pythontech 0:5868e8752d44 457 return mp_const_none;
pythontech 0:5868e8752d44 458 #else
pythontech 0:5868e8752d44 459 return MP_OBJ_NULL; // op not supported
pythontech 0:5868e8752d44 460 #endif
pythontech 0:5868e8752d44 461 }
pythontech 0:5868e8752d44 462
pythontech 0:5868e8752d44 463 mp_obj_array_t *res;
pythontech 0:5868e8752d44 464 size_t sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL);
pythontech 0:5868e8752d44 465 assert(sz > 0);
pythontech 0:5868e8752d44 466 if (0) {
pythontech 0:5868e8752d44 467 // dummy
pythontech 0:5868e8752d44 468 #if MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 469 } else if (o->base.type == &mp_type_memoryview) {
pythontech 0:5868e8752d44 470 res = m_new_obj(mp_obj_array_t);
pythontech 0:5868e8752d44 471 *res = *o;
pythontech 0:5868e8752d44 472 res->free += slice.start;
pythontech 0:5868e8752d44 473 res->len = slice.stop - slice.start;
pythontech 0:5868e8752d44 474 #endif
pythontech 0:5868e8752d44 475 } else {
pythontech 0:5868e8752d44 476 res = array_new(o->typecode, slice.stop - slice.start);
pythontech 0:5868e8752d44 477 memcpy(res->items, (uint8_t*)o->items + slice.start * sz, (slice.stop - slice.start) * sz);
pythontech 0:5868e8752d44 478 }
pythontech 0:5868e8752d44 479 return MP_OBJ_FROM_PTR(res);
pythontech 0:5868e8752d44 480 #endif
pythontech 0:5868e8752d44 481 } else {
pythontech 0:5868e8752d44 482 mp_uint_t index = mp_get_index(o->base.type, o->len, index_in, false);
pythontech 0:5868e8752d44 483 #if MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 484 if (o->base.type == &mp_type_memoryview) {
pythontech 0:5868e8752d44 485 index += o->free;
pythontech 0:5868e8752d44 486 if (value != MP_OBJ_SENTINEL && (o->typecode & 0x80) == 0) {
pythontech 0:5868e8752d44 487 // store to read-only memoryview
pythontech 0:5868e8752d44 488 return MP_OBJ_NULL;
pythontech 0:5868e8752d44 489 }
pythontech 0:5868e8752d44 490 }
pythontech 0:5868e8752d44 491 #endif
pythontech 0:5868e8752d44 492 if (value == MP_OBJ_SENTINEL) {
pythontech 0:5868e8752d44 493 // load
pythontech 0:5868e8752d44 494 return mp_binary_get_val_array(o->typecode & TYPECODE_MASK, o->items, index);
pythontech 0:5868e8752d44 495 } else {
pythontech 0:5868e8752d44 496 // store
pythontech 0:5868e8752d44 497 mp_binary_set_val_array(o->typecode & TYPECODE_MASK, o->items, index, value);
pythontech 0:5868e8752d44 498 return mp_const_none;
pythontech 0:5868e8752d44 499 }
pythontech 0:5868e8752d44 500 }
pythontech 0:5868e8752d44 501 }
pythontech 0:5868e8752d44 502 }
pythontech 0:5868e8752d44 503
pythontech 0:5868e8752d44 504 STATIC mp_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
pythontech 0:5868e8752d44 505 mp_obj_array_t *o = MP_OBJ_TO_PTR(o_in);
pythontech 0:5868e8752d44 506 size_t sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL);
pythontech 0:5868e8752d44 507 bufinfo->buf = o->items;
pythontech 0:5868e8752d44 508 bufinfo->len = o->len * sz;
pythontech 0:5868e8752d44 509 bufinfo->typecode = o->typecode & TYPECODE_MASK;
pythontech 0:5868e8752d44 510 #if MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 511 if (o->base.type == &mp_type_memoryview) {
pythontech 0:5868e8752d44 512 if ((o->typecode & 0x80) == 0 && (flags & MP_BUFFER_WRITE)) {
pythontech 0:5868e8752d44 513 // read-only memoryview
pythontech 0:5868e8752d44 514 return 1;
pythontech 0:5868e8752d44 515 }
pythontech 0:5868e8752d44 516 bufinfo->buf = (uint8_t*)bufinfo->buf + (mp_uint_t)o->free * sz;
pythontech 0:5868e8752d44 517 }
pythontech 0:5868e8752d44 518 #else
pythontech 0:5868e8752d44 519 (void)flags;
pythontech 0:5868e8752d44 520 #endif
pythontech 0:5868e8752d44 521 return 0;
pythontech 0:5868e8752d44 522 }
pythontech 0:5868e8752d44 523
pythontech 0:5868e8752d44 524 #if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY
pythontech 0:5868e8752d44 525 STATIC const mp_rom_map_elem_t array_locals_dict_table[] = {
pythontech 0:5868e8752d44 526 { MP_ROM_QSTR(MP_QSTR_append), MP_ROM_PTR(&array_append_obj) },
pythontech 0:5868e8752d44 527 { MP_ROM_QSTR(MP_QSTR_extend), MP_ROM_PTR(&array_extend_obj) },
pythontech 0:5868e8752d44 528 };
pythontech 0:5868e8752d44 529
pythontech 0:5868e8752d44 530 STATIC MP_DEFINE_CONST_DICT(array_locals_dict, array_locals_dict_table);
pythontech 0:5868e8752d44 531 #endif
pythontech 0:5868e8752d44 532
pythontech 0:5868e8752d44 533 #if MICROPY_PY_ARRAY
pythontech 0:5868e8752d44 534 const mp_obj_type_t mp_type_array = {
pythontech 0:5868e8752d44 535 { &mp_type_type },
pythontech 0:5868e8752d44 536 .name = MP_QSTR_array,
pythontech 0:5868e8752d44 537 .print = array_print,
pythontech 0:5868e8752d44 538 .make_new = array_make_new,
pythontech 0:5868e8752d44 539 .getiter = array_iterator_new,
pythontech 0:5868e8752d44 540 .unary_op = array_unary_op,
pythontech 0:5868e8752d44 541 .binary_op = array_binary_op,
pythontech 0:5868e8752d44 542 .subscr = array_subscr,
pythontech 0:5868e8752d44 543 .buffer_p = { .get_buffer = array_get_buffer },
pythontech 0:5868e8752d44 544 .locals_dict = (mp_obj_dict_t*)&array_locals_dict,
pythontech 0:5868e8752d44 545 };
pythontech 0:5868e8752d44 546 #endif
pythontech 0:5868e8752d44 547
pythontech 0:5868e8752d44 548 #if MICROPY_PY_BUILTINS_BYTEARRAY
pythontech 0:5868e8752d44 549 const mp_obj_type_t mp_type_bytearray = {
pythontech 0:5868e8752d44 550 { &mp_type_type },
pythontech 0:5868e8752d44 551 .name = MP_QSTR_bytearray,
pythontech 0:5868e8752d44 552 .print = array_print,
pythontech 0:5868e8752d44 553 .make_new = bytearray_make_new,
pythontech 0:5868e8752d44 554 .getiter = array_iterator_new,
pythontech 0:5868e8752d44 555 .unary_op = array_unary_op,
pythontech 0:5868e8752d44 556 .binary_op = array_binary_op,
pythontech 0:5868e8752d44 557 .subscr = array_subscr,
pythontech 0:5868e8752d44 558 .buffer_p = { .get_buffer = array_get_buffer },
pythontech 0:5868e8752d44 559 .locals_dict = (mp_obj_dict_t*)&array_locals_dict,
pythontech 0:5868e8752d44 560 };
pythontech 0:5868e8752d44 561 #endif
pythontech 0:5868e8752d44 562
pythontech 0:5868e8752d44 563 #if MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 564 const mp_obj_type_t mp_type_memoryview = {
pythontech 0:5868e8752d44 565 { &mp_type_type },
pythontech 0:5868e8752d44 566 .name = MP_QSTR_memoryview,
pythontech 0:5868e8752d44 567 .make_new = memoryview_make_new,
pythontech 0:5868e8752d44 568 .getiter = array_iterator_new,
pythontech 0:5868e8752d44 569 .unary_op = array_unary_op,
pythontech 0:5868e8752d44 570 .binary_op = array_binary_op,
pythontech 0:5868e8752d44 571 .subscr = array_subscr,
pythontech 0:5868e8752d44 572 .buffer_p = { .get_buffer = array_get_buffer },
pythontech 0:5868e8752d44 573 };
pythontech 0:5868e8752d44 574 #endif
pythontech 0:5868e8752d44 575
pythontech 0:5868e8752d44 576 /* unused
pythontech 0:5868e8752d44 577 mp_uint_t mp_obj_array_len(mp_obj_t self_in) {
pythontech 0:5868e8752d44 578 return ((mp_obj_array_t *)self_in)->len;
pythontech 0:5868e8752d44 579 }
pythontech 0:5868e8752d44 580 */
pythontech 0:5868e8752d44 581
pythontech 0:5868e8752d44 582 #if MICROPY_PY_BUILTINS_BYTEARRAY
pythontech 0:5868e8752d44 583 mp_obj_t mp_obj_new_bytearray(mp_uint_t n, void *items) {
pythontech 0:5868e8752d44 584 mp_obj_array_t *o = array_new(BYTEARRAY_TYPECODE, n);
pythontech 0:5868e8752d44 585 memcpy(o->items, items, n);
pythontech 0:5868e8752d44 586 return MP_OBJ_FROM_PTR(o);
pythontech 0:5868e8752d44 587 }
pythontech 0:5868e8752d44 588
pythontech 0:5868e8752d44 589 // Create bytearray which references specified memory area
pythontech 0:5868e8752d44 590 mp_obj_t mp_obj_new_bytearray_by_ref(mp_uint_t n, void *items) {
pythontech 0:5868e8752d44 591 mp_obj_array_t *o = m_new_obj(mp_obj_array_t);
pythontech 0:5868e8752d44 592 o->base.type = &mp_type_bytearray;
pythontech 0:5868e8752d44 593 o->typecode = BYTEARRAY_TYPECODE;
pythontech 0:5868e8752d44 594 o->free = 0;
pythontech 0:5868e8752d44 595 o->len = n;
pythontech 0:5868e8752d44 596 o->items = items;
pythontech 0:5868e8752d44 597 return MP_OBJ_FROM_PTR(o);
pythontech 0:5868e8752d44 598 }
pythontech 0:5868e8752d44 599 #endif
pythontech 0:5868e8752d44 600
pythontech 0:5868e8752d44 601 /******************************************************************************/
pythontech 0:5868e8752d44 602 // array iterator
pythontech 0:5868e8752d44 603
pythontech 0:5868e8752d44 604 typedef struct _mp_obj_array_it_t {
pythontech 0:5868e8752d44 605 mp_obj_base_t base;
pythontech 0:5868e8752d44 606 mp_obj_array_t *array;
pythontech 0:5868e8752d44 607 mp_uint_t offset;
pythontech 0:5868e8752d44 608 mp_uint_t cur;
pythontech 0:5868e8752d44 609 } mp_obj_array_it_t;
pythontech 0:5868e8752d44 610
pythontech 0:5868e8752d44 611 STATIC mp_obj_t array_it_iternext(mp_obj_t self_in) {
pythontech 0:5868e8752d44 612 mp_obj_array_it_t *self = MP_OBJ_TO_PTR(self_in);
pythontech 0:5868e8752d44 613 if (self->cur < self->array->len) {
pythontech 0:5868e8752d44 614 return mp_binary_get_val_array(self->array->typecode & TYPECODE_MASK, self->array->items, self->offset + self->cur++);
pythontech 0:5868e8752d44 615 } else {
pythontech 0:5868e8752d44 616 return MP_OBJ_STOP_ITERATION;
pythontech 0:5868e8752d44 617 }
pythontech 0:5868e8752d44 618 }
pythontech 0:5868e8752d44 619
pythontech 0:5868e8752d44 620 STATIC const mp_obj_type_t array_it_type = {
pythontech 0:5868e8752d44 621 { &mp_type_type },
pythontech 0:5868e8752d44 622 .name = MP_QSTR_iterator,
pythontech 0:5868e8752d44 623 .getiter = mp_identity,
pythontech 0:5868e8752d44 624 .iternext = array_it_iternext,
pythontech 0:5868e8752d44 625 };
pythontech 0:5868e8752d44 626
pythontech 0:5868e8752d44 627 STATIC mp_obj_t array_iterator_new(mp_obj_t array_in) {
pythontech 0:5868e8752d44 628 mp_obj_array_t *array = MP_OBJ_TO_PTR(array_in);
pythontech 0:5868e8752d44 629 mp_obj_array_it_t *o = m_new0(mp_obj_array_it_t, 1);
pythontech 0:5868e8752d44 630 o->base.type = &array_it_type;
pythontech 0:5868e8752d44 631 o->array = array;
pythontech 0:5868e8752d44 632 #if MICROPY_PY_BUILTINS_MEMORYVIEW
pythontech 0:5868e8752d44 633 if (array->base.type == &mp_type_memoryview) {
pythontech 0:5868e8752d44 634 o->offset = array->free;
pythontech 0:5868e8752d44 635 }
pythontech 0:5868e8752d44 636 #endif
pythontech 0:5868e8752d44 637 return MP_OBJ_FROM_PTR(o);
pythontech 0:5868e8752d44 638 }
pythontech 0:5868e8752d44 639
pythontech 0:5868e8752d44 640 #endif // MICROPY_PY_ARRAY || MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_BUILTINS_MEMORYVIEW