summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/builtin.c18
-rw-r--r--py/builtinevex.c9
-rw-r--r--py/builtinimport.c12
-rw-r--r--py/lexer.c34
-rw-r--r--py/mpconfig.h1
-rw-r--r--py/obj.c18
-rw-r--r--py/obj.h32
-rw-r--r--py/objarray.c6
-rw-r--r--py/objbool.c4
-rw-r--r--py/objboundmeth.c2
-rw-r--r--py/objcell.c2
-rw-r--r--py/objclosure.c2
-rw-r--r--py/objcomplex.c4
-rw-r--r--py/objdict.c16
-rw-r--r--py/objenumerate.c2
-rw-r--r--py/objexcept.c108
-rw-r--r--py/objfilter.c4
-rw-r--r--py/objfloat.c4
-rw-r--r--py/objfun.c22
-rw-r--r--py/objgenerator.c16
-rw-r--r--py/objgetitemiter.c4
-rw-r--r--py/objint.c10
-rw-r--r--py/objlist.c10
-rw-r--r--py/objmap.c4
-rw-r--r--py/objmodule.c2
-rw-r--r--py/objnone.c2
-rw-r--r--py/objrange.c4
-rw-r--r--py/objset.c10
-rw-r--r--py/objslice.c4
-rw-r--r--py/objstr.c16
-rw-r--r--py/objtuple.c6
-rw-r--r--py/objtype.c70
-rw-r--r--py/objzip.c2
-rw-r--r--py/parse.c15
-rw-r--r--py/parse.h10
-rw-r--r--py/parsehelper.c49
-rw-r--r--py/parsehelper.h2
-rw-r--r--py/py.mk1
-rw-r--r--py/qstrdefs.h1
-rw-r--r--py/runtime.c95
-rw-r--r--py/runtime.h1
-rw-r--r--py/sequence.c2
-rw-r--r--py/stream.c20
-rw-r--r--py/strtonum.c4
-rw-r--r--py/vm.c6
-rw-r--r--stm/adc.c8
-rw-r--r--stm/file.c2
-rw-r--r--stm/i2c.c2
-rw-r--r--stm/led.c2
-rw-r--r--stm/main.c19
-rw-r--r--stm/sdcard.c2
-rw-r--r--stm/servo.c2
-rw-r--r--stm/usart.c2
-rw-r--r--stm/usb.c3
-rw-r--r--teensy/led.c2
-rw-r--r--teensy/main.c16
-rw-r--r--teensy/servo.c4
-rw-r--r--unix-cpy/main.c9
-rw-r--r--unix/ffi.c41
-rw-r--r--unix/file.c4
-rw-r--r--unix/main.c11
-rw-r--r--unix/qstrdefsport.h4
-rw-r--r--unix/socket.c12
-rw-r--r--windows/main.c9
64 files changed, 473 insertions, 347 deletions
diff --git a/py/builtin.c b/py/builtin.c
index 91e54faedb..ef9e70c940 100644
--- a/py/builtin.c
+++ b/py/builtin.c
@@ -36,7 +36,7 @@ STATIC mp_obj_t mp_builtin___build_class__(uint n_args, const mp_obj_t *args) {
mp_obj_t meta;
if (n_args == 2) {
// no explicit bases, so use 'type'
- meta = (mp_obj_t)&mp_const_type;
+ meta = (mp_obj_t)&mp_type_type;
} else {
// use type of first base object
meta = mp_obj_get_type(args[2]);
@@ -142,7 +142,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
byte str[1] = {ord};
return mp_obj_new_str(str, 1, true);
} else {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "chr() arg not in range(0x110000)"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "chr() arg not in range(0x110000)"));
}
}
@@ -187,7 +187,7 @@ STATIC mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
args[1] = MP_OBJ_NEW_SMALL_INT(i1 % i2);
return rt_build_tuple(2, args);
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in)));
}
}
@@ -209,7 +209,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_iter_obj, mp_builtin_iter);
STATIC mp_obj_t mp_builtin_len(mp_obj_t o_in) {
mp_obj_t len = mp_obj_len_maybe(o_in);
if (len == NULL) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "object of type '%s' has no len()", mp_obj_get_type_str(o_in)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object of type '%s' has no len()", mp_obj_get_type_str(o_in)));
} else {
return len;
}
@@ -229,7 +229,7 @@ STATIC mp_obj_t mp_builtin_max(uint n_args, const mp_obj_t *args) {
}
}
if (max_obj == NULL) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "max() arg is an empty sequence"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "max() arg is an empty sequence"));
}
return max_obj;
} else {
@@ -258,7 +258,7 @@ STATIC mp_obj_t mp_builtin_min(uint n_args, const mp_obj_t *args) {
}
}
if (min_obj == NULL) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "min() arg is an empty sequence"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "min() arg is an empty sequence"));
}
return min_obj;
} else {
@@ -278,7 +278,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR(mp_builtin_min_obj, 1, mp_builtin_min);
STATIC mp_obj_t mp_builtin_next(mp_obj_t o) {
mp_obj_t ret = rt_iternext(o);
if (ret == mp_const_stop_iteration) {
- nlr_jump(mp_obj_new_exception(MP_QSTR_StopIteration));
+ nlr_jump(mp_obj_new_exception(&mp_type_StopIteration));
} else {
return ret;
}
@@ -294,7 +294,7 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
// TODO unicode
return mp_obj_new_int(((const byte*)str)[0]);
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "ord() expected a character, but string of length %d found", len));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "ord() expected a character, but string of length %d found", len));
}
}
@@ -364,7 +364,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj, 1, 2, mp_builtin_sum);
STATIC mp_obj_t mp_builtin_sorted(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
assert(n_args >= 1);
if (n_args > 1) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError,
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError,
"must use keyword argument for key function"));
}
mp_obj_t self = list_type.make_new((mp_obj_t)&list_type, 1, 0, args);
diff --git a/py/builtinevex.c b/py/builtinevex.c
index 3e3c9a6109..6e920e85f0 100644
--- a/py/builtinevex.c
+++ b/py/builtinevex.c
@@ -13,6 +13,7 @@
#include "lexerunix.h"
#include "parse.h"
#include "obj.h"
+#include "parsehelper.h"
#include "compile.h"
#include "runtime0.h"
#include "runtime.h"
@@ -28,14 +29,13 @@ STATIC mp_obj_t parse_compile_execute(mp_obj_t o_in, mp_parse_input_kind_t parse
qstr source_name = mp_lexer_source_name(lex);
// parse the string
- qstr parse_exc_id;
- const char *parse_exc_msg;
- mp_parse_node_t pn = mp_parse(lex, parse_input_kind, &parse_exc_id, &parse_exc_msg);
+ mp_parse_error_kind_t parse_error_kind;
+ mp_parse_node_t pn = mp_parse(lex, parse_input_kind, &parse_error_kind);
mp_lexer_free(lex);
if (pn == MP_PARSE_NODE_NULL) {
// parse error; raise exception
- nlr_jump(mp_obj_new_exception_msg(parse_exc_id, parse_exc_msg));
+ nlr_jump(mp_parse_make_exception(parse_error_kind));
}
// compile the string
@@ -74,6 +74,7 @@ STATIC mp_obj_t mp_builtin_exec(uint n_args, const mp_obj_t *args) {
rt_locals_set(mp_obj_dict_get_map(locals));
}
mp_obj_t res = parse_compile_execute(args[0], MP_PARSE_FILE_INPUT);
+ // TODO if the above call throws an exception, then we never get to reset the globals/locals
rt_globals_set(old_globals);
rt_locals_set(old_locals);
return res;
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 0e44676c3b..c90625e9e0 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -13,6 +13,7 @@
#include "lexerunix.h"
#include "parse.h"
#include "obj.h"
+#include "parsehelper.h"
#include "compile.h"
#include "runtime0.h"
#include "runtime.h"
@@ -77,7 +78,7 @@ void do_load(mp_obj_t module_obj, vstr_t *file) {
if (lex == NULL) {
// we verified the file exists using stat, but lexer could still fail
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ImportError, "ImportError: No module named '%s'", vstr_str(file)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "ImportError: No module named '%s'", vstr_str(file)));
}
qstr source_name = mp_lexer_source_name(lex);
@@ -91,16 +92,15 @@ void do_load(mp_obj_t module_obj, vstr_t *file) {
rt_globals_set(mp_obj_module_get_globals(module_obj));
// parse the imported script
- qstr parse_exc_id;
- const char *parse_exc_msg;
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_exc_id, &parse_exc_msg);
+ mp_parse_error_kind_t parse_error_kind;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind);
mp_lexer_free(lex);
if (pn == MP_PARSE_NODE_NULL) {
// parse error; clean up and raise exception
rt_locals_set(old_locals);
rt_globals_set(old_globals);
- nlr_jump(mp_obj_new_exception_msg(parse_exc_id, parse_exc_msg));
+ nlr_jump(mp_parse_make_exception(parse_error_kind));
}
// compile the imported script
@@ -172,7 +172,7 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
// fail if we couldn't find the file
if (stat == MP_IMPORT_STAT_NO_EXIST) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ImportError, "ImportError: No module named '%s'", qstr_str(mod_name)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "ImportError: No module named '%s'", qstr_str(mod_name)));
}
module_obj = mp_obj_module_get(mod_name);
diff --git a/py/lexer.c b/py/lexer.c
index c3c992aeeb..be0b1883c5 100644
--- a/py/lexer.c
+++ b/py/lexer.c
@@ -51,6 +51,7 @@ bool str_strn_equal(const char *str, const char *strn, int len) {
return i == len && *str == 0;
}
+#ifdef MICROPY_DEBUG_PRINTERS
void mp_token_show(const mp_token_t *tok) {
printf("(%d:%d) kind:%d str:%p len:%d", tok->src_line, tok->src_column, tok->kind, tok->str, tok->len);
if (tok->str != NULL && tok->len > 0) {
@@ -69,6 +70,7 @@ void mp_token_show(const mp_token_t *tok) {
}
printf("\n");
}
+#endif
#define CUR_CHAR(lex) ((lex)->chr0)
@@ -711,35 +713,3 @@ const mp_token_t *mp_lexer_cur(const mp_lexer_t *lex) {
bool mp_lexer_is_kind(mp_lexer_t *lex, mp_token_kind_t kind) {
return lex->tok_cur.kind == kind;
}
-
-/*
-bool mp_lexer_is_str(mp_lexer_t *lex, const char *str) {
- return mp_token_is_str(&lex->tok_cur, str);
-}
-
-bool mp_lexer_opt_kind(mp_lexer_t *lex, mp_token_kind_t kind) {
- if (mp_lexer_is_kind(lex, kind)) {
- mp_lexer_to_next(lex);
- return true;
- }
- return false;
-}
-
-bool mp_lexer_opt_str(mp_lexer_t *lex, const char *str) {
- if (mp_lexer_is_str(lex, str)) {
- mp_lexer_to_next(lex);
- return true;
- }
- return false;
-}
-*/
-
-bool mp_lexer_show_error_pythonic_prefix(mp_lexer_t *lex) {
- printf(" File \"%s\", line %d column %d\n", qstr_str(lex->source_name), lex->tok_cur.src_line, lex->tok_cur.src_column);
- return false;
-}
-
-bool mp_lexer_show_error_pythonic(mp_lexer_t *lex, const char *msg) {
- printf(" File \"%s\", line %d column %d\n%s\n", qstr_str(lex->source_name), lex->tok_cur.src_line, lex->tok_cur.src_column, msg);
- return false;
-}
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 6ff0692915..00e2439e4d 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -40,6 +40,7 @@
#endif
// Whether to build functions that print debugging info:
+// mp_token_show
// mp_byte_code_print
// mp_parse_node_print
#ifndef MICROPY_DEBUG_PRINTERS
diff --git a/py/obj.c b/py/obj.c
index 86c0edc15b..0068af4c43 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -51,7 +51,7 @@ void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) {
// helper function to print an exception with traceback
void mp_obj_print_exception(mp_obj_t exc) {
- if (MP_OBJ_IS_TYPE(exc, &exception_type)) {
+ if (mp_obj_is_exception_instance(exc)) {
machine_uint_t n, *values;
mp_obj_exception_get_traceback(exc, &n, &values);
if (n > 0) {
@@ -133,7 +133,7 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
}
}
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_NotImplementedError,
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_NotImplementedError,
"Equality for '%s' and '%s' types not yet implemented", mp_obj_get_type_str(o1), mp_obj_get_type_str(o2)));
return false;
}
@@ -160,7 +160,7 @@ machine_int_t mp_obj_get_int(mp_obj_t arg) {
} else if (MP_OBJ_IS_TYPE(arg, &int_type)) {
return mp_obj_int_get_checked(arg);
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "can't convert %s to int", mp_obj_get_type_str(arg)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to int", mp_obj_get_type_str(arg)));
}
}
@@ -175,7 +175,7 @@ machine_float_t mp_obj_get_float(mp_obj_t arg) {
} else if (MP_OBJ_IS_TYPE(arg, &float_type)) {
return mp_obj_float_get(arg);
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg)));
}
}
@@ -195,7 +195,7 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) {
} else if (MP_OBJ_IS_TYPE(arg, &complex_type)) {
mp_obj_complex_get(arg, real, imag);
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg)));
}
}
#endif
@@ -210,11 +210,11 @@ mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o_in, machine_int_t n) {
mp_obj_list_get(o_in, &seq_len, &seq_items);
}
if (seq_len != n) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_IndexError, "requested length %d but object has length %d", n, seq_len));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_IndexError, "requested length %d but object has length %d", n, seq_len));
}
return seq_items;
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o_in)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o_in)));
}
}
@@ -226,11 +226,11 @@ uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index)
i += len;
}
if (i < 0 || i >= len) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_IndexError, "%s index out of range", qstr_str(type->name)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_IndexError, "%s index out of range", qstr_str(type->name)));
}
return i;
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "%s indices must be integers, not %s", qstr_str(type->name), mp_obj_get_type_str(index)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "%s indices must be integers, not %s", qstr_str(type->name), mp_obj_get_type_str(index)));
}
}
diff --git a/py/obj.h b/py/obj.h
index bed119c0a2..dd6d217e4d 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -188,9 +188,27 @@ struct _mp_obj_type_t {
typedef struct _mp_obj_type_t mp_obj_type_t;
+// Constant types, globally accessible
+
+extern const mp_obj_type_t mp_type_type;
+extern const mp_obj_type_t mp_type_BaseException;
+extern const mp_obj_type_t mp_type_AssertionError;
+extern const mp_obj_type_t mp_type_AttributeError;
+extern const mp_obj_type_t mp_type_ImportError;
+extern const mp_obj_type_t mp_type_IndentationError;
+extern const mp_obj_type_t mp_type_IndexError;
+extern const mp_obj_type_t mp_type_KeyError;
+extern const mp_obj_type_t mp_type_NameError;
+extern const mp_obj_type_t mp_type_SyntaxError;
+extern const mp_obj_type_t mp_type_TypeError;
+extern const mp_obj_type_t mp_type_ValueError;
+extern const mp_obj_type_t mp_type_OverflowError;
+extern const mp_obj_type_t mp_type_OSError;
+extern const mp_obj_type_t mp_type_NotImplementedError;
+extern const mp_obj_type_t mp_type_StopIteration;
+
// Constant objects, globally accessible
-extern const mp_obj_type_t mp_const_type;
extern const mp_obj_t mp_const_none;
extern const mp_obj_t mp_const_false;
extern const mp_obj_t mp_const_true;
@@ -213,9 +231,9 @@ mp_obj_t mp_obj_new_bytes(const byte* data, uint len);
mp_obj_t mp_obj_new_float(mp_float_t val);
mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
#endif
-mp_obj_t mp_obj_new_exception(qstr id);
-mp_obj_t mp_obj_new_exception_msg(qstr id, const char *msg);
-mp_obj_t mp_obj_new_exception_msg_varg(qstr id, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
+mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type);
+mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg);
+mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!)
mp_obj_t mp_obj_new_range(int start, int stop, int step);
mp_obj_t mp_obj_new_range_iterator(int cur, int stop, int step);
mp_obj_t mp_obj_new_fun_bc(int n_args, mp_obj_t def_args, uint n_state, const byte *code);
@@ -235,6 +253,7 @@ mp_obj_t mp_obj_new_module(qstr module_name);
mp_obj_type_t *mp_obj_get_type(mp_obj_t o_in);
const char *mp_obj_get_type_str(mp_obj_t o_in);
+bool mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo);
void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind);
void mp_obj_print(mp_obj_t o, mp_print_kind_t kind);
@@ -274,8 +293,9 @@ machine_int_t mp_obj_int_get(mp_obj_t self_in);
machine_int_t mp_obj_int_get_checked(mp_obj_t self_in);
// exception
-extern const mp_obj_type_t exception_type;
-qstr mp_obj_exception_get_type(mp_obj_t self_in);
+bool mp_obj_is_exception_type(mp_obj_t self_in);
+bool mp_obj_is_exception_instance(mp_obj_t self_in);
+void mp_obj_exception_clear_traceback(mp_obj_t self_in);
void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, machine_uint_t line, qstr block);
void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine_uint_t **values);
diff --git a/py/objarray.c b/py/objarray.c
index 4a70f9f7f5..9e36196e5b 100644
--- a/py/objarray.c
+++ b/py/objarray.c
@@ -82,7 +82,7 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) {
STATIC mp_obj_t array_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
if (n_args < 1 || n_args > 2) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "unexpected # of arguments, %d given", n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unexpected # of arguments, %d given", n_args));
}
// TODO check args
uint l;
@@ -160,7 +160,7 @@ STATIC const mp_method_t array_type_methods[] = {
};
const mp_obj_type_t array_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_array,
.print = array_print,
.make_new = array_make_new,
@@ -222,7 +222,7 @@ mp_obj_t array_it_iternext(mp_obj_t self_in) {
}
STATIC const mp_obj_type_t array_it_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_iterator,
.iternext = array_it_iternext,
};
diff --git a/py/objbool.c b/py/objbool.c
index 2dd019b720..1dc5e5760e 100644
--- a/py/objbool.c
+++ b/py/objbool.c
@@ -29,7 +29,7 @@ STATIC mp_obj_t bool_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp
switch (n_args) {
case 0: return mp_const_false;
case 1: if (rt_is_true(args[0])) { return mp_const_true; } else { return mp_const_false; }
- default: nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "bool takes at most 1 argument, %d given", n_args));
+ default: nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "bool takes at most 1 argument, %d given", n_args));
}
}
@@ -46,7 +46,7 @@ STATIC mp_obj_t bool_unary_op(int op, mp_obj_t o_in) {
}
const mp_obj_type_t bool_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_bool,
.print = bool_print,
.make_new = bool_make_new,
diff --git a/py/objboundmeth.c b/py/objboundmeth.c
index 72fbc233f1..0b5fc10a07 100644
--- a/py/objboundmeth.c
+++ b/py/objboundmeth.c
@@ -40,7 +40,7 @@ mp_obj_t bound_meth_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_
}
const mp_obj_type_t bound_meth_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_bound_method,
.call = bound_meth_call,
};
diff --git a/py/objcell.c b/py/objcell.c
index ce8f360141..3666617474 100644
--- a/py/objcell.c
+++ b/py/objcell.c
@@ -25,7 +25,7 @@ void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj) {
}
const mp_obj_type_t cell_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_, // should never need to print cell type
};
diff --git a/py/objclosure.c b/py/objclosure.c
index 39e38c9d27..e2de0e0451 100644
--- a/py/objclosure.c
+++ b/py/objclosure.c
@@ -41,7 +41,7 @@ mp_obj_t closure_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *
}
const mp_obj_type_t closure_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_closure,
.call = closure_call,
};
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 3b5de03ed3..188c334132 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -66,7 +66,7 @@ STATIC mp_obj_t complex_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
}
default:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "complex takes at most 2 arguments, %d given", n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "complex takes at most 2 arguments, %d given", n_args));
}
}
@@ -86,7 +86,7 @@ STATIC mp_obj_t complex_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
}
const mp_obj_type_t complex_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_complex,
.print = complex_print,
.make_new = complex_make_new,
diff --git a/py/objdict.c b/py/objdict.c
index 15e738dff1..31a80bd6cb 100644
--- a/py/objdict.c
+++ b/py/objdict.c
@@ -60,7 +60,7 @@ STATIC mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
// dict load
mp_map_elem_t *elem = mp_map_lookup(&o->map, rhs_in, MP_MAP_LOOKUP);
if (elem == NULL) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "<value>"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_KeyError, "<value>"));
} else {
return elem->value;
}
@@ -112,7 +112,7 @@ mp_obj_t dict_it_iternext(mp_obj_t self_in) {
}
STATIC const mp_obj_type_t dict_it_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_iterator,
.iternext = dict_it_iternext,
};
@@ -187,7 +187,7 @@ STATIC mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, mp
if (elem == NULL || elem->value == NULL) {
if (deflt == NULL) {
if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "<value>"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_KeyError, "<value>"));
} else {
value = mp_const_none;
}
@@ -246,7 +246,7 @@ STATIC mp_obj_t dict_popitem(mp_obj_t self_in) {
assert(MP_OBJ_IS_TYPE(self_in, &dict_type));
mp_obj_dict_t *self = self_in;
if (self->map.used == 0) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "popitem(): dictionary is empty"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_KeyError, "popitem(): dictionary is empty"));
}
mp_obj_dict_it_t *iter = mp_obj_new_dict_iterator(self, 0);
@@ -276,7 +276,7 @@ STATIC mp_obj_t dict_update(mp_obj_t self_in, mp_obj_t iterable) {
|| value == mp_const_stop_iteration
|| stop != mp_const_stop_iteration) {
nlr_jump(mp_obj_new_exception_msg(
- MP_QSTR_ValueError,
+ &mp_type_ValueError,
"dictionary update sequence has the wrong length"));
} else {
mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
@@ -341,7 +341,7 @@ STATIC mp_obj_t dict_view_it_iternext(mp_obj_t self_in) {
}
STATIC const mp_obj_type_t dict_view_it_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_iterator,
.iternext = dict_view_it_iternext,
.methods = NULL, /* set operations still to come */
@@ -385,7 +385,7 @@ STATIC mp_obj_t dict_view_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
STATIC const mp_obj_type_t dict_view_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_dict_view,
.print = dict_view_print,
.binary_op = dict_view_binary_op,
@@ -440,7 +440,7 @@ STATIC const mp_method_t dict_type_methods[] = {
};
const mp_obj_type_t dict_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_dict,
.print = dict_print,
.make_new = dict_make_new,
diff --git a/py/objenumerate.c b/py/objenumerate.c
index 2ca4dcd775..1c858ff56f 100644
--- a/py/objenumerate.c
+++ b/py/objenumerate.c
@@ -27,7 +27,7 @@ STATIC mp_obj_t enumerate_make_new(mp_obj_t type_in, uint n_args, uint n_kw, con
}
const mp_obj_type_t enumerate_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_enumerate,
.make_new = enumerate_make_new,
.iternext = enumerate_iternext,
diff --git a/py/objexcept.c b/py/objexcept.c
index e2c154de97..d5c056a8d9 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -17,19 +17,18 @@
typedef struct mp_obj_exception_t {
mp_obj_base_t base;
mp_obj_t traceback; // a list object, holding (file,line,block) as numbers (not Python objects); a hack for now
- qstr id;
vstr_t *msg;
mp_obj_tuple_t args;
} mp_obj_exception_t;
-STATIC void exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
+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 (o->msg != NULL) {
- print(env, "%s: %s", qstr_str(o->id), vstr_str(o->msg));
+ print(env, "%s: %s", qstr_str(o->base.type->name), vstr_str(o->msg));
} else {
// Yes, that's how CPython has it
if (kind == PRINT_REPR) {
- print(env, "%s", qstr_str(o->id));
+ print(env, "%s", qstr_str(o->base.type->name));
}
if (kind == PRINT_STR) {
if (o->args.len == 0) {
@@ -44,46 +43,74 @@ STATIC void exception_print(void (*print)(void *env, const char *fmt, ...), void
}
}
-STATIC mp_obj_t exception_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- mp_obj_exception_t *base = self_in;
+STATIC mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
+ mp_obj_type_t *type = type_in;
if (n_kw != 0) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "%s does not take keyword arguments", qstr_str(base->id)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "%s does not take keyword arguments", type->name));
}
mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, mp_obj_t, n_args);
- o->base.type = &exception_type;
+ o->base.type = type;
o->traceback = MP_OBJ_NULL;
- o->id = base->id;
o->msg = NULL;
o->args.len = n_args;
memcpy(o->args.items, args, n_args * sizeof(mp_obj_t));
return o;
}
-const mp_obj_type_t exception_type = {
- { &mp_const_type },
- .name = MP_QSTR_, // TODO proper exception names
- .print = exception_print,
- .call = exception_call,
+const mp_obj_type_t mp_type_BaseException = {
+ { &mp_type_type },
+ .name = MP_QSTR_BaseException,
+ .print = mp_obj_exception_print,
+ .make_new = mp_obj_exception_make_new,
};
-mp_obj_t mp_obj_new_exception(qstr id) {
- return mp_obj_new_exception_msg_varg(id, NULL);
+#define MP_DEFINE_EXCEPTION(exc_name) \
+STATIC const mp_obj_tuple_t mp_type_ ## exc_name ## _bases_tuple = {{&tuple_type}, 1, {(mp_obj_t)&mp_type_BaseException}};\
+const mp_obj_type_t mp_type_ ## exc_name = { \
+ { &mp_type_type }, \
+ .name = MP_QSTR_ ## exc_name, \
+ .print = mp_obj_exception_print, \
+ .make_new = mp_obj_exception_make_new, \
+ .bases_tuple = (mp_obj_t)&mp_type_ ## exc_name ## _bases_tuple, \
+};
+
+MP_DEFINE_EXCEPTION(AssertionError)
+MP_DEFINE_EXCEPTION(AttributeError)
+MP_DEFINE_EXCEPTION(ImportError)
+MP_DEFINE_EXCEPTION(IndentationError)
+MP_DEFINE_EXCEPTION(IndexError)
+MP_DEFINE_EXCEPTION(KeyError)
+MP_DEFINE_EXCEPTION(NameError)
+MP_DEFINE_EXCEPTION(SyntaxError)
+MP_DEFINE_EXCEPTION(TypeError)
+MP_DEFINE_EXCEPTION(ValueError)
+MP_DEFINE_EXCEPTION(OverflowError)
+MP_DEFINE_EXCEPTION(OSError)
+MP_DEFINE_EXCEPTION(NotImplementedError)
+MP_DEFINE_EXCEPTION(StopIteration)
+
+mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type) {
+ return mp_obj_new_exception_msg_varg(exc_type, NULL);
}
-mp_obj_t mp_obj_new_exception_msg(qstr id, const char *msg) {
- return mp_obj_new_exception_msg_varg(id, msg);
+mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg) {
+ return mp_obj_new_exception_msg_varg(exc_type, msg);
}
-mp_obj_t mp_obj_new_exception_msg_varg(qstr id, const char *fmt, ...) {
+mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...) {
+ // check that the given type is an exception type
+ assert(exc_type->make_new == mp_obj_exception_make_new);
+
// make exception object
- mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, mp_obj_t*, 0);
- o->base.type = &exception_type;
+ mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, mp_obj_t, 0);
+ o->base.type = exc_type;
o->traceback = MP_OBJ_NULL;
- o->id = id;
o->args.len = 0;
+
if (fmt == NULL) {
+ // no message
o->msg = NULL;
} else {
// render exception message
@@ -97,18 +124,41 @@ mp_obj_t mp_obj_new_exception_msg_varg(qstr id, const char *fmt, ...) {
return o;
}
-qstr mp_obj_exception_get_type(mp_obj_t self_in) {
- assert(MP_OBJ_IS_TYPE(self_in, &exception_type));
+// return true if the given object is an exception type
+// TODO make this work for user defined exceptions
+bool mp_obj_is_exception_type(mp_obj_t self_in) {
+ if (MP_OBJ_IS_TYPE(self_in, &mp_type_type)) {
+ mp_obj_type_t *self = self_in;
+ return self->make_new == mp_obj_exception_make_new;
+ } else {
+ return false;
+ }
+}
+
+// return true if the given object is an instance of an exception type
+// TODO make this work for user defined exceptions
+bool mp_obj_is_exception_instance(mp_obj_t self_in) {
+ return mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new;
+}
+
+void mp_obj_exception_clear_traceback(mp_obj_t self_in) {
+ // 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;
- return self->id;
+
+ // just set the traceback to the null object
+ // we don't want to call any memory management functions here
+ self->traceback = MP_OBJ_NULL;
}
void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, machine_uint_t line, qstr block) {
- assert(MP_OBJ_IS_TYPE(self_in, &exception_type));
+ // 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;
+
// for traceback, we are just using the list object for convenience, it's not really a list of Python objects
if (self->traceback == MP_OBJ_NULL) {
- self->traceback = mp_obj_new_list(0, NULL);
+ self->traceback = mp_obj_new_list(3, NULL);
}
mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)file);
mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)line);
@@ -116,8 +166,10 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, machine_uint_t
}
void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine_uint_t **values) {
- assert(MP_OBJ_IS_TYPE(self_in, &exception_type));
+ // 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;
diff --git a/py/objfilter.c b/py/objfilter.c
index 4dde7fac8c..dc400f1a2f 100644
--- a/py/objfilter.c
+++ b/py/objfilter.c
@@ -16,7 +16,7 @@ typedef struct _mp_obj_filter_t {
STATIC mp_obj_t filter_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
if (n_args != 2 || n_kw != 0) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "filter expected 2 arguments"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "filter expected 2 arguments"));
}
assert(n_args == 2);
mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t);
@@ -45,7 +45,7 @@ STATIC mp_obj_t filter_iternext(mp_obj_t self_in) {
}
const mp_obj_type_t filter_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_filter,
.make_new = filter_make_new,
.getiter = mp_identity,
diff --git a/py/objfloat.c b/py/objfloat.c
index 83b98266e0..9d7b796895 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -40,7 +40,7 @@ STATIC mp_obj_t float_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
}
default:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "float takes at most 1 argument, %d given", n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "float takes at most 1 argument, %d given", n_args));
}
}
@@ -64,7 +64,7 @@ STATIC mp_obj_t float_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
}
const mp_obj_type_t float_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_float,
.print = float_print,
.make_new = float_make_new,
diff --git a/py/objfun.c b/py/objfun.c
index 56ea692eaf..433da039bb 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -20,23 +20,23 @@
STATIC void check_nargs(mp_obj_fun_native_t *self, int n_args, int n_kw) {
if (n_kw && !self->is_kw) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError,
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError,
"function does not take keyword arguments"));
}
if (self->n_args_min == self->n_args_max) {
if (n_args != self->n_args_min) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"function takes %d positional arguments but %d were given",
self->n_args_min, n_args));
}
} else {
if (n_args < self->n_args_min) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"<fun name>() missing %d required positional arguments: <list of names of params>",
self->n_args_min - n_args));
} else if (n_args > self->n_args_max) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"<fun name> expected at most %d arguments, got %d",
self->n_args_max, n_args));
}
@@ -89,7 +89,7 @@ STATIC mp_obj_t fun_native_call(mp_obj_t self_in, uint n_args, uint n_kw, const
}
const mp_obj_type_t fun_native_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_function,
.call = fun_native_call,
};
@@ -143,10 +143,10 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o
mp_obj_fun_bc_t *self = self_in;
if (n_args < self->n_args - self->n_def_args || n_args > self->n_args) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args));
}
if (n_kw != 0) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
}
uint use_def_args = self->n_args - n_args;
@@ -159,7 +159,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o
}
const mp_obj_type_t fun_bc_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_function,
.call = fun_bc_call,
};
@@ -252,10 +252,10 @@ STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_
mp_obj_fun_asm_t *self = self_in;
if (n_args != self->n_args) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args));
}
if (n_kw != 0) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
}
machine_uint_t ret;
@@ -276,7 +276,7 @@ STATIC mp_obj_t fun_asm_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_
}
STATIC const mp_obj_type_t fun_asm_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_function,
.call = fun_asm_call,
};
diff --git a/py/objgenerator.c b/py/objgenerator.c
index 4e7d3a199b..226b902daf 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -28,17 +28,17 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp
const byte *bc_code;
mp_obj_fun_bc_get(self_fun, &bc_n_args, &bc_n_state, &bc_code);
if (n_args != bc_n_args) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", bc_n_args, n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", bc_n_args, n_args));
}
if (n_kw != 0) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
}
return mp_obj_new_gen_instance(bc_code, bc_n_state, n_args, args);
}
const mp_obj_type_t gen_wrap_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_generator,
.call = gen_wrap_call,
};
@@ -77,7 +77,7 @@ STATIC mp_obj_t gen_next_send(mp_obj_t self_in, mp_obj_t send_value) {
}
if (self->sp == self->state - 1) {
if (send_value != mp_const_none) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "can't send non-None value to a just-started generator"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "can't send non-None value to a just-started generator"));
}
} else {
*self->sp = send_value;
@@ -108,10 +108,12 @@ mp_obj_t gen_instance_iternext(mp_obj_t self_in) {
STATIC mp_obj_t gen_instance_send(mp_obj_t self_in, mp_obj_t send_value) {
mp_obj_t ret = gen_next_send(self_in, send_value);
if (ret == mp_const_stop_iteration) {
- nlr_jump(mp_obj_new_exception(MP_QSTR_StopIteration));
+ nlr_jump(mp_obj_new_exception(&mp_type_StopIteration));
+ } else {
+ return ret;
}
- return ret;
}
+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(gen_instance_send_obj, gen_instance_send);
STATIC const mp_method_t gen_type_methods[] = {
@@ -120,7 +122,7 @@ STATIC const mp_method_t gen_type_methods[] = {
};
const mp_obj_type_t gen_instance_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_generator,
.print = gen_instance_print,
.getiter = gen_instance_getiter,
diff --git a/py/objgetitemiter.c b/py/objgetitemiter.c
index 28b118a526..bf466c05d9 100644
--- a/py/objgetitemiter.c
+++ b/py/objgetitemiter.c
@@ -26,7 +26,7 @@ STATIC mp_obj_t it_iternext(mp_obj_t self_in) {
return value;
} else {
// an exception was raised
- if (MP_OBJ_IS_TYPE(nlr.ret_val, &exception_type) && mp_obj_exception_get_type(nlr.ret_val) == MP_QSTR_StopIteration) {
+ if (mp_obj_get_type(nlr.ret_val) == &mp_type_StopIteration) {
// return mp_const_stop_iteration instead of raising StopIteration
return mp_const_stop_iteration;
} else {
@@ -37,7 +37,7 @@ STATIC mp_obj_t it_iternext(mp_obj_t self_in) {
}
STATIC const mp_obj_type_t it_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_iterator,
.iternext = it_iternext
};
diff --git a/py/objint.c b/py/objint.c
index 1ae3cebbf7..b33557b64d 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -39,7 +39,7 @@ STATIC mp_obj_t int_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_
}
default:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "int takes at most 2 arguments, %d given", n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "int takes at most 2 arguments, %d given", n_args));
}
}
@@ -65,7 +65,7 @@ mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
// This is called only with strings whose value doesn't fit in SMALL_INT
mp_obj_t mp_obj_new_int_from_long_str(const char *s) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OverflowError, "long int not supported in this build"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_OverflowError, "long int not supported in this build"));
return mp_const_none;
}
@@ -75,7 +75,7 @@ mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value) {
if ((value & (WORD_MSBIT_HIGH | (WORD_MSBIT_HIGH >> 1))) == 0) {
return MP_OBJ_NEW_SMALL_INT(value);
}
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OverflowError, "small int overflow"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow"));
return mp_const_none;
}
@@ -83,7 +83,7 @@ mp_obj_t mp_obj_new_int(machine_int_t value) {
if (MP_OBJ_FITS_SMALL_INT(value)) {
return MP_OBJ_NEW_SMALL_INT(value);
}
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OverflowError, "small int overflow"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow"));
return mp_const_none;
}
@@ -98,7 +98,7 @@ machine_int_t mp_obj_int_get_checked(mp_obj_t self_in) {
#endif // MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
const mp_obj_type_t int_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_int,
.print = int_print,
.make_new = int_make_new,
diff --git a/py/objlist.c b/py/objlist.c
index 844f9cc81f..a6fbe4e423 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -62,7 +62,7 @@ STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp
}
default:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "list takes at most 1 argument, %d given", n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "list takes at most 1 argument, %d given", n_args));
}
return NULL;
}
@@ -188,7 +188,7 @@ STATIC mp_obj_t list_pop(uint n_args, const mp_obj_t *args) {
assert(MP_OBJ_IS_TYPE(args[0], &list_type));
mp_obj_list_t *self = args[0];
if (self->len == 0) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_IndexError, "pop from empty list"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_IndexError, "pop from empty list"));
}
uint index = mp_get_index(self->base.type, self->len, n_args == 1 ? mp_obj_new_int(-1) : args[1]);
mp_obj_t ret = self->items[index];
@@ -228,7 +228,7 @@ mp_obj_t mp_obj_list_sort(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
assert(n_args >= 1);
assert(MP_OBJ_IS_TYPE(args[0], &list_type));
if (n_args > 1) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError,
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError,
"list.sort takes no positional arguments"));
}
mp_obj_list_t *self = args[0];
@@ -346,7 +346,7 @@ STATIC const mp_method_t list_type_methods[] = {
};
const mp_obj_type_t list_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_list,
.print = list_print,
.make_new = list_make_new,
@@ -408,7 +408,7 @@ mp_obj_t list_it_iternext(mp_obj_t self_in) {
}
STATIC const mp_obj_type_t list_it_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_iterator,
.iternext = list_it_iternext,
};
diff --git a/py/objmap.c b/py/objmap.c
index 012f0aadb5..cbaef6fb9a 100644
--- a/py/objmap.c
+++ b/py/objmap.c
@@ -17,7 +17,7 @@ typedef struct _mp_obj_map_t {
STATIC mp_obj_t map_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
if (n_args < 2 || n_kw != 0) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "map must have at least 2 arguments and no keyword arguments"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "map must have at least 2 arguments and no keyword arguments"));
}
assert(n_args >= 2);
mp_obj_map_t *o = m_new_obj_var(mp_obj_map_t, mp_obj_t, n_args - 1);
@@ -51,7 +51,7 @@ STATIC mp_obj_t map_iternext(mp_obj_t self_in) {
}
const mp_obj_type_t map_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_map,
.make_new = map_make_new,
.getiter = map_getiter,
diff --git a/py/objmodule.c b/py/objmodule.c
index 14a2491711..ab460fbd39 100644
--- a/py/objmodule.c
+++ b/py/objmodule.c
@@ -38,7 +38,7 @@ STATIC bool module_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
}
const mp_obj_type_t module_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_module,
.print = module_print,
.load_attr = module_load_attr,
diff --git a/py/objnone.c b/py/objnone.c
index 73f2601be4..489d34d138 100644
--- a/py/objnone.c
+++ b/py/objnone.c
@@ -24,7 +24,7 @@ STATIC mp_obj_t none_unary_op(int op, mp_obj_t o_in) {
}
const mp_obj_type_t none_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_NoneType,
.print = none_print,
.unary_op = none_unary_op,
diff --git a/py/objrange.c b/py/objrange.c
index a526ebcec6..80c5928385 100644
--- a/py/objrange.c
+++ b/py/objrange.c
@@ -24,7 +24,7 @@ STATIC mp_obj_t range_getiter(mp_obj_t o_in) {
}
STATIC const mp_obj_type_t range_type = {
- { &mp_const_type} ,
+ { &mp_type_type} ,
.name = MP_QSTR_range,
.getiter = range_getiter,
};
@@ -62,7 +62,7 @@ STATIC mp_obj_t range_it_iternext(mp_obj_t o_in) {
}
STATIC const mp_obj_type_t range_it_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_iterator,
.iternext = range_it_iternext,
};
diff --git a/py/objset.c b/py/objset.c
index 580b9de8e6..aea107fc1c 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -67,12 +67,12 @@ STATIC mp_obj_t set_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_
}
default:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "set takes at most 1 argument, %d given", n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "set takes at most 1 argument, %d given", n_args));
}
}
const mp_obj_type_t set_it_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_iterator,
.iternext = set_it_iternext,
};
@@ -310,7 +310,7 @@ STATIC mp_obj_t set_pop(mp_obj_t self_in) {
mp_obj_set_t *self = self_in;
if (self->set.used == 0) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "pop from an empty set"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_KeyError, "pop from an empty set"));
}
mp_obj_t obj = mp_set_lookup(&self->set, NULL,
MP_MAP_LOOKUP_REMOVE_IF_FOUND | MP_MAP_LOOKUP_FIRST);
@@ -322,7 +322,7 @@ STATIC mp_obj_t set_remove(mp_obj_t self_in, mp_obj_t item) {
assert(MP_OBJ_IS_TYPE(self_in, &set_type));
mp_obj_set_t *self = self_in;
if (mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_REMOVE_IF_FOUND) == MP_OBJ_NULL) {
- nlr_jump(mp_obj_new_exception(MP_QSTR_KeyError));
+ nlr_jump(mp_obj_new_exception(&mp_type_KeyError));
}
return mp_const_none;
}
@@ -446,7 +446,7 @@ STATIC const mp_method_t set_type_methods[] = {
};
const mp_obj_type_t set_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_set,
.print = set_print,
.make_new = set_make_new,
diff --git a/py/objslice.c b/py/objslice.c
index 66a3c7a7a7..10df671fea 100644
--- a/py/objslice.c
+++ b/py/objslice.c
@@ -22,7 +22,7 @@ void ellipsis_print(void (*print)(void *env, const char *fmt, ...), void *env, m
}
const mp_obj_type_t ellipsis_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_Ellipsis,
.print = ellipsis_print,
};
@@ -49,7 +49,7 @@ void slice_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_o
}
const mp_obj_type_t slice_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_slice,
.print = slice_print,
};
diff --git a/py/objstr.c b/py/objstr.c
index 6ccd239959..a1291a2203 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -124,7 +124,7 @@ STATIC mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
} else {
// Message doesn't match CPython, but we don't have so much bytes as they
// to spend them on verbose wording
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "index must be int"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "index must be int"));
}
case RT_BINARY_OP_ADD:
@@ -235,7 +235,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) {
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"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "?str.join expecting a list of str's"));
}
#define is_ws(c) ((c) == ' ' || (c) == '\t')
@@ -387,7 +387,7 @@ mp_obj_t str_format(uint n_args, const mp_obj_t *args) {
} else {
while (str < top && *str != '}') str++;
if (arg_i >= n_args) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_IndexError, "tuple index out of range"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_IndexError, "tuple index out of range"));
}
// TODO: may be PRINT_REPR depending on formatting code
mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, args[arg_i], PRINT_STR);
@@ -507,7 +507,7 @@ STATIC const mp_method_t str_type_methods[] = {
};
const mp_obj_type_t str_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_str,
.print = str_print,
.binary_op = str_binary_op,
@@ -517,7 +517,7 @@ const mp_obj_type_t str_type = {
// Reuses most of methods from str
const mp_obj_type_t bytes_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_bytes,
.print = str_print,
.binary_op = str_binary_op,
@@ -589,7 +589,7 @@ bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) {
void bad_implicit_conversion(mp_obj_t self_in) __attribute__((noreturn));
void bad_implicit_conversion(mp_obj_t self_in) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(self_in)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(self_in)));
}
uint mp_obj_str_get_hash(mp_obj_t self_in) {
@@ -667,7 +667,7 @@ STATIC mp_obj_t str_it_iternext(mp_obj_t self_in) {
}
STATIC const mp_obj_type_t str_it_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_iterator,
.iternext = str_it_iternext,
};
@@ -685,7 +685,7 @@ STATIC mp_obj_t bytes_it_iternext(mp_obj_t self_in) {
}
STATIC const mp_obj_type_t bytes_it_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_iterator,
.iternext = bytes_it_iternext,
};
diff --git a/py/objtuple.c b/py/objtuple.c
index de49ce74ef..41ad8a5d58 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -70,7 +70,7 @@ STATIC mp_obj_t tuple_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
}
default:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "tuple takes at most 1 argument, %d given", n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "tuple takes at most 1 argument, %d given", n_args));
}
}
@@ -174,7 +174,7 @@ STATIC const mp_method_t tuple_type_methods[] = {
};
const mp_obj_type_t tuple_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_tuple,
.print = tuple_print,
.make_new = tuple_make_new,
@@ -241,7 +241,7 @@ STATIC mp_obj_t tuple_it_iternext(mp_obj_t self_in) {
}
STATIC const mp_obj_type_t tuple_it_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_iterator,
.iternext = tuple_it_iternext,
};
diff --git a/py/objtype.c b/py/objtype.c
index a1592140cb..46b96c7314 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -64,7 +64,7 @@ STATIC mp_obj_t mp_obj_class_lookup(const mp_obj_type_t *type, qstr attr) {
return NULL;
}
for (uint i = 0; i < len - 1; i++) {
- assert(MP_OBJ_IS_TYPE(items[i], &mp_const_type));
+ assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type));
mp_obj_t obj = mp_obj_class_lookup((mp_obj_type_t*)items[i], attr);
if (obj != MP_OBJ_NULL) {
return obj;
@@ -72,7 +72,7 @@ STATIC mp_obj_t mp_obj_class_lookup(const mp_obj_type_t *type, qstr attr) {
}
// search last base (simple tail recursion elimination)
- assert(MP_OBJ_IS_TYPE(items[len - 1], &mp_const_type));
+ assert(MP_OBJ_IS_TYPE(items[len - 1], &mp_type_type));
type = (mp_obj_type_t*)items[len - 1];
}
}
@@ -82,7 +82,7 @@ STATIC void class_print(void (*print)(void *env, const char *fmt, ...), void *en
}
STATIC mp_obj_t class_make_new(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
- assert(MP_OBJ_IS_TYPE(self_in, &mp_const_type));
+ assert(MP_OBJ_IS_TYPE(self_in, &mp_type_type));
mp_obj_type_t *self = self_in;
mp_obj_t o = mp_obj_new_class(self_in);
@@ -103,13 +103,13 @@ STATIC mp_obj_t class_make_new(mp_obj_t self_in, uint n_args, uint n_kw, const m
m_del(mp_obj_t, args2, 1 + n_args + 2 * n_kw);
}
if (init_ret != mp_const_none) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret)));
}
} else {
// TODO
if (n_args != 0) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "function takes 0 positional arguments but %d were given", n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes 0 positional arguments but %d were given", n_args));
}
}
@@ -252,7 +252,7 @@ bool class_store_item(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
/******************************************************************************/
// type object
// - the struct is mp_obj_type_t and is defined in obj.h so const types can be made
-// - there is a constant mp_obj_type_t (called mp_const_type) for the 'type' object
+// - there is a constant mp_obj_type_t (called mp_type_type) for the 'type' object
// - creating a new class (a new type) creates a new mp_obj_type_t
STATIC void type_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
@@ -274,7 +274,7 @@ STATIC mp_obj_t type_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp
return mp_obj_new_type(mp_obj_str_get_qstr(args[0]), args[1], args[2]);
default:
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "type takes 1 or 3 arguments"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "type takes 1 or 3 arguments"));
}
}
@@ -284,7 +284,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj
mp_obj_type_t *self = self_in;
if (self->make_new == NULL) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "cannot create '%s' instances", qstr_str(self->name)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "cannot create '%s' instances", qstr_str(self->name)));
}
// make new instance
@@ -296,7 +296,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj
// for fail, do nothing; for attr, dest[0] = value; for method, dest[0] = method, dest[1] = self
STATIC void type_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
- assert(MP_OBJ_IS_TYPE(self_in, &mp_const_type));
+ assert(MP_OBJ_IS_TYPE(self_in, &mp_type_type));
mp_obj_type_t *self = self_in;
mp_obj_t member = mp_obj_class_lookup(self, attr);
if (member != MP_OBJ_NULL) {
@@ -318,7 +318,7 @@ STATIC void type_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
}
STATIC bool type_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
- assert(MP_OBJ_IS_TYPE(self_in, &mp_const_type));
+ assert(MP_OBJ_IS_TYPE(self_in, &mp_type_type));
mp_obj_type_t *self = self_in;
// TODO CPython allows STORE_ATTR to a class, but is this the correct implementation?
@@ -333,8 +333,8 @@ STATIC bool type_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
}
}
-const mp_obj_type_t mp_const_type = {
- { &mp_const_type },
+const mp_obj_type_t mp_type_type = {
+ { &mp_type_type },
.name = MP_QSTR_type,
.print = type_print,
.make_new = type_make_new,
@@ -347,7 +347,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
assert(MP_OBJ_IS_TYPE(bases_tuple, &tuple_type)); // Micro Python restriction, for now
assert(MP_OBJ_IS_TYPE(locals_dict, &dict_type)); // Micro Python restriction, for now
mp_obj_type_t *o = m_new0(mp_obj_type_t, 1);
- o->base.type = &mp_const_type;
+ o->base.type = &mp_type_type;
o->name = name;
o->print = class_print;
o->make_new = class_make_new;
@@ -383,7 +383,7 @@ STATIC mp_obj_t super_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const m
if (n_args != 2 || n_kw != 0) {
// 0 arguments are turned into 2 in the compiler
// 1 argument is not yet implemented
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "super() requires 2 arguments"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "super() requires 2 arguments"));
}
return mp_obj_new_super(args[0], args[1]);
}
@@ -393,7 +393,7 @@ STATIC void super_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
assert(MP_OBJ_IS_TYPE(self_in, &super_type));
mp_obj_super_t *self = self_in;
- assert(MP_OBJ_IS_TYPE(self->type, &mp_const_type));
+ assert(MP_OBJ_IS_TYPE(self->type, &mp_type_type));
mp_obj_type_t *type = self->type;
@@ -406,7 +406,7 @@ STATIC void super_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
mp_obj_t *items;
mp_obj_tuple_get(type->bases_tuple, &len, &items);
for (uint i = 0; i < len; i++) {
- assert(MP_OBJ_IS_TYPE(items[i], &mp_const_type));
+ assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type));
mp_obj_t member = mp_obj_class_lookup((mp_obj_type_t*)items[i], attr);
if (member != MP_OBJ_NULL) {
// XXX this and the code in class_load_attr need to be factored out
@@ -438,7 +438,7 @@ STATIC void super_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
}
const mp_obj_type_t super_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_super,
.print = super_print,
.make_new = super_make_new,
@@ -452,42 +452,42 @@ mp_obj_t mp_obj_new_super(mp_obj_t type, mp_obj_t obj) {
}
/******************************************************************************/
-// built-ins specific to types
+// subclassing and built-ins specific to types
-STATIC mp_obj_t mp_builtin_issubclass(mp_obj_t object, mp_obj_t classinfo) {
- if (!MP_OBJ_IS_TYPE(object, &mp_const_type)) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "issubclass() arg 1 must be a class"));
+bool mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) {
+ if (!MP_OBJ_IS_TYPE(object, &mp_type_type)) {
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "issubclass() arg 1 must be a class"));
}
// TODO support a tuple of classes for second argument
- if (!MP_OBJ_IS_TYPE(classinfo, &mp_const_type)) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "issubclass() arg 2 must be a class"));
+ if (!MP_OBJ_IS_TYPE(classinfo, &mp_type_type)) {
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "issubclass() arg 2 must be a class"));
}
for (;;) {
if (object == classinfo) {
- return mp_const_true;
+ return true;
}
// not equivalent classes, keep searching base classes
- assert(MP_OBJ_IS_TYPE(object, &mp_const_type));
+ assert(MP_OBJ_IS_TYPE(object, &mp_type_type));
mp_obj_type_t *self = object;
// for a const struct, this entry might be NULL
if (self->bases_tuple == MP_OBJ_NULL) {
- return mp_const_false;
+ return false;
}
uint len;
mp_obj_t *items;
mp_obj_tuple_get(self->bases_tuple, &len, &items);
if (len == 0) {
- return mp_const_false;
+ return false;
}
for (uint i = 0; i < len - 1; i++) {
- if (mp_builtin_issubclass(items[i], classinfo) == mp_const_true) {
- return mp_const_true;
+ if (mp_obj_is_subclass(items[i], classinfo)) {
+ return true;
}
}
@@ -496,10 +496,14 @@ STATIC mp_obj_t mp_builtin_issubclass(mp_obj_t object, mp_obj_t classinfo) {
}
}
+STATIC mp_obj_t mp_builtin_issubclass(mp_obj_t object, mp_obj_t classinfo) {
+ return MP_BOOL(mp_obj_is_subclass(object, classinfo));
+}
+
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_issubclass_obj, mp_builtin_issubclass);
STATIC mp_obj_t mp_builtin_isinstance(mp_obj_t object, mp_obj_t classinfo) {
- return mp_builtin_issubclass(mp_obj_get_type(object), classinfo);
+ return MP_BOOL(mp_obj_is_subclass(mp_obj_get_type(object), classinfo));
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_isinstance_obj, mp_builtin_isinstance);
@@ -511,7 +515,7 @@ STATIC mp_obj_t static_class_method_make_new(mp_obj_t self_in, uint n_args, uint
assert(self_in == &mp_type_staticmethod || self_in == &mp_type_classmethod);
if (n_args != 1 || n_kw != 0) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "function takes 1 positional argument but %d were given", n_args));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes 1 positional argument but %d were given", n_args));
}
mp_obj_static_class_method_t *o = m_new_obj(mp_obj_static_class_method_t);
@@ -520,13 +524,13 @@ STATIC mp_obj_t static_class_method_make_new(mp_obj_t self_in, uint n_args, uint
}
const mp_obj_type_t mp_type_staticmethod = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_staticmethod,
.make_new = static_class_method_make_new
};
const mp_obj_type_t mp_type_classmethod = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_classmethod,
.make_new = static_class_method_make_new
};
diff --git a/py/objzip.c b/py/objzip.c
index 8f1bfe143f..b939ff6cb9 100644
--- a/py/objzip.c
+++ b/py/objzip.c
@@ -51,7 +51,7 @@ STATIC mp_obj_t zip_iternext(mp_obj_t self_in) {
}
const mp_obj_type_t zip_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_zip,
.make_new = zip_make_new,
.getiter = zip_getiter,
diff --git a/py/parse.c b/py/parse.c
index d2e892b390..bbab19d352 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -302,7 +302,7 @@ STATIC void push_result_rule(parser_t *parser, int src_line, const rule_t *rule,
push_result_node(parser, (mp_parse_node_t)pn);
}
-mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, qstr *exc_id_out, const char **exc_msg_out) {
+mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_parse_error_kind_t *parse_error_kind_out) {
// allocate memory for the parser and its stacks
@@ -634,19 +634,18 @@ finished:
syntax_error:
if (mp_lexer_is_kind(lex, MP_TOKEN_INDENT)) {
- *exc_id_out = MP_QSTR_IndentationError;
- *exc_msg_out = "unexpected indent";
+ *parse_error_kind_out = MP_PARSE_ERROR_UNEXPECTED_INDENT;
} else if (mp_lexer_is_kind(lex, MP_TOKEN_DEDENT_MISMATCH)) {
- *exc_id_out = MP_QSTR_IndentationError;
- *exc_msg_out = "unindent does not match any outer indentation level";
+ *parse_error_kind_out = MP_PARSE_ERROR_UNMATCHED_UNINDENT;
} else {
- *exc_id_out = MP_QSTR_SyntaxError;
- *exc_msg_out = "invalid syntax";
+ *parse_error_kind_out = MP_PARSE_ERROR_INVALID_SYNTAX;
#ifdef USE_RULE_NAME
// debugging: print the rule name that failed and the token
- mp_lexer_show_error_pythonic(lex, rule->rule_name);
+ printf("rule: %s\n", rule->rule_name);
+#if MICROPY_DEBUG_PRINTERS
mp_token_show(mp_lexer_cur(lex));
#endif
+#endif
}
result = MP_PARSE_NODE_NULL;
goto finished;
diff --git a/py/parse.h b/py/parse.h
index 9797873d1b..66efd8a208 100644
--- a/py/parse.h
+++ b/py/parse.h
@@ -63,5 +63,11 @@ typedef enum {
MP_PARSE_EVAL_INPUT,
} mp_parse_input_kind_t;
-// returns MP_PARSE_NODE_NULL on error, and then exc_id_out and exc_msg_out are valid
-mp_parse_node_t mp_parse(struct _mp_lexer_t *lex, mp_parse_input_kind_t input_kind, qstr *exc_id_out, const char **exc_msg_out);
+typedef enum {
+ MP_PARSE_ERROR_UNEXPECTED_INDENT,
+ MP_PARSE_ERROR_UNMATCHED_UNINDENT,
+ MP_PARSE_ERROR_INVALID_SYNTAX,
+} mp_parse_error_kind_t;
+
+// returns MP_PARSE_NODE_NULL on error, and then parse_error_kind_out is valid
+mp_parse_node_t mp_parse(struct _mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_parse_error_kind_t *parse_error_kind_out);
diff --git a/py/parsehelper.c b/py/parsehelper.c
new file mode 100644
index 0000000000..3177e9a341
--- /dev/null
+++ b/py/parsehelper.c
@@ -0,0 +1,49 @@
+// these functions are separate from parse.c to keep parser independent of mp_obj_t
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "misc.h"
+#include "mpconfig.h"
+#include "qstr.h"
+#include "lexer.h"
+#include "parse.h"
+#include "obj.h"
+#include "parsehelper.h"
+
+#define STR_UNEXPECTED_INDENT "unexpected indent"
+#define STR_UNMATCHED_UNINDENT "unindent does not match any outer indentation level"
+#define STR_INVALID_SYNTAX "invalid syntax"
+
+void mp_parse_show_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_kind) {
+ printf(" File \"%s\", line %d, column %d\n", qstr_str(mp_lexer_source_name(lex)), mp_lexer_cur(lex)->src_line, mp_lexer_cur(lex)->src_column);
+ switch (parse_error_kind) {
+ case MP_PARSE_ERROR_UNEXPECTED_INDENT:
+ printf("IndentationError: %s\n", STR_UNEXPECTED_INDENT);
+ break;
+
+ case MP_PARSE_ERROR_UNMATCHED_UNINDENT:
+ printf("IndentationError: %s\n", STR_UNMATCHED_UNINDENT);
+ break;
+
+ case MP_PARSE_ERROR_INVALID_SYNTAX:
+ default:
+ printf("SyntaxError: %s\n", STR_INVALID_SYNTAX);
+ break;
+ }
+}
+
+mp_obj_t mp_parse_make_exception(mp_parse_error_kind_t parse_error_kind) {
+ // TODO add source file and line number to exception?
+ switch (parse_error_kind) {
+ case MP_PARSE_ERROR_UNEXPECTED_INDENT:
+ return mp_obj_new_exception_msg(&mp_type_IndentationError, STR_UNEXPECTED_INDENT);
+
+ case MP_PARSE_ERROR_UNMATCHED_UNINDENT:
+ return mp_obj_new_exception_msg(&mp_type_IndentationError, STR_UNMATCHED_UNINDENT);
+
+ case MP_PARSE_ERROR_INVALID_SYNTAX:
+ default:
+ return mp_obj_new_exception_msg(&mp_type_SyntaxError, STR_INVALID_SYNTAX);
+ }
+}
diff --git a/py/parsehelper.h b/py/parsehelper.h
new file mode 100644
index 0000000000..1de70d19d6
--- /dev/null
+++ b/py/parsehelper.h
@@ -0,0 +1,2 @@
+void mp_parse_show_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_kind);
+mp_obj_t mp_parse_make_exception(mp_parse_error_kind_t parse_error_kind);
diff --git a/py/py.mk b/py/py.mk
index 1d9eb535ae..cbb63b4bfc 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -19,6 +19,7 @@ PY_O_BASENAME = \
lexerstr.o \
lexerunix.o \
parse.o \
+ parsehelper.o \
scope.o \
compile.o \
emitcommon.o \
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index ac106f9830..9f002777bb 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -30,6 +30,7 @@ Q(asm_thumb)
Q(Ellipsis)
Q(StopIteration)
+Q(BaseException)
Q(AssertionError)
Q(AttributeError)
Q(ImportError)
diff --git a/py/runtime.c b/py/runtime.c
index b473a951f3..68b8fe0778 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -108,7 +108,7 @@ STATIC const mp_builtin_elem_t builtin_table[] = {
{ MP_QSTR_set, (mp_obj_t)&set_type },
{ MP_QSTR_super, (mp_obj_t)&super_type },
{ MP_QSTR_tuple, (mp_obj_t)&tuple_type },
- { MP_QSTR_type, (mp_obj_t)&mp_const_type },
+ { MP_QSTR_type, (mp_obj_t)&mp_type_type },
{ MP_QSTR_zip, (mp_obj_t)&zip_type },
{ MP_QSTR_classmethod, (mp_obj_t)&mp_type_classmethod },
@@ -144,6 +144,25 @@ STATIC const mp_builtin_elem_t builtin_table[] = {
{ MP_QSTR_str, (mp_obj_t)&mp_builtin_str_obj },
{ MP_QSTR_bytearray, (mp_obj_t)&mp_builtin_bytearray_obj },
+ // built-in exceptions
+ { MP_QSTR_BaseException, (mp_obj_t)&mp_type_BaseException },
+ { MP_QSTR_AssertionError, (mp_obj_t)&mp_type_AssertionError },
+ { MP_QSTR_AttributeError, (mp_obj_t)&mp_type_AttributeError },
+ { MP_QSTR_ImportError, (mp_obj_t)&mp_type_ImportError },
+ { MP_QSTR_IndentationError, (mp_obj_t)&mp_type_IndentationError },
+ { MP_QSTR_IndexError, (mp_obj_t)&mp_type_IndexError },
+ { MP_QSTR_KeyError, (mp_obj_t)&mp_type_KeyError },
+ { MP_QSTR_NameError, (mp_obj_t)&mp_type_NameError },
+ { MP_QSTR_SyntaxError, (mp_obj_t)&mp_type_SyntaxError },
+ { MP_QSTR_TypeError, (mp_obj_t)&mp_type_TypeError },
+ { MP_QSTR_ValueError, (mp_obj_t)&mp_type_ValueError },
+ // Somehow CPython managed to have OverflowError not inherit from ValueError ;-/
+ // TODO: For MICROPY_CPYTHON_COMPAT==0 use ValueError to avoid exc proliferation
+ { MP_QSTR_OverflowError, (mp_obj_t)&mp_type_OverflowError },
+ { MP_QSTR_OSError, (mp_obj_t)&mp_type_OSError },
+ { MP_QSTR_NotImplementedError, (mp_obj_t)&mp_type_NotImplementedError },
+ { MP_QSTR_StopIteration, (mp_obj_t)&mp_type_StopIteration },
+
// Extra builtins as defined by a port
MICROPY_EXTRA_BUILTINS
@@ -166,23 +185,6 @@ void rt_init(void) {
// init loaded modules table
mp_map_init(&map_loaded_modules, 3);
- // built-in exceptions (TODO, make these proper classes, and const if possible)
- mp_map_add_qstr(&map_builtins, MP_QSTR_AttributeError, mp_obj_new_exception(MP_QSTR_AttributeError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_ImportError, mp_obj_new_exception(MP_QSTR_ImportError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_IndexError, mp_obj_new_exception(MP_QSTR_IndexError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_KeyError, mp_obj_new_exception(MP_QSTR_KeyError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_NameError, mp_obj_new_exception(MP_QSTR_NameError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_TypeError, mp_obj_new_exception(MP_QSTR_TypeError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_SyntaxError, mp_obj_new_exception(MP_QSTR_SyntaxError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_ValueError, mp_obj_new_exception(MP_QSTR_ValueError));
- // Somehow CPython managed to have OverflowError not inherit from ValueError ;-/
- // TODO: For MICROPY_CPYTHON_COMPAT==0 use ValueError to avoid exc proliferation
- mp_map_add_qstr(&map_builtins, MP_QSTR_OverflowError, mp_obj_new_exception(MP_QSTR_OverflowError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_OSError, mp_obj_new_exception(MP_QSTR_OSError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_AssertionError, mp_obj_new_exception(MP_QSTR_AssertionError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_NotImplementedError, mp_obj_new_exception(MP_QSTR_NotImplementedError));
- mp_map_add_qstr(&map_builtins, MP_QSTR_StopIteration, mp_obj_new_exception(MP_QSTR_StopIteration));
-
// built-in objects
mp_map_add_qstr(&map_builtins, MP_QSTR_Ellipsis, mp_const_ellipsis);
@@ -413,7 +415,7 @@ mp_obj_t rt_load_const_dec(qstr qstr) {
}
}
if (*s != 0) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_SyntaxError, "invalid syntax for number"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_SyntaxError, "invalid syntax for number"));
}
if (exp_neg) {
exp_val = -exp_val;
@@ -431,7 +433,7 @@ mp_obj_t rt_load_const_dec(qstr qstr) {
return mp_obj_new_float(dec_val);
}
#else
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_SyntaxError, "decimal numbers not supported"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_SyntaxError, "decimal numbers not supported"));
#endif
}
@@ -470,7 +472,7 @@ mp_obj_t rt_load_global(qstr qstr) {
return e->fun;
}
}
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_NameError, "name '%s' is not defined", qstr_str(qstr)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_NameError, "name '%s' is not defined", qstr_str(qstr)));
}
}
return elem->value;
@@ -529,7 +531,7 @@ mp_obj_t rt_unary_op(int op, mp_obj_t arg) {
}
}
// TODO specify in error message what the operator is
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "bad operand type for unary operator: '%s'", type->name));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "bad operand type for unary operator: '%s'", type->name));
}
}
@@ -569,9 +571,13 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
// deal with exception_match for all types
if (op == RT_BINARY_OP_EXCEPTION_MATCH) {
- // TODO properly! at the moment it just compares the exception identifier for equality
- if (MP_OBJ_IS_TYPE(lhs, &exception_type) && MP_OBJ_IS_TYPE(rhs, &exception_type)) {
- if (mp_obj_exception_get_type(lhs) == mp_obj_exception_get_type(rhs)) {
+ // rhs must be issubclass(rhs, BaseException)
+ if (mp_obj_is_exception_type(rhs)) {
+ // if lhs is an instance of an exception, then extract and use its type
+ if (mp_obj_is_exception_instance(lhs)) {
+ lhs = mp_obj_get_type(lhs);
+ }
+ if (mp_obj_is_subclass(lhs, rhs)) {
return mp_const_true;
} else {
return mp_const_false;
@@ -673,7 +679,7 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
}
nlr_jump(mp_obj_new_exception_msg_varg(
- MP_QSTR_TypeError, "'%s' object is not iterable",
+ &mp_type_TypeError, "'%s' object is not iterable",
mp_obj_get_type_str(rhs)));
return mp_const_none;
}
@@ -690,7 +696,7 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
// TODO implement dispatch for reverse binary ops
// TODO specify in error message what the operator is
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"unsupported operand types for binary operator: '%s', '%s'",
mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs)));
return mp_const_none;
@@ -772,7 +778,7 @@ mp_obj_t rt_call_function_n_kw(mp_obj_t fun_in, uint n_args, uint n_kw, const mp
if (type->call != NULL) {
return type->call(fun_in, n_args, n_kw, args);
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "'%s' object is not callable", type->name));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", type->name));
}
}
@@ -836,9 +842,9 @@ void rt_unpack_sequence(mp_obj_t seq_in, uint num, mp_obj_t *items) {
return;
too_short:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "need more than %d values to unpack", seq_len));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", seq_len));
too_long:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "too many values to unpack (expected %d)", num));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "too many values to unpack (expected %d)", num));
}
mp_obj_t rt_build_map(int n_args) {
@@ -925,10 +931,10 @@ void rt_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
if (dest[0] == MP_OBJ_NULL) {
// no attribute/method called attr
// following CPython, we give a more detailed error message for type objects
- if (MP_OBJ_IS_TYPE(base, &mp_const_type)) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_AttributeError, "type object '%s' has no attribute '%s'", ((mp_obj_type_t*)base)->name, qstr_str(attr)));
+ if (MP_OBJ_IS_TYPE(base, &mp_type_type)) {
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, "type object '%s' has no attribute '%s'", ((mp_obj_type_t*)base)->name, qstr_str(attr)));
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
}
}
}
@@ -941,7 +947,7 @@ void rt_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
return;
}
}
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
}
void rt_store_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) {
@@ -961,7 +967,7 @@ void rt_store_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) {
}
// TODO: call base classes here?
}
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "'%s' object does not support item assignment", mp_obj_get_type_str(base)));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object does not support item assignment", mp_obj_get_type_str(base)));
}
}
@@ -978,7 +984,7 @@ mp_obj_t rt_getiter(mp_obj_t o_in) {
return mp_obj_new_getitem_iter(dest);
} else {
// object not iterable
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "'%s' object is not iterable", type->name));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not iterable", type->name));
}
}
}
@@ -988,7 +994,22 @@ mp_obj_t rt_iternext(mp_obj_t o_in) {
if (type->iternext != NULL) {
return type->iternext(o_in);
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "'%s' object is not an iterator", type->name));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not an iterator", type->name));
+ }
+}
+
+mp_obj_t rt_make_raise_obj(mp_obj_t o) {
+ DEBUG_printf("raise %p\n", o);
+ if (mp_obj_is_exception_type(o)) {
+ // o is an exception type (it is derived from BaseException (or is BaseException))
+ // create and return a new exception instance by calling o
+ return rt_call_function_n_kw(o, 0, 0, NULL);
+ } else if (mp_obj_is_exception_instance(o)) {
+ // o is an instance of an exception, so use it as the exception
+ return o;
+ } else {
+ // o cannot be used as an exception, so return a type error (which will be raised by the caller)
+ return mp_obj_new_exception_msg(&mp_type_TypeError, "exceptions must derive from BaseException");
}
}
diff --git a/py/runtime.h b/py/runtime.h
index f5a9f2abc7..1eef99d2ff 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -37,6 +37,7 @@ void rt_store_attr(mp_obj_t base, qstr attr, mp_obj_t val);
void rt_store_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val);
mp_obj_t rt_getiter(mp_obj_t o);
mp_obj_t rt_iternext(mp_obj_t o);
+mp_obj_t rt_make_raise_obj(mp_obj_t o);
mp_obj_t rt_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level);
mp_obj_t rt_import_from(mp_obj_t module, qstr name);
void rt_import_all(mp_obj_t module);
diff --git a/py/sequence.c b/py/sequence.c
index f5310737a7..d3c3e32854 100644
--- a/py/sequence.c
+++ b/py/sequence.c
@@ -162,7 +162,7 @@ mp_obj_t mp_seq_index_obj(const mp_obj_t *items, uint len, uint n_args, const mp
}
}
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "object not in sequence"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "object not in sequence"));
}
mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value) {
diff --git a/py/stream.c b/py/stream.c
index f3487cc6ed..59877d7242 100644
--- a/py/stream.c
+++ b/py/stream.c
@@ -16,7 +16,7 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)args[0];
if (o->type->stream_p.read == NULL) {
// CPython: io.UnsupportedOperation, OSError subclass
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Operation not supported"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, "Operation not supported"));
}
machine_int_t sz;
@@ -27,7 +27,7 @@ STATIC mp_obj_t stream_read(uint n_args, const mp_obj_t *args) {
int error;
machine_int_t out_sz = o->type->stream_p.read(o, buf, sz, &error);
if (out_sz == -1) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
} else {
mp_obj_t s = mp_obj_new_str(buf, out_sz, false); // will reallocate to use exact size
m_free(buf, sz);
@@ -39,7 +39,7 @@ STATIC mp_obj_t stream_write(mp_obj_t self_in, mp_obj_t arg) {
struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)self_in;
if (o->type->stream_p.write == NULL) {
// CPython: io.UnsupportedOperation, OSError subclass
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Operation not supported"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, "Operation not supported"));
}
uint sz;
@@ -47,7 +47,7 @@ STATIC mp_obj_t stream_write(mp_obj_t self_in, mp_obj_t arg) {
int error;
machine_int_t out_sz = o->type->stream_p.write(self_in, buf, sz, &error);
if (out_sz == -1) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
} else {
// http://docs.python.org/3/library/io.html#io.RawIOBase.write
// "None is returned if the raw stream is set not to block and no single byte could be readily written to it."
@@ -62,7 +62,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)self_in;
if (o->type->stream_p.read == NULL) {
// CPython: io.UnsupportedOperation, OSError subclass
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Operation not supported"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, "Operation not supported"));
}
int total_size = 0;
@@ -74,7 +74,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
while (true) {
machine_int_t out_sz = o->type->stream_p.read(self_in, p, current_read, &error);
if (out_sz == -1) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
}
if (out_sz == 0) {
break;
@@ -88,7 +88,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in) {
p = vstr_extend(vstr, current_read);
if (p == NULL) {
// TODO
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError/*MP_QSTR_RuntimeError*/, "Out of memory"));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError/*&mp_type_RuntimeError*/, "Out of memory"));
}
}
}
@@ -103,7 +103,7 @@ STATIC mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)args[0];
if (o->type->stream_p.read == NULL) {
// CPython: io.UnsupportedOperation, OSError subclass
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Operation not supported"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, "Operation not supported"));
}
machine_int_t max_size = -1;
@@ -123,12 +123,12 @@ STATIC mp_obj_t stream_unbuffered_readline(uint n_args, const mp_obj_t *args) {
char *p = vstr_add_len(vstr, 1);
if (p == NULL) {
// TODO
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError/*MP_QSTR_RuntimeError*/, "Out of memory"));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError/*&mp_type_RuntimeError*/, "Out of memory"));
}
machine_int_t out_sz = o->type->stream_p.read(o, p, 1, &error);
if (out_sz == -1) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error));
}
if (out_sz == 0) {
// Back out previously added byte
diff --git a/py/strtonum.c b/py/strtonum.c
index 74fa3d6759..e83b9751dc 100644
--- a/py/strtonum.c
+++ b/py/strtonum.c
@@ -18,7 +18,7 @@ long strtonum(const char *restrict s, int base) {
// check radix base
if ((base != 0 && base < 2) || base > 36) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "ValueError: int() arg 2 must be >=2 and <= 36"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "ValueError: int() arg 2 must be >=2 and <= 36"));
}
// skip surrounded whitespace
while (isspace((c = *(p++))));
@@ -84,7 +84,7 @@ done:
return (found ^ neg) - neg;
value_error:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "invalid literal for int() with base %d: '%s'", base, s));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid literal for int() with base %d: '%s'", base, s));
}
#else /* defined(UNIX) */
diff --git a/py/vm.c b/py/vm.c
index 1fc5b4a57a..461fecbda8 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -371,7 +371,7 @@ unwind_jump:
// if TOS is None, just pops it and continues
// if TOS is an integer, does something else
// else error
- if (MP_OBJ_IS_TYPE(TOP(), &exception_type)) {
+ if (mp_obj_is_exception_instance(TOP())) {
nlr_jump(TOP());
}
if (TOP() == mp_const_none) {
@@ -575,7 +575,7 @@ unwind_return:
unum = *ip++;
assert(unum == 1);
obj1 = POP();
- nlr_jump(obj1);
+ nlr_jump(rt_make_raise_obj(obj1));
case MP_BC_YIELD_VALUE:
nlr_pop();
@@ -613,7 +613,7 @@ unwind_return:
// set file and line number that the exception occurred at
// TODO: don't set traceback for exceptions re-raised by END_FINALLY.
// But consider how to handle nested exceptions.
- if (MP_OBJ_IS_TYPE(nlr.ret_val, &exception_type)) {
+ if (mp_obj_is_exception_instance(nlr.ret_val)) {
machine_uint_t code_info_size = code_info[0] | (code_info[1] << 8) | (code_info[2] << 16) | (code_info[3] << 24);
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);
diff --git a/stm/adc.c b/stm/adc.c
index 89f137a08c..cd915b1724 100644
--- a/stm/adc.c
+++ b/stm/adc.c
@@ -332,7 +332,7 @@ static const mp_method_t adc_all_methods[] = {
};
static const mp_obj_type_t adc_all_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_ADC,
.print = adc_all_print,
.methods = adc_all_methods,
@@ -386,7 +386,7 @@ static const mp_method_t adc_methods[] = {
};
static const mp_obj_type_t adc_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_ADC,
.print = adc_print,
.methods = adc_methods,
@@ -427,7 +427,7 @@ mp_obj_t pyb_ADC(mp_obj_t pin_name_obj) {
}
if (i == ADC_NUM_CHANNELS) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %s does not have ADC capabilities", pin_name));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %s does not have ADC capabilities", pin_name));
}
// init ADC just for this channel
@@ -438,7 +438,7 @@ mp_obj_t pyb_ADC(mp_obj_t pin_name_obj) {
return o;
pin_error:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %s does not exist", pin_name));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %s does not exist", pin_name));
}
MP_DEFINE_CONST_FUN_OBJ_1(pyb_ADC_obj, pyb_ADC);
diff --git a/stm/file.c b/stm/file.c
index f50d3771a0..283159a69b 100644
--- a/stm/file.c
+++ b/stm/file.c
@@ -60,7 +60,7 @@ static const mp_method_t file_methods[] = {
};
static const mp_obj_type_t file_obj_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_File,
.print = file_obj_print,
.methods = file_methods,
diff --git a/stm/i2c.c b/stm/i2c.c
index f355878f2b..33d9a43f3a 100644
--- a/stm/i2c.c
+++ b/stm/i2c.c
@@ -335,7 +335,7 @@ static const mp_method_t i2c_methods[] = {
};
static const mp_obj_type_t i2c_obj_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_I2C,
.print = i2c_obj_print,
.methods = i2c_methods,
diff --git a/stm/led.c b/stm/led.c
index 3a7d8a7a7f..683e82bc66 100644
--- a/stm/led.c
+++ b/stm/led.c
@@ -148,7 +148,7 @@ static const mp_method_t led_methods[] = {
};
static const mp_obj_type_t led_obj_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_Led,
.print = led_obj_print,
.methods = led_methods,
diff --git a/stm/main.c b/stm/main.c
index 3484fd28d0..2bf7c1ba36 100644
--- a/stm/main.c
+++ b/stm/main.c
@@ -24,6 +24,7 @@
#include "lexerfatfs.h"
#include "parse.h"
#include "obj.h"
+#include "parsehelper.h"
#include "compile.h"
#include "runtime0.h"
#include "runtime.h"
@@ -404,15 +405,13 @@ void do_repl(void) {
}
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
- qstr parse_exc_id;
- const char *parse_exc_msg;
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_exc_id, &parse_exc_msg);
+ mp_parse_error_kind_t parse_error_kind;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_error_kind);
qstr source_name = mp_lexer_source_name(lex);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
- mp_lexer_show_error_pythonic_prefix(lex);
- printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_parse_show_exception(lex, parse_error_kind);
mp_lexer_free(lex);
} else {
// parse okay
@@ -456,15 +455,13 @@ bool do_file(const char *filename) {
return false;
}
- qstr parse_exc_id;
- const char *parse_exc_msg;
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_exc_id, &parse_exc_msg);
+ mp_parse_error_kind_t parse_error_kind;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind);
qstr source_name = mp_lexer_source_name(lex);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
- mp_lexer_show_error_pythonic_prefix(lex);
- printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_parse_show_exception(lex, parse_error_kind);
mp_lexer_free(lex);
return false;
}
@@ -536,7 +533,7 @@ mp_obj_t pyb_gpio(uint n_args, mp_obj_t *args) {
}
pin_error:
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %s does not exist", pin_name));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %s does not exist", pin_name));
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);
diff --git a/stm/sdcard.c b/stm/sdcard.c
index c98bab4d91..0b5fdb2c87 100644
--- a/stm/sdcard.c
+++ b/stm/sdcard.c
@@ -202,7 +202,7 @@ static const mp_method_t sdcard_methods[] = {
};
static const mp_obj_type_t sdcard_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_SDcard,
.methods = sdcard_methods,
};
diff --git a/stm/servo.c b/stm/servo.c
index 4b69eefcfb..4943a64425 100644
--- a/stm/servo.c
+++ b/stm/servo.c
@@ -144,7 +144,7 @@ static const mp_method_t servo_methods[] = {
};
static const mp_obj_type_t servo_obj_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_Servo,
.print = servo_obj_print,
.methods = servo_methods,
diff --git a/stm/usart.c b/stm/usart.c
index e24211a83c..6478f01152 100644
--- a/stm/usart.c
+++ b/stm/usart.c
@@ -242,7 +242,7 @@ static const mp_method_t usart_methods[] = {
};
static const mp_obj_type_t usart_obj_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_Usart,
.print = usart_obj_print,
.methods = usart_methods,
diff --git a/stm/usb.c b/stm/usb.c
index 0fe56d3212..718d432e61 100644
--- a/stm/usb.c
+++ b/stm/usb.c
@@ -41,7 +41,7 @@ void pyb_usb_dev_init(void) {
dev_is_enabled = 1;
// create an exception object for interrupting by VCP
- mp_const_vcp_interrupt = mp_obj_new_exception(qstr_from_str("VCPInterrupt"));
+ mp_const_vcp_interrupt = mp_obj_new_exception_msg(&mp_type_OSError, "VCPInterrupt");
#endif
}
@@ -66,6 +66,7 @@ void usb_vcp_receive(const char *buf, uint32_t len) {
// catch special interrupt character
if (buf[i] == interrupt_char) {
// raise exception when interrupts are finished
+ mp_obj_exception_clear_traceback(mp_const_vcp_interrupt);
pendsv_nlr_jump(mp_const_vcp_interrupt);
interrupt_char = VCP_CHAR_NONE;
continue;
diff --git a/teensy/led.c b/teensy/led.c
index 49ba46b4d2..e2a0574168 100644
--- a/teensy/led.c
+++ b/teensy/led.c
@@ -70,7 +70,7 @@ static const mp_method_t led_methods[] = {
};
static const mp_obj_type_t led_obj_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_Led,
.print = led_obj_print,
.methods = led_methods,
diff --git a/teensy/main.c b/teensy/main.c
index 70067927fe..ab7bd46812 100644
--- a/teensy/main.c
+++ b/teensy/main.c
@@ -346,15 +346,13 @@ bool do_file(const char *filename) {
return false;
}
- qstr parse_exc_id;
- const char *parse_exc_msg;
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_exc_id, &parse_exc_msg);
+ mp_parse_error_kind_t parse_error_kind;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind);
qstr source_name = mp_lexer_source_name(lex);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
- mp_lexer_show_error_pythonic_prefix(lex);
- printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_parse_show_exception(lex, parse_error_kind);
mp_lexer_free(lex);
return false;
}
@@ -413,15 +411,13 @@ void do_repl(void) {
}
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
- qstr parse_exc_id;
- const char *parse_exc_msg;
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_exc_id, &parse_exc_msg);
+ mp_parse_error_kind_t parse_error_kind;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_error_kind);
qstr source_name = mp_lexer_source_name(lex);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
- mp_lexer_show_error_pythonic_prefix(lex);
- printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_parse_show_exception(lex, parse_error_kind);
mp_lexer_free(lex);
} else {
// parse okay
diff --git a/teensy/servo.c b/teensy/servo.c
index c3a2b28889..51714dbcc5 100644
--- a/teensy/servo.c
+++ b/teensy/servo.c
@@ -189,7 +189,7 @@ static const mp_method_t servo_methods[] = {
*/
static const mp_obj_type_t servo_obj_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_Servo,
.print = servo_obj_print,
.methods = servo_methods,
@@ -217,7 +217,7 @@ mp_obj_t pyb_Servo(void) {
self->servo_id++;
}
m_del_obj(pyb_servo_obj_t, self);
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "No available servo ids"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_ValueError, "No available servo ids"));
return mp_const_none;
}
diff --git a/unix-cpy/main.c b/unix-cpy/main.c
index 10003c9929..52d63273ce 100644
--- a/unix-cpy/main.c
+++ b/unix-cpy/main.c
@@ -10,6 +10,7 @@
#include "lexerunix.h"
#include "parse.h"
#include "obj.h"
+#include "parsehelper.h"
#include "compile.h"
#include "runtime0.h"
@@ -29,14 +30,12 @@ void do_file(const char *file) {
} else {
// parse
- qstr parse_exc_id;
- const char *parse_exc_msg;
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_exc_id, &parse_exc_msg);
+ mp_parse_error_kind_t parse_error_kind;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
- mp_lexer_show_error_pythonic_prefix(lex);
- printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_parse_show_exception(lex, parse_error_kind);
mp_lexer_free(lex);
return;
}
diff --git a/unix/ffi.c b/unix/ffi.c
index a82e4e3386..ef9c6ea9d2 100644
--- a/unix/ffi.c
+++ b/unix/ffi.c
@@ -46,7 +46,7 @@ typedef struct _mp_obj_fficallback_t {
ffi_type *params[];
} mp_obj_fficallback_t;
-static const mp_obj_type_t opaque_type;
+//static const mp_obj_type_t opaque_type;
static const mp_obj_type_t ffimod_type;
static const mp_obj_type_t ffifunc_type;
static const mp_obj_type_t fficallback_type;
@@ -80,7 +80,7 @@ static ffi_type *get_ffi_type(mp_obj_t o_in)
}
// TODO: Support actual libffi type objects
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "Unknown type"));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Unknown type"));
}
static mp_obj_t return_ffi_value(ffi_arg val, char type)
@@ -118,7 +118,7 @@ static mp_obj_t ffimod_func(uint n_args, const mp_obj_t *args) {
void *sym = dlsym(self->handle, symname);
if (sym == NULL) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", errno));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno));
}
int nparams = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(args[3]));
mp_obj_ffifunc_t *o = m_new_obj_var(mp_obj_ffifunc_t, ffi_type*, nparams);
@@ -136,7 +136,7 @@ static mp_obj_t ffimod_func(uint n_args, const mp_obj_t *args) {
int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params);
if (res != FFI_OK) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "Error in ffi_prep_cif"));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error in ffi_prep_cif"));
}
return o;
@@ -173,12 +173,12 @@ static mp_obj_t mod_ffi_callback(mp_obj_t rettype_in, mp_obj_t func_in, mp_obj_t
int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params);
if (res != FFI_OK) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "Error in ffi_prep_cif"));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error in ffi_prep_cif"));
}
res = ffi_prep_closure_loc(o->clo, &o->cif, call_py_func, func_in, o->func);
if (res != FFI_OK) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "ffi_prep_closure_loc"));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "ffi_prep_closure_loc"));
}
return o;
@@ -192,7 +192,7 @@ static mp_obj_t ffimod_var(mp_obj_t self_in, mp_obj_t vartype_in, mp_obj_t symna
void *sym = dlsym(self->handle, symname);
if (sym == NULL) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", errno));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno));
}
mp_obj_ffivar_t *o = m_new_obj(mp_obj_ffivar_t);
o->base.type = &ffivar_type;
@@ -208,7 +208,7 @@ static mp_obj_t ffimod_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
void *mod = dlopen(fname, RTLD_NOW | RTLD_LOCAL);
if (mod == NULL) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", errno));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno));
}
mp_obj_ffimod_t *o = m_new_obj(mp_obj_ffimod_t);
o->base.type = type_in;
@@ -224,8 +224,8 @@ static const mp_method_t ffimod_type_methods[] = {
};
static const mp_obj_type_t ffimod_type = {
- { &mp_const_type },
- "ffimod",
+ { &mp_type_type },
+ .name = MP_QSTR_ffimod,
.print = ffimod_print,
.make_new = ffimod_make_new,
.methods = ffimod_type_methods,
@@ -270,8 +270,8 @@ mp_obj_t ffifunc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *
}
static const mp_obj_type_t ffifunc_type = {
- { &mp_const_type },
- "ffifunc",
+ { &mp_type_type },
+ .name = MP_QSTR_ffifunc,
.print = ffifunc_print,
.call = ffifunc_call,
};
@@ -284,8 +284,8 @@ static void fficallback_print(void (*print)(void *env, const char *fmt, ...), vo
}
static const mp_obj_type_t fficallback_type = {
- { &mp_const_type },
- "fficallback",
+ { &mp_type_type },
+ .name = MP_QSTR_fficallback,
.print = fficallback_print,
};
@@ -316,20 +316,21 @@ static const mp_method_t ffivar_type_methods[] = {
};
static const mp_obj_type_t ffivar_type = {
- { &mp_const_type },
- "ffivar",
+ { &mp_type_type },
+ .name = MP_QSTR_ffivar,
.print = ffivar_print,
.methods = ffivar_type_methods,
};
-// Generic opaque storage object
+// Generic opaque storage object (unused)
+/*
static const mp_obj_type_t opaque_type = {
- { &mp_const_type },
- "opaqueval",
+ { &mp_type_type },
+ .name = MP_QSTR_opaqueval,
// .print = opaque_print,
};
-
+*/
mp_obj_t mod_ffi_open(uint n_args, const mp_obj_t *args) {
return ffimod_make_new((mp_obj_t)&ffimod_type, n_args, 0, args);
diff --git a/unix/file.c b/unix/file.c
index 4e8fba54c8..444a05d491 100644
--- a/unix/file.c
+++ b/unix/file.c
@@ -99,7 +99,7 @@ static mp_obj_t fdfile_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
int fd = open(fname, mode, 0644);
if (fd == -1) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", errno));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno));
}
return fdfile_new(fd);
}
@@ -115,7 +115,7 @@ static const mp_method_t rawfile_type_methods[] = {
};
static const mp_obj_type_t rawfile_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_io_dot_FileIO,
.print = fdfile_print,
.make_new = fdfile_make_new,
diff --git a/unix/main.c b/unix/main.c
index 6aafe94ddd..8e6a76bbad 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -11,6 +11,7 @@
#include "lexerunix.h"
#include "parse.h"
#include "obj.h"
+#include "parsehelper.h"
#include "compile.h"
#include "runtime0.h"
#include "runtime.h"
@@ -49,14 +50,12 @@ static void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind
return;
}
- qstr parse_exc_id;
- const char *parse_exc_msg;
- mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_exc_id, &parse_exc_msg);
+ mp_parse_error_kind_t parse_error_kind;
+ mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_error_kind);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
- mp_lexer_show_error_pythonic_prefix(lex);
- printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_parse_show_exception(lex, parse_error_kind);
mp_lexer_free(lex);
return;
}
@@ -194,7 +193,7 @@ static const mp_method_t test_methods[] = {
};
static const mp_obj_type_t test_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_Test,
.print = test_print,
.methods = test_methods,
diff --git a/unix/qstrdefsport.h b/unix/qstrdefsport.h
index 42c88b4693..867afaeac0 100644
--- a/unix/qstrdefsport.h
+++ b/unix/qstrdefsport.h
@@ -17,3 +17,7 @@ Q(getaddrinfo)
Q(microsocket)
Q(io.FileIO)
+Q(ffimod)
+Q(ffifunc)
+Q(fficallback)
+Q(ffivar)
diff --git a/unix/socket.c b/unix/socket.c
index 25c4bfcb46..a9cf4a81a0 100644
--- a/unix/socket.c
+++ b/unix/socket.c
@@ -29,7 +29,7 @@ static const mp_obj_type_t microsocket_type;
// Helper functions
#define RAISE_ERRNO(err_flag, error_val) \
{ if (err_flag == -1) \
- { nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error_val)); } }
+ { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", error_val)); } }
static void get_buffer(mp_obj_t obj, buffer_info_t *bufinfo) {
mp_obj_base_t *o = (mp_obj_base_t *)obj;
@@ -43,7 +43,7 @@ static void get_buffer(mp_obj_t obj, buffer_info_t *bufinfo) {
return;
error:
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "Operation not supported"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_TypeError, "Operation not supported"));
}
static mp_obj_socket_t *socket_new(int fd) {
@@ -237,7 +237,7 @@ static const mp_method_t microsocket_type_methods[] = {
};
static const mp_obj_type_t microsocket_type = {
- { &mp_const_type },
+ { &mp_type_type },
.name = MP_QSTR_socket,
.print = socket_print,
.make_new = socket_make_new,
@@ -260,7 +260,7 @@ static mp_obj_t mod_socket_inet_aton(mp_obj_t arg) {
const char *s = mp_obj_str_get_str(arg);
struct in_addr addr;
if (!inet_aton(s, &addr)) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Invalid IP address"));
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, "Invalid IP address"));
}
return mp_obj_new_int(addr.s_addr);
@@ -273,7 +273,7 @@ static mp_obj_t mod_socket_gethostbyname(mp_obj_t arg) {
const char *s = mp_obj_str_get_str(arg);
struct hostent *h = gethostbyname(s);
if (h == NULL) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", errno));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno));
}
assert(h->h_length == 4);
return mp_obj_new_int(*(int*)*h->h_addr_list);
@@ -305,7 +305,7 @@ static mp_obj_t mod_socket_getaddrinfo(uint n_args, const mp_obj_t *args) {
int res = getaddrinfo(host, serv, NULL/*&hints*/, &addr);
if (res != 0) {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[addrinfo error %d]", res));
+ nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[addrinfo error %d]", res));
}
assert(addr);
diff --git a/windows/main.c b/windows/main.c
index da0cbca44a..4456a796d0 100644
--- a/windows/main.c
+++ b/windows/main.c
@@ -11,6 +11,7 @@
#include "lexerunix.h"
#include "parse.h"
#include "obj.h"
+#include "parsehelper.h"
#include "compile.h"
#include "runtime0.h"
#include "runtime.h"
@@ -39,14 +40,12 @@ static void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind
return;
}
- qstr parse_exc_id;
- const char *parse_exc_msg;
- mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_exc_id, &parse_exc_msg);
+ mp_parse_error_kind_t parse_error_kind;
+ mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_error_kind);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
- mp_lexer_show_error_pythonic_prefix(lex);
- printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_parse_show_exception(lex, parse_error_kind);
mp_lexer_free(lex);
return;
}