1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #ifndef _h_klib_symtab_
28 #define _h_klib_symtab_
29 
30 #ifndef _h_klib_extern_
31 #include <klib/extern.h>
32 #endif
33 
34 #ifndef _h_klib_vector_
35 #include <klib/vector.h>
36 #endif
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 
43 
44 /*--------------------------------------------------------------------------
45  * forwards
46  */
47 struct BSTree;
48 struct String;
49 struct KSymbol;
50 
51 
52 /*--------------------------------------------------------------------------
53  * KSymTable
54  *  scoped stack of BSTrees
55  */
56 typedef struct KSymTable KSymTable;
57 struct KSymTable
58 {
59     /* head of open namespace stack */
60     struct KSymbol *ns;
61 
62     /* scope stack */
63     Vector stack;
64 
65     /* intrinsic scope count */
66     uint32_t intrinsic;
67 };
68 
69 
70 /* Init
71  *  create an empty symbol table
72  *
73  *  "intrinsic" [ IN, NULL OKAY ] - initial protected scope
74  *  if not NULL, will be used as initial non-modifiable scope
75  */
76 KLIB_EXTERN rc_t CC KSymTableInit ( KSymTable *self, struct BSTree const *intrinsic );
77 
78 
79 /* Whack
80  *  must be called to clean up stack
81  */
82 #if NOT_MACRO
83 KLIB_EXTERN void CC KSymTableWhack ( KSymTable *self );
84 #endif
85 #define KSymTableWhack( self ) \
86     VectorWhack ( & ( self ) -> stack, NULL, NULL )
87 
88 
89 /* PushScope
90  *  pushes a tree onto stack
91  *
92  *  "scope" [ IN ] - current top scope
93  */
94 KLIB_EXTERN rc_t CC KSymTablePushScope ( const KSymTable *self, struct BSTree *scope );
95 
96 
97 /* PopScope
98  *  removes a tree from stack
99  *  noop if count <= self->intrinsic,
100  *  because stack bottom will be intrinsic scope
101  */
102 KLIB_EXTERN void CC KSymTablePopScope ( const KSymTable *self );
103 
104 
105 /* PushNamespace
106  *  pushes a namespace scope onto stack
107  */
108 KLIB_EXTERN rc_t CC KSymTablePushNamespace ( const KSymTable *self, struct KSymbol *ns );
109 
110 
111 /* PopNamespace
112  */
113 KLIB_EXTERN void CC KSymTablePopNamespace ( const KSymTable *self );
114 
115 
116 /* CreateNamespace
117  *  given a name, make it into a namespace,
118  *
119  *  "name" [ IN ] - name of namespace. if being created within
120  *  another namespace, it will be linked to the parent.
121  */
122 KLIB_EXTERN rc_t CC KSymTableCreateNamespace ( KSymTable *self,
123     struct KSymbol **ns, struct String const *name );
124 
125 
126 /* CreateSymbol
127  *  given a name, create an object reference
128  *
129  *  "sym" [ OUT, NULL OKAY ] - optional return parameter for
130  *  newly created symbol, which is entered into the top scope
131  *  and only returned for convenience.
132  *
133  *  "name" [ IN ] - symbol name. if being created within a
134  *  namespace, the symbol will be linked to the parent.
135  *
136  *  "id" [ IN ] - if the symbol type
137  *
138  *  "obj" [ IN, NULL OKAY ] - if the object has been created
139  *  at the point of symbol definition, it may be provided.
140  */
141 KLIB_EXTERN rc_t CC KSymTableCreateSymbol ( KSymTable *self, struct KSymbol **sym,
142     struct String const *name, uint32_t id, const void *obj );
143 #define KSymTableCreateConstSymbol( self, sym, name, id, obj ) \
144     KSymTableCreateSymbol ( self, ( struct KSymbol** ) ( sym ), name, id, obj )
145 
146 
147 /* DupSymbol
148  *  given a symbol, create a duplicate
149  *
150  *  "dup" [ OUT, NULL OKAY ] - optional return parameter for
151  *  newly created symbol, which is entered into the top scope
152  *  and only returned for convenience.
153  *
154  *  "sym" [ IN ] - symbol to copy.
155  *
156  *  "id" [ IN ] - if the symbol type
157  *
158  *  "obj" [ IN, NULL OKAY ] - if the object has been created
159  *  at the point of symbol definition, it may be provided.
160  */
161 KLIB_EXTERN rc_t CC KSymTableDupSymbol ( KSymTable *self, struct KSymbol **dup,
162     struct KSymbol const *sym, uint32_t id, const void *obj );
163 
164 
165 /* RemoveSymbol
166  *  removes symbol from table
167  *
168  *  "sym" [ IN ] - symbol to be removed
169  */
170 KLIB_EXTERN rc_t CC KSymTableRemoveSymbol ( KSymTable *self, struct KSymbol const *sym );
171 
172 
173 /* Find
174  *  finds a symbol within the scope stack
175  */
176 KLIB_EXTERN struct KSymbol* CC KSymTableFind ( const KSymTable *self,
177     struct String const *name );
178 KLIB_EXTERN struct KSymbol* CC KSymTableFindSymbol ( const KSymTable *self,
179     struct KSymbol const *sym );
180 
181 
182 /* FindIntrinsic
183  *  find an intrinsic symbol
184  *  looks in stack scopes <= self->intrinsic
185  */
186 KLIB_EXTERN struct KSymbol* CC KSymTableFindIntrinsic ( const KSymTable *self,
187     struct String const *name );
188 
189 
190 /* FindGlobal
191  *  find a symbol at global scope
192  */
193 KLIB_EXTERN struct KSymbol* CC KSymTableFindGlobal ( const KSymTable *self,
194     struct String const *name );
195 
196 
197 /* FindShallow
198  *  find a symbol in top scope
199  */
200 KLIB_EXTERN struct KSymbol* CC KSymTableFindShallow ( const KSymTable *self,
201     struct String const *name );
202 
203 
204 /* FindNext
205  *  given a symbol that was found in nearest scope
206  *  find next symbol of the same simple name in
207  *  farther scopes
208  *
209  *  "sym" [ IN ] - previously found symbol
210  *
211  *  "scope" [ IN/OUT, NULL OKAY ] - if NULL or value is 0,
212  *  the scope id for "sym" is dynamically located. otherwise,
213  *  the value on input is used for continuing a search. on
214  *  output and if not NULL, the value is set to the scope id
215  *  where the returned symbol was found, or 0 if not found.
216  */
217 KLIB_EXTERN struct KSymbol* CC KSymTableFindNext ( const KSymTable *self,
218     struct KSymbol const *sym, uint32_t *scope );
219 
220 KLIB_EXTERN void KSymTableDump ( const KSymTable *self );
221 
222 #ifdef __cplusplus
223 }
224 #endif
225 
226 #endif /* _h_klib_symtab_ */
227