#ifndef APFL_VALUE_H #define APFL_VALUE_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include "apfl.h" #include "bytecode.h" #include "gc.h" #include "hashmap.h" enum value_type { VALUE_NIL, VALUE_BOOLEAN, VALUE_NUMBER, VALUE_STRING, VALUE_CONST_STRING, VALUE_LIST, VALUE_DICT, VALUE_FUNC, VALUE_CFUNC, VALUE_USERDATA, }; struct list_header { struct apfl_value *items; size_t len; size_t cap; bool copy_on_write; }; struct dict_header { struct apfl_hashmap map; bool copy_on_write; }; struct subfunction { struct matcher *matcher; struct instruction_list *body; }; struct function { struct subfunction *subfunctions; size_t subfunctions_len; size_t subfunctions_cap; struct scope *scope; struct apfl_string *name; int line_defined; }; struct cfunction { apfl_cfunc func; struct apfl_value **slots; size_t slots_len; struct apfl_string *name; }; typedef struct dict_header *apfl_dict; struct apfl_value { enum value_type type; union { bool boolean; apfl_number number; struct apfl_string *string; struct apfl_string_view const_string; struct list_header *list; struct dict_header *dict; struct function *func; struct cfunction *cfunc; void *userdata; }; }; enum apfl_value_type apfl_value_type_to_abstract_type(enum value_type); #define VALUE_IS_A(v, t) (apfl_value_type_to_abstract_type((v).type) == (t)) bool apfl_value_eq(const struct apfl_value, const struct apfl_value); struct apfl_value apfl_value_move(struct apfl_value *src); bool apfl_value_format(struct apfl_value, struct apfl_format_writer); bool apfl_value_print(struct apfl_value, struct apfl_format_writer); apfl_hash apfl_value_hash(const struct apfl_value); enum comparison_result { CMP_LT, CMP_EQ, CMP_GT, CMP_UNCOMPARABLE, CMP_INCOMPATIBLE_TYPES, }; enum comparison_result apfl_value_cmp(const struct apfl_value a, const struct apfl_value b); enum get_item_result { GET_ITEM_OK, GET_ITEM_KEY_DOESNT_EXIST, GET_ITEM_NOT_A_CONTAINER, GET_ITEM_WRONG_KEY_TYPE, }; enum get_item_result apfl_value_get_item(struct apfl_value container, struct apfl_value key, struct apfl_value *out); // Set the Copy On Write flag of a value (if it's a value with such a flag). // Returns the same value again. struct apfl_value apfl_value_set_cow_flag(struct apfl_value); struct list_header *apfl_list_new(struct gc *, size_t initial_cap); size_t apfl_list_len(struct list_header *); void apfl_list_deinit(struct apfl_allocator, struct list_header *); bool apfl_list_splice( struct gc *gc, struct list_header **dst_ptr, size_t cut_start, size_t cut_len, const struct apfl_value *other, size_t other_len ); struct dict_header *apfl_dict_new(struct gc *); bool apfl_dict_set_raw( struct gc *gc, struct dict_header **_dict, struct apfl_value k, struct apfl_value v ); size_t apfl_dict_len(struct dict_header *); void apfl_dict_deinit(struct dict_header *); struct function *apfl_func_new(struct gc *, size_t cap, struct scope *, int line_defined); bool apfl_func_add_subfunc(struct function *, struct instruction_list *, struct matcher *); bool apfl_func_get_name(struct function *, struct apfl_string_view *name); void apfl_func_set_name(struct function *, struct apfl_string *name); void apfl_function_deinit(struct apfl_allocator, struct function *); struct cfunction *apfl_cfunc_new(struct gc *, apfl_cfunc, size_t nslots); void apfl_cfunction_deinit(struct apfl_allocator, struct cfunction *); // Functions for garbage collection struct gc_object *apfl_value_get_gc_object(struct apfl_value); void apfl_value_visit_gc_object(struct apfl_value value, gc_visitor cb, void *opaque); bool apfl_value_add_as_tmproot(struct gc *, struct apfl_value); void apfl_gc_list_traverse(struct list_header *, gc_visitor, void *); void apfl_gc_dict_traverse(struct dict_header *, gc_visitor, void *); void apfl_gc_func_traverse(struct function*, gc_visitor, void *); void apfl_gc_cfunc_traverse(struct cfunction*, gc_visitor, void *); #ifdef __cplusplus } #endif #endif