diff --git a/.gitmodules b/.gitmodules index 02849ec9bd..685fd55451 100644 --- a/.gitmodules +++ b/.gitmodules @@ -74,3 +74,6 @@ [submodule "lib/alif-security-toolkit"] path = lib/alif-security-toolkit url = https://github.com/micropython/alif-security-toolkit.git +[submodule "lib/preprocessor"] + path = lib/preprocessor + url = https://github.com/boostorg/preprocessor diff --git a/docs/develop/library.rst b/docs/develop/library.rst index 830211d81c..b317b36199 100644 --- a/docs/develop/library.rst +++ b/docs/develop/library.rst @@ -44,6 +44,7 @@ hypothetical new module ``subsystem`` in the file ``modsubsystem.c``: #include "py/builtin.h" #include "py/runtime.h" + #include "py/romtable.h" #if MICROPY_PY_SUBSYSTEM @@ -53,10 +54,10 @@ hypothetical new module ``subsystem`` in the file ``modsubsystem.c``: } MP_DEFINE_CONST_FUN_OBJ_0(subsystem_info_obj, py_subsystem_info); - static const mp_rom_map_elem_t mp_module_subsystem_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_subsystem) }, - { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&subsystem_info_obj) }, - }; + MP_ROM_TABLE(static, mp_module_subsystem_globals_table, + ((MP_QSTR___name__, MP_ROM_QSTR, MP_QSTR_subsystem)) + ((MP_QSTR_info, MP_ROM_PTR, &subsystem_info_obj)) + ); static MP_DEFINE_CONST_DICT(mp_module_subsystem_globals, mp_module_subsystem_globals_table); const mp_obj_module_t mp_module_subsystem = { @@ -84,3 +85,27 @@ After building and running the modified MicroPython, the module should now be im Our ``info()`` function currently returns just a single number but can be extended to do anything. Similarly, more functions can be added to this new module. + +Rom tables +---------- + +Rom tables are introduced with the ``MP_ROM_TABLE`` macro. +The format of the arguments to ``MP_ROM_TABLE`` are unusual due to the requirements of the boost preprocessor library. +This method is used instead of the traditional method of directly declaring an array of ``mp_rom_map_elem_t`` to allow for future flexibility. +Namely, it would save ROM space if the ROM qstr keys could be stored as ``qstr_short_t`` objects without extra padding. + +The macro invocation has 3 arguments: + * The storage class for the created table. This is usually "static". + * The name of the created table itself. + * A series of doubly parenthesized table entries (which lack trailing commas, making them a single macro argument). + +Each table entry consists of 3 arguments: + * An ``MP_QSTR_`` naming the table entry (without ``MP_ROM_QSTR`` or similar) + * A macro name such as MP_ROM_PTR or MP_OBJ_ROM_QSTR which says how to transform the value + * The value itself + +Note that none of these may themselves contain commas. In fact, the way that ``MP_ROM_PTR(&obj)`` _can_ +contain commas in its expansion is precisely why the 3-argument version is used. + +For example, in the code above the first key is ``MP_STR___name__``, its value +is ``MP_STR_subsystem``, and the value-transforming macro is ``MP_OBJ_ROM_QSTR`. diff --git a/docs/develop/porting.rst b/docs/develop/porting.rst index 99725e1000..a699925b8f 100644 --- a/docs/develop/porting.rst +++ b/docs/develop/porting.rst @@ -268,9 +268,9 @@ To add a custom module like ``myport``, first add the module definition in a fil } static MP_DEFINE_CONST_FUN_OBJ_0(myport_info_obj, myport_info); - static const mp_rom_map_elem_t myport_module_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_myport) }, - { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&myport_info_obj) }, + MP_ROM_TABLE(static, myport_module_globals_table, + (( MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR, MP_QSTR_myport )) + (( M_QSTR(MP_QSTR_info, MP_ROM_PTR, &myport_info_obj )) }; static MP_DEFINE_CONST_DICT(myport_module_globals, myport_module_globals_table); diff --git a/lib/preprocessor b/lib/preprocessor new file mode 160000 index 0000000000..cd1b1bd039 --- /dev/null +++ b/lib/preprocessor @@ -0,0 +1 @@ +Subproject commit cd1b1bd03900b68505822cfa25cb16851bd6caf1 diff --git a/py/mkrules.mk b/py/mkrules.mk index 3120066fd4..351c184436 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -11,6 +11,8 @@ ifeq ($(MICROPY_PREVIEW_VERSION_2),1) CFLAGS += -DMICROPY_PREVIEW_VERSION_2=1 endif +CFLAGS += -isystem $(TOP)/lib/preprocessor/include + HELP_BUILD_ERROR ?= "See \033[1;31mhttps://github.com/micropython/micropython/wiki/Build-Troubleshooting\033[0m" HELP_MPY_LIB_SUBMODULE ?= "\033[1;31mError: micropython-lib submodule is not initialized.\033[0m Run 'make submodules'" diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 51cf3137bf..0f5a217f36 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -600,168 +600,169 @@ MP_DEFINE_CONST_FUN_OBJ_0(mp_builtin_locals_obj, mp_builtin_locals); MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_id_obj, mp_obj_id); MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_len_obj, mp_obj_len); -static const mp_rom_map_elem_t mp_module_builtins_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_builtins) }, +#include "py/romtable.h" +MP_ROM_TABLE(static, mp_module_builtins_globals_table, + ((MP_QSTR___name__, MP_ROM_QSTR, MP_QSTR_builtins)) // built-in core functions - { MP_ROM_QSTR(MP_QSTR___build_class__), MP_ROM_PTR(&mp_builtin___build_class___obj) }, - { MP_ROM_QSTR(MP_QSTR___import__), MP_ROM_PTR(&mp_builtin___import___obj) }, - { MP_ROM_QSTR(MP_QSTR___repl_print__), MP_ROM_PTR(&mp_builtin___repl_print___obj) }, + ((MP_QSTR___build_class__, MP_ROM_PTR, &mp_builtin___build_class___obj)) + ((MP_QSTR___import__, MP_ROM_PTR, &mp_builtin___import___obj)) + ((MP_QSTR___repl_print__, MP_ROM_PTR, &mp_builtin___repl_print___obj)) // built-in types - { MP_ROM_QSTR(MP_QSTR_bool), MP_ROM_PTR(&mp_type_bool) }, - { MP_ROM_QSTR(MP_QSTR_bytes), MP_ROM_PTR(&mp_type_bytes) }, + ((MP_QSTR_bool, MP_ROM_PTR, &mp_type_bool)) + ((MP_QSTR_bytes, MP_ROM_PTR, &mp_type_bytes)) #if MICROPY_PY_BUILTINS_BYTEARRAY - { MP_ROM_QSTR(MP_QSTR_bytearray), MP_ROM_PTR(&mp_type_bytearray) }, + ((MP_QSTR_bytearray, MP_ROM_PTR, &mp_type_bytearray)) #endif #if MICROPY_PY_BUILTINS_COMPLEX - { MP_ROM_QSTR(MP_QSTR_complex), MP_ROM_PTR(&mp_type_complex) }, + ((MP_QSTR_complex, MP_ROM_PTR, &mp_type_complex)) #endif - { MP_ROM_QSTR(MP_QSTR_dict), MP_ROM_PTR(&mp_type_dict) }, + ((MP_QSTR_dict, MP_ROM_PTR, &mp_type_dict)) #if MICROPY_PY_BUILTINS_ENUMERATE - { MP_ROM_QSTR(MP_QSTR_enumerate), MP_ROM_PTR(&mp_type_enumerate) }, + ((MP_QSTR_enumerate, MP_ROM_PTR, &mp_type_enumerate)) #endif #if MICROPY_PY_BUILTINS_FILTER - { MP_ROM_QSTR(MP_QSTR_filter), MP_ROM_PTR(&mp_type_filter) }, + ((MP_QSTR_filter, MP_ROM_PTR, &mp_type_filter)) #endif #if MICROPY_PY_BUILTINS_FLOAT - { MP_ROM_QSTR(MP_QSTR_float), MP_ROM_PTR(&mp_type_float) }, + ((MP_QSTR_float, MP_ROM_PTR, &mp_type_float)) #endif #if MICROPY_PY_BUILTINS_SET && MICROPY_PY_BUILTINS_FROZENSET - { MP_ROM_QSTR(MP_QSTR_frozenset), MP_ROM_PTR(&mp_type_frozenset) }, + ((MP_QSTR_frozenset, MP_ROM_PTR, &mp_type_frozenset)) #endif - { MP_ROM_QSTR(MP_QSTR_int), MP_ROM_PTR(&mp_type_int) }, - { MP_ROM_QSTR(MP_QSTR_list), MP_ROM_PTR(&mp_type_list) }, - { MP_ROM_QSTR(MP_QSTR_map), MP_ROM_PTR(&mp_type_map) }, + ((MP_QSTR_int, MP_ROM_PTR, &mp_type_int)) + ((MP_QSTR_list, MP_ROM_PTR, &mp_type_list)) + ((MP_QSTR_map, MP_ROM_PTR, &mp_type_map)) #if MICROPY_PY_BUILTINS_MEMORYVIEW - { MP_ROM_QSTR(MP_QSTR_memoryview), MP_ROM_PTR(&mp_type_memoryview) }, + ((MP_QSTR_memoryview, MP_ROM_PTR, &mp_type_memoryview)) #endif - { MP_ROM_QSTR(MP_QSTR_object), MP_ROM_PTR(&mp_type_object) }, + ((MP_QSTR_object, MP_ROM_PTR, &mp_type_object)) #if MICROPY_PY_BUILTINS_PROPERTY - { MP_ROM_QSTR(MP_QSTR_property), MP_ROM_PTR(&mp_type_property) }, + ((MP_QSTR_property, MP_ROM_PTR, &mp_type_property)) #endif - { MP_ROM_QSTR(MP_QSTR_range), MP_ROM_PTR(&mp_type_range) }, + ((MP_QSTR_range, MP_ROM_PTR, &mp_type_range)) #if MICROPY_PY_BUILTINS_REVERSED - { MP_ROM_QSTR(MP_QSTR_reversed), MP_ROM_PTR(&mp_type_reversed) }, + ((MP_QSTR_reversed, MP_ROM_PTR, &mp_type_reversed)) #endif #if MICROPY_PY_BUILTINS_SET - { MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&mp_type_set) }, + ((MP_QSTR_set, MP_ROM_PTR, &mp_type_set)) #endif #if MICROPY_PY_BUILTINS_SLICE - { MP_ROM_QSTR(MP_QSTR_slice), MP_ROM_PTR(&mp_type_slice) }, + ((MP_QSTR_slice, MP_ROM_PTR, &mp_type_slice)) #endif - { MP_ROM_QSTR(MP_QSTR_str), MP_ROM_PTR(&mp_type_str) }, - { MP_ROM_QSTR(MP_QSTR_super), MP_ROM_PTR(&mp_type_super) }, - { MP_ROM_QSTR(MP_QSTR_tuple), MP_ROM_PTR(&mp_type_tuple) }, - { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&mp_type_type) }, - { MP_ROM_QSTR(MP_QSTR_zip), MP_ROM_PTR(&mp_type_zip) }, + ((MP_QSTR_str, MP_ROM_PTR, &mp_type_str)) + ((MP_QSTR_super, MP_ROM_PTR, &mp_type_super)) + ((MP_QSTR_tuple, MP_ROM_PTR, &mp_type_tuple)) + ((MP_QSTR_type, MP_ROM_PTR, &mp_type_type)) + ((MP_QSTR_zip, MP_ROM_PTR, &mp_type_zip)) - { MP_ROM_QSTR(MP_QSTR_classmethod), MP_ROM_PTR(&mp_type_classmethod) }, - { MP_ROM_QSTR(MP_QSTR_staticmethod), MP_ROM_PTR(&mp_type_staticmethod) }, + ((MP_QSTR_classmethod, MP_ROM_PTR, &mp_type_classmethod)) + ((MP_QSTR_staticmethod, MP_ROM_PTR, &mp_type_staticmethod)) // built-in objects - { MP_ROM_QSTR(MP_QSTR_Ellipsis), MP_ROM_PTR(&mp_const_ellipsis_obj) }, + ((MP_QSTR_Ellipsis, MP_ROM_PTR, &mp_const_ellipsis_obj)) #if MICROPY_PY_BUILTINS_NOTIMPLEMENTED - { MP_ROM_QSTR(MP_QSTR_NotImplemented), MP_ROM_PTR(&mp_const_notimplemented_obj) }, + ((MP_QSTR_NotImplemented, MP_ROM_PTR, &mp_const_notimplemented_obj)) #endif // built-in user functions - { MP_ROM_QSTR(MP_QSTR_abs), MP_ROM_PTR(&mp_builtin_abs_obj) }, - { MP_ROM_QSTR(MP_QSTR_all), MP_ROM_PTR(&mp_builtin_all_obj) }, - { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&mp_builtin_any_obj) }, - { MP_ROM_QSTR(MP_QSTR_bin), MP_ROM_PTR(&mp_builtin_bin_obj) }, - { MP_ROM_QSTR(MP_QSTR_callable), MP_ROM_PTR(&mp_builtin_callable_obj) }, + ((MP_QSTR_abs, MP_ROM_PTR, &mp_builtin_abs_obj)) + ((MP_QSTR_all, MP_ROM_PTR, &mp_builtin_all_obj)) + ((MP_QSTR_any, MP_ROM_PTR, &mp_builtin_any_obj)) + ((MP_QSTR_bin, MP_ROM_PTR, &mp_builtin_bin_obj)) + ((MP_QSTR_callable, MP_ROM_PTR, &mp_builtin_callable_obj)) #if MICROPY_PY_BUILTINS_COMPILE - { MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mp_builtin_compile_obj) }, + ((MP_QSTR_compile, MP_ROM_PTR, &mp_builtin_compile_obj)) #endif - { MP_ROM_QSTR(MP_QSTR_chr), MP_ROM_PTR(&mp_builtin_chr_obj) }, + ((MP_QSTR_chr, MP_ROM_PTR, &mp_builtin_chr_obj)) #if MICROPY_CPYTHON_COMPAT - { MP_ROM_QSTR(MP_QSTR_delattr), MP_ROM_PTR(&mp_builtin_delattr_obj) }, + ((MP_QSTR_delattr, MP_ROM_PTR, &mp_builtin_delattr_obj)) #endif - { MP_ROM_QSTR(MP_QSTR_dir), MP_ROM_PTR(&mp_builtin_dir_obj) }, - { MP_ROM_QSTR(MP_QSTR_divmod), MP_ROM_PTR(&mp_builtin_divmod_obj) }, + ((MP_QSTR_dir, MP_ROM_PTR, &mp_builtin_dir_obj)) + ((MP_QSTR_divmod, MP_ROM_PTR, &mp_builtin_divmod_obj)) #if MICROPY_PY_BUILTINS_EVAL_EXEC - { MP_ROM_QSTR(MP_QSTR_eval), MP_ROM_PTR(&mp_builtin_eval_obj) }, - { MP_ROM_QSTR(MP_QSTR_exec), MP_ROM_PTR(&mp_builtin_exec_obj) }, + ((MP_QSTR_eval, MP_ROM_PTR, &mp_builtin_eval_obj)) + ((MP_QSTR_exec, MP_ROM_PTR, &mp_builtin_exec_obj)) #endif #if MICROPY_PY_BUILTINS_EXECFILE - { MP_ROM_QSTR(MP_QSTR_execfile), MP_ROM_PTR(&mp_builtin_execfile_obj) }, + ((MP_QSTR_execfile, MP_ROM_PTR, &mp_builtin_execfile_obj)) #endif - { MP_ROM_QSTR(MP_QSTR_getattr), MP_ROM_PTR(&mp_builtin_getattr_obj) }, - { MP_ROM_QSTR(MP_QSTR_setattr), MP_ROM_PTR(&mp_builtin_setattr_obj) }, - { MP_ROM_QSTR(MP_QSTR_globals), MP_ROM_PTR(&mp_builtin_globals_obj) }, - { MP_ROM_QSTR(MP_QSTR_hasattr), MP_ROM_PTR(&mp_builtin_hasattr_obj) }, - { MP_ROM_QSTR(MP_QSTR_hash), MP_ROM_PTR(&mp_builtin_hash_obj) }, + ((MP_QSTR_getattr, MP_ROM_PTR, &mp_builtin_getattr_obj)) + ((MP_QSTR_setattr, MP_ROM_PTR, &mp_builtin_setattr_obj)) + ((MP_QSTR_globals, MP_ROM_PTR, &mp_builtin_globals_obj)) + ((MP_QSTR_hasattr, MP_ROM_PTR, &mp_builtin_hasattr_obj)) + ((MP_QSTR_hash, MP_ROM_PTR, &mp_builtin_hash_obj)) #if MICROPY_PY_BUILTINS_HELP - { MP_ROM_QSTR(MP_QSTR_help), MP_ROM_PTR(&mp_builtin_help_obj) }, + ((MP_QSTR_help, MP_ROM_PTR, &mp_builtin_help_obj)) #endif - { MP_ROM_QSTR(MP_QSTR_hex), MP_ROM_PTR(&mp_builtin_hex_obj) }, - { MP_ROM_QSTR(MP_QSTR_id), MP_ROM_PTR(&mp_builtin_id_obj) }, + ((MP_QSTR_hex, MP_ROM_PTR, &mp_builtin_hex_obj)) + ((MP_QSTR_id, MP_ROM_PTR, &mp_builtin_id_obj)) #if MICROPY_PY_BUILTINS_INPUT - { MP_ROM_QSTR(MP_QSTR_input), MP_ROM_PTR(&mp_builtin_input_obj) }, + ((MP_QSTR_input, MP_ROM_PTR, &mp_builtin_input_obj)) #endif - { MP_ROM_QSTR(MP_QSTR_isinstance), MP_ROM_PTR(&mp_builtin_isinstance_obj) }, - { MP_ROM_QSTR(MP_QSTR_issubclass), MP_ROM_PTR(&mp_builtin_issubclass_obj) }, - { MP_ROM_QSTR(MP_QSTR_iter), MP_ROM_PTR(&mp_builtin_iter_obj) }, - { MP_ROM_QSTR(MP_QSTR_len), MP_ROM_PTR(&mp_builtin_len_obj) }, - { MP_ROM_QSTR(MP_QSTR_locals), MP_ROM_PTR(&mp_builtin_locals_obj) }, + ((MP_QSTR_isinstance, MP_ROM_PTR, &mp_builtin_isinstance_obj)) + ((MP_QSTR_issubclass, MP_ROM_PTR, &mp_builtin_issubclass_obj)) + ((MP_QSTR_iter, MP_ROM_PTR, &mp_builtin_iter_obj)) + ((MP_QSTR_len, MP_ROM_PTR, &mp_builtin_len_obj)) + ((MP_QSTR_locals, MP_ROM_PTR, &mp_builtin_locals_obj)) #if MICROPY_PY_BUILTINS_MIN_MAX - { MP_ROM_QSTR(MP_QSTR_max), MP_ROM_PTR(&mp_builtin_max_obj) }, - { MP_ROM_QSTR(MP_QSTR_min), MP_ROM_PTR(&mp_builtin_min_obj) }, + ((MP_QSTR_max, MP_ROM_PTR, &mp_builtin_max_obj)) + ((MP_QSTR_min, MP_ROM_PTR, &mp_builtin_min_obj)) #endif - { MP_ROM_QSTR(MP_QSTR_next), MP_ROM_PTR(&mp_builtin_next_obj) }, - { MP_ROM_QSTR(MP_QSTR_oct), MP_ROM_PTR(&mp_builtin_oct_obj) }, + ((MP_QSTR_next, MP_ROM_PTR, &mp_builtin_next_obj)) + ((MP_QSTR_oct, MP_ROM_PTR, &mp_builtin_oct_obj)) #if MICROPY_PY_IO - { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) }, + ((MP_QSTR_open, MP_ROM_PTR, &mp_builtin_open_obj)) #endif - { MP_ROM_QSTR(MP_QSTR_ord), MP_ROM_PTR(&mp_builtin_ord_obj) }, - { MP_ROM_QSTR(MP_QSTR_pow), MP_ROM_PTR(&mp_builtin_pow_obj) }, - { MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&mp_builtin_print_obj) }, - { MP_ROM_QSTR(MP_QSTR_repr), MP_ROM_PTR(&mp_builtin_repr_obj) }, - { MP_ROM_QSTR(MP_QSTR_round), MP_ROM_PTR(&mp_builtin_round_obj) }, - { MP_ROM_QSTR(MP_QSTR_sorted), MP_ROM_PTR(&mp_builtin_sorted_obj) }, - { MP_ROM_QSTR(MP_QSTR_sum), MP_ROM_PTR(&mp_builtin_sum_obj) }, + ((MP_QSTR_ord, MP_ROM_PTR, &mp_builtin_ord_obj)) + ((MP_QSTR_pow, MP_ROM_PTR, &mp_builtin_pow_obj)) + ((MP_QSTR_print, MP_ROM_PTR, &mp_builtin_print_obj)) + ((MP_QSTR_repr, MP_ROM_PTR, &mp_builtin_repr_obj)) + ((MP_QSTR_round, MP_ROM_PTR, &mp_builtin_round_obj)) + ((MP_QSTR_sorted, MP_ROM_PTR, &mp_builtin_sorted_obj)) + ((MP_QSTR_sum, MP_ROM_PTR, &mp_builtin_sum_obj)) // built-in exceptions - { MP_ROM_QSTR(MP_QSTR_BaseException), MP_ROM_PTR(&mp_type_BaseException) }, - { MP_ROM_QSTR(MP_QSTR_ArithmeticError), MP_ROM_PTR(&mp_type_ArithmeticError) }, - { MP_ROM_QSTR(MP_QSTR_AssertionError), MP_ROM_PTR(&mp_type_AssertionError) }, - { MP_ROM_QSTR(MP_QSTR_AttributeError), MP_ROM_PTR(&mp_type_AttributeError) }, - { MP_ROM_QSTR(MP_QSTR_EOFError), MP_ROM_PTR(&mp_type_EOFError) }, - { MP_ROM_QSTR(MP_QSTR_Exception), MP_ROM_PTR(&mp_type_Exception) }, - { MP_ROM_QSTR(MP_QSTR_GeneratorExit), MP_ROM_PTR(&mp_type_GeneratorExit) }, - { MP_ROM_QSTR(MP_QSTR_ImportError), MP_ROM_PTR(&mp_type_ImportError) }, - { MP_ROM_QSTR(MP_QSTR_IndentationError), MP_ROM_PTR(&mp_type_IndentationError) }, - { MP_ROM_QSTR(MP_QSTR_IndexError), MP_ROM_PTR(&mp_type_IndexError) }, - { MP_ROM_QSTR(MP_QSTR_KeyboardInterrupt), MP_ROM_PTR(&mp_type_KeyboardInterrupt) }, - { MP_ROM_QSTR(MP_QSTR_KeyError), MP_ROM_PTR(&mp_type_KeyError) }, - { MP_ROM_QSTR(MP_QSTR_LookupError), MP_ROM_PTR(&mp_type_LookupError) }, - { MP_ROM_QSTR(MP_QSTR_MemoryError), MP_ROM_PTR(&mp_type_MemoryError) }, - { MP_ROM_QSTR(MP_QSTR_NameError), MP_ROM_PTR(&mp_type_NameError) }, - { MP_ROM_QSTR(MP_QSTR_NotImplementedError), MP_ROM_PTR(&mp_type_NotImplementedError) }, - { MP_ROM_QSTR(MP_QSTR_OSError), MP_ROM_PTR(&mp_type_OSError) }, - { MP_ROM_QSTR(MP_QSTR_OverflowError), MP_ROM_PTR(&mp_type_OverflowError) }, - { MP_ROM_QSTR(MP_QSTR_RuntimeError), MP_ROM_PTR(&mp_type_RuntimeError) }, + ((MP_QSTR_BaseException, MP_ROM_PTR, &mp_type_BaseException)) + ((MP_QSTR_ArithmeticError, MP_ROM_PTR, &mp_type_ArithmeticError)) + ((MP_QSTR_AssertionError, MP_ROM_PTR, &mp_type_AssertionError)) + ((MP_QSTR_AttributeError, MP_ROM_PTR, &mp_type_AttributeError)) + ((MP_QSTR_EOFError, MP_ROM_PTR, &mp_type_EOFError)) + ((MP_QSTR_Exception, MP_ROM_PTR, &mp_type_Exception)) + ((MP_QSTR_GeneratorExit, MP_ROM_PTR, &mp_type_GeneratorExit)) + ((MP_QSTR_ImportError, MP_ROM_PTR, &mp_type_ImportError)) + ((MP_QSTR_IndentationError, MP_ROM_PTR, &mp_type_IndentationError)) + ((MP_QSTR_IndexError, MP_ROM_PTR, &mp_type_IndexError)) + ((MP_QSTR_KeyboardInterrupt, MP_ROM_PTR, &mp_type_KeyboardInterrupt)) + ((MP_QSTR_KeyError, MP_ROM_PTR, &mp_type_KeyError)) + ((MP_QSTR_LookupError, MP_ROM_PTR, &mp_type_LookupError)) + ((MP_QSTR_MemoryError, MP_ROM_PTR, &mp_type_MemoryError)) + ((MP_QSTR_NameError, MP_ROM_PTR, &mp_type_NameError)) + ((MP_QSTR_NotImplementedError, MP_ROM_PTR, &mp_type_NotImplementedError)) + ((MP_QSTR_OSError, MP_ROM_PTR, &mp_type_OSError)) + ((MP_QSTR_OverflowError, MP_ROM_PTR, &mp_type_OverflowError)) + ((MP_QSTR_RuntimeError, MP_ROM_PTR, &mp_type_RuntimeError)) #if MICROPY_PY_ASYNC_AWAIT - { MP_ROM_QSTR(MP_QSTR_StopAsyncIteration), MP_ROM_PTR(&mp_type_StopAsyncIteration) }, + ((MP_QSTR_StopAsyncIteration, MP_ROM_PTR, &mp_type_StopAsyncIteration)) #endif - { MP_ROM_QSTR(MP_QSTR_StopIteration), MP_ROM_PTR(&mp_type_StopIteration) }, - { MP_ROM_QSTR(MP_QSTR_SyntaxError), MP_ROM_PTR(&mp_type_SyntaxError) }, - { MP_ROM_QSTR(MP_QSTR_SystemExit), MP_ROM_PTR(&mp_type_SystemExit) }, - { MP_ROM_QSTR(MP_QSTR_TypeError), MP_ROM_PTR(&mp_type_TypeError) }, + ((MP_QSTR_StopIteration, MP_ROM_PTR, &mp_type_StopIteration)) + ((MP_QSTR_SyntaxError, MP_ROM_PTR, &mp_type_SyntaxError)) + ((MP_QSTR_SystemExit, MP_ROM_PTR, &mp_type_SystemExit)) + ((MP_QSTR_TypeError, MP_ROM_PTR, &mp_type_TypeError)) #if MICROPY_PY_BUILTINS_STR_UNICODE - { MP_ROM_QSTR(MP_QSTR_UnicodeError), MP_ROM_PTR(&mp_type_UnicodeError) }, + ((MP_QSTR_UnicodeError, MP_ROM_PTR, &mp_type_UnicodeError)) #endif - { MP_ROM_QSTR(MP_QSTR_ValueError), MP_ROM_PTR(&mp_type_ValueError) }, + ((MP_QSTR_ValueError, MP_ROM_PTR, &mp_type_ValueError)) #if MICROPY_EMIT_NATIVE - { MP_ROM_QSTR(MP_QSTR_ViperTypeError), MP_ROM_PTR(&mp_type_ViperTypeError) }, + ((MP_QSTR_ViperTypeError, MP_ROM_PTR, &mp_type_ViperTypeError)) #endif - { MP_ROM_QSTR(MP_QSTR_ZeroDivisionError), MP_ROM_PTR(&mp_type_ZeroDivisionError) }, + ((MP_QSTR_ZeroDivisionError, MP_ROM_PTR, &mp_type_ZeroDivisionError)) // Extra builtins as defined by a port MICROPY_PORT_BUILTINS MICROPY_PORT_EXTRA_BUILTINS -}; + ); MP_DEFINE_CONST_DICT(mp_module_builtins_globals, mp_module_builtins_globals_table); diff --git a/py/modsys.c b/py/modsys.c index ef6273fc8c..e278fc2440 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -297,22 +297,23 @@ void mp_module_sys_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } #endif -static const mp_rom_map_elem_t mp_module_sys_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sys) }, +#include "py/romtable.h" +static const MP_ROM_TABLE(mp_module_sys_globals_table, + ((MP_QSTR___name__, MP_ROM_QSTR, MP_QSTR_sys)) #if MICROPY_PY_SYS_ARGV - { MP_ROM_QSTR(MP_QSTR_argv), MP_ROM_PTR(&MP_STATE_VM(mp_sys_argv_obj)) }, + ((MP_QSTR_argv, MP_ROM_PTR, &MP_STATE_VM(mp_sys_argv_obj))) #endif - { MP_ROM_QSTR(MP_QSTR_version), MP_ROM_PTR(&mp_sys_version_obj) }, - { MP_ROM_QSTR(MP_QSTR_version_info), MP_ROM_PTR(&mp_sys_version_info_obj) }, - { MP_ROM_QSTR(MP_QSTR_implementation), MP_ROM_PTR(&mp_sys_implementation_obj) }, + ((MP_QSTR_version, MP_ROM_PTR, &mp_sys_version_obj)) + ((MP_QSTR_version_info, MP_ROM_PTR, &mp_sys_version_info_obj)) + ((MP_QSTR_implementation, MP_ROM_PTR, &mp_sys_implementation_obj)) #ifdef MICROPY_PY_SYS_PLATFORM - { MP_ROM_QSTR(MP_QSTR_platform), MP_ROM_PTR(&mp_sys_platform_obj) }, + ((MP_QSTR_platform, MP_ROM_PTR, &mp_sys_platform_obj)) #endif #if MP_ENDIANNESS_LITTLE - { MP_ROM_QSTR(MP_QSTR_byteorder), MP_ROM_QSTR(MP_QSTR_little) }, + ((MP_QSTR_byteorder, MP_ROM_QSTR, MP_QSTR_little)) #else - { MP_ROM_QSTR(MP_QSTR_byteorder), MP_ROM_QSTR(MP_QSTR_big) }, + ((MP_QSTR_byteorder, MP_ROM_QSTR, MP_QSTR_big)) #endif #if MICROPY_PY_SYS_MAXSIZE @@ -322,53 +323,53 @@ static const mp_rom_map_elem_t mp_module_sys_globals_table[] = { // to not try to compare sys.maxsize to some literal number (as this // number might not fit in available int size), but instead count number // of "one" bits in sys.maxsize. - { MP_ROM_QSTR(MP_QSTR_maxsize), MP_ROM_INT(MP_SMALL_INT_MAX) }, + ((MP_QSTR_maxsize, MP_ROM_INT, MP_SMALL_INT_MAX)) #else - { MP_ROM_QSTR(MP_QSTR_maxsize), MP_ROM_PTR(&mp_sys_maxsize_obj) }, + ((MP_QSTR_maxsize, MP_ROM_PTR, &mp_sys_maxsize_obj)) #endif #endif #if MICROPY_PY_SYS_INTERN - { MP_ROM_QSTR(MP_QSTR_intern), MP_ROM_PTR(&mp_sys_intern_obj) }, + ((MP_QSTR_intern, MP_ROM_PTR, &mp_sys_intern_obj)) #endif #if MICROPY_PY_SYS_EXIT - { MP_ROM_QSTR(MP_QSTR_exit), MP_ROM_PTR(&mp_sys_exit_obj) }, + ((MP_QSTR_exit, MP_ROM_PTR, &mp_sys_exit_obj)) #endif #if MICROPY_PY_SYS_SETTRACE - { MP_ROM_QSTR(MP_QSTR_settrace), MP_ROM_PTR(&mp_sys_settrace_obj) }, + ((MP_QSTR_settrace, MP_ROM_PTR, &mp_sys_settrace_obj)) #endif #if MICROPY_PY_SYS_STDFILES - { MP_ROM_QSTR(MP_QSTR_stdin), MP_ROM_PTR(&mp_sys_stdin_obj) }, - { MP_ROM_QSTR(MP_QSTR_stdout), MP_ROM_PTR(&mp_sys_stdout_obj) }, - { MP_ROM_QSTR(MP_QSTR_stderr), MP_ROM_PTR(&mp_sys_stderr_obj) }, + ((MP_QSTR_stdin, MP_ROM_PTR, &mp_sys_stdin_obj)) + ((MP_QSTR_stdout, MP_ROM_PTR, &mp_sys_stdout_obj)) + ((MP_QSTR_stderr, MP_ROM_PTR, &mp_sys_stderr_obj)) #endif #if MICROPY_PY_SYS_MODULES - { MP_ROM_QSTR(MP_QSTR_modules), MP_ROM_PTR(&MP_STATE_VM(mp_loaded_modules_dict)) }, + ((MP_QSTR_modules, MP_ROM_PTR, &MP_STATE_VM(mp_loaded_modules_dict))) #endif #if MICROPY_PY_SYS_EXC_INFO - { MP_ROM_QSTR(MP_QSTR_exc_info), MP_ROM_PTR(&mp_sys_exc_info_obj) }, + ((MP_QSTR_exc_info, MP_ROM_PTR, &mp_sys_exc_info_obj)) #endif #if MICROPY_PY_SYS_GETSIZEOF - { MP_ROM_QSTR(MP_QSTR_getsizeof), MP_ROM_PTR(&mp_sys_getsizeof_obj) }, + ((MP_QSTR_getsizeof, MP_ROM_PTR, &mp_sys_getsizeof_obj)) #endif #if MICROPY_PY_SYS_EXECUTABLE - { MP_ROM_QSTR(MP_QSTR_executable), MP_ROM_PTR(&mp_sys_executable_obj) }, + ((MP_QSTR_executable, MP_ROM_PTR, &mp_sys_executable_obj)) #endif /* * Extensions to CPython */ - { MP_ROM_QSTR(MP_QSTR_print_exception), MP_ROM_PTR(&mp_sys_print_exception_obj) }, + ((MP_QSTR_print_exception, MP_ROM_PTR, &mp_sys_print_exception_obj)) #if MICROPY_PY_SYS_ATEXIT - { MP_ROM_QSTR(MP_QSTR_atexit), MP_ROM_PTR(&mp_sys_atexit_obj) }, + ((MP_QSTR_atexit, MP_ROM_PTR, &mp_sys_atexit_obj)) #endif -}; + ); static MP_DEFINE_CONST_DICT(mp_module_sys_globals, mp_module_sys_globals_table); diff --git a/py/romtable.h b/py/romtable.h new file mode 100644 index 0000000000..3ff9c5eb3a --- /dev/null +++ b/py/romtable.h @@ -0,0 +1,56 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2025 Jeff Epler + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_PY_ROMTABLE_H +#define MICROPY_INCLUDED_PY_ROMTABLE_H + +#include +#include +#include + +#define MP_TABLE_ENTRY(r, x, element) { \ + MP_ROM_QSTR(BOOST_PP_TUPLE_ELEM(0, element)), \ + BOOST_PP_TUPLE_ELEM(1, element) (BOOST_PP_TUPLE_ELEM(2, element)) \ +}, + +#define MP_ROM_TABLE_MERGED(storage, name, contents) const storage mp_rom_map_elem_t name[] = { \ + BOOST_PP_SEQ_FOR_EACH(MP_TABLE_ENTRY, _, contents) \ +} +#define MP_ROM_TABLE MP_ROM_TABLE_MERGED + +// A hypothetical future format for ROM tables +#define MP_TABLE_KEY(r, x, element) BOOST_PP_TUPLE_ELEM(0, element), +#define MP_TABLE_VALUE(r, x, element) \ + BOOST_PP_EXPAND(BOOST_PP_TUPLE_ELEM(1, element) (BOOST_PP_TUPLE_ELEM(2, element))), +#define ROM_TABLE_SEPARATE(storage, name, contents) \ + const storage struct { \ + qstr_short_t keys[BOOST_PP_SEQ_SIZE(contents)], \ + mp_rom_obj_t values[BOOST_PP_SEQ_SIZE(contents)], \ + } name = { \ + { BOOST_PP_SEQ_FOR_EACH(MP_TABLE_KEY, _, contents) }, \ + { BOOST_PP_SEQ_FOR_EACH(MP_TABLE_VALUE, _, contents) }, \ + } + +#endif diff --git a/tools/codeformat.py b/tools/codeformat.py index c65174ddc1..26e7fb6b07 100755 --- a/tools/codeformat.py +++ b/tools/codeformat.py @@ -120,6 +120,11 @@ def fixup_c(filename): if directive == "endif": dedent_stack.pop() + # MP_ROM_TABLE entries all should be indented 4 spaces + m = re.match(r" +\(\(MP_QSTR_", l) + if m: + l = " " + l.lstrip() + # Write out line. f.write(l)