Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/exception.hfa

    r5727c23 re68d092  
    1010// Created On       : Thu Apr  7 10:25:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Aug  4 16:22:00 2020
    13 // Update Count     : 3
     12// Last Modified On : Thu Apr  7 10:25:00 2020
     13// Update Count     : 0
    1414//
    1515
     
    1818// -----------------------------------------------------------------------------------------------
    1919
    20 // TRIVIAL_EXCEPTION_DECLARATION(exception_name);
     20// All internals helper macros begin with an underscore.
     21#define _CLOSE(...) __VA_ARGS__ }
     22#define _GLUE2(left, right) left##right
     23#define _GLUE3(left, middle, right) left##middle##right
     24#define _EXC_DISPATCH(to, ...) to(__VA_ARGS__,__cfaehm_base_exception_t,)
     25
     26// FWD_TRIVIAL_EXCEPTION(exception_name);
    2127// Declare a trivial exception, one that adds no fields or features.
    2228// This will make the exception visible and may go in a .hfa or .cfa file.
    23 #define TRIVIAL_EXCEPTION_DECLARATION(...) \
    24         _EXC_DISPATCH(_TRIVIAL_EXCEPTION_DECLARATION, __VA_ARGS__)
    25 
    26 // TRIVIAL_EXCEPTION_INSTANCE(exception_name);
     29#define FWD_TRIVIAL_EXCEPTION(...) _EXC_DISPATCH(_FWD_TRIVIAL_EXCEPTION, __VA_ARGS__)
     30// INST_TRIVIAL_EXCEPTION(exception_name);
    2731// Create the trival exception. This must be used exactly once and should be used in a .cfa file,
    2832// as it creates the unique instance of the virtual table.
    29 #define TRIVIAL_EXCEPTION_INSTANCE(...) _EXC_DISPATCH(_TRIVIAL_EXCEPTION_INSTANCE, __VA_ARGS__)
    30 
     33#define INST_TRIVIAL_EXCEPTION(...) _EXC_DISPATCH(_INST_TRIVIAL_EXCEPTION, __VA_ARGS__)
    3134// TRIVIAL_EXCEPTION(exception_name[, parent_name]);
    3235// Does both of the above, a short hand if the exception is only used in one .cfa file.
     
    3437// base exception. This feature may be removed or changed.
    3538#define TRIVIAL_EXCEPTION(...) \
    36         _EXC_DISPATCH(_TRIVIAL_EXCEPTION_DECLARATION, __VA_ARGS__); \
    37         _EXC_DISPATCH(_TRIVIAL_EXCEPTION_INSTANCE, __VA_ARGS__)
    38 
    39 // FORALL_TRIVIAL_EXCEPTION(exception_name, (assertions...), (parameters...));
    40 // Forward declare a polymorphic but otherwise trivial exception type. You must provide the entire
    41 // assertion list (exactly what would go in the forall clause) and parameters list (only the
    42 // parameter names from the assertion list, same order and comma seperated). This should be
    43 // visible where ever use the exception. This just generates the polymorphic framework, see
    44 // POLY_VTABLE_DECLARATION to allow instantiations.
    45 #define FORALL_TRIVIAL_EXCEPTION(exception_name, assertions, parameters) \
    46         _FORALL_TRIVIAL_EXCEPTION(exception_name, __cfaehm_base_exception_t, assertions, parameters, )
    47 
    48 // FORALL_TRIVIAL_INSTANCE(exception_name, (assertions...), (parameters...))
    49 // Create the forall trivial exception. The assertion list and parameters must match.
    50 // There must be exactly one use of this in a program for each exception type. This just
    51 // generates the polymorphic framework, see POLY_VTABLE_INSTANCE to allow instantiations.
    52 #define FORALL_TRIVIAL_INSTANCE(exception_name, assertions, parameters) \
    53         _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters)
    54 
    55 // DATA_EXCEPTION(exception_name)(fields...);
    56 // Forward declare an exception that adds fields but no features. The added fields go in the
    57 // second argument list. The virtual table instance must be provided later (see VTABLE_INSTANCE).
    58 #define DATA_EXCEPTION(...) _EXC_DISPATCH(_DATA_EXCEPTION, __VA_ARGS__)
    59 
    60 // FORALL_DATA_EXCEPTION(exception_name, (assertions...), (parameters...))(fields...);
    61 // Define a polymorphic exception that adds fields but no additional features. The assertion list
    62 // and matching parameters must match. Then you can give the list of fields. This should be
    63 // visible where ever you use the exception. This just generates the polymorphic framework, see
    64 // POLY_VTABLE_DECLARATION to allow instantiations.
    65 #define FORALL_DATA_EXCEPTION(exception_name, assertions, parameters) \
    66         _FORALL_DATA_EXCEPTION(exception_name, __cfaehm_base_exception_t, assertions, parameters, )
    67 
    68 // FORALL_DATA_INSTANCE(exception_name, (assertions...), (parameters...))
    69 // Create a polymorphic data exception. The assertion list and parameters must match. This should
    70 // appear once in each program. This just generates the polymorphic framework, see
    71 // POLY_VTABLE_INSTANCE to allow instantiations.
    72 #define FORALL_DATA_INSTANCE(exception_name, assertions, parameters) \
    73         _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters)
    74 
    75 // VTABLE_DECLARATION(exception_name)([new_features...]);
    76 // Declare a virtual table type for an exception with exception_name. You may also add features
    77 // (fields on the virtual table) by including them in the second list.
    78 #define VTABLE_DECLARATION(...) _EXC_DISPATCH(_VTABLE_DECLARATION, __VA_ARGS__)
    79 
    80 // VTABLE_INSTANCE(exception_name)(msg [, others...]);
    81 // Create the instance of the virtual table. There must be exactly one instance of a virtual table
    82 // for each exception type. This fills in most of the fields of the virtual table (uses ?=? and
    83 // ^?{}) but you must provide the message function and any other fields added in the declaration.
    84 #define VTABLE_INSTANCE(...) _EXC_DISPATCH(_VTABLE_INSTANCE, __VA_ARGS__)
    85 
    86 // FORALL_VTABLE_DECLARATION(exception_name, (assertions...), (parameters...))([new_features...]);
    87 // Declare a polymorphic virtual table type for an exception with exception_name, the given
    88 // assertions and parameters. You may also add features (fields on the virtual table). This just
    89 // generates the polymorphic framework, see POLY_VTABLE_DECLARATION to allow instantiations.
    90 #define FORALL_VTABLE_DECLARATION(exception_name, assertions, parameters) \
    91         _FORALL_VTABLE_DECLARATION(exception_name, __cfaehm_base_exception_t, assertions, parameters, )
    92 
    93 // POLY_VTABLE_DECLARATION(exception_name, types...);
    94 // Declares that an instantiation for this exception exists for the given types. This should be
    95 // visible anywhere you use the instantiation of the exception is used.
    96 #define POLY_VTABLE_DECLARATION(exception_name, ...) \
    97         void mark_exception(exception_name(__VA_ARGS__) *); \
    98         extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name)
    99 
    100 // POLY_VTABLE_INSTANCE(exception_name, types...)(msg [, others...]);
    101 // Creates an instantiation for the given exception for the given types. This should occur only
    102 // once in the entire program. You must fill in all features, message and any others given in the
    103 // initial declaration.
    104 #define POLY_VTABLE_INSTANCE(exception_name, ...) \
    105         _POLY_VTABLE_INSTANCE(exception_name, __cfaehm_base_exception_t, __VA_ARGS__)
    106 
    107 // VTABLE_TYPE(exception_name) | VTABLE_NAME(exception_name)
    108 // Get the name of the vtable type or the name of the vtable instance for an exception type.
    109 #define VTABLE_TYPE(exception_name) struct _GLUE2(exception_name,_vtable)
    110 #define VTABLE_NAME(exception_name) _GLUE3(_,exception_name,_vtable_instance)
    111 
    112 // VTABLE_FIELD(exception_name);
    113 // FORALL_VTABLE_FIELD(exception_name, (parameters-or-types));
    114 // The declaration of the virtual table field. Should be the first declaration in a virtual type.
    115 #define VTABLE_FIELD(exception_name) VTABLE_TYPE(exception_name) const * virtual_table
    116 #define FORALL_VTABLE_FIELD(exception_name, parameters) \
    117         VTABLE_TYPE(exception_name) parameters const * virtual_table
    118 
    119 // VTABLE_INIT(object_reference, exception_name);
    120 // Sets a virtual table field on an object to the virtual table instance for the type.
    121 #define VTABLE_INIT(this, exception_name) (this).virtual_table = &VTABLE_NAME(exception_name)
    122 
    123 // VTABLE_ASSERTION(exception_name, (parameters...))
    124 // The assertion that there is an instantiation of the vtable for the exception and types.
    125 #define VTABLE_ASSERTION(exception_name, parameters) \
    126         { VTABLE_TYPE(exception_name) parameters VTABLE_NAME(exception_name); }
    127 
    128 // All internal helper macros begin with an underscore.
    129 #define _CLOSE(...) __VA_ARGS__ }
    130 #define _GLUE2(left, right) left##right
    131 #define _GLUE3(left, middle, right) left##middle##right
    132 #define _EXC_DISPATCH(to, ...) to(__VA_ARGS__,__cfaehm_base_exception_t,)
    133 #define _UNPACK(...) __VA_ARGS__
    134 
    135 #define _TRIVIAL_EXCEPTION_DECLARATION(exception_name, parent_name, ...) \
     39        _EXC_DISPATCH(_FWD_TRIVIAL_EXCEPTION, __VA_ARGS__); \
     40        _EXC_DISPATCH(_INST_TRIVIAL_EXCEPTION, __VA_ARGS__)
     41#define _FWD_TRIVIAL_EXCEPTION(exception_name, parent_name, ...) \
    13642        _VTABLE_DECLARATION(exception_name, parent_name)(); \
    13743        struct exception_name { \
     
    14046        void ?{}(exception_name & this); \
    14147        const char * _GLUE2(exception_name,_msg)(exception_name * this)
    142 
    143 #define _TRIVIAL_EXCEPTION_INSTANCE(exception_name, parent_name, ...) \
     48#define _INST_TRIVIAL_EXCEPTION(exception_name, parent_name, ...) \
    14449        void ?{}(exception_name & this) { \
    14550                VTABLE_INIT(this, exception_name); \
     
    15055        _VTABLE_INSTANCE(exception_name, parent_name,)(_GLUE2(exception_name,_msg))
    15156
    152 #define _FORALL_TRIVIAL_EXCEPTION(exception_name, parent_name, assertions, \
    153                 parameters, parent_parameters) \
    154         _FORALL_VTABLE_DECLARATION(exception_name, parent_name, assertions, \
    155                 parameters, parent_parameters)(); \
    156         forall assertions struct exception_name { \
    157                 FORALL_VTABLE_FIELD(exception_name, parameters); \
    158         }; \
    159         _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters)
    160 
    161 #define _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) \
    162         forall(_UNPACK assertions | VTABLE_ASSERTION(exception_name, parameters) ) \
    163         void ?{}(exception_name parameters & this)
    164 
    165 #define _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters) \
    166         _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) { \
    167                 VTABLE_INIT(this, exception_name); \
    168         }
    169 
     57// DATA_EXCEPTION(exception_name)(fields...);
     58// Forward declare an exception that adds fields but no features. The added fields go in the
     59// second argument list. The virtual table instance must be provided later (see VTABLE_INSTANCE).
     60#define DATA_EXCEPTION(...) _EXC_DISPATCH(_DATA_EXCEPTION, __VA_ARGS__)
    17061#define _DATA_EXCEPTION(exception_name, parent_name, ...) \
    17162        _VTABLE_DECLARATION(exception_name, parent_name)(); \
    172         struct exception_name { \
    173                 VTABLE_FIELD(exception_name); \
    174                 _CLOSE
     63        struct exception_name { VTABLE_FIELD(exception_name); _CLOSE
    17564
    176 #define _FORALL_DATA_EXCEPTION(exception_name, parent_name, \
    177                 assertions, parameters, parent_parameters) \
    178         _FORALL_VTABLE_DECLARATION(exception_name, parent_name, \
    179                 assertions, parameters, parent_parameters)(); \
    180         _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters); \
    181         forall assertions struct exception_name { \
    182                 FORALL_VTABLE_FIELD(exception_name, parameters); \
    183                 _CLOSE
    184 
     65// VTABLE_DECLARATION(exception_name)([new_features...]);
     66// Declare a virtual table type for an exception with exception_name. You may also add features
     67// (fields on the virtual table) by including them in the second list.
     68#define VTABLE_DECLARATION(...) _EXC_DISPATCH(_VTABLE_DECLARATION, __VA_ARGS__)
    18569#define _VTABLE_DECLARATION(exception_name, parent_name, ...) \
    18670        struct exception_name; \
    187         void mark_exception(exception_name *); \
    18871        VTABLE_TYPE(exception_name); \
    18972        extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \
     
    19679                _CLOSE
    19780
     81// VTABLE_INSTANCE(exception_name)(msg [, others...]);
     82// Create the instance of the virtual table. There must be exactly one instance of a virtual table
     83// for each exception type. This fills in most of the fields of the virtual table (uses ?=? and
     84// ^?{}) but you must provide the message function and any other fields added in the declaration.
     85#define VTABLE_INSTANCE(...) _EXC_DISPATCH(_VTABLE_INSTANCE, __VA_ARGS__)
    19886#define _VTABLE_INSTANCE(exception_name, parent_name, ...) \
    199         void mark_exception(exception_name *) {} \
    20087        void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \
    20188                *this = *other; \
     
    20693                _CLOSE
    20794
    208 #define _FORALL_VTABLE_DECLARATION(exception_name, parent_name, assertions, \
    209                 parameters, parent_parameters) \
    210         forall assertions struct exception_name; \
    211         forall assertions VTABLE_TYPE(exception_name) { \
    212                 VTABLE_TYPE(parent_name) parent_parameters const * parent; \
    213                 size_t size; \
    214                 void (*copy)(exception_name parameters * this, exception_name parameters * other); \
    215                 void (*free)(exception_name parameters & this); \
    216                 const char * (*msg)(exception_name parameters * this); \
    217                 _CLOSE
     95// VTABLE_TYPE(exception_name) | VTABLE_NAME(exception_name)
     96// Get the name of the vtable type or the name of the vtable instance for an exception type.
     97#define VTABLE_TYPE(exception_name) struct _GLUE2(exception_name,_vtable)
     98#define VTABLE_NAME(exception_name) _GLUE3(_,exception_name,_vtable_instance)
    21899
    219 #define _POLY_VTABLE_INSTANCE(exception_name, parent_name, ...) \
    220         void mark_exception(exception_name(__VA_ARGS__) *) {} \
    221         void _GLUE2(exception_name,_copy)( \
    222                         exception_name(__VA_ARGS__) * this, exception_name(__VA_ARGS__) * other) { \
    223                 *this = *other; \
    224         } \
    225         VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name) @= { \
    226                 &VTABLE_NAME(parent_name), sizeof(exception_name(__VA_ARGS__)), \
    227                 _GLUE2(exception_name,_copy), ^?{}, \
    228                 _CLOSE
     100// VTABLE_FIELD(exception_name);
     101// The declaration of the virtual table field. Should be the first declaration in a virtual type.
     102#define VTABLE_FIELD(exception_name) VTABLE_TYPE(exception_name) const * virtual_table
     103
     104// VTABLE_INIT(object_reference, exception_name);
     105// Sets a virtual table field on an object to the virtual table instance for the type.
     106#define VTABLE_INIT(this, exception_name) (this).virtual_table = &VTABLE_NAME(exception_name)
Note: See TracChangeset for help on using the changeset viewer.