]> git.sur5r.net Git - cc65/blob - src/ca65/symbol.c
More work on .sizeof
[cc65] / src / ca65 / symbol.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 symbol.c                                  */
4 /*                                                                           */
5 /*                   Parse a symbol name and search for it                   */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
10 /*               Römerstraße 52                                              */
11 /*               D-70794 Filderstadt                                         */
12 /* EMail:        uz@cc65.org                                                 */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <string.h>
37
38 /* common */
39 #include "strbuf.h"
40
41 /* ca65 */
42 #include "error.h"
43 #include "nexttok.h"
44 #include "scanner.h"
45 #include "symbol.h"
46 #include "symtab.h"
47
48
49
50 /*****************************************************************************/
51 /*                                   Code                                    */
52 /*****************************************************************************/
53
54
55
56 SymTable* ParseScopedIdent (char* Name, StrBuf* FullName)
57 /* Parse a (possibly scoped) identifer. Name must point to a buffer big enough
58  * to hold such an identifier. The scope of the name must exist and is returned
59  * as function result, while the last part (the identifier) which may be either
60  * a symbol or a scope depending on the context is returned in Name. FullName
61  * is a string buffer that is used to store the full name of the identifier
62  * including the scope. It is used internally and may be used by the caller
63  * for error messages or similar.
64  */
65 {
66     /* Get the starting table */
67     SymTable* Scope;
68     if (Tok == TOK_NAMESPACE) {
69
70         /* Start from the root scope */
71         Scope = RootScope;
72
73     } else if (Tok == TOK_IDENT) {
74
75         /* Remember the name and skip it */
76         SB_AppendStr (FullName, strcpy (Name, SVal));
77         NextTok ();
78
79         /* If no namespace symbol follows, we're already done */
80         if (Tok != TOK_NAMESPACE) {
81             SB_Terminate (FullName);
82             return CurrentScope;
83         }
84
85         /* The scope must exist, so search for it starting with the current
86          * scope.
87          */
88         Scope = SymFindAnyScope (CurrentScope, Name);
89         if (Scope == 0) {
90             /* Scope not found */
91             SB_Terminate (FullName);
92             Error ("No such scope: `%s'", SB_GetConstBuf (FullName));
93             return 0;
94         }
95
96     } else {
97
98         /* Invalid token */
99         Error ("Identifier expected");
100         SB_Terminate (FullName);
101         Name[0] = '\0';
102         return 0;
103
104     }
105
106     /* Skip the namespace token that follows */
107     SB_AppendStr (FullName, "::");
108     NextTok ();
109
110     /* Resolve scopes. */
111     while (1) {
112
113         /* Next token must be an identifier. */
114         if (Tok != TOK_IDENT) {
115             Error ("Identifier expected");
116             SB_Terminate (FullName);
117             Name[0] = '\0';
118             return 0;
119         }
120
121         /* Remember and skip the identifier */
122         SB_AppendStr (FullName, strcpy (Name, SVal));
123         NextTok ();
124
125         /* If a namespace token follows, we search for another scope, otherwise
126          * the name is a symbol and we're done.
127          */
128         if (Tok != TOK_NAMESPACE) {
129             /* Symbol */
130             SB_Terminate (FullName);
131             return Scope;
132         }
133
134         /* Search for the child scope */
135         Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING);
136         if (Scope == 0) {
137             /* Scope not found */
138             SB_Terminate (FullName);
139             Error ("No such scope: `%s'", SB_GetConstBuf (FullName));
140             return 0;
141         }
142
143         /* Skip the namespace token that follows */
144         SB_AppendStr (FullName, "::");
145         NextTok ();
146     }
147 }
148
149
150
151 SymEntry* ParseScopedSymName (int AllocNew)
152 /* Parse a (possibly scoped) symbol name, search for it in the symbol table
153  * and return the symbol table entry.
154  */
155 {
156     StrBuf    FullName = AUTO_STRBUF_INITIALIZER;
157     char      Ident[sizeof (SVal)];
158
159     /* Parse the scoped symbol name */
160     SymTable* Scope = ParseScopedIdent (Ident, &FullName);
161
162     /* We don't need FullName any longer */
163     DoneStrBuf (&FullName);
164
165     /* Check if the scope is valid. Errors have already been diagnosed by
166      * the routine, so just exit.
167      */
168     if (Scope) {
169         /* Search for the symbol and return it */
170         return SymFind (Scope, Ident, AllocNew);
171     } else {
172         /* No scope ==> no symbol. To avoid errors in the calling routine that
173          * may not expect NULL to be returned if AllocNew is true, create a new
174          * symbol.
175          */
176         if (AllocNew) {
177             return NewSymEntry (Ident);
178         } else {
179             return 0;
180         }
181     }
182 }
183
184
185
186 SymTable* ParseScopedSymTable (void)
187 /* Parse a (possibly scoped) symbol table (scope) name, search for it in the
188  * symbol space and return the symbol table struct.
189  */
190 {
191     StrBuf    FullName = AUTO_STRBUF_INITIALIZER;
192     char      Ident[sizeof (SVal)];
193
194     /* Parse the scoped symbol name */
195     SymTable* Scope = ParseScopedIdent (Ident, &FullName);
196
197     /* We don't need FullName any longer */
198     DoneStrBuf (&FullName);
199
200     /* Check if the scope is valid. Errors have already been diagnosed by
201      * the routine, so just exit.
202      */
203     if (Scope) {
204         /* Search for the last scope */
205         Scope = SymFindScope (Scope, Ident, SYM_FIND_EXISTING);
206     }
207     return Scope;
208 }
209
210
211