1 /**************************************************************************** 2 * Copyright (C) 2012 by Matteo Franchin * 3 * * 4 * This file is part of Box. * 5 * * 6 * Box is free software: you can redistribute it and/or modify it * 7 * under the terms of the GNU Lesser General Public License as published * 8 * by the Free Software Foundation, either version 3 of the License, or * 9 * (at your option) any later version. * 10 * * 11 * Box is distributed in the hope that it will be useful, * 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 * GNU Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with Box. If not, see <http://www.gnu.org/licenses/>. * 18 ****************************************************************************/ 19 20 /** 21 * @file combs.h 22 * @brief Module to add, find and manipulate type combinations. 23 * 24 * This header gives access to the part of the Box type system which allows 25 * creating and finding combinations. A type combination is a relation 26 * between two types. 27 */ 28 29 #ifndef _BOX_COMBS_H 30 # define _BOX_COMBS_H 31 32 # include <box/types.h> 33 # include <box/callable.h> 34 35 /** 36 * @brief Define a combination and associate a callable to it. 37 * 38 * Define the combination of the given type between the child @p child and the 39 * parent @parent. The given callable is associated to the combination and the 40 * combination node is returned. 41 * @param parent The parent type. 42 * @param type The type of combination. 43 * @param child The child type. 44 * @param callable The callable to be associated to the combination. 45 * @return The combination node, if the operation succeed else MNUL 46 */ 47 BOXEXPORT BoxType * 48 BoxType_Define_Combination(BoxType *parent, BoxCombType type, BoxType *child, 49 BoxCallable *callable); 50 51 /** 52 * @brief Register a combination with a #BoxCall2 implementation. 53 * @note Use of this function is discouraged outside the Box runtime 54 * implementation. 55 * 56 * @param child Child type for the combination (the type on the left of @@). 57 * @param comb_type Type of combination. See #BoxCombType. 58 * @param parent Parent type for the combination (the type on the right of @@). 59 * @param uid A string used to identify the combination during linking. 60 * @param fn The C implementation of the combination. 61 * @return Whether the operation was successful. 62 */ 63 BOXEXPORT BoxBool 64 BoxType_Define_CCall2_Combination(BoxType *child, BoxCombType comb_type, 65 BoxType *parent, const char *uid, 66 BoxCCall2 fn); 67 68 /** 69 * @brief Convenience macro to for calling BoxType_Define_CCall2_Combination(). 70 * 71 * This macro expands to a call to BoxType_Define_CCall2_Combination() where 72 * the @c uid parameter is stringified. 73 */ 74 #define BOXTYPE_DEFINE_CCALL2_COMBINATION(child, comb_type, parent, fn) \ 75 BoxType_Define_CCall2_Combination((child), (comb_type), (parent), #fn, (fn)) 76 77 /** 78 * @brief Undefine a combination defined with BoxType_Define_Combination(). 79 * 80 * @param parent The parent in the combination to be removed. 81 * @param comb The combination node, as returned by BoxType_Find_Combination() 82 * or BoxType_Define_Combination(). 83 */ 84 BOXEXPORT void 85 BoxType_Undefine_Combination(BoxType *parent, BoxType *comb); 86 87 /** 88 * @brief Find a (possibly inherited) combination <tt>child@@parent</tt> 89 * of @c parent. 90 * 91 * The function returns: 92 * - @p child if the combination was found and the type @p child is equal to 93 * the combination's child type; 94 * - the expansion type, if the combination was found but @p child must be 95 * expanded; 96 * - @c NULL if the procedure was not found. 97 * 98 * @param parent The parent type. 99 * @param comb_type The combination type, see #BoxCombType. 100 * @param child The child type. 101 * @param expand How @p child compares with the found combination's child type. 102 * @return The type of the found combination's child type (@c NULL if the 103 * combination was not found). 104 * @see BoxCombType 105 * @see BoxType_Find_Own_Combination 106 */ 107 BOXEXPORT BoxType * 108 BoxType_Find_Combination(BoxType *parent, BoxCombType comb_type, 109 BoxType *child, BoxTypeCmp *expand); 110 111 /** 112 * Similar to #BoxType_Find_Combination, but restrict the search to the 113 * @p parent type, excluding the inherited combinations. 114 * @param parent The parent type. 115 * @param comb_type The combination type, see #BoxCombType. 116 * @param child The child type. 117 * @param expand How @p child compares with the found combination's child type. 118 * @return The type of the found combination's child type (@c NULL if the 119 * combination was not found). 120 * @see BoxCombType 121 * @see BoxType_Find_Combination 122 */ 123 BOXEXPORT BoxType * 124 BoxType_Find_Own_Combination(BoxType *parent, BoxCombType comb_type, 125 BoxType *child, BoxTypeCmp *expand); 126 127 /** 128 * Similar to BoxType_Find_Combination, but uses the type ID (BoxTypeId) 129 * instead of a BoxType * for the child. 130 */ 131 BOXEXPORT BoxType * 132 BoxType_Find_Own_Combination_With_Id(BoxType *parent, BoxCombType type, 133 BoxTypeId child_id, BoxTypeCmp *expand); 134 135 /** 136 * Get details about a combination found with BoxType_Find_Combination. 137 * @param comb The combination, as returned by #BoxType_Find_Combination. 138 * @param type Where to put the child type (if not NULL). 139 * @param cb Where to put the callable (if not NULL). 140 * @return BOXBOOL_TRUE if comb is a combination node, BOXBOOL_FALSE otherwise. 141 */ 142 BOXEXPORT BoxBool 143 BoxType_Get_Combination_Info(BoxType *comb, BoxType **child, BoxCallable **cb); 144 145 /** 146 * @brief Generate a call number for calling a combination from bytecode. 147 * 148 * Generate a call number for calling the combination @p comb from the virtual 149 * machine @p vm. If the operation succeed, the function returns 150 * @c BOXBOOL_TRUE and the call number is stored in <tt>*call_num</tt>. 151 * @param comb The combination, as returned by #BoxType_Find_Combination. 152 * @param vm The virtual machine for which a call number is generated. 153 * @param call_num Where to store the call number (ignored if @c NULL). 154 * @return A boolean which is true iff the operation succeeded. 155 * @remarks Note that - if necessary - the current callable for the combination 156 * is replaced with a corresponding VM callable for @p vm. 157 */ 158 BOXEXPORT BoxBool 159 BoxType_Generate_Combination_Call_Num(BoxType *comb, BoxVM *vm, 160 BoxVMCallNum *call_num); 161 162 /** 163 * @brief Structure used with 'BoxCombDef_Define() and friends. 164 * @note Use the #BOXCOMBDEF_T_AT_T and friends to create values for initialize 165 * a #BoxCombDef value. 166 */ 167 typedef struct { 168 BoxType *parent, /**< Parent. If @c NULL, use @c parent_id instead. */ 169 *child; /**< Child. If @c NULL, use @c child_id instead. */ 170 BoxTypeId parent_id, /**< Parent-id, used when @c parent is @c NULL. */ 171 child_id; /**< Child-id, used when @c child is @c NULL. */ 172 BoxCombType comb_type; /**< Combination type. */ 173 const char *name; /**< Name used during linking. */ 174 BoxCCall2 call2; /**< C implementation. */ 175 } BoxCombDef; 176 177 /** 178 * @brief Convenience function used to define many combinations at once. 179 * 180 * @param defs An array of #BoxCombDef object. Each item in the array describe 181 * one combination to define. 182 * @param num_defs Number of items in the #BoxCombDef array. 183 * @return The number of consecutive items in @p defs (starting from 0) which 184 * could be successfully defined. 185 */ 186 BOXEXPORT size_t 187 BoxCombDef_Define(BoxCombDef *defs, size_t num_defs); 188 189 /** 190 * @brief Macro to generate a #BoxCombDef value from parent and child type. 191 * 192 * @param child type of the child. 193 * @param parent type of the parent. 194 * @param fn Pointer to the C implementation (a #BoxCCall2). 195 * @note The string identifying the combination (when linking) is obtained by 196 * stringifying @p fn. 197 */ 198 #define BOXCOMBDEF_T_AT_T(child, parent, fn) \ 199 {(parent), (child), BOXTYPEID_NONE, BOXTYPEID_NONE, \ 200 BOXCOMBTYPE_AT, #fn, (fn)} 201 202 /** 203 * @brief Macro to generate a #BoxCombDef value from parent type and child id. 204 * 205 * @param child type of the child. 206 * @param parent type-id of the parent. 207 * @param fn See #BOXCOMBDEF_T_AT_T. 208 */ 209 #define BOXCOMBDEF_I_AT_T(child_id, parent, fn) \ 210 {(parent), NULL, BOXTYPEID_NONE, (child_id), BOXCOMBTYPE_AT, #fn, (fn)} 211 212 /** 213 * @brief Macro to generate a #BoxCombDef value from parent type and child id. 214 * 215 * @param child type-id of the child. 216 * @param parent type of the parent. 217 * @param fn See #BOXCOMBDEF_T_AT_T. 218 */ 219 #define BOXCOMBDEF_T_AT_I(child, parent_id, fn) \ 220 {NULL, (child), (parent_id), BOXTYPEID_NONE, BOXCOMBTYPE_AT, #fn, (fn)} 221 222 /** 223 * @brief Macro to generate a #BoxCombDef value from parent type and child id. 224 * 225 * @param child type-id of the child. 226 * @param parent type-id of the parent. 227 * @param fn See #BOXCOMBDEF_T_AT_T. 228 */ 229 #define BOXCOMBDEF_I_AT_I(child_id, parent_id, fn) \ 230 {NULL, NULL, (parent_id), (child_id), BOXCOMBTYPE_AT, #fn, (fn)} 231 232 /** 233 * @brief Macro to generate a #BoxCombDef value from parent and child type. 234 * 235 * @param child type of the child. 236 * @param parent type of the parent. 237 * @param fn Pointer to the C implementation (a #BoxCCall2). 238 * @note The string identifying the combination (when linking) is obtained by 239 * stringifying @p fn. 240 */ 241 #define BOXCOMBDEF_T_TO_T(child, parent, fn) \ 242 {(parent), (child), BOXTYPEID_NONE, BOXTYPEID_NONE, \ 243 BOXCOMBTYPE_COPY, #fn, (fn)} 244 245 #endif /* _BOX_COMBS_H */ 246