scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint unique_code_id, uint emit_options) { scope_t *scope = m_new(scope_t, 1); scope->kind = kind; scope->parent = NULL; scope->next = NULL; scope->pn = pn; scope->source_file = source_file; switch (kind) { case SCOPE_MODULE: scope->simple_name = MP_QSTR__lt_module_gt_; break; case SCOPE_FUNCTION: case SCOPE_CLASS: assert(MP_PARSE_NODE_IS_STRUCT(pn)); scope->simple_name = MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t*)pn)->nodes[0]); break; case SCOPE_LAMBDA: scope->simple_name = MP_QSTR__lt_lambda_gt_; break; case SCOPE_LIST_COMP: scope->simple_name = MP_QSTR__lt_listcomp_gt_; break; case SCOPE_DICT_COMP: scope->simple_name = MP_QSTR__lt_dictcomp_gt_; break; case SCOPE_SET_COMP: scope->simple_name = MP_QSTR__lt_setcomp_gt_; break; case SCOPE_GEN_EXPR: scope->simple_name = MP_QSTR__lt_genexpr_gt_; break; default: assert(0); } scope->id_info_alloc = 8; scope->id_info_len = 0; scope->id_info = m_new(id_info_t, scope->id_info_alloc); scope->flags = 0; scope->num_params = 0; /* not needed scope->num_default_params = 0; scope->num_dict_params = 0; */ scope->num_locals = 0; scope->unique_code_id = unique_code_id; scope->emit_options = emit_options; return scope; }
STATIC mp_obj_t esp_flash_read(mp_obj_t offset_in, mp_obj_t len_or_buf_in) { mp_int_t offset = mp_obj_get_int(offset_in); mp_int_t len; byte *buf; bool alloc_buf = MP_OBJ_IS_INT(len_or_buf_in); if (alloc_buf) { len = mp_obj_get_int(len_or_buf_in); buf = m_new(byte, len); } else { mp_buffer_info_t bufinfo; mp_get_buffer_raise(len_or_buf_in, &bufinfo, MP_BUFFER_WRITE); len = bufinfo.len; buf = bufinfo.buf; } // We know that allocation will be 4-byte aligned for sure SpiFlashOpResult res = spi_flash_read(offset, (uint32_t*)buf, len); if (res == SPI_FLASH_RESULT_OK) { if (alloc_buf) { return mp_obj_new_bytes(buf, len); } return mp_const_none; } if (alloc_buf) { m_del(byte, buf, len); } mp_raise_OSError(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO); }
static mp_obj_t translate(mp_obj_t words) { mp_uint_t len, outlen; const char *txt = mp_obj_str_get_data(words, &len); // Reciter truncates *output* at about 120 characters. // So to avoid that we must disallow any input that will exceed that. if (len > 80) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "text too long.")); } reciter_memory *mem = m_new(reciter_memory, 1); MP_STATE_PORT(speech_data) = mem; for (mp_uint_t i = 0; i < len; i++) { mem->input[i] = txt[i]; } mem->input[len] = '['; if (!TextToPhonemes(mem)) { MP_STATE_PORT(speech_data) = NULL; nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "could not parse input.")); } for (outlen = 0; outlen < 255; outlen++) { if (mem->input[outlen] == 155) { break; } } mp_obj_t res = mp_obj_new_str_of_type(&mp_type_str, (byte *)mem->input, outlen); // Prevent input becoming invisible to GC due to tail-call optimisation. MP_STATE_PORT(speech_data) = NULL; return res; }MP_DEFINE_CONST_FUN_OBJ_1(translate_obj, translate);
STATIC mp_obj_t mod_zlibd_decompress(uint n_args, mp_obj_t *args) { mp_obj_t data = args[0]; mp_buffer_info_t bufinfo; mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); tinfl_decompressor *decomp = m_new_obj(tinfl_decompressor); tinfl_init(decomp); DEBUG_printf("sizeof(tinfl_decompressor)=" UINT_FMT "\n", sizeof(tinfl_decompressor)); byte *out = m_new(byte, bufinfo.len); size_t out_len = bufinfo.len; size_t in_buf_ofs = 0, dst_buf_ofs = 0; size_t dst_buf_sz = bufinfo.len; while (1) { size_t in_buf_sz = bufinfo.len - in_buf_ofs; DEBUG_printf("tinfl in: in_ofs=%d in_sz=%d dst_ofs=%d, dst_sz=%d\n", in_buf_ofs, in_buf_sz, dst_buf_ofs, dst_buf_sz); tinfl_status st = tinfl_decompress(decomp, (mz_uint8*) bufinfo.buf + in_buf_ofs, &in_buf_sz, out, out + dst_buf_ofs, &dst_buf_sz, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | TINFL_FLAG_PARSE_ZLIB_HEADER); DEBUG_printf("tinfl out: st=%d, in_sz=%d, out_sz=%d\n", st, in_buf_sz, dst_buf_sz); in_buf_ofs += in_buf_sz; dst_buf_ofs += dst_buf_sz; if (st != TINFL_STATUS_HAS_MORE_OUTPUT) { break; } out = m_renew(byte, out, out_len, dst_buf_ofs + 256); out_len = dst_buf_ofs + 256; dst_buf_sz = out_len - dst_buf_ofs; } m_del_obj(tinfl_decompressor, decomp); return mp_obj_new_bytearray_by_ref(dst_buf_ofs, out); }
STATIC mp_obj_t socket_recvfrom(size_t n_args, const mp_obj_t *args) { mp_obj_socket_t *self = MP_OBJ_TO_PTR(args[0]); int sz = MP_OBJ_SMALL_INT_VALUE(args[1]); int flags = 0; if (n_args > 2) { flags = MP_OBJ_SMALL_INT_VALUE(args[2]); } struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); byte *buf = m_new(byte, sz); int out_sz = recvfrom(self->fd, buf, sz, flags, (struct sockaddr*)&addr, &addr_len); RAISE_ERRNO(out_sz, errno); mp_obj_t buf_o = mp_obj_new_str_of_type(&mp_type_bytes, buf, out_sz); m_del(char, buf, sz); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); t->items[0] = buf_o; t->items[1] = mp_obj_from_sockaddr((struct sockaddr*)&addr, addr_len); return MP_OBJ_FROM_PTR(t); }
// TODO: Make sure to handle "empty" values, which are signified by None in CPython mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) { assert(ostep == NULL); machine_int_t start = 0, stop = 0; if (ostart != mp_const_none) { start = mp_obj_get_int(ostart); } if (ostop != mp_const_none) { stop = mp_obj_get_int(ostop); if (stop == 0) { // [x:0] is a special case - in our slice object, stop = 0 means // "end of sequence". Fortunately, [x:0] is an empty seqence for // any x (including negative). [x:x] is also always empty sequence. // but x also can be 0. But note that b""[x:x] is b"" for any x (i.e. // no IndexError, at least in Python 3.3.3). So, we just use -1's to // signify that. -1 is catchy "special" number in case someone will // try to print [x:0] slice ever. start = stop = -1; } } mp_obj_slice_t *o = m_new(mp_obj_slice_t, 1); o->base.type = &slice_type; o->start = start; o->stop = stop; return (mp_obj_t)o; }
mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader) { mp_lexer_t *lex = m_new_obj(mp_lexer_t); lex->source_name = src_name; lex->reader = reader; lex->line = 1; lex->column = (size_t)-2; // account for 3 dummy bytes lex->emit_dent = 0; lex->nested_bracket_level = 0; lex->alloc_indent_level = MICROPY_ALLOC_LEXER_INDENT_INIT; lex->num_indent_level = 1; lex->indent_level = m_new(uint16_t, lex->alloc_indent_level); vstr_init(&lex->vstr, 32); // store sentinel for first indentation level lex->indent_level[0] = 0; // load lexer with start of file, advancing lex->column to 1 // start with dummy bytes and use next_char() for proper EOL/EOF handling lex->chr0 = lex->chr1 = lex->chr2 = 0; next_char(lex); next_char(lex); next_char(lex); // preload first token mp_lexer_to_next(lex); // Check that the first token is in the first column. If it's not then we // convert the token kind to INDENT so that the parser gives a syntax error. if (lex->tok_column != 1) { lex->tok_kind = MP_TOKEN_INDENT; } return lex; }
void mp_obj_list_init(mp_obj_list_t *o, uint n) { o->base.type = &mp_type_list; o->alloc = n < LIST_MIN_ALLOC ? LIST_MIN_ALLOC : n; o->len = n; o->items = m_new(mp_obj_t, o->alloc); mp_seq_clear(o->items, n, o->alloc, sizeof(*o->items)); }
STATIC mp_obj_t mod_uzlib_decompress(mp_uint_t n_args, const mp_obj_t *args) { (void)n_args; mp_obj_t data = args[0]; mp_buffer_info_t bufinfo; mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); TINF_DATA *decomp = m_new_obj(TINF_DATA); DEBUG_printf("sizeof(TINF_DATA)=" UINT_FMT "\n", sizeof(*decomp)); decomp->destSize = (bufinfo.len + 15) & ~15; decomp->destStart = m_new(byte, decomp->destSize); DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize); decomp->destGrow = mod_uzlib_grow_buf; decomp->source = bufinfo.buf; int st; if (n_args > 1 && MP_OBJ_SMALL_INT_VALUE(args[1]) < 0) { st = tinf_uncompress_dyn(decomp); } else { st = tinf_zlib_uncompress_dyn(decomp, bufinfo.len); } if (st != 0) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_ValueError, MP_OBJ_NEW_SMALL_INT(st))); } mp_uint_t final_sz = decomp->dest - decomp->destStart; DEBUG_printf("uzlib: Resizing from " UINT_FMT " to final size: " UINT_FMT " bytes\n", decomp->destSize, final_sz); decomp->destStart = (byte*)m_renew(byte, decomp->destStart, decomp->destSize, final_sz); mp_obj_t res = mp_obj_new_bytearray_by_ref(final_sz, decomp->destStart); m_del_obj(TINF_DATA, decomp); return res; }
STATIC void esp_socket_recv_callback(void *arg, char *pdata, unsigned short len) { struct espconn *conn = arg; esp_socket_obj_t *s = conn->reverse; if (s->cb_recv != mp_const_none) { call_function_2_protected(s->cb_recv, s, mp_obj_new_bytes((byte *)pdata, len)); } else { if (s->recvbuf == NULL) { s->recvbuf = m_new(uint8_t, len); s->recvbuf_len = len; if (s->recvbuf != NULL) { memcpy(s->recvbuf, pdata, len); } } else { s->recvbuf = m_renew(uint8_t, s->recvbuf, s->recvbuf_len, s->recvbuf_len + len); if (s->recvbuf != NULL) { memcpy(&s->recvbuf[s->recvbuf_len], pdata, len); s->recvbuf_len += len; } } if (s->recvbuf == NULL) { esp_socket_close(s); return; } } }
STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 2, false); mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t); o->base.type = type; memset(&o->decomp, 0, sizeof(o->decomp)); o->decomp.readSource = read_src_stream; o->src_stream = args[0]; o->eof = false; mp_int_t dict_opt = 0; int dict_sz; if (n_args > 1) { dict_opt = mp_obj_get_int(args[1]); } if (dict_opt >= 16) { int st = uzlib_gzip_parse_header(&o->decomp); if (st != TINF_OK) { goto header_error; } dict_sz = 1 << (dict_opt - 16); } else if (dict_opt >= 0) { dict_opt = uzlib_zlib_parse_header(&o->decomp); if (dict_opt < 0) { header_error: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "compression header")); } dict_sz = 1 << dict_opt; } else { dict_sz = 1 << -dict_opt; } uzlib_uncompress_init(&o->decomp, m_new(byte, dict_sz), dict_sz); return MP_OBJ_FROM_PTR(o); }
emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t max_num_labels) { emit_inline_asm_t *emit = m_new_obj(emit_inline_asm_t); emit->max_num_labels = max_num_labels; emit->label_lookup = m_new(qstr, max_num_labels); emit->as = asm_thumb_new(max_num_labels); return emit; }
static mp_obj_list_t *list_new(uint n) { mp_obj_list_t *o = m_new_obj(mp_obj_list_t); o->base.type = &list_type; o->alloc = n < 4 ? 4 : n; o->len = n; o->items = m_new(mp_obj_t, o->alloc); return o; }
emit_inline_asm_t *emit_inline_thumb_new(uint max_num_labels) { emit_inline_asm_t *emit = m_new_obj(emit_inline_asm_t); emit->max_num_labels = max_num_labels; emit->label_lookup = m_new(qstr, max_num_labels); memset(emit->label_lookup, 0, emit->max_num_labels * sizeof(qstr)); emit->as = asm_thumb_new(max_num_labels); return emit; }
mp_obj_t file_obj_read(mp_obj_t self_in, mp_obj_t arg) { pyb_file_obj_t *self = self_in; int n = mp_obj_get_int(arg); byte *buf = m_new(byte, n); UINT n_out; f_read(&self->fp, buf, n, &n_out); return mp_obj_new_str(buf, n_out, false); }
emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t max_num_labels) { emit_inline_asm_t *emit = m_new_obj(emit_inline_asm_t); memset(&emit->as, 0, sizeof(emit->as)); mp_asm_base_init(&emit->as.base, max_num_labels); emit->max_num_labels = max_num_labels; emit->label_lookup = m_new(qstr, max_num_labels); return emit; }
static mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) { uint8_t *dest = m_new(uint8_t, SDCARD_BLOCK_SIZE); if (!sdcard_read_blocks(dest, mp_obj_get_int(block_num), 1)) { m_free(dest, SDCARD_BLOCK_SIZE); return mp_const_none; } return mp_obj_new_bytearray_by_ref(SDCARD_BLOCK_SIZE, dest); }
static void alloc_unique_codes(void) { if (unique_codes == NULL) { unique_codes = m_new(mp_code_t, next_unique_code_id + 10); // XXX hack until we fix the REPL allocation problem for (int i = 0; i < next_unique_code_id; i++) { unique_codes[i].kind = MP_CODE_NONE; } } }
STATIC mp_obj_list_t *list_new(uint n) { mp_obj_list_t *o = m_new_obj(mp_obj_list_t); o->base.type = &mp_type_list; o->alloc = n < LIST_MIN_ALLOC ? LIST_MIN_ALLOC : n; o->len = n; o->items = m_new(mp_obj_t, o->alloc); return o; }
mp_obj_t py_file_read(py_file_obj_t *file, mp_obj_t n_obj) { UINT n_out; UINT n = mp_obj_get_int(n_obj); byte *buf = m_new(byte, n); f_read(py_file_cobj(&file->fp), buf, n, &n_out); return mp_obj_new_str(buf, n_out, false); }
asm_x86_t *asm_x86_new(mp_uint_t max_num_labels) { asm_x86_t *as; as = m_new0(asm_x86_t, 1); as->max_num_labels = max_num_labels; as->label_offsets = m_new(mp_uint_t, max_num_labels); return as; }
STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) { mp_obj_t data = args[0]; mp_buffer_info_t bufinfo; mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); TINF_DATA *decomp = m_new_obj(TINF_DATA); memset(decomp, 0, sizeof(*decomp)); DEBUG_printf("sizeof(TINF_DATA)=" UINT_FMT "\n", sizeof(*decomp)); uzlib_uncompress_init(decomp, NULL, 0); mp_uint_t dest_buf_size = (bufinfo.len + 15) & ~15; byte *dest_buf = m_new(byte, dest_buf_size); decomp->dest = dest_buf; decomp->destSize = dest_buf_size; DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize); decomp->source = bufinfo.buf; int st; bool is_zlib = true; if (n_args > 1 && MP_OBJ_SMALL_INT_VALUE(args[1]) < 0) { is_zlib = false; } if (is_zlib) { st = uzlib_zlib_parse_header(decomp); if (st < 0) { goto error; } } while (1) { st = uzlib_uncompress_chksum(decomp); if (st < 0) { goto error; } if (st == TINF_DONE) { break; } size_t offset = decomp->dest - dest_buf; dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256); dest_buf_size += 256; decomp->dest = dest_buf + offset; decomp->destSize = 256; } mp_uint_t final_sz = decomp->dest - dest_buf; DEBUG_printf("uzlib: Resizing from " UINT_FMT " to final size: " UINT_FMT " bytes\n", dest_buf_size, final_sz); dest_buf = (byte*)m_renew(byte, dest_buf, dest_buf_size, final_sz); mp_obj_t res = mp_obj_new_bytearray_by_ref(final_sz, dest_buf); m_del_obj(TINF_DATA, decomp); return res; error: nlr_raise(mp_obj_new_exception_arg1(&mp_type_ValueError, MP_OBJ_NEW_SMALL_INT(st))); }
STATIC mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) { uint8_t *dest = m_new(uint8_t, SDCARD_BLOCK_SIZE); mp_uint_t ret = sdcard_read_blocks(dest, mp_obj_get_int(block_num), 1); if (ret != 0) { m_del(uint8_t, dest, SDCARD_BLOCK_SIZE); nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "sdcard_read_blocks failed [%u]", ret)); } return mp_obj_new_bytearray_by_ref(SDCARD_BLOCK_SIZE, dest); }
// args are in reverse order in the array mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { mp_obj_fun_native_t *self = self_in; if (self->is_kw) { return fun_native_call_n_kw(self_in, n_args, 0, args); } if (self->n_args_min == self->n_args_max) { // function requires a fixed number of arguments // check number of arguments if (n_args != self->n_args_min) { nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args_min, (const char*)(machine_int_t)n_args)); } // dispatch function call switch (self->n_args_min) { case 0: return ((mp_fun_0_t)self->fun)(); case 1: return ((mp_fun_1_t)self->fun)(args[0]); case 2: return ((mp_fun_2_t)self->fun)(args[1], args[0]); case 3: return ((mp_fun_3_t)self->fun)(args[2], args[1], args[0]); default: assert(0); return mp_const_none; } } else { // function takes a variable number of arguments if (n_args < self->n_args_min) { nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "<fun name>() missing %d required positional arguments: <list of names of params>", (const char*)(machine_int_t)(self->n_args_min - n_args))); } else if (n_args > self->n_args_max) { nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "<fun name> expected at most %d arguments, got %d", (void*)(machine_int_t)self->n_args_max, (void*)(machine_int_t)n_args)); } // TODO really the args need to be passed in as a Python tuple, as the form f(*[1,2]) can be used to pass var args mp_obj_t *args_ordered = m_new(mp_obj_t, n_args); for (int i = 0; i < n_args; i++) { args_ordered[i] = args[n_args - i - 1]; } mp_obj_t res = ((mp_fun_var_t)self->fun)(n_args, args_ordered); m_del(mp_obj_t, args_ordered, n_args); return res; } }
mp_lexer_t *mp_lexer_new(const char *src_name, void *stream_data, mp_lexer_stream_next_char_t stream_next_char, mp_lexer_stream_close_t stream_close) { mp_lexer_t *lex = m_new(mp_lexer_t, 1); lex->name = src_name; // TODO do we need to strdup this? lex->stream_data = stream_data; lex->stream_next_char = stream_next_char; lex->stream_close = stream_close; lex->line = 1; lex->column = 1; lex->emit_dent = 0; lex->nested_bracket_level = 0; lex->alloc_indent_level = 16; lex->num_indent_level = 1; lex->indent_level = m_new(uint16_t, lex->alloc_indent_level); lex->indent_level[0] = 0; vstr_init(&lex->vstr); // preload characters lex->chr0 = stream_next_char(stream_data); lex->chr1 = stream_next_char(stream_data); lex->chr2 = stream_next_char(stream_data); // if input stream is 0, 1 or 2 characters long and doesn't end in a newline, then insert a newline at the end if (lex->chr0 == MP_LEXER_CHAR_EOF) { lex->chr0 = '\n'; } else if (lex->chr1 == MP_LEXER_CHAR_EOF) { if (lex->chr0 != '\n' && lex->chr0 != '\r') { lex->chr1 = '\n'; } } else if (lex->chr2 == MP_LEXER_CHAR_EOF) { if (lex->chr1 != '\n' && lex->chr1 != '\r') { lex->chr2 = '\n'; } } // preload first token mp_lexer_next_token_into(lex, &lex->tok_cur, true); return lex; }
/*----------------------------------------------------------------------------- * Current parse context *----------------------------------------------------------------------------*/ ParseCtx *ParseCtx_new(void) { ParseCtx *ctx = m_new(ParseCtx); utarray_new(ctx->tokens, &ut_Sym_icd); utarray_new(ctx->token_strings, &ut_str_icd); utarray_new(ctx->exprs, &ut_exprs_icd); utarray_new(ctx->open_structs, &ut_OpenStruct_icd); ctx->current_sm = SM_MAIN; return ctx; }
asm_x64_t* asm_x64_new(uint max_num_labels) { asm_x64_t* as; as = m_new(asm_x64_t, 1); as->pass = 0; as->code_offset = 0; as->code_size = 0; as->code_base = NULL; as->max_num_labels = max_num_labels; as->label_offsets = m_new(int, max_num_labels); return as; }
void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) { // store thread entry function into a global variable so we can access it ext_thread_entry = entry; if (*stack_size == 0) { *stack_size = 4096; // default stack size } else if (*stack_size < 2048) { *stack_size = 2048; // minimum stack size } // allocate TCB, stack and linked-list node (must be outside thread_mutex lock) StaticTask_t *tcb = m_new(StaticTask_t, 1); StackType_t *stack = m_new(StackType_t, *stack_size / sizeof(StackType_t)); thread_t *th = m_new_obj(thread_t); mp_thread_mutex_lock(&thread_mutex, 1); // create thread TaskHandle_t id = xTaskCreateStatic(freertos_entry, "Thread", *stack_size / sizeof(void*), arg, 2, stack, tcb); if (id == NULL) { mp_thread_mutex_unlock(&thread_mutex); mp_raise_msg(&mp_type_OSError, "can't create thread"); } // add thread to linked list of all threads th->id = id; th->ready = 0; th->arg = arg; th->stack = stack; th->stack_len = *stack_size / sizeof(StackType_t); th->next = thread; thread = th; mp_thread_mutex_unlock(&thread_mutex); // adjust stack_size to provide room to recover from hitting the limit *stack_size -= 512; }
mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader) { mp_lexer_t *lex = m_new_obj(mp_lexer_t); lex->source_name = src_name; lex->reader = reader; lex->line = 1; lex->column = 1; lex->emit_dent = 0; lex->nested_bracket_level = 0; lex->alloc_indent_level = MICROPY_ALLOC_LEXER_INDENT_INIT; lex->num_indent_level = 1; lex->indent_level = m_new(uint16_t, lex->alloc_indent_level); vstr_init(&lex->vstr, 32); // store sentinel for first indentation level lex->indent_level[0] = 0; // preload characters lex->chr0 = reader.readbyte(reader.data); lex->chr1 = reader.readbyte(reader.data); lex->chr2 = reader.readbyte(reader.data); // if input stream is 0, 1 or 2 characters long and doesn't end in a newline, then insert a newline at the end if (lex->chr0 == MP_LEXER_EOF) { lex->chr0 = '\n'; } else if (lex->chr1 == MP_LEXER_EOF) { if (lex->chr0 == '\r') { lex->chr0 = '\n'; } else if (lex->chr0 != '\n') { lex->chr1 = '\n'; } } else if (lex->chr2 == MP_LEXER_EOF) { if (lex->chr1 == '\r') { lex->chr1 = '\n'; } else if (lex->chr1 != '\n') { lex->chr2 = '\n'; } } // preload first token mp_lexer_to_next(lex); // Check that the first token is in the first column. If it's not then we // convert the token kind to INDENT so that the parser gives a syntax error. if (lex->tok_column != 1) { lex->tok_kind = MP_TOKEN_INDENT; } return lex; }
// args are in reverse order in the array mp_obj_t closure_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { mp_obj_closure_t *self = self_in; // concatenate args and closed-over-vars, in reverse order // TODO perhaps cache this array so we don't need to create it each time we are called mp_obj_t *args2 = m_new(mp_obj_t, self->n_closed + n_args); memcpy(args2, args, n_args * sizeof(mp_obj_t)); for (int i = 0; i < self->n_closed; i++) { args2[n_args + i] = self->closed[self->n_closed - 1 - i]; } // call the function with the new vars array return rt_call_function_n(self->fun, n_args + self->n_closed, args2); }