STATIC mp_obj_t neopixel_clear_(mp_obj_t self_in) { neopixel_obj_t *self = (neopixel_obj_t*)self_in; neopixel_clear(&self->strip); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(neopixel_clear_obj, neopixel_clear_); STATIC mp_obj_t neopixel_show_(mp_obj_t self_in) { neopixel_obj_t *self = (neopixel_obj_t*)self_in; neopixel_show(&self->strip); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(neopixel_show_obj, neopixel_show_); STATIC const mp_map_elem_t neopixel_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_clear), (mp_obj_t)&neopixel_clear_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_show), (mp_obj_t)&neopixel_show_obj }, }; STATIC MP_DEFINE_CONST_DICT(neopixel_locals_dict, neopixel_locals_dict_table); const mp_obj_type_t neopixel_type = { { &mp_type_type }, .name = MP_QSTR_NeoPixel, .print = NULL, .make_new = neopixel_make_new, .call = NULL, .unary_op = neopixel_unary_op, .binary_op = NULL, .attr = NULL, .subscr = neopixel_subscr,
STATIC mp_obj_t dict_keys(mp_obj_t self_in) { return dict_view(self_in, MP_DICT_VIEW_KEYS); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_keys_obj, dict_keys); STATIC mp_obj_t dict_values(mp_obj_t self_in) { return dict_view(self_in, MP_DICT_VIEW_VALUES); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_values_obj, dict_values); /******************************************************************************/ /* dict constructors & public C API */ STATIC const mp_map_elem_t dict_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_clear), (mp_obj_t)&dict_clear_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_copy), (mp_obj_t)&dict_copy_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_fromkeys), (mp_obj_t)&dict_fromkeys_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_get), (mp_obj_t)&dict_get_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_items), (mp_obj_t)&dict_items_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_keys), (mp_obj_t)&dict_keys_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_pop), (mp_obj_t)&dict_pop_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_popitem), (mp_obj_t)&dict_popitem_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_setdefault), (mp_obj_t)&dict_setdefault_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_update), (mp_obj_t)&dict_update_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_values), (mp_obj_t)&dict_values_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR___getitem__), (mp_obj_t)&mp_op_getitem_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR___setitem__), (mp_obj_t)&mp_op_setitem_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR___delitem__), (mp_obj_t)&mp_op_delitem_obj }, };
STATIC mp_obj_t mp_builtin_bin(mp_obj_t o_in) { mp_obj_t args[] = { MP_OBJ_NEW_QSTR(MP_QSTR__brace_open__colon__hash_b_brace_close_), o_in }; return mp_obj_str_format(MP_ARRAY_SIZE(args), args, NULL); }
MP_DEFINE_CONST_FUN_OBJ_1(microbit_compass_get_x_obj, microbit_compass_get_x); mp_obj_t microbit_compass_get_y(mp_obj_t self_in) { microbit_compass_obj_t *self = (microbit_compass_obj_t*)self_in; return mp_obj_new_int(self->compass->getY()); } MP_DEFINE_CONST_FUN_OBJ_1(microbit_compass_get_y_obj, microbit_compass_get_y); mp_obj_t microbit_compass_get_z(mp_obj_t self_in) { microbit_compass_obj_t *self = (microbit_compass_obj_t*)self_in; return mp_obj_new_int(self->compass->getZ()); } MP_DEFINE_CONST_FUN_OBJ_1(microbit_compass_get_z_obj, microbit_compass_get_z); STATIC const mp_map_elem_t microbit_compass_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_heading), (mp_obj_t)µbit_compass_heading_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_is_calibrated), (mp_obj_t)µbit_compass_is_calibrated_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_calibrate), (mp_obj_t)µbit_compass_calibrate_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_is_calibrating), (mp_obj_t)µbit_compass_is_calibrating_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_clear_calibration), (mp_obj_t)µbit_compass_clear_calibration_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_get_x), (mp_obj_t)µbit_compass_get_x_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_get_y), (mp_obj_t)µbit_compass_get_y_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_get_z), (mp_obj_t)µbit_compass_get_z_obj }, }; STATIC MP_DEFINE_CONST_DICT(microbit_compass_locals_dict, microbit_compass_locals_dict_table); STATIC const mp_obj_type_t microbit_compass_type = { { &mp_type_type }, .name = MP_QSTR_MicroBitCompass, .print = NULL,
mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { #if DEBUG_PRINT printf("__import__:\n"); for (int i = 0; i < n_args; i++) { printf(" "); mp_obj_print(args[i], PRINT_REPR); printf("\n"); } #endif mp_obj_t module_name = args[0]; mp_obj_t fromtuple = mp_const_none; int level = 0; if (n_args >= 4) { fromtuple = args[3]; if (n_args >= 5) { level = MP_OBJ_SMALL_INT_VALUE(args[4]); } } uint mod_len; const char *mod_str = (const char*)mp_obj_str_get_data(module_name, &mod_len); if (level != 0) { // What we want to do here is to take name of current module, // chop <level> trailing components, and concatenate with passed-in // module name, thus resolving relative import name into absolue. // This even appears to be correct per // http://legacy.python.org/dev/peps/pep-0328/#relative-imports-and-name // "Relative imports use a module's __name__ attribute to determine that // module's position in the package hierarchy." mp_obj_t this_name_q = mp_obj_dict_get(mp_globals_get(), MP_OBJ_NEW_QSTR(MP_QSTR___name__)); assert(this_name_q != MP_OBJ_NULL); #if DEBUG_PRINT printf("Current module: "); mp_obj_print(this_name_q, PRINT_REPR); printf("\n"); #endif uint this_name_l; const char *this_name = (const char*)mp_obj_str_get_data(this_name_q, &this_name_l); uint dots_seen = 0; const char *p = this_name + this_name_l - 1; while (p > this_name) { if (*p == '.') { dots_seen++; if (--level == 0) { break; } } p--; } if (dots_seen == 0 && level == 1) { // http://legacy.python.org/dev/peps/pep-0328/#relative-imports-and-name // "If the module's name does not contain any package information // (e.g. it is set to '__main__') then relative imports are // resolved as if the module were a top level module, regardless // of where the module is actually located on the file system." // Supposedly this if catches this condition and resolve it properly // TODO: But nobody knows for sure. This condition happens when // package's __init__.py does something like "import .submod". So, // maybe we should check for package here? But quote above doesn't // talk about packages, it talks about dot-less module names. p = this_name + this_name_l; } else if (level != 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "Invalid relative import")); } uint new_mod_l = (mod_len == 0 ? p - this_name : p - this_name + 1 + mod_len); char *new_mod = alloca(new_mod_l); memcpy(new_mod, this_name, p - this_name); if (mod_len != 0) { new_mod[p - this_name] = '.'; memcpy(new_mod + (p - this_name) + 1, mod_str, mod_len); } qstr new_mod_q = qstr_from_strn(new_mod, new_mod_l); DEBUG_printf("Resolved relative name: %s\n", qstr_str(new_mod_q)); module_name = MP_OBJ_NEW_QSTR(new_mod_q); mod_str = new_mod; mod_len = new_mod_l; } // check if module already exists mp_obj_t module_obj = mp_module_get(mp_obj_str_get_qstr(module_name)); if (module_obj != MP_OBJ_NULL) { DEBUG_printf("Module already loaded\n"); // If it's not a package, return module right away char *p = strchr(mod_str, '.'); if (p == NULL) { return module_obj; } // If fromlist is not empty, return leaf module if (fromtuple != mp_const_none) { return module_obj; } // Otherwise, we need to return top-level package qstr pkg_name = qstr_from_strn(mod_str, p - mod_str); return mp_module_get(pkg_name); } DEBUG_printf("Module not yet loaded\n"); uint last = 0; VSTR_FIXED(path, MICROPY_ALLOC_PATH_MAX) module_obj = MP_OBJ_NULL; mp_obj_t top_module_obj = MP_OBJ_NULL; mp_obj_t outer_module_obj = MP_OBJ_NULL; uint i; for (i = 1; i <= mod_len; i++) { if (i == mod_len || mod_str[i] == '.') { // create a qstr for the module name up to this depth qstr mod_name = qstr_from_strn(mod_str, i); DEBUG_printf("Processing module: %s\n", qstr_str(mod_name)); DEBUG_printf("Previous path: %s\n", vstr_str(&path)); // find the file corresponding to the module name mp_import_stat_t stat; if (vstr_len(&path) == 0) { // first module in the dotted-name; search for a directory or file stat = find_file(mod_str, i, &path); } else { // latter module in the dotted-name; append to path vstr_add_char(&path, PATH_SEP_CHAR); vstr_add_strn(&path, mod_str + last, i - last); stat = stat_dir_or_file(&path); } DEBUG_printf("Current path: %s\n", vstr_str(&path)); // fail if we couldn't find the file if (stat == MP_IMPORT_STAT_NO_EXIST) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "No module named '%s'", qstr_str(mod_name))); } module_obj = mp_module_get(mod_name); if (module_obj == MP_OBJ_NULL) { // module not already loaded, so load it! module_obj = mp_obj_new_module(mod_name); if (stat == MP_IMPORT_STAT_DIR) { DEBUG_printf("%s is dir\n", vstr_str(&path)); // https://docs.python.org/3/reference/import.html // "Specifically, any module that contains a __path__ attribute is considered a package." mp_store_attr(module_obj, MP_QSTR___path__, mp_obj_new_str(vstr_str(&path), vstr_len(&path), false)); vstr_add_char(&path, PATH_SEP_CHAR); vstr_add_str(&path, "__init__.py"); if (mp_import_stat(vstr_str(&path)) != MP_IMPORT_STAT_FILE) { vstr_cut_tail_bytes(&path, sizeof("/__init__.py") - 1); // cut off /__init__.py printf("Notice: %s is imported as namespace package\n", vstr_str(&path)); } else { do_load(module_obj, &path); vstr_cut_tail_bytes(&path, sizeof("/__init__.py") - 1); // cut off /__init__.py } } else { // MP_IMPORT_STAT_FILE do_load(module_obj, &path); // TODO: We cannot just break here, at the very least, we must execute // trailer code below. But otherwise if there're remaining components, // that would be (??) object path within module, not modules path within FS. // break; } } if (outer_module_obj != MP_OBJ_NULL) { qstr s = qstr_from_strn(mod_str + last, i - last); mp_store_attr(outer_module_obj, s, module_obj); } outer_module_obj = module_obj; if (top_module_obj == MP_OBJ_NULL) { top_module_obj = module_obj; } last = i + 1; } } if (i < mod_len) { // we loaded a package, now need to load objects from within that package // TODO assert(0); } // If fromlist is not empty, return leaf module if (fromtuple != mp_const_none) { return module_obj; } // Otherwise, we need to return top-level package return top_module_obj; }
break; case '+': mode |= O_RDWR; break; } } int fd = open(fname, mode, 0644); if (fd == -1) { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno)); } return fdfile_new(fd); } STATIC const mp_map_elem_t rawfile_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_fileno), (mp_obj_t)&fdfile_fileno_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj}, { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&fdfile_close_obj }, }; STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table); static const mp_obj_type_t rawfile_type = { { &mp_type_type }, .name = MP_QSTR_io_dot_FileIO, .print = fdfile_print, .make_new = fdfile_make_new, .getiter = mp_identity,
int main(int argc, char **argv) { volatile int stack_dummy; stack_top = (void*)&stack_dummy; pre_process_options(argc, argv); #if MICROPY_ENABLE_GC char *heap = malloc(heap_size); gc_init(heap, heap + heap_size); #endif qstr_init(); mp_init(); char *home = getenv("HOME"); char *path = getenv("MICROPYPATH"); if (path == NULL) { path = "~/.micropython/lib:/usr/lib/micropython"; } uint path_num = 1; // [0] is for current dir (or base dir of the script) for (char *p = path; p != NULL; p = strchr(p, ':')) { path_num++; if (p != NULL) { p++; } } mp_obj_list_init(mp_sys_path, path_num); mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_); char *p = path; for (int i = 1; i < path_num; i++) { char *p1 = strchr(p, ':'); if (p1 == NULL) { p1 = p + strlen(p); } if (p[0] == '~' && p[1] == '/' && home != NULL) { // Expand standalone ~ to $HOME CHECKBUF(buf, PATH_MAX); CHECKBUF_APPEND(buf, home, strlen(home)); CHECKBUF_APPEND(buf, p + 1, p1 - p - 1); path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(buf, CHECKBUF_LEN(buf))); } else { path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(p, p1 - p)); } p = p1 + 1; } mp_obj_list_init(mp_sys_argv, 0); mp_store_name(qstr_from_str("test"), test_obj_new(42)); mp_store_name(qstr_from_str("mem_info"), mp_make_function_n(0, mem_info)); mp_store_name(qstr_from_str("qstr_info"), mp_make_function_n(0, qstr_info)); #if MICROPY_ENABLE_GC mp_store_name(qstr_from_str("gc"), (mp_obj_t)&pyb_gc_obj); #endif // Here is some example code to create a class and instance of that class. // First is the Python, then the C code. // // class TestClass: // pass // test_obj = TestClass() // test_obj.attr = 42 mp_obj_t test_class_type, test_class_instance; test_class_type = mp_obj_new_type(QSTR_FROM_STR_STATIC("TestClass"), mp_const_empty_tuple, mp_obj_new_dict(0)); mp_store_name(QSTR_FROM_STR_STATIC("test_obj"), test_class_instance = mp_call_function_0(test_class_type)); mp_store_attr(test_class_instance, QSTR_FROM_STR_STATIC("attr"), mp_obj_new_int(42)); /* printf("bytes:\n"); printf(" total %d\n", m_get_total_bytes_allocated()); printf(" cur %d\n", m_get_current_bytes_allocated()); printf(" peak %d\n", m_get_peak_bytes_allocated()); */ bool executed = false; for (int a = 1; a < argc; a++) { if (argv[a][0] == '-') { if (strcmp(argv[a], "-c") == 0) { if (a + 1 >= argc) { return usage(argv); } do_str(argv[a + 1]); executed = true; a += 1; } else if (strcmp(argv[a], "-X") == 0) { a += 1; } else { return usage(argv); } } else { char *basedir = realpath(argv[a], NULL); if (basedir == NULL) { fprintf(stderr, "%s: can't open file '%s': [Errno %d] ", argv[0], argv[1], errno); perror(""); // CPython exits with 2 in such case exit(2); } // Set base dir of the script as first entry in sys.path char *p = strrchr(basedir, '/'); path_items[0] = MP_OBJ_NEW_QSTR(qstr_from_strn(basedir, p - basedir)); free(basedir); for (int i = a; i < argc; i++) { mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i]))); } do_file(argv[a]); executed = true; break; } } if (!executed) { do_repl(); } mp_deinit(); //printf("total bytes = %d\n", m_get_total_bytes_allocated()); return 0; }
// set speed immediately self->time_left = 0; } else { // set speed over a given time (given in milli seconds) self->time_left = mp_obj_get_int(args[2]) / 20; self->pulse_accum = 0; } servo_timer_irq_callback(); return mp_const_none; } } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_servo_speed_obj, 1, 3, pyb_servo_speed); STATIC const mp_map_elem_t pyb_servo_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_pulse_width), (mp_obj_t)&pyb_servo_pulse_width_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_calibration), (mp_obj_t)&pyb_servo_calibration_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_angle), (mp_obj_t)&pyb_servo_angle_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_speed), (mp_obj_t)&pyb_servo_speed_obj }, }; STATIC MP_DEFINE_CONST_DICT(pyb_servo_locals_dict, pyb_servo_locals_dict_table); const mp_obj_type_t pyb_servo_type = { { &mp_type_type }, .name = MP_QSTR_Servo, .print = pyb_servo_print, .make_new = pyb_servo_make_new, .locals_dict = (mp_obj_t)&pyb_servo_locals_dict, };
STATIC mp_obj_t mod_os_mkdir(mp_obj_t path_in) { // TODO: Accept mode param const char *path = mp_obj_str_get_str(path_in); #ifdef _WIN32 int r = mkdir(path); #else int r = mkdir(path, 0777); #endif RAISE_ERRNO(r, errno); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_mkdir_obj, mod_os_mkdir); STATIC const mp_map_elem_t mp_module_os_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR__os) }, { MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&mod_os_stat_obj }, #if MICROPY_PY_OS_STATVFS { MP_OBJ_NEW_QSTR(MP_QSTR_statvfs), (mp_obj_t)&mod_os_statvfs_obj }, #endif { MP_OBJ_NEW_QSTR(MP_QSTR_system), (mp_obj_t)&mod_os_system_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_unlink),(mp_obj_t)&mod_os_unlink_obj}, { MP_OBJ_NEW_QSTR(MP_QSTR_getenv),(mp_obj_t)&mod_os_getenv_obj}, { MP_OBJ_NEW_QSTR(MP_QSTR_mkdir),(mp_obj_t)&mod_os_mkdir_obj}, }; STATIC MP_DEFINE_CONST_DICT(mp_module_os_globals, mp_module_os_globals_table); const mp_obj_module_t mp_module_os = { .base = { &mp_type_module }, .name = MP_QSTR__os,
netif_set_up(n); netif_set_default(n); mod_lwip_register_poll(slip_lwip_poll, n); return (mp_obj_t)&lwip_slip_obj; } STATIC mp_obj_t lwip_slip_status(mp_obj_t self_in) { // Null function for now. return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(lwip_slip_status_obj, lwip_slip_status); STATIC const mp_map_elem_t lwip_slip_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_status), (mp_obj_t)&lwip_slip_status_obj }, }; STATIC MP_DEFINE_CONST_DICT(lwip_slip_locals_dict, lwip_slip_locals_dict_table); STATIC const mp_obj_type_t lwip_slip_type = { { &mp_type_type }, .name = MP_QSTR_slip, .make_new = lwip_slip_make_new, .locals_dict = (mp_obj_t)&lwip_slip_locals_dict, }; #endif // MICROPY_PY_LWIP_SLIP /******************************************************************************/ // Table to convert lwIP err_t codes to socket errno codes, from the lwIP
return mp_const_none; } } } } STATIC mp_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { mp_obj_array_t *o = o_in; bufinfo->buf = o->items; bufinfo->len = o->len * mp_binary_get_size('@', o->typecode, NULL); bufinfo->typecode = o->typecode; return 0; } STATIC const mp_map_elem_t array_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_append), (mp_obj_t)&array_append_obj }, }; STATIC MP_DEFINE_CONST_DICT(array_locals_dict, array_locals_dict_table); const mp_obj_type_t mp_type_array = { { &mp_type_type }, .name = MP_QSTR_array, .print = array_print, .make_new = array_make_new, .getiter = array_iterator_new, .unary_op = array_unary_op, .binary_op = array_binary_op, .subscr = array_subscr, .buffer_p = { .get_buffer = array_get_buffer }, .locals_dict = (mp_obj_t)&array_locals_dict,
void mp_task(void *pvParameter) { volatile uint32_t sp = (uint32_t)get_sp(); #if MICROPY_PY_THREAD mp_thread_init(&mp_task_stack[0], MP_TASK_STACK_LEN); #endif uart_init(); // Allocate the uPy heap using malloc and get the largest available region size_t mp_task_heap_size = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT); void *mp_task_heap = malloc(mp_task_heap_size); soft_reset: // initialise the stack pointer for the main thread mp_stack_set_top((void *)sp); mp_stack_set_limit(MP_TASK_STACK_SIZE - 1024); gc_init(mp_task_heap, mp_task_heap + mp_task_heap_size); mp_init(); mp_obj_list_init(mp_sys_path, 0); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_init(mp_sys_argv, 0); readline_init0(); // initialise peripherals machine_pins_init(); // run boot-up scripts pyexec_frozen_module("_boot.py"); pyexec_file("boot.py"); if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { pyexec_file("main.py"); } for (;;) { if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { vprintf_like_t vprintf_log = esp_log_set_vprintf(vprintf_null); if (pyexec_raw_repl() != 0) { break; } esp_log_set_vprintf(vprintf_log); } else { if (pyexec_friendly_repl() != 0) { break; } } } #if MICROPY_PY_THREAD mp_thread_deinit(); #endif gc_sweep_all(); mp_hal_stdout_tx_str("PYB: soft reboot\r\n"); // deinitialise peripherals machine_pins_deinit(); usocket_events_deinit(); mp_deinit(); fflush(stdout); goto soft_reset; }
} } STATIC const mp_obj_type_t machine_mem_type = { { &mp_type_type }, .name = MP_QSTR_mem, .print = machine_mem_print, .subscr = machine_mem_subscr, }; STATIC const machine_mem_obj_t machine_mem8_obj = {{&machine_mem_type}, 1}; STATIC const machine_mem_obj_t machine_mem16_obj = {{&machine_mem_type}, 2}; STATIC const machine_mem_obj_t machine_mem32_obj = {{&machine_mem_type}, 4}; STATIC const mp_map_elem_t machine_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_machine) }, { MP_OBJ_NEW_QSTR(MP_QSTR_mem8), (mp_obj_t)&machine_mem8_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_mem16), (mp_obj_t)&machine_mem16_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_mem32), (mp_obj_t)&machine_mem32_obj }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); const mp_obj_module_t mp_module_machine = { .base = { &mp_type_module }, .name = MP_QSTR_machine, .globals = (mp_obj_dict_t*)&machine_module_globals, }; #endif // MICROPY_PY_MACHINE
if (args[0] != mp_const_none) { fname = mp_obj_str_get_str(args[0]); } void *mod = dlopen(fname, RTLD_NOW | RTLD_LOCAL); if (mod == NULL) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno))); } mp_obj_ffimod_t *o = m_new_obj(mp_obj_ffimod_t); o->base.type = type_in; o->handle = mod; return o; } STATIC const mp_map_elem_t ffimod_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_func), (mp_obj_t) &ffimod_func_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_var), (mp_obj_t) &ffimod_var_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_addr), (mp_obj_t) &ffimod_addr_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t) &ffimod_close_obj }, }; STATIC MP_DEFINE_CONST_DICT(ffimod_locals_dict, ffimod_locals_dict_table); STATIC const mp_obj_type_t ffimod_type = { { &mp_type_type }, .name = MP_QSTR_ffimod, .print = ffimod_print, .make_new = ffimod_make_new, .locals_dict = (mp_obj_t)&ffimod_locals_dict, };
STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) { // This function is pretty complicated. It's main aim is to be efficient in speed and RAM // usage for the common case of positional only args. DEBUG_printf("Input n_args: %d, n_kw: %d\n", n_args, n_kw); DEBUG_printf("Input pos args: "); dump_args(args, n_args); DEBUG_printf("Input kw args: "); dump_args(args + n_args, n_kw * 2); mp_obj_fun_bc_t *self = self_in; DEBUG_printf("Func n_def_args: %d\n", self->n_def_args); const byte *ip = self->bytecode; // get code info size, and skip line number table machine_uint_t code_info_size = ip[0] | (ip[1] << 8) | (ip[2] << 16) | (ip[3] << 24); ip += code_info_size; // bytecode prelude: state size and exception stack size; 16 bit uints machine_uint_t n_state = ip[0] | (ip[1] << 8); machine_uint_t n_exc_stack = ip[2] | (ip[3] << 8); ip += 4; #if VM_DETECT_STACK_OVERFLOW n_state += 1; #endif // allocate state for locals and stack uint state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t); mp_code_state *code_state; if (state_size > VM_MAX_STATE_ON_STACK) { code_state = m_new_obj_var(mp_code_state, byte, state_size); } else { code_state = alloca(sizeof(mp_code_state) + state_size); } code_state->code_info = self->bytecode; code_state->sp = &code_state->state[0] - 1; code_state->exc_sp = (mp_exc_stack_t*)(code_state->state + n_state) - 1; code_state->n_state = n_state; // zero out the local stack to begin with memset(code_state->state, 0, n_state * sizeof(*code_state->state)); const mp_obj_t *kwargs = args + n_args; // var_pos_kw_args points to the stack where the var-args tuple, and var-kw dict, should go (if they are needed) mp_obj_t *var_pos_kw_args = &code_state->state[n_state - 1 - self->n_pos_args - self->n_kwonly_args]; // check positional arguments if (n_args > self->n_pos_args) { // given more than enough arguments if (!self->takes_var_args) { fun_pos_args_mismatch(self, self->n_pos_args, n_args); } // put extra arguments in varargs tuple *var_pos_kw_args-- = mp_obj_new_tuple(n_args - self->n_pos_args, args + self->n_pos_args); n_args = self->n_pos_args; } else { if (self->takes_var_args) { DEBUG_printf("passing empty tuple as *args\n"); *var_pos_kw_args-- = mp_const_empty_tuple; } // Apply processing and check below only if we don't have kwargs, // otherwise, kw handling code below has own extensive checks. if (n_kw == 0 && !self->has_def_kw_args) { if (n_args >= self->n_pos_args - self->n_def_args) { // given enough arguments, but may need to use some default arguments for (uint i = n_args; i < self->n_pos_args; i++) { code_state->state[n_state - 1 - i] = self->extra_args[i - (self->n_pos_args - self->n_def_args)]; } } else { fun_pos_args_mismatch(self, self->n_pos_args - self->n_def_args, n_args); } } } // copy positional args into state for (uint i = 0; i < n_args; i++) { code_state->state[n_state - 1 - i] = args[i]; } // check keyword arguments if (n_kw != 0 || self->has_def_kw_args) { DEBUG_printf("Initial args: "); dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); mp_obj_t dict = MP_OBJ_NULL; if (self->takes_kw_args) { dict = mp_obj_new_dict(n_kw); // TODO: better go conservative with 0? *var_pos_kw_args = dict; } for (uint i = 0; i < n_kw; i++) { qstr arg_name = MP_OBJ_QSTR_VALUE(kwargs[2 * i]); for (uint j = 0; j < self->n_pos_args + self->n_kwonly_args; j++) { if (arg_name == self->args[j]) { if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function got multiple values for argument '%s'", qstr_str(arg_name))); } code_state->state[n_state - 1 - j] = kwargs[2 * i + 1]; goto continue2; } } // Didn't find name match with positional args if (!self->takes_kw_args) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments")); } mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]); continue2:; } DEBUG_printf("Args with kws flattened: "); dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); // fill in defaults for positional args mp_obj_t *d = &code_state->state[n_state - self->n_pos_args]; mp_obj_t *s = &self->extra_args[self->n_def_args - 1]; for (int i = self->n_def_args; i > 0; i--, d++, s--) { if (*d == MP_OBJ_NULL) { *d = *s; } } DEBUG_printf("Args after filling default positional: "); dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); // Check that all mandatory positional args are specified while (d < &code_state->state[n_state]) { if (*d++ == MP_OBJ_NULL) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function missing required positional argument #%d", &code_state->state[n_state] - d)); } } // Check that all mandatory keyword args are specified // Fill in default kw args if we have them for (uint i = 0; i < self->n_kwonly_args; i++) { if (code_state->state[n_state - 1 - self->n_pos_args - i] == MP_OBJ_NULL) { mp_map_elem_t *elem = NULL; if (self->has_def_kw_args) { elem = mp_map_lookup(&((mp_obj_dict_t*)self->extra_args[self->n_def_args])->map, MP_OBJ_NEW_QSTR(self->args[self->n_pos_args + i]), MP_MAP_LOOKUP); } if (elem != NULL) { code_state->state[n_state - 1 - self->n_pos_args - i] = elem->value; } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function missing required keyword argument '%s'", qstr_str(self->args[self->n_pos_args + i]))); } } } } else { // no keyword arguments given if (self->n_kwonly_args != 0) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function missing keyword-only argument")); } if (self->takes_kw_args) { *var_pos_kw_args = mp_obj_new_dict(0); } } // bytecode prelude: initialise closed over variables for (uint n_local = *ip++; n_local > 0; n_local--) { uint local_num = *ip++; code_state->state[n_state - 1 - local_num] = mp_obj_new_cell(code_state->state[n_state - 1 - local_num]); } // now that we skipped over the prelude, set the ip for the VM code_state->ip = ip; DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", self->n_pos_args, self->n_kwonly_args); dump_args(code_state->state + n_state - self->n_pos_args - self->n_kwonly_args, self->n_pos_args + self->n_kwonly_args); dump_args(code_state->state, n_state); // execute the byte code with the correct globals context mp_obj_dict_t *old_globals = mp_globals_get(); mp_globals_set(self->globals); mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode(code_state, MP_OBJ_NULL); mp_globals_set(old_globals); #if VM_DETECT_STACK_OVERFLOW if (vm_return_kind == MP_VM_RETURN_NORMAL) { if (code_state->sp < code_state->state) { printf("VM stack underflow: " INT_FMT "\n", code_state->sp - code_state->state); assert(0); } } // We can't check the case when an exception is returned in state[n_state - 1] // and there are no arguments, because in this case our detection slot may have // been overwritten by the returned exception (which is allowed). if (!(vm_return_kind == MP_VM_RETURN_EXCEPTION && self->n_pos_args + self->n_kwonly_args == 0)) { // Just check to see that we have at least 1 null object left in the state. bool overflow = true; for (uint i = 0; i < n_state - self->n_pos_args - self->n_kwonly_args; i++) { if (code_state->state[i] == MP_OBJ_NULL) { overflow = false; break; } } if (overflow) { printf("VM stack overflow state=%p n_state+1=" UINT_FMT "\n", code_state->state, n_state); assert(0); } } #endif mp_obj_t result; switch (vm_return_kind) { case MP_VM_RETURN_NORMAL: // return value is in *sp result = *code_state->sp; break; case MP_VM_RETURN_EXCEPTION: // return value is in state[n_state - 1] result = code_state->state[n_state - 1]; break; case MP_VM_RETURN_YIELD: // byte-code shouldn't yield default: assert(0); result = mp_const_none; vm_return_kind = MP_VM_RETURN_NORMAL; break; } // free the state if it was allocated on the heap if (state_size > VM_MAX_STATE_ON_STACK) { m_del_var(mp_code_state, byte, state_size, code_state); } if (vm_return_kind == MP_VM_RETURN_NORMAL) { return result; } else { // MP_VM_RETURN_EXCEPTION nlr_raise(result); } }
assert(MP_OBJ_IS_SMALL_INT(args[1])); type = MP_OBJ_SMALL_INT_VALUE(args[1]); if (n_args > 2) { assert(MP_OBJ_IS_SMALL_INT(args[2])); proto = MP_OBJ_SMALL_INT_VALUE(args[2]); } } } int fd = socket(family, type, proto); RAISE_ERRNO(fd, errno); return socket_new(fd); } STATIC const mp_map_elem_t usocket_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_fileno), (mp_obj_t)&socket_fileno_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_makefile), (mp_obj_t)&socket_makefile_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj}, { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&socket_connect_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_bind), (mp_obj_t)&socket_bind_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_listen), (mp_obj_t)&socket_listen_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&socket_accept_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&socket_recv_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_recvfrom), (mp_obj_t)&socket_recvfrom_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&socket_send_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sendto), (mp_obj_t)&socket_sendto_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_setsockopt), (mp_obj_t)&socket_setsockopt_obj },
STATIC mp_obj_t tuple_count(mp_obj_t self_in, mp_obj_t value) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_tuple)); mp_obj_tuple_t *self = self_in; return mp_seq_count_obj(self->items, self->len, value); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(tuple_count_obj, tuple_count); STATIC mp_obj_t tuple_index(mp_uint_t n_args, const mp_obj_t *args) { assert(MP_OBJ_IS_TYPE(args[0], &mp_type_tuple)); mp_obj_tuple_t *self = args[0]; return mp_seq_index_obj(self->items, self->len, n_args, args); } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(tuple_index_obj, 2, 4, tuple_index); STATIC const mp_map_elem_t tuple_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_count), (mp_obj_t)&tuple_count_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_index), (mp_obj_t)&tuple_index_obj }, }; STATIC MP_DEFINE_CONST_DICT(tuple_locals_dict, tuple_locals_dict_table); const mp_obj_type_t mp_type_tuple = { { &mp_type_type }, .name = MP_QSTR_tuple, .print = mp_obj_tuple_print, .make_new = mp_obj_tuple_make_new, .unary_op = mp_obj_tuple_unary_op, .binary_op = mp_obj_tuple_binary_op, .subscr = mp_obj_tuple_subscr, .getiter = mp_obj_tuple_getiter, .locals_dict = (mp_obj_t)&tuple_locals_dict,
STATIC mp_obj_t mod_socket_getaddrinfo(mp_uint_t n_args, const mp_obj_t *args) { // TODO: Implement all args assert(n_args >= 2 && n_args <= 4); assert(MP_OBJ_IS_STR(args[0])); const char *host = mp_obj_str_get_str(args[0]); const char *serv = NULL; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); // getaddrinfo accepts port in string notation, so however // it may seem stupid, we need to convert int to str if (MP_OBJ_IS_SMALL_INT(args[1])) { unsigned port = (unsigned short)MP_OBJ_SMALL_INT_VALUE(args[1]); char buf[6]; sprintf(buf, "%u", port); serv = buf; hints.ai_flags = AI_NUMERICSERV; #ifdef __UCLIBC_MAJOR__ #if __UCLIBC_MAJOR__ == 0 && (__UCLIBC_MINOR__ < 9 || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ <= 32)) // "warning" requires -Wno-cpp which is a relatively new gcc option, so we choose not to use it. //#warning Working around uClibc bug with numeric service name // Older versions og uClibc have bugs when numeric ports in service // arg require also hints.ai_socktype (or hints.ai_protocol) != 0 // This actually was fixed in 0.9.32.1, but uClibc doesn't allow to // test for that. // http://git.uclibc.org/uClibc/commit/libc/inet/getaddrinfo.c?id=bc3be18145e4d5 // Note that this is crude workaround, precluding UDP socket addresses // to be returned. TODO: set only if not set by Python args. hints.ai_socktype = SOCK_STREAM; #endif #endif } else { serv = mp_obj_str_get_str(args[1]); } if (n_args > 2) { hints.ai_family = MP_OBJ_SMALL_INT_VALUE(args[2]); if (n_args > 3) { hints.ai_socktype = MP_OBJ_SMALL_INT_VALUE(args[3]); } } struct addrinfo *addr_list; int res = getaddrinfo(host, serv, &hints, &addr_list); if (res != 0) { // CPython: socket.gaierror nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[addrinfo error %d]", res)); } assert(addr_list); mp_obj_t list = mp_obj_new_list(0, NULL); for (struct addrinfo *addr = addr_list; addr; addr = addr->ai_next) { mp_obj_tuple_t *t = mp_obj_new_tuple(5, NULL); t->items[0] = MP_OBJ_NEW_SMALL_INT(addr->ai_family); t->items[1] = MP_OBJ_NEW_SMALL_INT(addr->ai_socktype); t->items[2] = MP_OBJ_NEW_SMALL_INT(addr->ai_protocol); // "canonname will be a string representing the canonical name of the host // if AI_CANONNAME is part of the flags argument; else canonname will be empty." ?? if (addr->ai_canonname) { t->items[3] = MP_OBJ_NEW_QSTR(qstr_from_str(addr->ai_canonname)); } else { t->items[3] = mp_const_none; } t->items[4] = mp_obj_new_bytearray(addr->ai_addrlen, addr->ai_addr); mp_obj_list_append(list, t); } freeaddrinfo(addr_list); return list; }
STATIC mp_obj_t test_get(mp_obj_t self_in) { test_obj_t *self = self_in; return mp_obj_new_int(self->value); } STATIC mp_obj_t test_set(mp_obj_t self_in, mp_obj_t arg) { test_obj_t *self = self_in; self->value = mp_obj_get_int(arg); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(test_get_obj, test_get); STATIC MP_DEFINE_CONST_FUN_OBJ_2(test_set_obj, test_set); STATIC const mp_map_elem_t test_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_get), (mp_obj_t)&test_get_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_set), (mp_obj_t)&test_set_obj }, }; STATIC MP_DEFINE_CONST_DICT(test_locals_dict, test_locals_dict_table); STATIC const mp_obj_type_t test_type = { { &mp_type_type }, .name = MP_QSTR_Test, .print = test_print, .locals_dict = (mp_obj_t)&test_locals_dict, }; mp_obj_t test_obj_new(int value) { test_obj_t *o = m_new_obj(test_obj_t); o->base.type = &test_type;
return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_deepsleep_obj, machine_deepsleep); STATIC mp_obj_t machine_reset_cause (void) { return mp_obj_new_int(pyb_sleep_get_reset_cause()); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause); STATIC mp_obj_t machine_wake_reason (void) { return mp_obj_new_int(pyb_sleep_get_wake_reason()); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_wake_reason_obj, machine_wake_reason); STATIC const mp_map_elem_t machine_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_machine) }, { MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&machine_reset_obj }, #ifdef DEBUG { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&machine_info_obj }, #endif { MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&machine_freq_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_unique_id), (mp_obj_t)&machine_unique_id_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&machine_main_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&machine_rng_get_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_idle), (mp_obj_t)&machine_idle_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&machine_sleep_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_deepsleep), (mp_obj_t)&machine_deepsleep_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_reset_cause), (mp_obj_t)&machine_reset_cause_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_wake_reason), (mp_obj_t)&machine_wake_reason_obj },
STATIC mp_obj_t ffimod_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { const char *fname = mp_obj_str_get_str(args[0]); void *mod = dlopen(fname, RTLD_NOW | RTLD_LOCAL); if (mod == NULL) { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno)); } mp_obj_ffimod_t *o = m_new_obj(mp_obj_ffimod_t); o->base.type = type_in; o->handle = mod; return o; } STATIC const mp_map_elem_t ffimod_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_func), (mp_obj_t) &ffimod_func_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_var), (mp_obj_t) &ffimod_var_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t) &ffimod_close_obj }, }; STATIC MP_DEFINE_CONST_DICT(ffimod_locals_dict, ffimod_locals_dict_table); STATIC const mp_obj_type_t ffimod_type = { { &mp_type_type }, .name = MP_QSTR_ffimod, .print = ffimod_print, .make_new = ffimod_make_new, .locals_dict = (mp_obj_t)&ffimod_locals_dict, }; // FFI function
STATIC void set_sys_argv(char *argv[], int argc, int start_arg) { for (int i = start_arg; i < argc; i++) { mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i]))); } }
// if (n_args == 0) { // rasPi.panic(); // } else { // rasPi.panic(mp_obj_get_int(args[0])); // } // return mp_const_none; //} //MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(microbit_panic_obj, 0, 1, microbit_panic); // //STATIC mp_obj_t microbit_temperature(void) { // return mp_obj_new_int(rasPi.thermometer.getTemperature()); //} //MP_DEFINE_CONST_FUN_OBJ_0(microbit_temperature_obj, microbit_temperature); STATIC const mp_map_elem_t microbit_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sdlpi) }, // { MP_OBJ_NEW_QSTR(MP_QSTR_Image), (mp_obj_t)µbit_image_type }, // // { MP_OBJ_NEW_QSTR(MP_QSTR_display), (mp_obj_t)µbit_display_obj }, // { MP_OBJ_NEW_QSTR(MP_QSTR_button_a), (mp_obj_t)µbit_button_a_obj }, // { MP_OBJ_NEW_QSTR(MP_QSTR_button_b), (mp_obj_t)µbit_button_b_obj }, // { MP_OBJ_NEW_QSTR(MP_QSTR_accelerometer), (mp_obj_t)µbit_accelerometer_obj }, // { MP_OBJ_NEW_QSTR(MP_QSTR_compass), (mp_obj_t)µbit_compass_obj }, // { MP_OBJ_NEW_QSTR(MP_QSTR_i2c), (mp_obj_t)µbit_i2c_obj }, // { MP_OBJ_NEW_QSTR(MP_QSTR_uart), (mp_obj_t)µbit_uart_obj }, // { MP_OBJ_NEW_QSTR(MP_QSTR_spi), (mp_obj_t)µbit_spi_obj }, // // { MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)µbit_reset_obj }, // { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)µbit_sleep_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_running_time), (mp_obj_t)µbit_running_time_obj },
int main(int argc, char **argv) { prompt_read_history(); mp_stack_set_limit(40000 * (BYTES_PER_WORD / 4)); pre_process_options(argc, argv); #if MICROPY_ENABLE_GC char *heap = malloc(heap_size); gc_init(heap, heap + heap_size); #endif mp_init(); #ifndef _WIN32 // create keyboard interrupt object MP_STATE_VM(keyboard_interrupt_obj) = mp_obj_new_exception(&mp_type_KeyboardInterrupt); #endif char *home = getenv("HOME"); char *path = getenv("MICROPYPATH"); if (path == NULL) { path = "~/.micropython/lib:/usr/lib/micropython"; } mp_uint_t path_num = 1; // [0] is for current dir (or base dir of the script) for (char *p = path; p != NULL; p = strchr(p, PATHLIST_SEP_CHAR)) { path_num++; if (p != NULL) { p++; } } mp_obj_list_init(mp_sys_path, path_num); mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_); { char *p = path; for (mp_uint_t i = 1; i < path_num; i++) { char *p1 = strchr(p, PATHLIST_SEP_CHAR); if (p1 == NULL) { p1 = p + strlen(p); } if (p[0] == '~' && p[1] == '/' && home != NULL) { // Expand standalone ~ to $HOME CHECKBUF(buf, PATH_MAX); CHECKBUF_APPEND(buf, home, strlen(home)); CHECKBUF_APPEND(buf, p + 1, (size_t)(p1 - p - 1)); path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(buf, CHECKBUF_LEN(buf))); } else { path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(p, p1 - p)); } p = p1 + 1; } } mp_obj_list_init(mp_sys_argv, 0); #if defined(MICROPY_UNIX_COVERAGE) { MP_DECLARE_CONST_FUN_OBJ(extra_coverage_obj); mp_store_global(QSTR_FROM_STR_STATIC("extra_coverage"), (mp_obj_t)&extra_coverage_obj); } #endif // Here is some example code to create a class and instance of that class. // First is the Python, then the C code. // // class TestClass: // pass // test_obj = TestClass() // test_obj.attr = 42 // // mp_obj_t test_class_type, test_class_instance; // test_class_type = mp_obj_new_type(QSTR_FROM_STR_STATIC("TestClass"), mp_const_empty_tuple, mp_obj_new_dict(0)); // mp_store_name(QSTR_FROM_STR_STATIC("test_obj"), test_class_instance = mp_call_function_0(test_class_type)); // mp_store_attr(test_class_instance, QSTR_FROM_STR_STATIC("attr"), mp_obj_new_int(42)); /* printf("bytes:\n"); printf(" total %d\n", m_get_total_bytes_allocated()); printf(" cur %d\n", m_get_current_bytes_allocated()); printf(" peak %d\n", m_get_peak_bytes_allocated()); */ const int NOTHING_EXECUTED = -2; int ret = NOTHING_EXECUTED; for (int a = 1; a < argc; a++) { if (argv[a][0] == '-') { if (strcmp(argv[a], "-c") == 0) { if (a + 1 >= argc) { return usage(argv); } ret = do_str(argv[a + 1]); if (ret & FORCED_EXIT) { break; } a += 1; } else if (strcmp(argv[a], "-m") == 0) { if (a + 1 >= argc) { return usage(argv); } mp_obj_t import_args[4]; import_args[0] = mp_obj_new_str(argv[a + 1], strlen(argv[a + 1]), false); import_args[1] = import_args[2] = mp_const_none; // Ask __import__ to handle imported module specially - set its __name__ // to __main__, and also return this leaf module, not top-level package // containing it. import_args[3] = mp_const_false; // TODO: https://docs.python.org/3/using/cmdline.html#cmdoption-m : // "the first element of sys.argv will be the full path to // the module file (while the module file is being located, // the first element will be set to "-m")." set_sys_argv(argv, argc, a + 1); mp_obj_t mod; nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mod = mp_builtin___import__(MP_ARRAY_SIZE(import_args), import_args); nlr_pop(); } else { // uncaught exception return handle_uncaught_exception((mp_obj_t)nlr.ret_val) & 0xff; } if (mp_obj_is_package(mod)) { // TODO fprintf(stderr, "%s: -m for packages not yet implemented\n", argv[0]); exit(1); } ret = 0; break; } else if (strcmp(argv[a], "-X") == 0) { a += 1; } else if (strcmp(argv[a], "-v") == 0) { mp_verbose_flag++; } else if (strncmp(argv[a], "-O", 2) == 0) { if (isdigit(argv[a][2])) { MP_STATE_VM(mp_optimise_value) = argv[a][2] & 0xf; } else { MP_STATE_VM(mp_optimise_value) = 0; for (char *p = argv[a] + 1; *p && *p == 'O'; p++, MP_STATE_VM(mp_optimise_value)++); } } else { return usage(argv); } } else { char *pathbuf = malloc(PATH_MAX); char *basedir = realpath(argv[a], pathbuf); if (basedir == NULL) { fprintf(stderr, "%s: can't open file '%s': [Errno %d] ", argv[0], argv[a], errno); perror(""); // CPython exits with 2 in such case ret = 2; break; } // Set base dir of the script as first entry in sys.path char *p = strrchr(basedir, '/'); path_items[0] = MP_OBJ_NEW_QSTR(qstr_from_strn(basedir, p - basedir)); free(pathbuf); set_sys_argv(argv, argc, a); ret = do_file(argv[a]); break; } } if (ret == NOTHING_EXECUTED) { ret = do_repl(); } #if MICROPY_PY_MICROPYTHON_MEM_INFO if (mp_verbose_flag) { mp_micropython_mem_info(0, NULL); } #endif mp_deinit(); #if MICROPY_ENABLE_GC && !defined(NDEBUG) // We don't really need to free memory since we are about to exit the // process, but doing so helps to find memory leaks. free(heap); #endif //printf("total bytes = %d\n", m_get_total_bytes_allocated()); prompt_write_history(); return ret & 0xff; }
} } STATIC const mp_obj_type_t stm_mem_type = { { &mp_type_type }, .name = MP_QSTR_mem, .print = stm_mem_print, .subscr = stm_mem_subscr, }; STATIC const stm_mem_obj_t stm_mem8_obj = {{&stm_mem_type}, 1}; STATIC const stm_mem_obj_t stm_mem16_obj = {{&stm_mem_type}, 2}; STATIC const stm_mem_obj_t stm_mem32_obj = {{&stm_mem_type}, 4}; STATIC const mp_map_elem_t stm_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_stm) }, { MP_OBJ_NEW_QSTR(MP_QSTR_mem8), (mp_obj_t)&stm_mem8_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_mem16), (mp_obj_t)&stm_mem16_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_mem32), (mp_obj_t)&stm_mem32_obj }, #include "modstmconst.gen.c" }; STATIC const mp_obj_dict_t stm_module_globals = { .base = {&mp_type_dict}, .map = { .all_keys_are_qstrs = 1, .table_is_fixed_array = 1, .used = ARRAY_SIZE(stm_module_globals_table), .alloc = ARRAY_SIZE(stm_module_globals_table),
case MP_BINARY_OP_IN: { mp_obj_set_t *o = lhs; mp_obj_t elem = mp_set_lookup(&o->set, rhs, MP_MAP_LOOKUP); return MP_BOOL(elem != NULL); } default: return MP_OBJ_NULL; // op not supported } } /******************************************************************************/ /* set constructors & public C API */ STATIC const mp_map_elem_t set_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_add), (mp_obj_t)&set_add_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_clear), (mp_obj_t)&set_clear_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_copy), (mp_obj_t)&set_copy_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_discard), (mp_obj_t)&set_discard_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_difference), (mp_obj_t)&set_diff_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_difference_update), (mp_obj_t)&set_diff_update_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_intersection), (mp_obj_t)&set_intersect_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_intersection_update), (mp_obj_t)&set_intersect_update_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_isdisjoint), (mp_obj_t)&set_isdisjoint_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_issubset), (mp_obj_t)&set_issubset_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_issuperset), (mp_obj_t)&set_issuperset_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_pop), (mp_obj_t)&set_pop_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&set_remove_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_symmetric_difference), (mp_obj_t)&set_symmetric_difference_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_symmetric_difference_update), (mp_obj_t)&set_symmetric_difference_update_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_union), (mp_obj_t)&set_union_obj },
} return mp_obj_new_int(len); } void py_file_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { print(env, "<file>"); } static MP_DEFINE_CONST_FUN_OBJ_1(py_file_close_obj, py_file_close); static MP_DEFINE_CONST_FUN_OBJ_2(py_file_read_obj, py_file_read); static MP_DEFINE_CONST_FUN_OBJ_2(py_file_write_obj, py_file_write); static const mp_map_elem_t locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&py_file_close_obj}, { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&py_file_read_obj}, { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&py_file_write_obj}, { NULL, NULL }, }; STATIC MP_DEFINE_CONST_DICT(locals_dict, locals_dict_table); static const mp_obj_type_t py_file_type = { { &mp_type_type }, .name = MP_QSTR_file, .print = py_file_print, .locals_dict = (mp_obj_t)&locals_dict, }; mp_obj_t py_file_open(mp_obj_t path, mp_obj_t mode_str)
const mp_stream_p_t *stream_p = mp_get_stream_raise(self->sock, MP_STREAM_OP_WRITE); return stream_p->write(self->sock, buf, size, errcode); } STATIC mp_obj_t webrepl_set_password(mp_obj_t passwd_in) { mp_uint_t len; const char *passwd = mp_obj_str_get_data(passwd_in, &len); len = MIN(len, sizeof(webrepl_passwd) - 1); memcpy(webrepl_passwd, passwd, len); webrepl_passwd[len] = 0; return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(webrepl_set_password_obj, webrepl_set_password); STATIC const mp_map_elem_t webrepl_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj }, }; STATIC MP_DEFINE_CONST_DICT(webrepl_locals_dict, webrepl_locals_dict_table); STATIC const mp_stream_p_t webrepl_stream_p = { .read = webrepl_read, .write = webrepl_write, }; STATIC const mp_obj_type_t webrepl_type = { { &mp_type_type }, .name = MP_QSTR__webrepl, .make_new = webrepl_make_new, .stream_p = &webrepl_stream_p, .locals_dict = (mp_obj_t)&webrepl_locals_dict,
// expires before anything interesting happens, -1 is returned on error. if (nfds == -1) { // select failed nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "select failed")); } else if (nfds) { // an fd is ready get_fds(rlist, rlist_len, fds[0], &rfds); get_fds(wlist, wlist_len, fds[1], &wfds); get_fds(xlist, xlist_len, fds[2], &xfds); } // select timedout return mp_obj_new_tuple(3, fds); } static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_select_obj, 3, 4, py_select); // select module static const mp_map_elem_t module_globals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_select) }, { MP_OBJ_NEW_QSTR(MP_QSTR_select), (mp_obj_t)&py_select_obj }, }; static MP_DEFINE_CONST_DICT(module_globals_dict, module_globals_dict_table); const mp_obj_module_t select_module = { .base = { &mp_type_module }, .name = MP_QSTR_select, .globals = (mp_obj_dict_t*)&module_globals_dict, }; const mp_obj_module_t *py_select_init() { return &select_module; }
} STATIC MP_DEFINE_CONST_FUN_OBJ_2(list_append_obj, mp_obj_list_append); STATIC MP_DEFINE_CONST_FUN_OBJ_2(list_extend_obj, list_extend); STATIC MP_DEFINE_CONST_FUN_OBJ_1(list_clear_obj, list_clear); STATIC MP_DEFINE_CONST_FUN_OBJ_1(list_copy_obj, list_copy); STATIC MP_DEFINE_CONST_FUN_OBJ_2(list_count_obj, list_count); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(list_index_obj, 2, 4, list_index); STATIC MP_DEFINE_CONST_FUN_OBJ_3(list_insert_obj, list_insert); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(list_pop_obj, 1, 2, list_pop); STATIC MP_DEFINE_CONST_FUN_OBJ_2(list_remove_obj, list_remove); STATIC MP_DEFINE_CONST_FUN_OBJ_1(list_reverse_obj, list_reverse); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(list_sort_obj, 0, mp_obj_list_sort); STATIC const mp_map_elem_t list_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_append), (mp_obj_t)&list_append_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_clear), (mp_obj_t)&list_clear_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_copy), (mp_obj_t)&list_copy_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_count), (mp_obj_t)&list_count_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_extend), (mp_obj_t)&list_extend_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_index), (mp_obj_t)&list_index_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_insert), (mp_obj_t)&list_insert_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_pop), (mp_obj_t)&list_pop_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&list_remove_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_reverse), (mp_obj_t)&list_reverse_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sort), (mp_obj_t)&list_sort_obj }, }; STATIC MP_DEFINE_CONST_DICT(list_locals_dict, list_locals_dict_table); const mp_obj_type_t mp_type_list = {