diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/builtin.c | 15 | ||||
-rw-r--r-- | py/builtin.h | 1 | ||||
-rw-r--r-- | py/builtinimport.c | 1 | ||||
-rw-r--r-- | py/builtintables.c | 1 | ||||
-rw-r--r-- | py/compile.c | 2 | ||||
-rw-r--r-- | py/compile.h | 2 | ||||
-rw-r--r-- | py/emitglue.c | 25 | ||||
-rw-r--r-- | py/emitglue.h | 3 | ||||
-rw-r--r-- | py/lexer.c | 22 | ||||
-rw-r--r-- | py/modstruct.c | 84 | ||||
-rw-r--r-- | py/mpz.c | 4 | ||||
-rw-r--r-- | py/obj.c | 7 | ||||
-rw-r--r-- | py/objarray.c | 1 | ||||
-rw-r--r-- | py/objbool.c | 10 | ||||
-rw-r--r-- | py/objcomplex.c | 9 | ||||
-rw-r--r-- | py/objfloat.c | 7 | ||||
-rw-r--r-- | py/objfun.c | 1 | ||||
-rw-r--r-- | py/objgenerator.c | 1 | ||||
-rw-r--r-- | py/objint.c | 7 | ||||
-rw-r--r-- | py/objint_longlong.c | 1 | ||||
-rw-r--r-- | py/objlist.c | 7 | ||||
-rw-r--r-- | py/objnamedtuple.c | 1 | ||||
-rw-r--r-- | py/objproperty.c | 5 | ||||
-rw-r--r-- | py/objset.c | 17 | ||||
-rw-r--r-- | py/objstr.c | 22 | ||||
-rw-r--r-- | py/objtuple.c | 8 | ||||
-rw-r--r-- | py/objtype.c | 3 | ||||
-rw-r--r-- | py/objzip.c | 2 | ||||
-rw-r--r-- | py/qstrdefs.h | 1 | ||||
-rw-r--r-- | py/runtime.c | 14 | ||||
-rw-r--r-- | py/runtime.h | 2 | ||||
-rw-r--r-- | py/sequence.c | 1 | ||||
-rw-r--r-- | py/showbc.c | 6 | ||||
-rw-r--r-- | py/stream.c | 1 | ||||
-rw-r--r-- | py/vm.c | 2 |
35 files changed, 196 insertions, 100 deletions
diff --git a/py/builtin.c b/py/builtin.c index 8d5779e42c..7f0d2a4d9f 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -462,6 +462,21 @@ STATIC mp_obj_t mp_builtin_getattr(uint n_args, const mp_obj_t *args) { MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_getattr_obj, 2, 3, mp_builtin_getattr); +STATIC mp_obj_t mp_builtin_hasattr(mp_obj_t object_in, mp_obj_t attr_in) { + assert(MP_OBJ_IS_QSTR(attr_in)); + + mp_obj_t dest[2]; + // TODO: https://docs.python.org/3.3/library/functions.html?highlight=hasattr#hasattr + // explicitly says "This is implemented by calling getattr(object, name) and seeing + // whether it raises an AttributeError or not.", so we should explicitly wrap this + // in nlr_push and handle exception. + mp_load_method_maybe(object_in, MP_OBJ_QSTR_VALUE(attr_in), dest); + + return MP_BOOL(dest[0] != MP_OBJ_NULL); +} + +MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_hasattr_obj, mp_builtin_hasattr); + // These two are defined in terms of MicroPython API functions right away MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_globals_obj, mp_globals_get); MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_locals_obj, mp_locals_get); diff --git a/py/builtin.h b/py/builtin.h index baf444a208..2929c1018a 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -41,6 +41,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_eval_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_exec_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_getattr_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_globals_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hasattr_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hash_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hex_obj); MP_DECLARE_CONST_FUN_OBJ(mp_builtin_id_obj); diff --git a/py/builtinimport.c b/py/builtinimport.c index e6bb7586c8..e758158a64 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/builtintables.c b/py/builtintables.c index a1888a6e97..133c14a269 100644 --- a/py/builtintables.c +++ b/py/builtintables.c @@ -90,6 +90,7 @@ STATIC const mp_map_elem_t mp_builtin_object_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_exec), (mp_obj_t)&mp_builtin_exec_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_getattr), (mp_obj_t)&mp_builtin_getattr_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_globals), (mp_obj_t)&mp_builtin_globals_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_hasattr), (mp_obj_t)&mp_builtin_hasattr_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_hash), (mp_obj_t)&mp_builtin_hash_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_hex), (mp_obj_t)&mp_builtin_hex_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_id), (mp_obj_t)&mp_builtin_id_obj }, diff --git a/py/compile.c b/py/compile.c index 36ffa928ee..cdd3a5b030 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1147,7 +1147,7 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_ qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]); if (attr == MP_QSTR_bytecode) { - *emit_options = MP_EMIT_OPT_BYTE_CODE; + *emit_options = MP_EMIT_OPT_BYTECODE; #if MICROPY_EMIT_NATIVE } else if (attr == MP_QSTR_native) { *emit_options = MP_EMIT_OPT_NATIVE_PYTHON; diff --git a/py/compile.h b/py/compile.h index 4606378976..52c42aff4f 100644 --- a/py/compile.h +++ b/py/compile.h @@ -27,7 +27,7 @@ // These must fit in 8 bits; see scope.h enum { MP_EMIT_OPT_NONE, - MP_EMIT_OPT_BYTE_CODE, + MP_EMIT_OPT_BYTECODE, MP_EMIT_OPT_NATIVE_PYTHON, MP_EMIT_OPT_VIPER, MP_EMIT_OPT_ASM_THUMB, diff --git a/py/emitglue.c b/py/emitglue.c index 7265a206a8..528c3bd36c 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -49,24 +49,6 @@ #define DEBUG_OP_printf(...) (void)0 #endif -#ifdef WRITE_CODE -FILE *fp_write_code = NULL; -#endif - -void mp_emit_glue_init(void) { -#ifdef WRITE_CODE - fp_write_code = fopen("out-code", "wb"); -#endif -} - -void mp_emit_glue_deinit(void) { -#ifdef WRITE_CODE - if (fp_write_code != NULL) { - fclose(fp_write_code); - } -#endif -} - mp_raw_code_t *mp_emit_glue_new_raw_code(void) { mp_raw_code_t *rc = m_new0(mp_raw_code_t, 1); rc->kind = MP_CODE_RESERVED; @@ -123,10 +105,9 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void DEBUG_printf("\n"); #ifdef WRITE_CODE - if (fp_write_code != NULL) { - fwrite(fun_data, len, 1, fp_write_code); - fflush(fp_write_code); - } + FILE *fp_write_code = fopen("out-code", "wb"); + fwrite(fun_data, len, 1, fp_write_code); + fclose(fp_write_code); #endif #endif } diff --git a/py/emitglue.h b/py/emitglue.h index 43bfb5e08a..c6cbb6283d 100644 --- a/py/emitglue.h +++ b/py/emitglue.h @@ -52,9 +52,6 @@ typedef struct _mp_code_t { }; } mp_raw_code_t; -void mp_emit_glue_init(void); -void mp_emit_glue_deinit(void); - mp_raw_code_t *mp_emit_glue_new_raw_code(void); void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint n_pos_args, uint n_kwonly_args, qstr *arg_names, uint scope_flags); diff --git a/py/lexer.c b/py/lexer.c index f736ef3030..e2dfea78c8 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -64,6 +64,13 @@ struct _mp_lexer_t { mp_token_t tok_cur; }; +// debug flag for __debug__ constant +STATIC mp_token_kind_t mp_debug_value; + +void mp_set_debug(bool value) { + mp_debug_value = value ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE; +} + // TODO replace with a call to a standard function bool str_strn_equal(const char *str, const char *strn, int len) { uint i = 0; @@ -303,7 +310,7 @@ STATIC const char *tok_kw[] = { "while", "with", "yield", - NULL, + "__debug__", }; STATIC int hex_digit(unichar c) { @@ -687,9 +694,18 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs // check for keywords if (tok->kind == MP_TOKEN_NAME) { - for (int i = 0; tok_kw[i] != NULL; i++) { + // We check for __debug__ here and convert it to its value. This is so + // the parser gives a syntax error on, eg, x.__debug__. Otherwise, we + // need to check for this special token in many places in the compiler. + // TODO improve speed of these string comparisons + //for (int i = 0; tok_kw[i] != NULL; i++) { + for (int i = 0; i < ARRAY_SIZE(tok_kw); i++) { if (str_strn_equal(tok_kw[i], tok->str, tok->len)) { - tok->kind = MP_TOKEN_KW_FALSE + i; + if (i == ARRAY_SIZE(tok_kw) - 1) { + tok->kind = mp_debug_value; + } else { + tok->kind = MP_TOKEN_KW_FALSE + i; + } break; } } diff --git a/py/modstruct.c b/py/modstruct.c index 68c5ce9baa..95a282e2ec 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,6 +35,7 @@ #include "objtuple.h" #include "objstr.h" #include "binary.h" +#include "parsenum.h" #if MICROPY_ENABLE_MOD_STRUCT @@ -56,9 +58,26 @@ STATIC char get_fmt_type(const char **fmt) { return t; } +STATIC machine_uint_t get_fmt_num(const char **p) { + const char *num = *p; + uint len = 1; + while (unichar_isdigit(*++num)) { + len++; + } + machine_uint_t val = (machine_uint_t)MP_OBJ_SMALL_INT_VALUE(mp_parse_num_integer(*p, len, 10)); + *p = num; + return val; +} + STATIC uint calcsize_items(const char *fmt) { - // TODO - return strlen(fmt); + uint cnt = 0; + while (*fmt) { + // TODO supports size spec only for "s" + if (!unichar_isdigit(*fmt++)) { + cnt++; + } + } + return cnt; } STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) { @@ -67,9 +86,23 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) { machine_uint_t size; for (size = 0; *fmt; fmt++) { uint align; - int sz = mp_binary_get_size(fmt_type, *fmt, &align); + machine_uint_t cnt = 1; + if (unichar_isdigit(*fmt)) { + cnt = get_fmt_num(&fmt); + } + if (cnt > 1) { + // TODO: count spec support only for string len + assert(*fmt == 's'); + } + + machine_uint_t sz; + if (*fmt == 's') { + sz = cnt; + } else { + sz = (machine_uint_t)mp_binary_get_size(fmt_type, *fmt, &align); + } // TODO - assert(sz != -1); + assert(sz != (machine_uint_t)-1); // Apply alignment size = (size + align - 1) & ~(align - 1); size += sz; @@ -89,7 +122,22 @@ STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) { byte *p = bufinfo.buf; for (uint i = 0; i < size; i++) { - mp_obj_t item = mp_binary_get_val(fmt_type, *fmt++, &p); + machine_uint_t sz = 1; + if (unichar_isdigit(*fmt)) { + sz = get_fmt_num(&fmt); + } + if (sz > 1) { + // TODO: size spec support only for string len + assert(*fmt == 's'); + } + mp_obj_t item; + if (*fmt == 's') { + item = mp_obj_new_bytes(p, sz); + p += sz; + fmt++; + } else { + item = mp_binary_get_val(fmt_type, *fmt++, &p); + } res->items[i] = item; } return res; @@ -106,11 +154,33 @@ STATIC mp_obj_t struct_pack(uint n_args, mp_obj_t *args) { memset(p, 0, size); for (uint i = 1; i < n_args; i++) { - mp_binary_set_val(fmt_type, *fmt++, args[i], &p); + machine_uint_t sz = 1; + if (unichar_isdigit(*fmt)) { + sz = get_fmt_num(&fmt); + } + if (sz > 1) { + // TODO: size spec support only for string len + assert(*fmt == 's'); + } + + if (*fmt == 's') { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[i], &bufinfo, MP_BUFFER_READ); + machine_uint_t to_copy = sz; + if (bufinfo.len < to_copy) { + to_copy = bufinfo.len; + } + memcpy(p, bufinfo.buf, to_copy); + memset(p + to_copy, 0, sz - to_copy); + p += sz; + fmt++; + } else { + mp_binary_set_val(fmt_type, *fmt++, args[i], &p); + } } return res; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, -1, struct_pack); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack); STATIC const mp_map_elem_t mp_module_struct_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_struct) }, @@ -213,8 +213,8 @@ STATIC uint mpn_and(mpz_dig_t *idig, const mpz_dig_t *jdig, uint jlen, const mpz *idig = *jdig & *kdig; } - for (; jlen > 0; --jlen, ++idig) { - *idig = 0; + // remove trailing zeros + for (; idig > oidig && *idig == 0; --idig) { } return idig - oidig; @@ -357,7 +357,12 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) { } else { mp_obj_type_t *type = mp_obj_get_type(o_in); if (type->unary_op != NULL) { - return type->unary_op(MP_UNARY_OP_LEN, o_in); + mp_obj_t val = type->unary_op(MP_UNARY_OP_LEN, o_in); + // TODO: Here's the case of having MP_OBJ_NOT_SUPPORTED is confusing + if (val == MP_OBJ_NOT_SUPPORTED) { + return MP_OBJ_NULL; + } + return val; } else { return MP_OBJ_NULL; } diff --git a/py/objarray.c b/py/objarray.c index b394d77461..81ab57139a 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objbool.c b/py/objbool.c index 179ab76596..e31e7a2a42 100644 --- a/py/objbool.c +++ b/py/objbool.c @@ -49,12 +49,14 @@ STATIC void bool_print(void (*print)(void *env, const char *fmt, ...), void *env } STATIC mp_obj_t bool_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 + mp_arg_check_num(n_args, n_kw, 0, 1, false); switch (n_args) { - case 0: return mp_const_false; - case 1: if (mp_obj_is_true(args[0])) { return mp_const_true; } else { return mp_const_false; } - default: nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "bool takes at most 1 argument, %d given", n_args)); + case 0: + return mp_const_false; + case 1: + default: // must be 0 or 1 + if (mp_obj_is_true(args[0])) { return mp_const_true; } else { return mp_const_false; } } } diff --git a/py/objcomplex.c b/py/objcomplex.c index 1caa49ede4..18e0edc519 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -34,6 +34,7 @@ #include "obj.h" #include "parsenum.h" #include "runtime0.h" +#include "runtime.h" #if MICROPY_ENABLE_FLOAT @@ -74,7 +75,7 @@ STATIC void complex_print(void (*print)(void *env, const char *fmt, ...), void * } STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 + mp_arg_check_num(n_args, n_kw, 0, 2, false); switch (n_args) { case 0: @@ -94,7 +95,8 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const return mp_obj_new_complex(mp_obj_get_float(args[0]), 0); } - case 2: { + case 2: + default: { mp_float_t real, imag; if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { mp_obj_complex_get(args[0], &real, &imag); @@ -112,9 +114,6 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const } return mp_obj_new_complex(real, imag); } - - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "complex takes at most 2 arguments, %d given", n_args)); } } diff --git a/py/objfloat.c b/py/objfloat.c index 5260fadc1c..e27942143d 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -37,6 +37,7 @@ #include "obj.h" #include "parsenum.h" #include "runtime0.h" +#include "runtime.h" #if MICROPY_ENABLE_FLOAT @@ -66,13 +67,14 @@ STATIC void float_print(void (*print)(void *env, const char *fmt, ...), void *en } STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 + mp_arg_check_num(n_args, n_kw, 0, 1, false); switch (n_args) { case 0: return mp_obj_new_float(0); case 1: + default: if (MP_OBJ_IS_STR(args[0])) { // a string, parse it uint l; @@ -85,9 +87,6 @@ STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m // something else, try to cast it to a float return mp_obj_new_float(mp_obj_get_float(args[0])); } - - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "float takes at most 1 argument, %d given", n_args)); } } diff --git a/py/objfun.c b/py/objfun.c index 732009376d..7915ddad0f 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objgenerator.c b/py/objgenerator.c index fb8366bae5..de2ecdd488 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objint.c b/py/objint.c index 73b4c5d0be..d1d99a253f 100644 --- a/py/objint.c +++ b/py/objint.c @@ -46,7 +46,7 @@ // This dispatcher function is expected to be independent of the implementation of long int STATIC mp_obj_t mp_obj_int_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 + mp_arg_check_num(n_args, n_kw, 0, 2, false); switch (n_args) { case 0: @@ -67,16 +67,13 @@ STATIC mp_obj_t mp_obj_int_make_new(mp_obj_t type_in, uint n_args, uint n_kw, co } case 2: - { + default: { // should be a string, parse it // TODO proper error checking of argument types uint l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_integer(s, l, mp_obj_get_int(args[1])); } - - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "int takes at most 2 arguments, %d given", n_args)); } } diff --git a/py/objint_longlong.c b/py/objint_longlong.c index f648615a73..fe35d54a48 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objlist.c b/py/objlist.c index 9e30ebb4aa..0ef685daeb 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -69,7 +69,7 @@ STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) { } STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 + mp_arg_check_num(n_args, n_kw, 0, 1, false); switch (n_args) { case 0: @@ -77,15 +77,12 @@ STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp return mp_obj_new_list(0, NULL); case 1: - { + default: { // make list from iterable // TODO: optimize list/tuple mp_obj_t list = mp_obj_new_list(0, NULL); return list_extend_from_iter(list, args[0]); } - - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "list takes at most 1 argument, %d given", n_args)); } } diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 212cf131c8..a55dd643b0 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objproperty.c b/py/objproperty.c index 439cb9ad8a..b4f2e7d490 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -42,13 +42,10 @@ typedef struct _mp_obj_property_t { } mp_obj_property_t; STATIC mp_obj_t property_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 + mp_arg_check_num(n_args, n_kw, 0, 4, false); mp_obj_property_t *o = m_new_obj(mp_obj_property_t); o->base.type = &mp_type_property; - if (n_args >= 5) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "property takes at most 4 arguments")); - } if (n_args >= 4) { // doc ignored } diff --git a/py/objset.c b/py/objset.c index 4198dac18f..a6f1fe7339 100644 --- a/py/objset.c +++ b/py/objset.c @@ -121,15 +121,19 @@ STATIC void set_print(void (*print)(void *env, const char *fmt, ...), void *env, STATIC mp_obj_t set_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 + mp_arg_check_num(n_args, n_kw, 0, 1, false); switch (n_args) { - case 0: - // return a new, empty set - return mp_obj_new_set(0, NULL); + case 0: { + // create a new, empty set + mp_obj_set_t *set = mp_obj_new_set(0, NULL); + // set actual set/frozenset type + set->base.type = type_in; + return set; + } case 1: - { + default: { // can only be 0 or 1 arg // 1 argument, an iterable from which we make a new set mp_obj_set_t *set = mp_obj_new_set(0, NULL); mp_obj_t iterable = mp_getiter(args[0]); @@ -141,9 +145,6 @@ STATIC mp_obj_t set_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_ set->base.type = type_in; return set; } - - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "set takes at most 1 argument, %d given", n_args)); } } diff --git a/py/objstr.c b/py/objstr.c index 33bfcc3756..3a4b0b97f3 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -332,6 +333,7 @@ STATIC mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { } STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { + mp_obj_type_t *type = mp_obj_get_type(self_in); GET_STR_DATA_LEN(self_in, self_data, self_len); if (value == MP_OBJ_SENTINEL) { // load @@ -341,10 +343,9 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (!mp_seq_get_fast_slice_indexes(self_len, index, &start, &stop)) { assert(0); } - return mp_obj_new_str(self_data + start, stop - start, false); + return str_new(type, self_data + start, stop - start); } #endif - mp_obj_type_t *type = mp_obj_get_type(self_in); uint index_val = mp_get_index(type, self_len, index, false); if (type == &mp_type_bytes) { return MP_OBJ_NEW_SMALL_INT((mp_small_int_t)self_data[index_val]); @@ -357,7 +358,8 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { - assert(MP_OBJ_IS_STR(self_in)); + assert(is_str_or_bytes(self_in)); + const mp_obj_type_t *self_type = mp_obj_get_type(self_in); // get separation string GET_STR_DATA_LEN(self_in, sep_str, sep_len); @@ -379,8 +381,9 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { // count required length int required_len = 0; for (int i = 0; i < seq_len; i++) { - if (!MP_OBJ_IS_STR(seq_items[i])) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "join expected a list of str's")); + if (mp_obj_get_type(seq_items[i]) != self_type) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, + "join expects a list of str/bytes objects consistent with self object")); } if (i > 0) { required_len += sep_len; @@ -391,7 +394,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { // make joined string byte *data; - mp_obj_t joined_str = mp_obj_str_builder_start(mp_obj_get_type(self_in), required_len, &data); + mp_obj_t joined_str = mp_obj_str_builder_start(self_type, required_len, &data); for (int i = 0; i < seq_len; i++) { if (i > 0) { memcpy(data, sep_str, sep_len); @@ -409,6 +412,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { #define is_ws(c) ((c) == ' ' || (c) == '\t') STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) { + const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); machine_int_t splits = -1; mp_obj_t sep = mp_const_none; if (n_args > 1) { @@ -430,7 +434,7 @@ STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) { while (s < top && splits != 0) { const byte *start = s; while (s < top && !is_ws(*s)) s++; - mp_obj_list_append(res, mp_obj_new_str(start, s - start, false)); + mp_obj_list_append(res, str_new(self_type, start, s - start)); if (s >= top) { break; } @@ -441,7 +445,7 @@ STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) { } if (s < top) { - mp_obj_list_append(res, mp_obj_new_str(s, top - s, false)); + mp_obj_list_append(res, str_new(self_type, s, top - s)); } } else { @@ -465,7 +469,7 @@ STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) { } s++; } - mp_obj_list_append(res, mp_obj_new_str(start, s - start, false)); + mp_obj_list_append(res, str_new(self_type, start, s - start)); if (s >= top) { break; } diff --git a/py/objtuple.c b/py/objtuple.c index 1ec75239bd..44ee95dd96 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -57,14 +57,15 @@ void mp_obj_tuple_print(void (*print)(void *env, const char *fmt, ...), void *en } STATIC mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 + mp_arg_check_num(n_args, n_kw, 0, 1, false); switch (n_args) { case 0: // return a empty tuple return mp_const_empty_tuple; - case 1: { + case 1: + default: { // 1 argument, an iterable from which we make a new tuple if (MP_OBJ_IS_TYPE(args[0], &mp_type_tuple)) { return args[0]; @@ -91,9 +92,6 @@ STATIC mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, return tuple; } - - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "tuple takes at most 1 argument, %d given", n_args)); } } diff --git a/py/objtype.c b/py/objtype.c index c579477db7..4827595bbe 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -540,7 +541,7 @@ STATIC void type_print(void (*print)(void *env, const char *fmt, ...), void *env } STATIC mp_obj_t type_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 + mp_arg_check_num(n_args, n_kw, 1, 3, false); switch (n_args) { case 1: diff --git a/py/objzip.c b/py/objzip.c index 8f8946264d..97a14eb870 100644 --- a/py/objzip.c +++ b/py/objzip.c @@ -40,7 +40,7 @@ typedef struct _mp_obj_zip_t { } mp_obj_zip_t; STATIC mp_obj_t zip_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // TODO check n_kw == 0 + mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args); o->base.type = &mp_type_zip; diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 13476b3be8..1679d8b39c 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -142,6 +142,7 @@ Q(float) Q(from_bytes) Q(getattr) Q(globals) +Q(hasattr) Q(hash) Q(hex) Q(%#x) diff --git a/py/runtime.c b/py/runtime.c index a2de2d75b1..7c89ec4e2e 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -69,12 +69,13 @@ const mp_obj_module_t mp_module___main__ = { }; void mp_init(void) { - // call port specific initialization if any + // call port specific initialization if any #ifdef MICROPY_PORT_INIT_FUNC MICROPY_PORT_INIT_FUNC; #endif - mp_emit_glue_init(); + // __debug__ enabled by default + mp_set_debug(true); // init global module stuff mp_module_init(); @@ -90,7 +91,6 @@ void mp_init(void) { void mp_deinit(void) { //mp_obj_dict_free(&dict_main); mp_module_deinit(); - mp_emit_glue_deinit(); // call port specific deinitialization if any #ifdef MICROPY_PORT_INIT_FUNC @@ -884,9 +884,14 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { } mp_obj_t mp_getiter(mp_obj_t o_in) { + assert(o_in); mp_obj_type_t *type = mp_obj_get_type(o_in); if (type->getiter != NULL) { - return type->getiter(o_in); + mp_obj_t iter = type->getiter(o_in); + if (iter == MP_OBJ_NULL) { + goto not_iterable; + } + return iter; } else { // check for __iter__ method mp_obj_t dest[2]; @@ -901,6 +906,7 @@ mp_obj_t mp_getiter(mp_obj_t o_in) { return mp_obj_new_getitem_iter(dest); } else { // object not iterable +not_iterable: nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(o_in))); } } diff --git a/py/runtime.h b/py/runtime.h index 910a485446..a5d6743034 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -54,6 +54,8 @@ typedef struct _mp_arg_t { void mp_init(void); void mp_deinit(void); +void mp_set_debug(bool value); // sets the value of __debug__; see lexer.c + void mp_arg_check_num(uint n_args, uint n_kw, uint n_args_min, uint n_args_max, bool takes_kw); void mp_arg_parse_all(uint n_pos, const mp_obj_t *pos, mp_map_t *kws, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); void mp_arg_parse_all_kw_array(uint n_pos, uint n_kw, const mp_obj_t *args, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); diff --git a/py/sequence.c b/py/sequence.c index 91162fc099..1af2ad27ef 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/showbc.c b/py/showbc.c index 48d5328c20..91b7572db9 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -404,14 +404,10 @@ void mp_bytecode_print2(const byte *ip, int len) { printf("STORE_MAP"); break; - /* case MP_BC_MAP_ADD: DECODE_UINT; - // I think it's guaranteed by the compiler that sp[unum + 1] is a map - rt_store_map(sp[unum + 1], sp[0], sp[1]); - sp += 2; + printf("MAP_ADD " UINT_FMT, unum); break; - */ case MP_BC_BUILD_SET: DECODE_UINT; diff --git a/py/stream.c b/py/stream.c index 9eb438b538..599582b510 100644 --- a/py/stream.c +++ b/py/stream.c @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -4,6 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -663,6 +664,7 @@ unwind_jump: ENTRY(MP_BC_FOR_ITER): DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward save_sp = sp; + assert(TOP()); obj1 = mp_iternext_allow_raise(TOP()); if (obj1 == MP_OBJ_STOP_ITERATION) { --sp; // pop the exhausted iterator |