1    /*******************************************************/
2    /*      "C" Language Integrated Production System      */
3    /*                                                     */
4    /*             CLIPS Version 6.30  02/03/15            */
5    /*                                                     */
6    /*                 SYMBOL HEADER FILE                  */
7    /*******************************************************/
8 
9 /*************************************************************/
10 /* Purpose: Manages the atomic data value hash tables for    */
11 /*   storing symbols, integers, floats, and bit maps.        */
12 /*   Contains routines for adding entries, examining the     */
13 /*   hash tables, and performing garbage collection to       */
14 /*   remove entries no longer in use.                        */
15 /*                                                           */
16 /* Principal Programmer(s):                                  */
17 /*      Gary D. Riley                                        */
18 /*                                                           */
19 /* Contributing Programmer(s):                               */
20 /*                                                           */
21 /* Revision History:                                         */
22 /*                                                           */
23 /*      6.23: Correction for FalseSymbol/TrueSymbol. DR0859  */
24 /*                                                           */
25 /*      6.24: CLIPS crashing on AMD64 processor in the       */
26 /*            function used to generate a hash value for     */
27 /*            integers. DR0871                               */
28 /*                                                           */
29 /*            Support for run-time programs directly passing */
30 /*            the hash tables for initialization.            */
31 /*                                                           */
32 /*            Corrected code generating compilation          */
33 /*            warnings.                                      */
34 /*                                                           */
35 /*      6.30: Changed integer type/precision.                */
36 /*                                                           */
37 /*            Removed conditional code for unsupported       */
38 /*            compilers/operating systems (IBM_MCW,          */
39 /*            MAC_MCW, and IBM_TBC).                         */
40 /*                                                           */
41 /*            Support for hashing EXTERNAL_ADDRESS data      */
42 /*            type.                                          */
43 /*                                                           */
44 /*            Support for long long integers.                */
45 /*                                                           */
46 /*            Changed garbage collection algorithm.          */
47 /*                                                           */
48 /*            Used genstrcpy instead of strcpy.              */
49 /*                                                           */
50 /*            Added support for external address hash table  */
51 /*            and subtyping.                                 */
52 /*                                                           */
53 /*            Added const qualifiers to remove C++           */
54 /*            deprecation warnings.                          */
55 /*                                                           */
56 /*            Converted API macros to function calls.        */
57 /*                                                           */
58 /*            Added ValueToPointer and EnvValueToPointer     */
59 /*            macros.                                        */
60 /*                                                           */
61 /*************************************************************/
62 
63 #ifndef _H_symbol
64 #define _H_symbol
65 
66 #ifdef LOCALE
67 #undef LOCALE
68 #endif
69 
70 #ifdef _SYMBOL_SOURCE_
71 #define LOCALE
72 #else
73 #define LOCALE extern
74 #endif
75 
76 #include <stdlib.h>
77 
78 #ifndef _H_multifld
79 #include "multifld.h"
80 #endif
81 
82 #ifndef SYMBOL_HASH_SIZE
83 #define SYMBOL_HASH_SIZE       63559L
84 #endif
85 
86 #ifndef FLOAT_HASH_SIZE
87 #define FLOAT_HASH_SIZE         8191
88 #endif
89 
90 #ifndef INTEGER_HASH_SIZE
91 #define INTEGER_HASH_SIZE       8191
92 #endif
93 
94 #ifndef BITMAP_HASH_SIZE
95 #define BITMAP_HASH_SIZE        8191
96 #endif
97 
98 #ifndef EXTERNAL_ADDRESS_HASH_SIZE
99 #define EXTERNAL_ADDRESS_HASH_SIZE        8191
100 #endif
101 
102 /************************************************************/
103 /* symbolHashNode STRUCTURE:                                */
104 /************************************************************/
105 struct symbolHashNode
106   {
107    struct symbolHashNode *next;
108    long count;
109    unsigned int permanent : 1;
110    unsigned int markedEphemeral : 1;
111    unsigned int neededSymbol : 1;
112    unsigned int bucket : 29;
113    const char *contents;
114   };
115 
116 /************************************************************/
117 /* floatHashNode STRUCTURE:                                  */
118 /************************************************************/
119 struct floatHashNode
120   {
121    struct floatHashNode *next;
122    long count;
123    unsigned int permanent : 1;
124    unsigned int markedEphemeral : 1;
125    unsigned int neededFloat : 1;
126    unsigned int bucket : 29;
127    double contents;
128   };
129 
130 /************************************************************/
131 /* integerHashNode STRUCTURE:                               */
132 /************************************************************/
133 struct integerHashNode
134   {
135    struct integerHashNode *next;
136    long count;
137    unsigned int permanent : 1;
138    unsigned int markedEphemeral : 1;
139    unsigned int neededInteger : 1;
140    unsigned int bucket : 29;
141    long long contents;
142   };
143 
144 /************************************************************/
145 /* bitMapHashNode STRUCTURE:                                */
146 /************************************************************/
147 struct bitMapHashNode
148   {
149    struct bitMapHashNode *next;
150    long count;
151    unsigned int permanent : 1;
152    unsigned int markedEphemeral : 1;
153    unsigned int neededBitMap : 1;
154    unsigned int bucket : 29;
155    const char *contents;
156    unsigned short size;
157   };
158 
159 /************************************************************/
160 /* externalAddressHashNode STRUCTURE:                       */
161 /************************************************************/
162 struct externalAddressHashNode
163   {
164    struct externalAddressHashNode *next;
165    long count;
166    unsigned int permanent : 1;
167    unsigned int markedEphemeral : 1;
168    unsigned int neededPointer : 1;
169    unsigned int bucket : 29;
170    void *externalAddress;
171    unsigned short type;
172   };
173 
174 /************************************************************/
175 /* genericHashNode STRUCTURE:                               */
176 /************************************************************/
177 struct genericHashNode
178   {
179    struct genericHashNode *next;
180    long count;
181    unsigned int permanent : 1;
182    unsigned int markedEphemeral : 1;
183    unsigned int needed : 1;
184    unsigned int bucket : 29;
185   };
186 
187 typedef struct symbolHashNode SYMBOL_HN;
188 typedef struct floatHashNode FLOAT_HN;
189 typedef struct integerHashNode INTEGER_HN;
190 typedef struct bitMapHashNode BITMAP_HN;
191 typedef struct externalAddressHashNode EXTERNAL_ADDRESS_HN;
192 typedef struct genericHashNode GENERIC_HN;
193 
194 /**********************************************************/
195 /* EPHEMERON STRUCTURE: Data structure used to keep track */
196 /*   of ephemeral symbols, floats, and integers.          */
197 /*                                                        */
198 /*   associatedValue: Contains a pointer to the storage   */
199 /*   structure for the symbol, float, or integer which is */
200 /*   ephemeral.                                           */
201 /*                                                        */
202 /*   next: Contains a pointer to the next ephemeral item  */
203 /*   in a list of ephemeral items.                        */
204 /**********************************************************/
205 struct ephemeron
206   {
207    GENERIC_HN *associatedValue;
208    struct ephemeron *next;
209   };
210 
211 /************************************************************/
212 /* symbolMatch STRUCTURE:                               */
213 /************************************************************/
214 struct symbolMatch
215   {
216    struct symbolHashNode *match;
217    struct symbolMatch *next;
218   };
219 
220 #define ValueToString(target) (((struct symbolHashNode *) (target))->contents)
221 #define ValueToDouble(target) (((struct floatHashNode *) (target))->contents)
222 #define ValueToLong(target) (((struct integerHashNode *) (target))->contents)
223 #define ValueToInteger(target) ((int) (((struct integerHashNode *) (target))->contents))
224 #define ValueToBitMap(target) ((void *) ((struct bitMapHashNode *) (target))->contents)
225 #define ValueToPointer(target) ((void *) target)
226 #define ValueToExternalAddress(target) ((void *) ((struct externalAddressHashNode *) (target))->externalAddress)
227 
228 #define EnvValueToString(theEnv,target) (((struct symbolHashNode *) (target))->contents)
229 #define EnvValueToDouble(theEnv,target) (((struct floatHashNode *) (target))->contents)
230 #define EnvValueToLong(theEnv,target) (((struct integerHashNode *) (target))->contents)
231 #define EnvValueToInteger(theEnv,target) ((int) (((struct integerHashNode *) (target))->contents))
232 #define EnvValueToBitMap(theEnv,target) ((void *) ((struct bitMapHashNode *) (target))->contents)
233 #define EnvValueToPointer(theEnv,target) ((void *) target)
234 #define EnvValueToExternalAddress(theEnv,target) ((void *) ((struct externalAddressHashNode *) (target))->externalAddress)
235 
236 #define IncrementSymbolCount(theValue) (((SYMBOL_HN *) theValue)->count++)
237 #define IncrementFloatCount(theValue) (((FLOAT_HN *) theValue)->count++)
238 #define IncrementIntegerCount(theValue) (((INTEGER_HN *) theValue)->count++)
239 #define IncrementBitMapCount(theValue) (((BITMAP_HN *) theValue)->count++)
240 #define IncrementExternalAddressCount(theValue) (((EXTERNAL_ADDRESS_HN *) theValue)->count++)
241 
242 /*==================*/
243 /* ENVIRONMENT DATA */
244 /*==================*/
245 
246 #define SYMBOL_DATA 49
247 
248 struct symbolData
249   {
250    void *TrueSymbolHN;
251    void *FalseSymbolHN;
252    void *PositiveInfinity;
253    void *NegativeInfinity;
254    void *Zero;
255    SYMBOL_HN **SymbolTable;
256    FLOAT_HN **FloatTable;
257    INTEGER_HN **IntegerTable;
258    BITMAP_HN **BitMapTable;
259    EXTERNAL_ADDRESS_HN **ExternalAddressTable;
260 #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE || BLOAD_INSTANCES || BSAVE_INSTANCES
261    long NumberOfSymbols;
262    long NumberOfFloats;
263    long NumberOfIntegers;
264    long NumberOfBitMaps;
265    long NumberOfExternalAddresses;
266    SYMBOL_HN **SymbolArray;
267    struct floatHashNode **FloatArray;
268    INTEGER_HN **IntegerArray;
269    BITMAP_HN **BitMapArray;
270    EXTERNAL_ADDRESS_HN **ExternalAddressArray;
271 #endif
272   };
273 
274 #define SymbolData(theEnv) ((struct symbolData *) GetEnvironmentData(theEnv,SYMBOL_DATA))
275 
276    LOCALE void                           InitializeAtomTables(void *,struct symbolHashNode **,struct floatHashNode **,
277                                                               struct integerHashNode **,struct bitMapHashNode **,
278                                                               struct externalAddressHashNode **);
279    LOCALE void                          *EnvAddSymbol(void *,const char *);
280    LOCALE SYMBOL_HN                     *FindSymbolHN(void *,const char *);
281    LOCALE void                          *EnvAddDouble(void *,double);
282    LOCALE void                          *EnvAddLong(void *,long long);
283    LOCALE void                          *EnvAddBitMap(void *,void *,unsigned);
284    LOCALE void                          *EnvAddExternalAddress(void *,void *,unsigned);
285    LOCALE INTEGER_HN                    *FindLongHN(void *,long long);
286    LOCALE unsigned long                  HashSymbol(const char *,unsigned long);
287    LOCALE unsigned long                  HashFloat(double,unsigned long);
288    LOCALE unsigned long                  HashInteger(long long,unsigned long);
289    LOCALE unsigned long                  HashBitMap(const char *,unsigned long,unsigned);
290    LOCALE unsigned long                  HashExternalAddress(void *,unsigned long);
291    LOCALE void                           DecrementSymbolCount(void *,struct symbolHashNode *);
292    LOCALE void                           DecrementFloatCount(void *,struct floatHashNode *);
293    LOCALE void                           DecrementIntegerCount(void *,struct integerHashNode *);
294    LOCALE void                           DecrementBitMapCount(void *,struct bitMapHashNode *);
295    LOCALE void                           DecrementExternalAddressCount(void *,struct externalAddressHashNode *);
296    LOCALE void                           RemoveEphemeralAtoms(void *);
297    LOCALE struct symbolHashNode        **GetSymbolTable(void *);
298    LOCALE void                           SetSymbolTable(void *,struct symbolHashNode **);
299    LOCALE struct floatHashNode          **GetFloatTable(void *);
300    LOCALE void                           SetFloatTable(void *,struct floatHashNode **);
301    LOCALE struct integerHashNode       **GetIntegerTable(void *);
302    LOCALE void                           SetIntegerTable(void *,struct integerHashNode **);
303    LOCALE struct bitMapHashNode        **GetBitMapTable(void *);
304    LOCALE void                           SetBitMapTable(void *,struct bitMapHashNode **);
305    LOCALE struct externalAddressHashNode
306                                        **GetExternalAddressTable(void *);
307    LOCALE void                           SetExternalAddressTable(void *,struct externalAddressHashNode **);
308    LOCALE void                           RefreshSpecialSymbols(void *);
309    LOCALE struct symbolMatch            *FindSymbolMatches(void *,const char *,unsigned *,size_t *);
310    LOCALE void                           ReturnSymbolMatches(void *,struct symbolMatch *);
311    LOCALE SYMBOL_HN                     *GetNextSymbolMatch(void *,const char *,size_t,SYMBOL_HN *,int,size_t *);
312    LOCALE void                           ClearBitString(void *,unsigned);
313    LOCALE void                           SetAtomicValueIndices(void *,int);
314    LOCALE void                           RestoreAtomicValueBuckets(void *);
315    LOCALE void                          *EnvFalseSymbol(void *);
316    LOCALE void                          *EnvTrueSymbol(void *);
317    LOCALE void                           EphemerateValue(void *,int,void *);
318    LOCALE void                           EphemerateMultifield(void *,struct multifield *);
319 
320 #if ALLOW_ENVIRONMENT_GLOBALS
321 
322    LOCALE void                          *AddDouble(double);
323    LOCALE void                          *AddLong(long long);
324    LOCALE void                          *AddSymbol(const char *);
325    LOCALE void                          *FalseSymbol(void);
326    LOCALE void                          *TrueSymbol(void);
327 
328 #endif /* ALLOW_ENVIRONMENT_GLOBALS */
329 
330 #endif /* _H_symbol */
331 
332 
333 
334