paul@353 | 1 | /* Common operations. |
paul@353 | 2 | |
paul@971 | 3 | Copyright (C) 2015, 2016, 2017, 2018, 2023 Paul Boddie <paul@boddie.org.uk> |
paul@353 | 4 | |
paul@353 | 5 | This program is free software; you can redistribute it and/or modify it under |
paul@353 | 6 | the terms of the GNU General Public License as published by the Free Software |
paul@353 | 7 | Foundation; either version 3 of the License, or (at your option) any later |
paul@353 | 8 | version. |
paul@353 | 9 | |
paul@353 | 10 | This program is distributed in the hope that it will be useful, but WITHOUT |
paul@353 | 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
paul@353 | 12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
paul@353 | 13 | details. |
paul@353 | 14 | |
paul@353 | 15 | You should have received a copy of the GNU General Public License along with |
paul@353 | 16 | this program. If not, see <http://www.gnu.org/licenses/>. |
paul@353 | 17 | */ |
paul@126 | 18 | |
paul@126 | 19 | #ifndef __OPS_H__ |
paul@126 | 20 | #define __OPS_H__ |
paul@126 | 21 | |
paul@126 | 22 | #include "types.h" |
paul@148 | 23 | #include <string.h> /* for __COPY */ |
paul@126 | 24 | |
paul@757 | 25 | /* Get object reference from attribute. */ |
paul@757 | 26 | |
paul@757 | 27 | __ref __VALUE(__attr attr); |
paul@757 | 28 | |
paul@126 | 29 | /* Direct access and manipulation of static objects. */ |
paul@126 | 30 | |
paul@577 | 31 | __attr __load_static_ignore(__ref obj); |
paul@757 | 32 | __attr __load_static_replace(__attr context, __ref obj); |
paul@757 | 33 | __attr __load_static_test(__attr context, __ref obj); |
paul@126 | 34 | |
paul@989 | 35 | /* Direct retrieval operations, returning attribute locations. */ |
paul@989 | 36 | |
paul@989 | 37 | __attr *__get_class_attr_ref__(__ref obj, int pos); |
paul@989 | 38 | |
paul@989 | 39 | #define __get_object_attr_ref__(OBJ, POS) (&(OBJ)->attrs[POS]) |
paul@989 | 40 | |
paul@989 | 41 | #define __get_object_attr_ref(OBJ, ATTRNAME) (__get_object_attr_ref__(OBJ, __ATTRPOS(ATTRNAME))) |
paul@989 | 42 | #define __get_class_attr_ref(OBJ, ATTRNAME) (__get_class_attr_ref__(OBJ, __ATTRPOS(ATTRNAME))) |
paul@989 | 43 | |
paul@989 | 44 | /* Attribute location operations. */ |
paul@989 | 45 | |
paul@989 | 46 | #define __load_via_attr_ref(ATTR) (*(ATTR)) |
paul@989 | 47 | #define __store_via_attr_ref(ATTR, VALUE) __set_attr(ATTR, VALUE) |
paul@989 | 48 | |
paul@126 | 49 | /* Direct retrieval operations, returning attributes. */ |
paul@126 | 50 | |
paul@624 | 51 | __attr __load_via_class__(__ref obj, int pos); |
paul@624 | 52 | __attr __load_via_object__(__ref obj, int pos); |
paul@624 | 53 | __attr __get_class_and_load__(__ref obj, int pos); |
paul@624 | 54 | |
paul@624 | 55 | #define __load_via_class(OBJ, ATTRNAME) (__load_via_class__(OBJ, __ATTRPOS(ATTRNAME))) |
paul@624 | 56 | #define __load_via_object(OBJ, ATTRNAME) (__load_via_object__(OBJ, __ATTRPOS(ATTRNAME))) |
paul@624 | 57 | #define __get_class_and_load(OBJ, ATTRNAME) (__get_class_and_load__(OBJ, __ATTRPOS(ATTRNAME))) |
paul@126 | 58 | |
paul@126 | 59 | /* Introspection. */ |
paul@126 | 60 | |
paul@126 | 61 | int __is_instance(__ref obj); |
paul@655 | 62 | int __is_subclass(__ref obj, __attr cls); |
paul@655 | 63 | int __is_instance_subclass(__ref obj, __attr cls); |
paul@274 | 64 | int __is_type_instance(__ref obj); |
paul@126 | 65 | __ref __get_class(__ref obj); |
paul@231 | 66 | __attr __get_class_attr(__ref obj); |
paul@126 | 67 | |
paul@126 | 68 | /* Attribute testing operations. */ |
paul@126 | 69 | |
paul@237 | 70 | __ref __test_specific_instance(__ref obj, __ref type); |
paul@237 | 71 | __ref __test_specific_object(__ref obj, __ref type); |
paul@237 | 72 | __ref __test_specific_type(__ref obj, __ref type); |
paul@624 | 73 | |
paul@624 | 74 | __ref __test_common_instance__(__ref obj, int pos, int code); |
paul@624 | 75 | __ref __test_common_object__(__ref obj, int pos, int code); |
paul@624 | 76 | __ref __test_common_type__(__ref obj, int pos, int code); |
paul@624 | 77 | |
paul@825 | 78 | #define __to_error(REF) (REF ? REF : (__raise_type_error(), (__ref) 0)) |
paul@825 | 79 | |
paul@624 | 80 | #define __test_common_instance(OBJ, TYPENAME) (__test_common_instance__(OBJ, __ATTRPOS(TYPENAME), __ATTRCODE(TYPENAME))) |
paul@624 | 81 | #define __test_common_object(OBJ, TYPENAME) (__test_common_object__(OBJ, __ATTRPOS(TYPENAME), __ATTRCODE(TYPENAME))) |
paul@624 | 82 | #define __test_common_type(OBJ, TYPENAME) (__test_common_type__(OBJ, __ATTRPOS(TYPENAME), __ATTRCODE(TYPENAME))) |
paul@126 | 83 | |
paul@989 | 84 | /* Attribute testing and location operations, returning the address of the |
paul@989 | 85 | attribute as opposed to its value. */ |
paul@989 | 86 | |
paul@989 | 87 | __attr *__check_and_get_object_attr_ref_null(__ref obj, int pos, int code); |
paul@989 | 88 | |
paul@989 | 89 | __attr *__check_and_get_object_attr_ref__(__ref obj, int pos, int code); |
paul@989 | 90 | |
paul@989 | 91 | #define __check_and_get_object_attr_ref(OBJ, ATTRNAME) (__check_and_get_object_attr_ref__(OBJ, __ATTRPOS(ATTRNAME), __ATTRCODE(ATTRNAME))) |
paul@989 | 92 | |
paul@126 | 93 | /* Attribute testing and retrieval operations. */ |
paul@126 | 94 | |
paul@487 | 95 | __attr __check_and_load_via_object_null(__ref obj, int pos, int code); |
paul@624 | 96 | |
paul@624 | 97 | __attr __check_and_load_via_class__(__ref obj, int pos, int code); |
paul@624 | 98 | __attr __check_and_load_via_object__(__ref obj, int pos, int code); |
paul@624 | 99 | __attr __check_and_load_via_any__(__ref obj, int pos, int code); |
paul@624 | 100 | |
paul@624 | 101 | #define __check_and_load_via_class(OBJ, ATTRNAME) (__check_and_load_via_class__(OBJ, __ATTRPOS(ATTRNAME), __ATTRCODE(ATTRNAME))) |
paul@624 | 102 | #define __check_and_load_via_object(OBJ, ATTRNAME) (__check_and_load_via_object__(OBJ, __ATTRPOS(ATTRNAME), __ATTRCODE(ATTRNAME))) |
paul@624 | 103 | #define __check_and_load_via_any(OBJ, ATTRNAME) (__check_and_load_via_any__(OBJ, __ATTRPOS(ATTRNAME), __ATTRCODE(ATTRNAME))) |
paul@126 | 104 | |
paul@126 | 105 | /* Context-related operations. */ |
paul@126 | 106 | |
paul@852 | 107 | int __test_context_update(__attr context, __attr attr, int invoke); |
paul@757 | 108 | __attr __test_context(__attr context, __attr attr); |
paul@757 | 109 | __attr __update_context(__attr context, __attr attr); |
paul@757 | 110 | __attr __test_context_revert(int target, __attr context, __attr attr, __attr contexts[]); |
paul@757 | 111 | __attr __test_context_static(int target, __attr context, __ref value, __attr contexts[]); |
paul@595 | 112 | |
paul@858 | 113 | #define __get_accessor(__TARGET) (__tmp_values[__TARGET]) |
paul@989 | 114 | #define __get_attr_ref(__TARGET) (__tmp_attr_refs[__TARGET]) |
paul@591 | 115 | #define __get_context(__TARGET) (__tmp_contexts[__TARGET]) |
paul@757 | 116 | #define __set_context(__TARGET, __ATTR) (__tmp_contexts[__TARGET] = (__ATTR)) |
paul@757 | 117 | #define __set_private_context(__ATTR) (__tmp_private_context = (__ATTR)) |
paul@858 | 118 | #define __set_accessor(__TARGET, __ATTR) (__tmp_values[__TARGET] = (__ATTR)) |
paul@757 | 119 | #define __set_target_accessor(__ATTR) (__tmp_target_value = (__ATTR)) |
paul@989 | 120 | #define __set_attr_ref(__TARGET, __ATTR) (__tmp_attr_refs[__TARGET] = (__ATTR)) |
paul@126 | 121 | |
paul@523 | 122 | /* Context testing for invocations. */ |
paul@523 | 123 | |
paul@577 | 124 | __attr __unwrap_callable(__attr callable); |
paul@763 | 125 | __attr (*__get_function_unchecked(__attr target))(); |
paul@763 | 126 | __attr (*__get_function(__attr context, __attr target))(); |
paul@764 | 127 | __attr (*__get_function_unwrapped(__attr context, __attr target))(); |
paul@776 | 128 | __attr (*__get_function_member(__attr target))(); |
paul@763 | 129 | __attr (*__check_and_get_function(__attr context, __attr target))(); |
paul@764 | 130 | __attr (*__check_and_get_function_unwrapped(__attr context, __attr target))(); |
paul@523 | 131 | |
paul@126 | 132 | /* Parameter position operations. */ |
paul@126 | 133 | |
paul@126 | 134 | int __HASPARAM(const __ptable *ptable, int ppos, int pcode); |
paul@126 | 135 | |
paul@126 | 136 | /* Conversions. */ |
paul@126 | 137 | |
paul@126 | 138 | __attr __CONTEXT_AS_VALUE(__attr attr); |
paul@126 | 139 | |
paul@126 | 140 | /* Type testing. */ |
paul@126 | 141 | |
paul@144 | 142 | __ref __ISFUNC(__ref obj); |
paul@889 | 143 | |
paul@971 | 144 | #define __ISNULL(__ATTR) (!(__ATTR).value) |
paul@126 | 145 | |
paul@126 | 146 | /* Attribute codes and positions for type objects. */ |
paul@126 | 147 | |
paul@126 | 148 | unsigned int __TYPECODE(__ref obj); |
paul@126 | 149 | unsigned int __TYPEPOS(__ref obj); |
paul@126 | 150 | |
paul@260 | 151 | /* Memory allocation. */ |
paul@260 | 152 | |
paul@260 | 153 | void *__ALLOCATE(size_t nmemb, size_t size); |
paul@756 | 154 | void *__ALLOCATEIM(size_t nmemb, size_t size); |
paul@260 | 155 | void *__REALLOCATE(void *ptr, size_t size); |
paul@260 | 156 | |
paul@148 | 157 | /* Copying of structures. */ |
paul@148 | 158 | |
paul@151 | 159 | __ref __COPY(__ref obj, int size); |
paul@148 | 160 | |
paul@971 | 161 | /* Result target administration for potential value replacement. */ |
paul@971 | 162 | |
paul@989 | 163 | __attr __set_attr(volatile __attr *target, __attr attr); |
paul@971 | 164 | |
paul@126 | 165 | #endif /* __OPS_H__ */ |