STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *dest) { #if MICROPY_PY_SYS // extract the list of paths mp_uint_t path_num; mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); if (path_num == 0) { #endif // mp_sys_path is empty, so just use the given file name vstr_add_strn(dest, file_str, file_len); return stat_dir_or_file(dest); #if MICROPY_PY_SYS } else { // go through each path looking for a directory or file for (mp_uint_t i = 0; i < path_num; i++) { vstr_reset(dest); mp_uint_t p_len; const char *p = mp_obj_str_get_data(path_items[i], &p_len); if (p_len > 0) { vstr_add_strn(dest, p, p_len); vstr_add_char(dest, PATH_SEP_CHAR); } vstr_add_strn(dest, file_str, file_len); mp_import_stat_t stat = stat_dir_or_file(dest); if (stat != MP_IMPORT_STAT_NO_EXIST) { return stat; } } // could not find a directory or file return MP_IMPORT_STAT_NO_EXIST; } #endif }
// convert a Micro Python object to a sensible value for inline asm machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { // TODO for byte_array, pass pointer to the array if (MP_OBJ_IS_SMALL_INT(obj)) { return MP_OBJ_SMALL_INT_VALUE(obj); } else if (obj == mp_const_none) { return 0; } else if (obj == mp_const_false) { return 0; } else if (obj == mp_const_true) { return 1; } else if (MP_OBJ_IS_TYPE(obj, &str_type)) { // pointer to the string (it's probably constant though!) return (machine_uint_t)qstr_str(mp_obj_str_get(obj)); #if MICROPY_ENABLE_FLOAT } else if (MP_OBJ_IS_TYPE(obj, &float_type)) { // convert float to int (could also pass in float registers) return (machine_int_t)mp_obj_float_get(obj); #endif } else if (MP_OBJ_IS_TYPE(obj, &tuple_type)) { // pointer to start of tuple (could pass length, but then could use len(x) for that) uint len; mp_obj_t *items; mp_obj_tuple_get(obj, &len, &items); return (machine_uint_t)items; } else if (MP_OBJ_IS_TYPE(obj, &list_type)) { // pointer to start of list (could pass length, but then could use len(x) for that) uint len; mp_obj_t *items; mp_obj_list_get(obj, &len, &items); return (machine_uint_t)items; } else { // just pass along a pointer to the object return (machine_uint_t)obj; } }
// method socket.accept() STATIC mp_obj_t esp_socket_accept(mp_obj_t self_in) { esp_socket_obj_t *s = self_in; if (s->connlist == NULL) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "not listening")); } do { mp_uint_t len; mp_obj_t *items; mp_obj_list_get(s->connlist, &len, &items); if (len == 0) { break; } esp_socket_obj_t *rs = items[0]; mp_obj_list_remove(s->connlist, rs); if (rs->espconn->state != ESPCONN_CLOSE) { return rs; } } while (true); nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no connection in queue")); }
void mp_obj_get_array(mp_obj_t o, uint *len, mp_obj_t **items) { if (MP_OBJ_IS_TYPE(o, &mp_type_tuple)) { mp_obj_tuple_get(o, len, items); } else if (MP_OBJ_IS_TYPE(o, &mp_type_list)) { mp_obj_list_get(o, len, items); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o))); } }
void mp_obj_exception_get_traceback(mp_obj_t self_in, mp_uint_t *n, mp_uint_t **values) { GET_NATIVE_EXCEPTION(self, self_in); if (self->traceback == MP_OBJ_NULL) { *n = 0; *values = NULL; } else { mp_uint_t n2; mp_obj_list_get(self->traceback, &n2, (mp_obj_t**)values); *n = n2; } }
STATIC void mp_help_print_modules(void) { mp_obj_t list = mp_obj_new_list(0, NULL); mp_help_add_from_map(list, &mp_builtin_module_map); #if MICROPY_MODULE_WEAK_LINKS mp_help_add_from_map(list, &mp_builtin_module_weak_links_map); #endif #if MICROPY_MODULE_FROZEN_STR extern const char mp_frozen_str_names[]; mp_help_add_from_names(list, mp_frozen_str_names); #endif #if MICROPY_MODULE_FROZEN_MPY extern const char mp_frozen_mpy_names[]; mp_help_add_from_names(list, mp_frozen_mpy_names); #endif // sort the list so it's printed in alphabetical order mp_obj_list_sort(1, &list, (mp_map_t*)&mp_const_empty_map); // print the list of modules in a column-first order #define NUM_COLUMNS (4) #define COLUMN_WIDTH (18) mp_uint_t len; mp_obj_t *items; mp_obj_list_get(list, &len, &items); unsigned int num_rows = (len + NUM_COLUMNS - 1) / NUM_COLUMNS; for (unsigned int i = 0; i < num_rows; ++i) { unsigned int j = i; for (;;) { int l = mp_print_str(MP_PYTHON_PRINTER, mp_obj_str_get_str(items[j])); j += num_rows; if (j >= len) { break; } int gap = COLUMN_WIDTH - l; while (gap < 1) { gap += COLUMN_WIDTH; } while (gap--) { mp_print_str(MP_PYTHON_PRINTER, " "); } } mp_print_str(MP_PYTHON_PRINTER, "\n"); } // let the user know there may be other modules available from the filesystem mp_print_str(MP_PYTHON_PRINTER, "Plus any modules on the filesystem\n"); }
void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine_uint_t **values) { // make sure self_in is an exception instance assert(mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new); mp_obj_exception_t *self = self_in; if (self->traceback == MP_OBJ_NULL) { *n = 0; *values = NULL; } else { uint n2; mp_obj_list_get(self->traceback, &n2, (mp_obj_t**)values); *n = n2; } }
// note: returned value in *items may point to the interior of a GC block void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { if (MP_OBJ_IS_TYPE(o, &mp_type_tuple)) { mp_obj_tuple_get(o, len, items); } else if (MP_OBJ_IS_TYPE(o, &mp_type_list)) { mp_obj_list_get(o, len, items); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_raise_TypeError("expected tuple/list"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object '%s' isn't a tuple or list", mp_obj_get_type_str(o))); } } }
mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { assert(MP_OBJ_IS_STR(self_in)); // get separation string GET_STR_DATA_LEN(self_in, sep_str, sep_len); // process args uint seq_len; mp_obj_t *seq_items; if (MP_OBJ_IS_TYPE(arg, &tuple_type)) { mp_obj_tuple_get(arg, &seq_len, &seq_items); } else if (MP_OBJ_IS_TYPE(arg, &list_type)) { mp_obj_list_get(arg, &seq_len, &seq_items); } else { goto bad_arg; } // count required length int required_len = 0; for (int i = 0; i < seq_len; i++) { if (!MP_OBJ_IS_STR(seq_items[i])) { goto bad_arg; } if (i > 0) { required_len += sep_len; } GET_STR_LEN(seq_items[i], l); required_len += l; } // make joined string byte *data; mp_obj_t joined_str = mp_obj_str_builder_start(required_len, &data); for (int i = 0; i < seq_len; i++) { if (i > 0) { memcpy(data, sep_str, sep_len); data += sep_len; } GET_STR_DATA_LEN(seq_items[i], s, l); memcpy(data, s, l); data += l; } // return joined string return mp_obj_str_builder_end(joined_str); bad_arg: nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "?str.join expecting a list of str's")); }
void mp_obj_get_array_fixed_n(mp_obj_t o, uint len, mp_obj_t **items) { if (MP_OBJ_IS_TYPE(o, &mp_type_tuple) || MP_OBJ_IS_TYPE(o, &mp_type_list)) { uint seq_len; if (MP_OBJ_IS_TYPE(o, &mp_type_tuple)) { mp_obj_tuple_get(o, &seq_len, items); } else { mp_obj_list_get(o, &seq_len, items); } if (seq_len != len) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError, "requested length %d but object has length %d", len, seq_len)); } } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o))); } }
// convert a Micro Python object to a sensible value for inline asm STATIC machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { // TODO for byte_array, pass pointer to the array if (MP_OBJ_IS_SMALL_INT(obj)) { return MP_OBJ_SMALL_INT_VALUE(obj); } else if (obj == mp_const_none) { return 0; } else if (obj == mp_const_false) { return 0; } else if (obj == mp_const_true) { return 1; } else if (MP_OBJ_IS_STR(obj)) { // pointer to the string (it's probably constant though!) uint l; return (machine_uint_t)mp_obj_str_get_data(obj, &l); } else { mp_obj_type_t *type = mp_obj_get_type(obj); if (0) { #if MICROPY_PY_BUILTINS_FLOAT } else if (type == &mp_type_float) { // convert float to int (could also pass in float registers) return (machine_int_t)mp_obj_float_get(obj); #endif } else if (type == &mp_type_tuple) { // pointer to start of tuple (could pass length, but then could use len(x) for that) uint len; mp_obj_t *items; mp_obj_tuple_get(obj, &len, &items); return (machine_uint_t)items; } else if (type == &mp_type_list) { // pointer to start of list (could pass length, but then could use len(x) for that) uint len; mp_obj_t *items; mp_obj_list_get(obj, &len, &items); return (machine_uint_t)items; } else { mp_buffer_info_t bufinfo; if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_WRITE)) { // supports the buffer protocol, return a pointer to the data return (machine_uint_t)bufinfo.buf; } else { // just pass along a pointer to the object return (machine_uint_t)obj; } } } }
static int py_load_vars(py_handle_t* py) { mp_obj_t obj; mp_obj_t* items; mp_uint_t n; size_t i; size_t j; for (i = 0; i != py->nvar; ++i) { py_var_t* const v = py->vars[i]; if ((v->flags & PY_FLAG_OUT) == 0) continue ; obj = mp_load_name(v->name); if (v->flags & PY_FLAG_ARRAY) { mp_obj_list_get(obj, &n, &items); if (n > v->dim) n = v->dim; } else { items = &obj; n = 1; } if (v->flags & PY_FLAG_INT) { for (j = 0; j != (size_t)n; ++j) v->data.i[j] = mp_obj_get_int(items[j]); } else { for (j = 0; j != (size_t)n; ++j) v->data.f[j] = mp_obj_float_get(items[j]); } } return 0; }
static int py_init(void) { mp_stack_set_limit(40000 * (BYTES_PER_WORD / 4)); #if MICROPY_ENABLE_GC static long heap_size = 1024 * 1024 * (sizeof(mp_uint_t) / 4); char *heap = malloc(heap_size); gc_init(heap, heap + heap_size); #endif mp_init(); #if 0 static mp_uint_t path_num = 1; mp_obj_t *path_items; mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), path_num); mp_obj_list_get(mp_sys_path, &path_num, &path_items); path_items[0] = MP_OBJ_NEW_QSTR(MP_QSTR_); mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); #endif return 0; }
STATIC mp_obj_t esp_socket_onconnect(mp_obj_t self_in, mp_obj_t lambda_in) { esp_socket_obj_t *s = self_in; s->cb_connect = lambda_in; if (s->connlist != NULL) { do { mp_uint_t len; mp_obj_t *items; mp_obj_list_get(s->connlist, &len, &items); if (len == 0) { break; } esp_socket_obj_t *rs = items[0]; mp_obj_list_remove(s->connlist, rs); if (s->espconn->state != ESPCONN_CLOSE) { call_function_1_protected(s->cb_connect, rs); } } while (true); } return mp_const_none; }
int main(int argc, char **argv) { 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) { #ifdef MICROPY_PY_SYS_PATH_DEFAULT path = MICROPY_PY_SYS_PATH_DEFAULT; #else path = "~/.micropython/lib:/usr/lib/micropython"; #endif } 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) { if (isatty(0)) { prompt_read_history(); ret = do_repl(); prompt_write_history(); } else { mp_lexer_t *lex = mp_lexer_new_from_fd(MP_QSTR__lt_stdin_gt_, 0, false); ret = execute_from_lexer(lex, MP_PARSE_FILE_INPUT, false); } } #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()); return ret & 0xff; }
int main(int argc, char **argv) { mp_stack_set_limit(32768); pre_process_options(argc, argv); #if MICROPY_ENABLE_GC char *heap = malloc(heap_size); gc_init(heap, heap + heap_size); #endif mp_init(); 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 (int 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, 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("mem_info"), (mp_obj_t*)&mem_info_obj); mp_store_name(qstr_from_str("qstr_info"), (mp_obj_t*)&qstr_info_obj); // 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]); a += 1; } 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_optimise_value = argv[a][2] & 0xf; } else { mp_optimise_value = 0; for (char *p = argv[a] + 1; *p && *p == 'O'; p++, 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); for (int i = a; i < argc; i++) { mp_obj_list_append(mp_sys_argv, MP_OBJ_NEW_QSTR(qstr_from_str(argv[i]))); } ret = do_file(argv[a]); break; } } if (ret == NOTHING_EXECUTED) { do_repl(); ret = 0; } mp_deinit(); //printf("total bytes = %d\n", m_get_total_bytes_allocated()); return ret; }
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; }