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 types_priv.h
22  * @brief Private declaration for types.h
23  *
24  * Header defining what is needed by the files which implement the Box type
25  * system and the functionality around the BoxType object.
26  */
27 
28 #ifndef _BOX_TYPES_PRIV_H
29 #  define _BOX_TYPES_PRIV_H
30 
31 #  include <box/types.h>
32 #  include <box/combs.h>
33 #  include <box/core.h>
34 
35 
36 /**
37  * Maximum number of types linked to a type.
38  * This is a constant value useful when using the function MyType_Get_Refs.
39  */
40 #define BOX_MAX_NUM_REFS_IN_TYPE 4
41 
42 /**
43  * Maximum number of allocations for a type.
44  * This is a constant value useful when using the function MyType_Get_Refs.
45  */
46 #define BOX_MAX_NUM_MEMS_IN_TYPE 3
47 
48 /**
49  * @brief List node (used in structures, enums, etc.)
50  */
51 typedef struct {
52   BoxType *next, *previous;
53 } BoxTypeNode;
54 
55 /**
56  * @brief Intrinsic Box type.
57  *
58  * This is basically a piece of memory handled opaquely by C initializers,
59  * finalizers, etc. (e.g. Int, Real, Str, ...)
60  */
61 typedef struct {
62   BoxTypeId id;
63   size_t    size,
64             alignment;
65 } BoxTypePrimary;
66 
67 /**
68  * @brief Intrinsic Box type.
69  *
70  * This is basically a piece of memory handled opaquely by C initializers,
71  * finalizers, etc. (e.g. Int, Real, Str, ...)
72  */
73 typedef struct {
74   size_t  size,
75           alignment;
76 } BoxTypeIntrinsic;
77 
78 /**
79  * @brief Collection of combinations allowing combination searches.
80  *
81  * This object is used internally by the type system.
82  */
83 typedef struct BoxCombs_struct {
84   BoxTypeNode node;
85 } BoxCombs;
86 
87 /**
88  * @brief Collection of subtypes which allow fast search (hash table).
89  *
90  * This object is used internally by the type system.
91  */
92 typedef struct BoxSubtypes_struct {
93   BoxTypeNode node;
94 } BoxSubtypes;
95 
96 /**
97  * @brief Subtype node.
98  */
99 typedef struct {
100   BoxTypeNode node;
101   char        *name;
102   BoxType     *parent;
103   BoxType     *type;
104   BoxCombs    combs;
105   BoxSubtypes subtypes;
106 } BoxTypeSubtypeNode;
107 
108 /**
109  * @brief A type identifier.
110  *
111  * This is basically a node in the type tree which allows the type to be
112  * visible and used in the Box language.
113  */
114 typedef struct {
115   char         *name;
116   BoxType      *source;
117   /*BoxNamespace namespace;*/
118   BoxCombs     combs;
119   BoxSubtypes  subtypes;
120 } BoxTypeIdent;
121 
122 /**
123  * @brief A raised type.
124  *
125  * A raised type is a type which is identical to the source type it refers to,
126  * but is treated as different when matching combinations. Object whose type is
127  * raised can be un-raised, e.g. transformed to object of the original type.
128  */
129 typedef struct {
130   BoxType *source;
131 } BoxTypeRaised;
132 
133 /**
134  * @brief Structure type.
135  *
136  * Objects of this type contain a fixed number of objects of other types, which
137  * can be referred by name.
138  */
139 typedef struct {
140   BoxTypeNode node;
141   size_t      size,
142               alignment,
143               num_items;
144 } BoxTypeStructure;
145 
146 /**
147  * @brief Structure node: basically, a structure member.
148  */
149 typedef struct {
150   BoxTypeNode node;
151   char        *name;
152   size_t      offset,
153               size;
154   BoxType     *type;
155 } BoxTypeStructureNode;
156 
157 /**
158  * @brief Species type.
159  */
160 typedef struct {
161   BoxTypeNode node;
162   size_t      num_items;
163 } BoxTypeSpecies;
164 
165 /**
166  * @brief Species node.
167  */
168 typedef struct {
169   BoxTypeNode node;
170   BoxType     *type;
171 } BoxTypeSpeciesNode;
172 
173 /**
174  * @brief Combination node.
175  */
176 typedef struct {
177   BoxTypeNode node;
178   BoxType     *child;
179   BoxCombType comb_type;
180   BoxCallable *callable;
181 } BoxTypeCombNode;
182 
183 /**
184  * @brief A function type: a type for something which can be called with an
185  * input and returns an output.
186  */
187 typedef struct {
188   BoxType *child,
189           *parent;
190 } BoxTypeFunction;
191 
192 /**
193  * @brief Pointer type.
194  */
195 typedef struct {
196   BoxType *source;
197 } BoxTypePointer;
198 
199 /**
200  * @brief Any type.
201  */
202 typedef struct {
203   BoxCombs     combs;
204 } BoxTypeAny;
205 
206 struct BoxType_struct {
207   BoxTypeClass   type_class;
208 
209 #if 0
210   struct {
211     unsigned int can_self_ref : 1, /**< Can reference itself (directly or
212                                       indirectly). For garbage collection. */
213                  is_global    : 1; /**< Whether the type is global. Global
214                                       types do not need to be referenced by
215                                       their instances. */
216   }              attr;
217 #endif
218 };
219 
220 typedef struct BoxTypeBundle_struct {
221   /* The header. */
222   BoxType                header;
223 
224   /* The data part. */
225   union {
226     BoxTypeStructureNode structure_node;
227     BoxTypeSpeciesNode   species_node;
228     BoxTypeCombNode      comb_node;
229     BoxTypeSubtypeNode   subtype_node;
230     BoxTypePrimary       primary;
231     BoxTypeIntrinsic     intrinsic;
232     BoxTypeIdent         ident;
233     BoxTypeRaised        raised;
234     BoxTypeStructure     structure;
235     BoxTypeSpecies       species;
236     BoxTypeFunction      function;
237     BoxTypePointer       pointer;
238   }                      data;
239 } BoxTypeBundle;
240 
241 /**
242  * Internal function. Not meant to be called by ordinary users.
243  */
244 BoxBool Box_Register_Type_Combs(BoxCoreTypes *core_types);
245 
246 /**
247  * Generic allocation function for BoxType objects. This function allocates a
248  * type header plus a the type data, whose size and composition depend on the
249  * particular type class.
250  * This is an internal function of the type system.
251  */
252 void *BoxType_Alloc(BoxType **t, BoxTypeClass tc);
253 
254 /**
255  * Append one BoxTypeNode item to a top BoxTypeNode item. This is used
256  * internally in the implementation of structures, enums, etc. to add members.
257  * This is an internal function of the type system.
258  */
259 void BoxTypeNode_Append_Node(BoxTypeNode *node, BoxType *item);
260 
261 /**
262  * Prepend one BoxTypeNode item to a top BoxTypeNode item. This is similar
263  * to BoxTypeNode_Append_Node, but the item is inserted at the other end of
264  * the linked list.
265  */
266 void
267 BoxTypeNode_Prepend_Node(BoxTypeNode *node, BoxType *item);
268 
269 /**
270  * @brief Remove a #BoxTypeNode from a top #BoxTypeNode item.
271  *
272  * @param top_node The top node, identifying the linked list to which @p this
273  *   belongs to.
274  * @param item The item to remove from the linked list.
275  * @return The removed node. This may be destroyed or inserted into another
276  *   linked list.
277  */
278 BoxTypeNode *
279 BoxTypeNode_Remove_Node(BoxTypeNode *top_node, BoxType *item);
280 
281 /**
282  * @brief Initialise a #BoxCombs structure (list of combinations).
283  */
284 void
285 BoxCombs_Init(BoxCombs *combs);
286 
287 #endif /* _BOX_TYPES_PRIV_H */
288