// helper function to print an exception with traceback void mp_obj_print_exception(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t exc) { if (mp_obj_is_exception_instance(exc)) { mp_uint_t n, *values; mp_obj_exception_get_traceback(exc, &n, &values); if (n > 0) { assert(n % 3 == 0); print(env, "Traceback (most recent call last):\n"); for (int i = n - 3; i >= 0; i -= 3) { #if MICROPY_ENABLE_SOURCE_LINE print(env, " File \"%s\", line %d", qstr_str(values[i]), (int)values[i + 1]); #else print(env, " File \"%s\"", qstr_str(values[i])); #endif // the block name can be NULL if it's unknown qstr block = values[i + 2]; if (block == MP_QSTR_NULL) { print(env, "\n"); } else { print(env, ", in %s\n", qstr_str(block)); } } } } mp_obj_print_helper(print, env, exc, PRINT_EXC); print(env, "\n"); }
void mp_parse_node_show(mp_parse_node_t pn, int indent) { for (int i = 0; i < indent; i++) { printf(" "); } if (MP_PARSE_NODE_IS_NULL(pn)) { printf("NULL\n"); } else if (MP_PARSE_NODE_IS_LEAF(pn)) { int arg = MP_PARSE_NODE_LEAF_ARG(pn); switch (MP_PARSE_NODE_LEAF_KIND(pn)) { case MP_PARSE_NODE_ID: printf("id(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_SMALL_INT: printf("int(%d)\n", arg); break; case MP_PARSE_NODE_INTEGER: printf("int(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_DECIMAL: printf("dec(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_STRING: printf("str(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_BYTES: printf("bytes(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_TOKEN: printf("tok(%d)\n", arg); break; default: assert(0); } } else { mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pn; int n = pns2->kind_num_nodes >> 8; #ifdef USE_RULE_NAME printf("%s(%d) (n=%d)\n", rules[MP_PARSE_NODE_STRUCT_KIND(pns2)]->rule_name, MP_PARSE_NODE_STRUCT_KIND(pns2), n); #else printf("rule(%u) (n=%d)\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns2), n); #endif for (int i = 0; i < n; i++) { mp_parse_node_show(pns2->nodes[i], indent + 2); } } }
/// \method __str__() /// Return a string describing the pin object. STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { pin_obj_t *self = self_in; // pin name print(env, "Pin(Pin.cpu.%s, mode=Pin.", qstr_str(self->name)); uint32_t mode = pin_get_mode(self); if (mode == GPIO_MODE_ANALOG) { // analog print(env, "ANALOG)"); } else { // IO mode bool af = false; qstr mode_qst; if (mode == GPIO_MODE_INPUT) { mode_qst = MP_QSTR_IN; } else if (mode == GPIO_MODE_OUTPUT_PP) { mode_qst = MP_QSTR_OUT_PP; } else if (mode == GPIO_MODE_OUTPUT_OD) { mode_qst = MP_QSTR_OUT_OD; } else { af = true; if (mode == GPIO_MODE_AF_PP) { mode_qst = MP_QSTR_AF_PP; } else { mode_qst = MP_QSTR_AF_OD; } } print(env, qstr_str(mode_qst)); // safe because mode_qst has no formating chars // pull mode qstr pull_qst = MP_QSTR_NULL; uint32_t pull = pin_get_pull(self); if (pull == GPIO_PULLUP) { pull_qst = MP_QSTR_PULL_UP; } else if (pull == GPIO_PULLDOWN) { pull_qst = MP_QSTR_PULL_DOWN; } if (pull_qst != MP_QSTR_NULL) { print(env, ", pull=Pin.%s", qstr_str(pull_qst)); } // AF mode if (af) { mp_uint_t af_idx = pin_get_af(self); const pin_af_obj_t *af_obj = pin_find_af_by_index(self, af_idx); if (af_obj == NULL) { print(env, ", af=%d)", af_idx); } else { print(env, ", af=Pin.%s)", qstr_str(af_obj->name)); } } else { print(env, ")"); } } }
void exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) { mp_obj_exception_t *o = o_in; if (o->msg != 0) { print(env, "%s: %s", qstr_str(o->id), qstr_str(o->msg)); } else { print(env, "%s", qstr_str(o->id)); tuple_print(print, env, &o->args); } }
STATIC int get_arg_i(qstr op, mp_parse_node_t *pn_args, int wanted_arg_num, int fit_mask) { if (!MP_PARSE_NODE_IS_SMALL_INT(pn_args[wanted_arg_num])) { printf("SyntaxError: '%s' expects an integer in position %d\n", qstr_str(op), wanted_arg_num); return 0; } int i = MP_PARSE_NODE_LEAF_SMALL_INT(pn_args[wanted_arg_num]); if ((i & (~fit_mask)) != 0) { printf("SyntaxError: '%s' integer 0x%x does not fit in mask 0x%x\n", qstr_str(op), i, fit_mask); return 0; } return i; }
STATIC uint get_arg_rlo(qstr op, mp_parse_node_t *pn_args, int wanted_arg_num) { if (!MP_PARSE_NODE_IS_ID(pn_args[wanted_arg_num])) { printf("SyntaxError: '%s' expects a register in position %d\n", qstr_str(op), wanted_arg_num); return 0; } qstr reg_qstr = MP_PARSE_NODE_LEAF_ARG(pn_args[wanted_arg_num]); const char *reg_str = qstr_str(reg_qstr); if (!(strlen(reg_str) == 2 && reg_str[0] == 'r' && ('0' <= reg_str[1] && reg_str[1] <= '7'))) { printf("SyntaxError: '%s' expects a register in position %d\n", qstr_str(op), wanted_arg_num); return 0; } return reg_str[1] - '0'; }
id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added) { for (int i = 0; i < scope->id_info_len; i++) { if (scope->id_info[i].qstr == qstr) { *added = false; return &scope->id_info[i]; } } // make sure we have enough memory if (scope->id_info_len >= scope->id_info_alloc) { scope->id_info = m_renew(id_info_t, scope->id_info, scope->id_info_alloc, scope->id_info_alloc * 2); scope->id_info_alloc *= 2; } id_info_t *id_info; { /* // just pick next slot in array id_info = &scope->id_info[scope->id_info_len++]; */ } if (0) { // sort insert into id_info array, so we are equivalent to CPython (no other reason to do it) // actually, seems that this is not what CPython does... scope->id_info_len += 1; for (int i = scope->id_info_len - 1;; i--) { if (i == 0 || strcmp(qstr_str(scope->id_info[i - 1].qstr), qstr_str(qstr)) < 0) { id_info = &scope->id_info[i]; break; } else { scope->id_info[i] = scope->id_info[i - 1]; } } } else { // just add new id to end of array of all ids; this seems to match CPython // important thing is that function arguments are first, but that is // handled by the compiler because it adds arguments before compiling the body id_info = &scope->id_info[scope->id_info_len++]; } id_info->param = false; id_info->kind = 0; id_info->qstr = qstr; id_info->local_num = 0; *added = true; return id_info; }
void mp_parse_node_print(mp_parse_node_t pn, size_t indent) { if (MP_PARSE_NODE_IS_STRUCT(pn)) { printf("[% 4d] ", (int)((mp_parse_node_struct_t*)pn)->source_line); } else { printf(" "); } for (size_t i = 0; i < indent; i++) { printf(" "); } if (MP_PARSE_NODE_IS_NULL(pn)) { printf("NULL\n"); } else if (MP_PARSE_NODE_IS_SMALL_INT(pn)) { mp_int_t arg = MP_PARSE_NODE_LEAF_SMALL_INT(pn); printf("int(" INT_FMT ")\n", arg); } else if (MP_PARSE_NODE_IS_LEAF(pn)) { uintptr_t arg = MP_PARSE_NODE_LEAF_ARG(pn); switch (MP_PARSE_NODE_LEAF_KIND(pn)) { case MP_PARSE_NODE_ID: printf("id(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_STRING: printf("str(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_BYTES: printf("bytes(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_TOKEN: printf("tok(%u)\n", (uint)arg); break; default: assert(0); } } else { // node must be a mp_parse_node_struct_t mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_string) { printf("literal str(%.*s)\n", (int)pns->nodes[1], (char*)pns->nodes[0]); } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_bytes) { printf("literal bytes(%.*s)\n", (int)pns->nodes[1], (char*)pns->nodes[0]); } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_const_object) { #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D printf("literal const(%016llx)\n", (uint64_t)pns->nodes[0] | ((uint64_t)pns->nodes[1] << 32)); #else printf("literal const(%p)\n", (mp_obj_t)pns->nodes[0]); #endif } else { size_t n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); #ifdef USE_RULE_NAME printf("%s(%u) (n=%u)\n", rules[MP_PARSE_NODE_STRUCT_KIND(pns)]->rule_name, (uint)MP_PARSE_NODE_STRUCT_KIND(pns), (uint)n); #else printf("rule(%u) (n=%u)\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns), (uint)n); #endif for (size_t i = 0; i < n; i++) { mp_parse_node_print(pns->nodes[i], indent + 2); } } } }
STATIC void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_exception_t *o = MP_OBJ_TO_PTR(o_in); mp_print_kind_t k = kind & ~PRINT_EXC_SUBCLASS; bool is_subclass = kind & PRINT_EXC_SUBCLASS; if (!is_subclass && (k == PRINT_REPR || k == PRINT_EXC)) { mp_print_str(print, qstr_str(o->base.type->name)); } if (k == PRINT_EXC) { mp_print_str(print, ": "); } if (k == PRINT_STR || k == PRINT_EXC) { if (o->args == NULL || o->args->len == 0) { mp_print_str(print, ""); return; } else if (o->args->len == 1) { #if MICROPY_PY_UERRNO // try to provide a nice OSError error message if (o->base.type == &mp_type_OSError && MP_OBJ_IS_SMALL_INT(o->args->items[0])) { qstr qst = mp_errno_to_str(o->args->items[0]); if (qst != MP_QSTR_NULL) { mp_printf(print, "[Errno %d] %q", MP_OBJ_SMALL_INT_VALUE(o->args->items[0]), qst); return; } } #endif mp_obj_print_helper(print, o->args->items[0], PRINT_STR); return; } } mp_obj_tuple_print(print, MP_OBJ_FROM_PTR(o->args), kind); }
STATIC void jobject_attr(mp_obj_t self_in, qstr attr_in, mp_obj_t *dest) { if (dest[0] == MP_OBJ_NULL) { // load attribute mp_obj_jobject_t *self = self_in; const char *attr = qstr_str(attr_in); jclass obj_class = JJ(GetObjectClass, self->obj); jstring field_name = JJ(NewStringUTF, attr); jobject field = JJ(CallObjectMethod, obj_class, Class_getField_mid, field_name); JJ(DeleteLocalRef, field_name); JJ(DeleteLocalRef, obj_class); if (!JJ1(ExceptionCheck)) { jfieldID field_id = JJ(FromReflectedField, field); JJ(DeleteLocalRef, field); jobject obj = JJ(GetObjectField, self->obj, field_id); dest[0] = new_jobject(obj); return; } //JJ1(ExceptionDescribe); JJ1(ExceptionClear); mp_obj_jmethod_t *o = m_new_obj(mp_obj_jmethod_t); o->base.type = &jmethod_type; o->name = attr_in; o->meth = NULL; o->obj = self->obj; o->is_static = false; dest[0] = o; } }
// 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; } }
void mp_emit_glue_assign_byte_code(mp_raw_code_t *rc, byte *code, uint len, uint n_pos_args, uint n_kwonly_args, qstr *arg_names, uint scope_flags) { rc->kind = MP_CODE_BYTE; rc->scope_flags = scope_flags; rc->n_pos_args = n_pos_args; rc->n_kwonly_args = n_kwonly_args; rc->arg_names = arg_names; rc->u_byte.code = code; rc->u_byte.len = len; #ifdef DEBUG_PRINT DEBUG_printf("assign byte code: code=%p len=%u n_pos_args=%d n_kwonly_args=%d flags=%x\n", code, len, n_pos_args, n_kwonly_args, scope_flags); DEBUG_printf(" arg names:"); for (int i = 0; i < n_pos_args + n_kwonly_args; i++) { DEBUG_printf(" %s", qstr_str(arg_names[i])); } DEBUG_printf("\n"); for (int i = 0; i < 128 && i < len; i++) { if (i > 0 && i % 16 == 0) { DEBUG_printf("\n"); } DEBUG_printf(" %02x", code[i]); } DEBUG_printf("\n"); #if MICROPY_DEBUG_PRINTERS mp_byte_code_print(code, len); #endif #endif }
void mp_bytecode_print(const void *descr, const byte *ip, int len) { const byte *ip_start = ip; // get code info size machine_uint_t code_info_size = ip[0] | (ip[1] << 8) | (ip[2] << 16) | (ip[3] << 24); const byte *code_info = ip; ip += code_info_size; qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24); qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24); printf("File %s, code block '%s' (descriptor: %p, bytecode @%p %d bytes)\n", qstr_str(source_file), qstr_str(block_name), descr, code_info, len); // bytecode prelude: state size and exception stack size; 16 bit uints { uint n_state = ip[0] | (ip[1] << 8); uint n_exc_stack = ip[2] | (ip[3] << 8); ip += 4; printf("(N_STATE %u)\n", n_state); printf("(N_EXC_STACK %u)\n", n_exc_stack); } // bytecode prelude: initialise closed over variables { uint n_local = *ip++; printf("(NUM_LOCAL %u)\n", n_local); for (; n_local > 0; n_local--) { uint local_num = *ip++; printf("(INIT_CELL %u)\n", local_num); } len -= ip - ip_start; ip_start = ip; } // print out line number info { machine_int_t bc = (code_info + code_info_size) - ip; machine_uint_t source_line = 1; printf(" bc=" INT_FMT " line=" UINT_FMT "\n", bc, source_line); for (const byte* ci = code_info + 12; *ci; ci++) { bc += *ci & 31; source_line += *ci >> 5; printf(" bc=" INT_FMT " line=" UINT_FMT "\n", bc, source_line); } } mp_bytecode_print2(ip, len - 0); }
void mp_arg_parse_all(mp_uint_t n_pos, const mp_obj_t *pos, mp_map_t *kws, mp_uint_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals) { mp_uint_t pos_found = 0, kws_found = 0; for (mp_uint_t i = 0; i < n_allowed; i++) { mp_obj_t given_arg; if (i < n_pos) { if (allowed[i].flags & MP_ARG_KW_ONLY) { goto extra_positional; } pos_found++; given_arg = pos[i]; } else { mp_map_elem_t *kw = mp_map_lookup(kws, MP_OBJ_NEW_QSTR(allowed[i].qst), MP_MAP_LOOKUP); if (kw == NULL) { if (allowed[i].flags & MP_ARG_REQUIRED) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' argument required", qstr_str(allowed[i].qst))); } } out_vals[i] = allowed[i].defval; continue; } else { kws_found++; given_arg = kw->value; } } if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_BOOL) { out_vals[i].u_bool = mp_obj_is_true(given_arg); } else if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_INT) { out_vals[i].u_int = mp_obj_get_int(given_arg); } else if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_OBJ) { out_vals[i].u_obj = given_arg; } else { assert(0); } } if (pos_found < n_pos) { extra_positional: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else { // TODO better error message nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "extra positional arguments given")); } } if (kws_found < kws->used) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else { // TODO better error message nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "extra keyword arguments given")); } } }
mp_lexer_t *mp_import_open_file(qstr mod_name) { vstr_t *vstr = vstr_new(); if (import_base_dir != NULL) { vstr_printf(vstr, "%s/", import_base_dir); } vstr_printf(vstr, "%s.py", qstr_str(mod_name)); return mp_lexer_new_from_file(vstr_str(vstr)); // TODO does lexer need to copy the string? can we free it here? }
STATIC int get_arg_label(emit_inline_asm_t *emit, qstr op, mp_parse_node_t *pn_args, int wanted_arg_num) { if (!MP_PARSE_NODE_IS_ID(pn_args[wanted_arg_num])) { printf("SyntaxError: '%s' expects a label in position %d\n", qstr_str(op), wanted_arg_num); return 0; } qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn_args[wanted_arg_num]); for (int i = 0; i < emit->max_num_labels; i++) { if (emit->label_lookup[i] == label_qstr) { return i; } } // only need to have the labels on the last pass if (emit->pass == PASS_3) { printf("SyntaxError: label '%s' not defined\n", qstr_str(label_qstr)); } return 0; }
STATIC bool check_n_arg(qstr op, int n_args, int wanted_n_args) { if (wanted_n_args == n_args) { return true; } else { printf("SyntaxError: '%s' expects %d arguments'\n", qstr_str(op), wanted_n_args); return false; } }
void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_type_t *type = mp_obj_get_type(o_in); if (type->print != NULL) { type->print(print, env, o_in, kind); } else { print(env, "<%s>", qstr_str(type->name)); } }
// return empty string in case of error, so we can attempt to parse the string // without a special check if it was in fact a string STATIC const char *get_arg_str(mp_parse_node_t pn) { if (MP_PARSE_NODE_IS_ID(pn)) { qstr qst = MP_PARSE_NODE_LEAF_ARG(pn); return qstr_str(qst); } else { return ""; } }
/// \method __str__() /// Return a string describing the pin object. STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { pin_obj_t *self = MP_OBJ_TO_PTR(self_in); // pin name mp_printf(print, "Pin(Pin.cpu.%q, mode=Pin.", self->name); uint32_t mode = pin_get_mode(self); if (mode == GPIO_MODE_ANALOG) { // analog mp_print_str(print, "ANALOG)"); } else { // IO mode bool af = false; qstr mode_qst; if (mode == GPIO_MODE_INPUT) { mode_qst = MP_QSTR_IN; } else if (mode == GPIO_MODE_OUTPUT_PP) { mode_qst = MP_QSTR_OUT; } else if (mode == GPIO_MODE_OUTPUT_OD) { mode_qst = MP_QSTR_OPEN_DRAIN; } else { af = true; if (mode == GPIO_MODE_AF_PP) { mode_qst = MP_QSTR_ALT; } else { mode_qst = MP_QSTR_ALT_OPEN_DRAIN; } } mp_print_str(print, qstr_str(mode_qst)); // pull mode qstr pull_qst = MP_QSTR_NULL; uint32_t pull = pin_get_pull(self); if (pull == GPIO_PULLUP) { pull_qst = MP_QSTR_PULL_UP; } else if (pull == GPIO_PULLDOWN) { pull_qst = MP_QSTR_PULL_DOWN; } if (pull_qst != MP_QSTR_NULL) { mp_printf(print, ", pull=Pin.%q", pull_qst); } // AF mode if (af) { mp_uint_t af_idx = pin_get_af(self); const pin_af_obj_t *af_obj = pin_find_af_by_index(self, af_idx); if (af_obj == NULL) { mp_printf(print, ", af=%d)", af_idx); } else { mp_printf(print, ", af=Pin.%q)", af_obj->name); } } else { mp_print_str(print, ")"); } } }
STATIC void pin_named_pins_obj_load_attr(mp_obj_t self_in, qstr attr_qstr, mp_obj_t *dest) { pin_named_pins_obj_t *self = self_in; const char *attr = qstr_str(attr_qstr); const pin_obj_t *pin = pin_find_named_pin(self->named_pins, attr); if (pin) { dest[0] = (mp_obj_t)pin; dest[1] = MP_OBJ_NULL; } }
STATIC void mp_obj_exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_exception_t *o = o_in; if (kind == PRINT_REPR) { print(env, "%s", qstr_str(o->base.type->name)); } else if (kind == PRINT_EXC) { print(env, "%s: ", qstr_str(o->base.type->name)); } if (kind == PRINT_STR || kind == PRINT_EXC) { if (o->args == NULL || o->args->len == 0) { print(env, ""); return; } else if (o->args->len == 1) { mp_obj_print_helper(print, env, o->args->items[0], PRINT_STR); return; } } tuple_print(print, env, o->args, kind); }
STATIC void namedtuple_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_namedtuple_t *self = self_in; const char *fields = ((mp_obj_namedtuple_type_t*)self->tuple.base.type)->fields; int id = namedtuple_find_field(qstr_str(attr), fields); if (id < 0) { return; } dest[0] = self->tuple.items[id]; }
void exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) { mp_obj_exception_t *o = o_in; switch (o->n_args) { case 0: print(env, "%s", qstr_str(o->id)); break; case 1: print(env, "%s: %s", qstr_str(o->id), (const char*)o->args[0]); break; case 2: print(env, "%s: ", qstr_str(o->id)); print(env, (const char*)o->args[0], o->args[1]); break; default: // here we just assume at least 3 args, but only use first 3 print(env, "%s: ", qstr_str(o->id)); print(env, (const char*)o->args[0], o->args[1], o->args[2]); break; } }
// helper function to print an exception with traceback void mp_obj_print_exception(mp_obj_t exc) { if (mp_obj_is_exception_instance(exc)) { machine_uint_t n, *values; mp_obj_exception_get_traceback(exc, &n, &values); if (n > 0) { assert(n % 3 == 0); printf("Traceback (most recent call last):\n"); for (int i = n - 3; i >= 0; i -= 3) { #if MICROPY_ENABLE_SOURCE_LINE printf(" File \"%s\", line %d, in %s\n", qstr_str(values[i]), (int)values[i + 1], qstr_str(values[i + 2])); #else printf(" File \"%s\", in %s\n", qstr_str(values[i]), qstr_str(values[i + 2])); #endif } } } mp_obj_print(exc, PRINT_EXC); printf("\n"); }
void mp_parse_node_print(mp_parse_node_t pn, int indent) { if (MP_PARSE_NODE_IS_STRUCT(pn)) { printf("[% 4d] ", (int)((mp_parse_node_struct_t*)pn)->source_line); } else { printf(" "); } for (int i = 0; i < indent; i++) { printf(" "); } if (MP_PARSE_NODE_IS_NULL(pn)) { printf("NULL\n"); } else if (MP_PARSE_NODE_IS_SMALL_INT(pn)) { machine_int_t arg = MP_PARSE_NODE_LEAF_SMALL_INT(pn); printf("int(" INT_FMT ")\n", arg); } else if (MP_PARSE_NODE_IS_LEAF(pn)) { machine_uint_t arg = MP_PARSE_NODE_LEAF_ARG(pn); switch (MP_PARSE_NODE_LEAF_KIND(pn)) { case MP_PARSE_NODE_ID: printf("id(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_INTEGER: printf("int(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_DECIMAL: printf("dec(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_STRING: printf("str(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_BYTES: printf("bytes(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_TOKEN: printf("tok(" INT_FMT ")\n", arg); break; default: assert(0); } } else { // node must be a mp_parse_node_struct_t mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_string) { printf("literal str(%.*s)\n", (int)pns->nodes[1], (char*)pns->nodes[0]); } else { uint n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); #ifdef USE_RULE_NAME printf("%s(%d) (n=%d)\n", rules[MP_PARSE_NODE_STRUCT_KIND(pns)]->rule_name, MP_PARSE_NODE_STRUCT_KIND(pns), n); #else printf("rule(%u) (n=%d)\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns), n); #endif for (uint i = 0; i < n; i++) { mp_parse_node_print(pns->nodes[i], indent + 2); } } } }
void exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) { mp_obj_exception_t *o = o_in; if (o->msg != NULL) { print(env, "%s: %s", qstr_str(o->id), vstr_str(o->msg)); } else { // Yes, that's how CPython has it if (kind == PRINT_REPR) { print(env, "%s", qstr_str(o->id)); } if (kind == PRINT_STR) { if (o->args.len == 0) { print(env, ""); return; } else if (o->args.len == 1) { mp_obj_print_helper(print, env, o->args.items[0], PRINT_STR); return; } } tuple_print(print, env, &o->args, kind); } }
mp_obj_t rt_load_global(qstr qstr) { // logic: search globals, builtins DEBUG_OP_printf("load global %s\n", qstr_str(qstr)); mp_map_elem_t *elem = mp_qstr_map_lookup(map_globals, qstr, false); if (elem == NULL) { elem = mp_qstr_map_lookup(&map_builtins, qstr, false); if (elem == NULL) { nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_NameError, "name '%s' is not defined", qstr_str(qstr))); } } return elem->value; }
STATIC void mod_sf2d_RenderTarget_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { SELF(self_in); const char *name = qstr_str(attr); bool load = dest[0] == MP_OBJ_NULL; if (load) { // Methods ATTR_METHOD(__del__) else ATTR_METHOD(clear) else ATTR_METHOD(start_frame) else ATTR_METHOD(end_frame) if (dest[0] != MP_OBJ_NULL) { dest[1] = self_in; return; } } // Variables if (!strcmp(name, qstr_str(MP_QSTR_clear_color))) { if (load) { dest[0] = mp_obj_new_int(self->clear_color); } else { self->clear_color = mp_obj_get_int(dest[1]); dest[0] = MP_OBJ_NULL; } } else if (!strcmp(name, qstr_str(MP_QSTR_texture))) { if (load) { dest[0] = self->texture; } } else if (!strcmp(name, qstr_str(MP_QSTR_width))) { if (load) { dest[0] = mp_obj_new_int(self->target->texture.width); } } else if (!strcmp(name, qstr_str(MP_QSTR_height))) { if (load) { dest[0] = mp_obj_new_int(self->target->texture.height); } } }
/// \method getScanData() /// Return list of the scan data tupples (ad_type, description, value) /// STATIC mp_obj_t scan_entry_get_scan_data(mp_obj_t self_in) { ubluepy_scan_entry_obj_t * self = MP_OBJ_TO_PTR(self_in); mp_obj_t retval_list = mp_obj_new_list(0, NULL); // TODO: check if self->data is set mp_obj_array_t * data = MP_OBJ_TO_PTR(self->data); uint16_t byte_index = 0; while (byte_index < data->len) { mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)); uint8_t adv_item_len = ((uint8_t * )data->items)[byte_index]; uint8_t adv_item_type = ((uint8_t * )data->items)[byte_index + 1]; mp_obj_t description = mp_const_none; mp_map_t *constant_map = mp_obj_dict_get_map(ubluepy_constants_ad_types_type.locals_dict); mp_map_elem_t *ad_types_table = MP_OBJ_TO_PTR(constant_map->table); uint16_t num_of_elements = constant_map->used; for (uint16_t i = 0; i < num_of_elements; i++) { mp_map_elem_t element = (mp_map_elem_t)*ad_types_table; ad_types_table++; uint16_t element_value = mp_obj_get_int(element.value); if (adv_item_type == element_value) { qstr key_qstr = MP_OBJ_QSTR_VALUE(element.key); const char * text = qstr_str(key_qstr); size_t len = qstr_len(key_qstr); vstr_t vstr; vstr_init(&vstr, len); vstr_printf(&vstr, "%s", text); description = mp_obj_new_str(vstr.buf, vstr.len); vstr_clear(&vstr); } } t->items[0] = MP_OBJ_NEW_SMALL_INT(adv_item_type); t->items[1] = description; t->items[2] = mp_obj_new_bytearray(adv_item_len - 1, &((uint8_t * )data->items)[byte_index + 2]); mp_obj_list_append(retval_list, MP_OBJ_FROM_PTR(t)); byte_index += adv_item_len + 1; } return retval_list; }