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 core.h 22 * @brief Definition of core types and objects. 23 * 24 * This module defines Box core types and objects. 25 */ 26 27 #ifndef _BOX_CORE_H 28 # define _BOX_CORE_H 29 30 # include <float.h> 31 # include <stdlib.h> 32 33 /* Detect whether we are being compiled on MS Windows platforms */ 34 # ifndef __WINDOWS__ 35 # if defined(WIN32) || defined(_WIN32) 36 # define __WINDOWS__ 37 # endif 38 # endif 39 40 # ifdef __WINDOWS__ 41 /** 42 * Macro to use as a prefix when declaring functions in a shared library that 43 * are meant to be used from outside callers. 44 */ 45 # define BOXEXPORT extern __declspec(dllexport) 46 # else 47 # define BOXEXPORT extern 48 # endif 49 50 /** 51 * @brief Integers associated to the fundamental types. These constant values 52 * are used internally for caching combinations and - in general - for 53 * speeding up the type system (or at least speeding up usage of fundamental 54 * types). 55 */ 56 typedef enum { 57 BOXTYPEID_NONE =-1, 58 BOXTYPEID_MIN_VAL=0, 59 BOXTYPEID_FAST_LOWER = 0, 60 BOXTYPEID_CHAR = 0, 61 BOXTYPEID_INT = 1, 62 BOXTYPEID_REAL = 2, 63 BOXTYPEID_POINT = 3, 64 BOXTYPEID_PTR = 4, 65 BOXTYPEID_FAST_UPPER = 4, 66 BOXTYPEID_OBJ = 5, 67 BOXTYPEID_VOID, 68 BOXTYPEID_INIT, 69 BOXTYPEID_FINISH, 70 BOXTYPEID_COPY, 71 BOXTYPEID_BEGIN, 72 BOXTYPEID_END, 73 BOXTYPEID_PAUSE, 74 BOXTYPEID_CPTR, 75 BOXTYPEID_TYPE, 76 BOXTYPEID_ANY, 77 BOXTYPEID_SINT, 78 BOXTYPEID_SREAL, 79 BOXTYPEID_SPOINT, 80 BOXTYPEID_REAL_COUPLE, 81 BOXTYPEID_IF, 82 BOXTYPEID_ELSE, 83 BOXTYPEID_ELIF, 84 BOXTYPEID_FOR, 85 BOXTYPEID_NUM, 86 BOXTYPEID_STR, 87 BOXTYPEID_REPR, 88 BOXTYPEID_PRINT, 89 BOXTYPEID_COMPARE, 90 BOXTYPEID_Get, 91 BOXTYPEID_Getter, 92 BOXTYPEID_Set, 93 BOXTYPEID_ARRAY, 94 BOXTYPEID_Array, 95 BOXTYPEID_MAX_VAL 96 } BoxTypeId; 97 98 /** 99 * @brief A type in the Box type system. This is currently implemented as a 100 * pointer to an opaque structure. 101 */ 102 typedef struct BoxType_struct BoxType; 103 104 /** 105 * The BoxChar type, the smallest integer in terms of size. 106 */ 107 typedef unsigned char BoxChar; 108 109 /** 110 * The integer type of Box numbers and the integer type we will try 111 * to use whenever possible: this corresponds to the C long int. 112 */ 113 typedef long BoxInt; 114 115 /** 116 * The unsigned integer type that we will try to use whenever possible. 117 * Same size of Int. 118 */ 119 typedef unsigned long BoxUInt; 120 121 /** 122 * Fundamental boolean type used in the Box compiler API. 123 */ 124 typedef int BoxBool; 125 126 enum { 127 BOXBOOL_FALSE=0, 128 BOXBOOL_TRUE=1 129 }; 130 131 /** 132 * Here is the definition of the floating point type used by Box. 133 */ 134 typedef double BoxReal; 135 136 /** 137 * Conversion string --> Int 138 */ 139 # define BoxInt_Of_Str strtol 140 141 /** 142 * Conversion string --> Real 143 */ 144 # define BoxReal_Of_Str strtod 145 146 # define BOXREAL_MAX DBL_MAX 147 # define BOXREAL_MIN (-DBL_MAX) 148 149 /** 150 * The 2D point type. 151 */ 152 typedef struct BoxPoint_struct { 153 BoxReal x, y; 154 } BoxPoint; 155 156 /** 157 * We need more than just a pointer when referring to Box objects. 158 */ 159 typedef struct BoxPtr_struct { 160 void *ptr, /**< Pointer to the data inside this block */ 161 *block; /**< Pointer to the allocated memory block */ 162 } BoxPtr; 163 164 /** Reset an extended BoxPtr pointer to NULL (point to nothing) */ 165 # define BoxPtr_Init(p) \ 166 do {(p)->block = (p)->ptr = NULL;} while(0) 167 168 # define BoxPtr_Nullify BoxPtr_Init 169 170 /** Detach a pointer so that it does not reference its source */ 171 # define BoxPtr_Detach(p) \ 172 do {(p)->block = NULL;} while(0) 173 174 /** Whether a BoxPtr pointer is NULL */ 175 # define BoxPtr_Is_Null(p) ((p)->ptr == NULL) 176 177 /** Whether a BoxPtr pointer is detached (not bound to a memory block) */ 178 # define BoxPtr_Is_Detached(p) ((p)->block == NULL) 179 180 /** Get the target pointer associated to the given BoxPtr extended pointer. */ 181 # define BoxPtr_Get_Target(p) ((p)->ptr) 182 183 /** Get the block of the given BoxPtr extended pointer. */ 184 # define BoxPtr_Get_Block(p) ((p)->block) 185 186 /** 187 * This macro expands to nothing. It is used in function prototypes to indicate 188 * that the declared function steals a reference to the passed object. This 189 * macro has hence a purely aesthetical/declarative purpose. 190 */ 191 # define BOXIN 192 193 /** 194 * This macro expands to nothing. It is used in function prototypes to indicate 195 * that the declared function provides a newly created or existing object. This 196 * macro has hence a purely aesthetical/declarative purpose. 197 */ 198 # define BOXOUT 199 200 /** Type representing C pointers from Box */ 201 typedef void *BoxCPtr; 202 203 /** 204 * A subtype is simply a structure containing two pointers: one points 205 * to the parent, one to the child. 206 */ 207 typedef struct { 208 BoxPtr child, parent; 209 } BoxSubtype; 210 211 # define BoxSubtype_Get_Parent_Target(subtype_ptr) \ 212 ((subtype_ptr)->parent.ptr) 213 214 # define BoxSubtype_Get_Child_Target(subtype_ptr) \ 215 ((subtype_ptr)->child.ptr) 216 217 # define SUBTYPE_PARENT_PTR(subtype_ptr, parent_type) \ 218 ((parent_type *) (subtype_ptr)->parent.ptr) 219 220 # define SUBTYPE_CHILD_PTR(subtype_ptr, child_type) \ 221 (( child_type *) (subtype_ptr)->child.ptr) 222 223 224 /** 225 * Union of all the intrinsic Box types. 226 */ 227 typedef union { 228 BoxChar box_char; 229 BoxInt box_int; 230 BoxReal box_real; 231 BoxPoint box_point; 232 BoxPtr box_obj; 233 } BoxImmValue; 234 235 /* Strings containing the printf formats for the various types */ 236 # define BoxChar_Fmt "%c" 237 # define BoxUInt_Fmt "%lu" 238 # define BoxInt_Fmt "%ld" 239 # define BoxReal_Fmt "%g" 240 # define BoxPoint_Fmt "(%g, %g)" 241 242 /** 243 * @brief Type used from functions to communicate whether an operation 244 * succeeded or failed. 245 */ 246 typedef enum { 247 BOXTASK_OK = 0, /**< Function succeeded */ 248 BOXTASK_FAILURE = 1, /**< Function failed: caller needs to report error */ 249 BOXTASK_ERROR = 2 /**< Function failed: error already reported */ 250 } BoxTask; 251 252 /*****************************************************************************/ 253 /* Obsolete stuff below. */ 254 255 typedef struct { 256 BoxInt length; 257 char *text; 258 } BoxName; 259 260 # define BOXNAME(str) ((BoxName) {sizeof(str)-1, str}) 261 262 typedef BoxName BoxData; 263 264 /* Questa macro permette di usare una indicizzazione "circolare", secondo cui, 265 * data una lista di num_items elementi, l'indice 1 si riferisce al primo 266 * elemento, 2 al secondo, ..., num_items all'ultimo, num_items+1 al primo, 267 * num_items+2 al secondo, ... Inoltre l'indice 0 si riferisce all'ultimo 268 * elemento, -1 al pen'ultimo, ... 269 */ 270 #define BOX_CIRCULAR_INDEX(num_items, index) \ 271 ((index) > 0 ? ((index) - 1) % (num_items) \ 272 : (num_items) - 1 - ((-(index)) % (num_items))) 273 274 /* Shorthands. */ 275 # define SUInt BoxUInt_Fmt 276 # define SChar BoxChar_Fmt 277 # define SInt BoxInt_Fmt 278 # define SReal BoxReal_Fmt 279 # define SPoint BoxPoint_Fmt 280 # define CIRCULAR_INDEX BOX_CIRCULAR_INDEX 281 282 /*****************************************************************************/ 283 284 /** 285 * @brief Macro to call a function returning #BoxTask from a function returning 286 * #BoxTask. 287 */ 288 # define BOXTASK(x) \ 289 do {if (x) return BOXTASK_FAILURE;} while(0) 290 291 /** 292 * @brief This macro should be used to check - via an assert - that a function 293 * returning #BoxTask succeeded. 294 * 295 * @note This should be used with functions that are expected to succeed. 296 */ 297 # define ASSERT_TASK(x) \ 298 do {BoxTask t = (x); assert(t == BOXTASK_OK);} while(0) 299 300 typedef struct BoxCoreTypes_struct BoxCoreTypes; 301 302 /** 303 * @brief Initialize the core types of Box. 304 */ 305 BOXEXPORT BoxBool 306 BoxCoreTypes_Init(BoxCoreTypes *core_types); 307 308 /** 309 * @brief Finalize the core type of Box. 310 */ 311 BOXEXPORT void 312 BoxCoreTypes_Finish(BoxCoreTypes *core_types); 313 314 /** 315 * @brief Initialize the type system. 316 */ 317 BOXEXPORT BoxBool 318 Box_Initialize_Type_System(void); 319 320 /** 321 * @brief Initialize the type system. 322 */ 323 BOXEXPORT void 324 Box_Finalize_Type_System(void); 325 326 /** 327 * @brief Get the core type corresponding to the given type identifier. 328 * 329 * @param ct The set of core types from which the type is to be extracted. 330 * @param id The type identifier for the type to extract. 331 * @return The type corresponding to @p id, extracted from @p ct, or @c NULL 332 * if the operation failed. 333 * @note @p ct is initialized if it is not. In other words @p ct can be a 334 * pointer to a zeroed region of memory which can contain 335 * <tt>sizeof(BoxCoreTypes)</tt> bytes. 336 */ 337 BOXEXPORT BoxType * 338 BoxCoreTypes_Get_Type(BoxCoreTypes *ct, BoxTypeId id); 339 340 /** 341 * @brief Similar to BoxCoreTypes_Get_Type() but uses the global core type 342 * set. 343 * 344 * @see BoxCoreTypes_Get_Type(). 345 */ 346 BOXEXPORT BoxType * 347 Box_Get_Core_Type(BoxTypeId id); 348 349 # define BOX_FATAL_ERROR() Box_Fatal_Error(__FILE__, __LINE__) 350 351 /** 352 * @brief Install a core type (internal function). 353 * 354 * @param ct The set of core types. 355 * @param id Core type id. 356 * @param t The type to be associated to @p id. 357 * @note Aborts on failure. 358 */ 359 BOXEXPORT void 360 BoxCoreTypes_Install_Type(BoxCoreTypes *ct, BoxTypeId id, BoxType *t); 361 362 #endif /* _BOX_CORE_H */ 363