diff --git a/py/lexer.c b/py/lexer.c index f736ef303..e2dfea78c 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -64,6 +64,13 @@ struct _mp_lexer_t { mp_token_t tok_cur; }; +// debug flag for __debug__ constant +STATIC mp_token_kind_t mp_debug_value; + +void mp_set_debug(bool value) { + mp_debug_value = value ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE; +} + // TODO replace with a call to a standard function bool str_strn_equal(const char *str, const char *strn, int len) { uint i = 0; @@ -303,7 +310,7 @@ STATIC const char *tok_kw[] = { "while", "with", "yield", - NULL, + "__debug__", }; STATIC int hex_digit(unichar c) { @@ -687,9 +694,18 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs // check for keywords if (tok->kind == MP_TOKEN_NAME) { - for (int i = 0; tok_kw[i] != NULL; i++) { + // We check for __debug__ here and convert it to its value. This is so + // the parser gives a syntax error on, eg, x.__debug__. Otherwise, we + // need to check for this special token in many places in the compiler. + // TODO improve speed of these string comparisons + //for (int i = 0; tok_kw[i] != NULL; i++) { + for (int i = 0; i < ARRAY_SIZE(tok_kw); i++) { if (str_strn_equal(tok_kw[i], tok->str, tok->len)) { - tok->kind = MP_TOKEN_KW_FALSE + i; + if (i == ARRAY_SIZE(tok_kw) - 1) { + tok->kind = mp_debug_value; + } else { + tok->kind = MP_TOKEN_KW_FALSE + i; + } break; } } diff --git a/py/runtime.c b/py/runtime.c index 8852b7d80..3cdbd2230 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -69,11 +69,14 @@ const mp_obj_module_t mp_module___main__ = { }; void mp_init(void) { - // call port specific initialization if any + // call port specific initialization if any #ifdef MICROPY_PORT_INIT_FUNC MICROPY_PORT_INIT_FUNC; #endif + // __debug__ enabled by default + mp_set_debug(true); + mp_emit_glue_init(); // init global module stuff diff --git a/py/runtime.h b/py/runtime.h index 910a48544..a5d674303 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -54,6 +54,8 @@ typedef struct _mp_arg_t { void mp_init(void); void mp_deinit(void); +void mp_set_debug(bool value); // sets the value of __debug__; see lexer.c + void mp_arg_check_num(uint n_args, uint n_kw, uint n_args_min, uint n_args_max, bool takes_kw); void mp_arg_parse_all(uint n_pos, const mp_obj_t *pos, mp_map_t *kws, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); void mp_arg_parse_all_kw_array(uint n_pos, uint n_kw, const mp_obj_t *args, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals);