diff options
Diffstat (limited to 'py/obj.h')
-rw-r--r-- | py/obj.h | 256 |
1 files changed, 219 insertions, 37 deletions
@@ -1,56 +1,238 @@ -typedef machine_int_t py_small_int_t; // do we need to expose this in the public API? +// All Micro Python objects are at least this type +// It must be of pointer size + +typedef machine_ptr_t mp_obj_t; +typedef machine_const_ptr_t mp_const_obj_t; + +// Integers that fit in a pointer have this type +// (do we need to expose this in the public API?) + +typedef machine_int_t mp_small_int_t; + +// The machine floating-point type used for float and complex numbers #if MICROPY_ENABLE_FLOAT -typedef machine_float_t py_float_t; +typedef machine_float_t mp_float_t; #endif -// user defined objects +// Anything that wants to be a Micro Python object must +// have mp_obj_base_t as its first member (except NULL and small ints) + +typedef struct _mp_obj_base_t mp_obj_base_t; +typedef struct _mp_obj_type_t mp_obj_type_t; + +struct _mp_obj_base_t { + const mp_obj_type_t *type; +}; + +// The NULL object is used to indicate the absence of an object +// It *cannot* be used when an mp_obj_t is expected, except where explicitly allowed + +#define MP_OBJ_NULL ((mp_obj_t)NULL) + +// These macros check for small int or object, and access small int values + +#define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 1) == 0) +#define MP_OBJ_IS_SMALL_INT(o) ((((mp_small_int_t)(o)) & 1) != 0) +#define MP_OBJ_IS_TYPE(o, t) (((((mp_small_int_t)(o)) & 1) == 0) && (((mp_obj_base_t*)(o))->type == (t))) +#define MP_OBJ_SMALL_INT_VALUE(o) (((mp_small_int_t)(o)) >> 1) +#define MP_OBJ_NEW_SMALL_INT(o) ((mp_obj_t)(((o) << 1) | 1)) + +// These macros are used to declare and define constant function objects +// You can put "static" in front of the definitions to make them local + +#define MP_DECLARE_CONST_FUN_OBJ(obj_name) extern const mp_obj_fun_native_t obj_name -typedef struct _py_user_method_t { +#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, 0, 0, fun_name} +#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, 1, 1, fun_name} +#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, 2, 2, fun_name} +#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, n_args_min, (~((machine_uint_t)0)), fun_name} +#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, n_args_min, n_args_max, fun_name} + +// Type definitions for methods + +typedef mp_obj_t (*mp_fun_0_t)(void); +typedef mp_obj_t (*mp_fun_1_t)(mp_obj_t); +typedef mp_obj_t (*mp_fun_2_t)(mp_obj_t, mp_obj_t); +typedef mp_obj_t (*mp_fun_t)(void); +typedef mp_obj_t (*mp_fun_var_t)(int n, const mp_obj_t *); + +typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o); +typedef mp_obj_t (*mp_call_n_fun_t)(mp_obj_t fun, int n_args, const mp_obj_t *args); // args are in reverse order in the array +typedef mp_obj_t (*mp_unary_op_fun_t)(int op, mp_obj_t); +typedef mp_obj_t (*mp_binary_op_fun_t)(int op, mp_obj_t, mp_obj_t); + +typedef struct _mp_method_t { const char *name; - machine_uint_t kind; - void *fun; -} py_user_method_t; + mp_const_obj_t fun; +} mp_method_t; + +struct _mp_obj_type_t { + mp_obj_base_t base; + const char *name; + mp_print_fun_t print; + + mp_call_n_fun_t call_n; + mp_unary_op_fun_t unary_op; // can return NULL if op not supported + mp_binary_op_fun_t binary_op; // can return NULL if op not supported + + mp_fun_1_t getiter; + mp_fun_1_t iternext; + + const mp_method_t methods[]; + + /* + What we might need to add here: + + dynamic_type instance -typedef struct _py_user_info_t { - const char *type_name; - void (*print)(py_obj_t); - const py_user_method_t methods[]; -} py_user_info_t; + compare_op + load_attr instance class list + load_method instance str gen list user + store_attr instance class + store_subscr list dict -py_obj_t py_obj_new_int(machine_int_t value); -py_obj_t py_obj_new_const(const char *id); -py_obj_t py_obj_new_str(qstr qstr); + len str tuple list map + abs float complex + hash bool int none str + equal int str + less int + get_array_n tuple list + + unpack seq list tuple + __next__ gen-instance + */ +}; + +// 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; +extern const mp_obj_t mp_const_stop_iteration; // special object indicating end of iteration (not StopIteration exception!) + +// Need to declare this here so we are not dependent on map.h + +typedef struct _mp_map_t mp_map_t; + +// General API for objects + +mp_obj_t mp_obj_new_none(void); +mp_obj_t mp_obj_new_bool(bool value); +mp_obj_t mp_obj_new_int(machine_int_t value); +mp_obj_t mp_obj_new_str(qstr qstr); #if MICROPY_ENABLE_FLOAT -py_obj_t py_obj_new_float(py_float_t val); -py_obj_t py_obj_new_complex(py_float_t real, py_float_t imag); +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 -py_obj_t py_obj_new_exception_0(qstr id); -py_obj_t py_obj_new_exception_2(qstr id, const char *fmt, const char *s1, const char *s2); -py_obj_t py_obj_new_range(int start, int stop, int step); -py_obj_t py_obj_new_range_iterator(int cur, int stop, int step); -py_obj_t py_obj_new_user(const py_user_info_t *info, machine_uint_t data1, machine_uint_t data2); +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_1_arg(qstr id, const char *fmt, const char *a1); +mp_obj_t mp_obj_new_exception_msg_2_args(qstr id, const char *fmt, const char *a1, const char *a2); +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, uint n_state, const byte *code); +mp_obj_t mp_obj_new_fun_asm(uint n_args, void *fun); +mp_obj_t mp_obj_new_gen_wrap(uint n_locals, uint n_cells, uint n_stack, mp_obj_t fun); +mp_obj_t mp_obj_new_gen_instance(mp_obj_t state, const byte *ip, mp_obj_t *sp); +mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_obj_t closure_tuple); +mp_obj_t mp_obj_new_tuple(uint n, mp_obj_t *items); +mp_obj_t mp_obj_new_tuple_reverse(uint n, mp_obj_t *items); +mp_obj_t mp_obj_new_list(uint n, mp_obj_t *items); +mp_obj_t mp_obj_new_list_reverse(uint n, mp_obj_t *items); +mp_obj_t mp_obj_new_dict(int n_args); +mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items); +mp_obj_t mp_obj_new_bound_meth(mp_obj_t self, mp_obj_t meth); +mp_obj_t mp_obj_new_class(mp_map_t *class_locals); +mp_obj_t mp_obj_new_instance(mp_obj_t clas); -const char *py_obj_get_type_str(py_obj_t o_in); +const char *mp_obj_get_type_str(mp_obj_t o_in); -void py_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, py_obj_t o_in); -void py_obj_print(py_obj_t o); +void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in); +void mp_obj_print(mp_obj_t o); -bool py_obj_is_callable(py_obj_t o_in); -machine_int_t py_obj_hash(py_obj_t o_in); -bool py_obj_equal(py_obj_t o1, py_obj_t o2); -bool py_obj_less(py_obj_t o1, py_obj_t o2); +bool mp_obj_is_callable(mp_obj_t o_in); +machine_int_t mp_obj_hash(mp_obj_t o_in); +bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2); +bool mp_obj_less(mp_obj_t o1, mp_obj_t o2); -machine_int_t py_obj_get_int(py_obj_t arg); +machine_int_t mp_obj_get_int(mp_obj_t arg); #if MICROPY_ENABLE_FLOAT -machine_float_t py_obj_get_float(py_obj_t arg); -void py_obj_get_complex(py_obj_t arg, py_float_t *real, py_float_t *imag); +mp_float_t mp_obj_get_float(mp_obj_t self_in); +void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag); #endif -qstr py_obj_get_qstr(py_obj_t arg); -py_obj_t *py_obj_get_array_fixed_n(py_obj_t o, machine_int_t n); +qstr mp_obj_get_qstr(mp_obj_t arg); +mp_obj_t *mp_obj_get_array_fixed_n(mp_obj_t o, machine_int_t n); +uint mp_get_index(const mp_obj_type_t *type, machine_uint_t len, mp_obj_t index); + +// none +extern const mp_obj_type_t none_type; + +// bool +extern const mp_obj_type_t bool_type; + +// cell +mp_obj_t mp_obj_cell_get(mp_obj_t self_in); +void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj); + +// str +extern const mp_obj_type_t str_type; +qstr mp_obj_str_get(mp_obj_t self_in); + +#if MICROPY_ENABLE_FLOAT +// float +extern const mp_obj_type_t float_type; +mp_float_t mp_obj_float_get(mp_obj_t self_in); + +// complex +extern const mp_obj_type_t complex_type; +void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag); +#endif + +// tuple +extern const mp_obj_type_t tuple_type; +void mp_obj_tuple_get(mp_obj_t self_in, uint *len, mp_obj_t **items); + +// list +extern const mp_obj_type_t list_type; +mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg); +void mp_obj_list_get(mp_obj_t self_in, uint *len, mp_obj_t **items); +void mp_obj_list_store(mp_obj_t self_in, mp_obj_t index, mp_obj_t value); + +// dict +extern const mp_obj_type_t dict_type; +mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value); + +// set +void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item); + +// functions +typedef struct _mp_obj_fun_native_t { // need this so we can define static objects + mp_obj_base_t base; + machine_uint_t n_args_min; // inclusive + machine_uint_t n_args_max; // inclusive + void *fun; +} mp_obj_fun_native_t; +extern const mp_obj_type_t fun_native_type; +extern const mp_obj_type_t fun_bc_type; +void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code); + +// generator +extern const mp_obj_type_t gen_instance_type; +mp_obj_t mp_obj_gen_instance_next(mp_obj_t self_in); +MP_DECLARE_CONST_FUN_OBJ(mp_obj_gen_instance_next_obj); + +// class +extern const mp_obj_type_t class_type; +extern const mp_obj_t gen_instance_next_obj; +mp_map_t *mp_obj_class_get_locals(mp_obj_t self_in); -void py_user_get_data(py_obj_t o, machine_uint_t *data1, machine_uint_t *data2); -void py_user_set_data(py_obj_t o, machine_uint_t data1, machine_uint_t data2); +// instance +extern const mp_obj_type_t instance_type; +mp_obj_t mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr); +void mp_obj_instance_load_method(mp_obj_t self_in, qstr attr, mp_obj_t *dest); +void mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value); // temporary way of making C modules -py_obj_t py_module_new(void); +mp_obj_t mp_module_new(void); |