blob: 057cce8406359fdee56e8c6f220bdcd3f682d13a [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001/****************************************************************************\
2Copyright (c) 2002, NVIDIA Corporation.
3
4NVIDIA Corporation("NVIDIA") supplies this software to you in
5consideration of your agreement to the following terms, and your use,
6installation, modification or redistribution of this NVIDIA software
7constitutes acceptance of these terms. If you do not agree with these
8terms, please do not use, install, modify or redistribute this NVIDIA
9software.
10
11In consideration of your agreement to abide by the following terms, and
12subject to these terms, NVIDIA grants you a personal, non-exclusive
13license, under NVIDIA's copyrights in this original NVIDIA software (the
14"NVIDIA Software"), to use, reproduce, modify and redistribute the
15NVIDIA Software, with or without modifications, in source and/or binary
16forms; provided that if you redistribute the NVIDIA Software, you must
17retain the copyright notice of NVIDIA, this notice and the following
18text and disclaimers in all such redistributions of the NVIDIA Software.
19Neither the name, trademarks, service marks nor logos of NVIDIA
20Corporation may be used to endorse or promote products derived from the
21NVIDIA Software without specific prior written permission from NVIDIA.
22Except as expressly stated in this notice, no other rights or licenses
23express or implied, are granted by NVIDIA herein, including but not
24limited to any patent rights that may be infringed by your derivative
25works or by other works in which the NVIDIA Software may be
26incorporated. No hardware is licensed hereunder.
27
28THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
29WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
30INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
31NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
32ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
33PRODUCTS.
34
35IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
36INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
37TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
38USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
39OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
40NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
41TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
42NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43\****************************************************************************/
44//
45// tokens.c
46//
47
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000048#include <stdlib.h>
49#include <stdio.h>
50#include <string.h>
51#include <ctype.h>
52
alokp@chromium.org91b72322010-06-02 15:50:56 +000053#include "compiler/debug.h"
daniel@transgaming.come6842292010-04-20 18:52:50 +000054#include "compiler/preprocessor/slglobals.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000055
56///////////////////////////////////////////////////////////////////////////////////////////////
57//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
58///////////////////////////////////////////////////////////////////////////////////////////////
59
60/*
61 * idstr()
62 * Copy a string to a malloc'ed block and convert it into something suitable
63 * for an ID
64 *
65 */
66
67static char *idstr(const char *fstr, MemoryPool *pool)
68{
69 size_t len;
70 char *str, *t;
71 const char *f;
72
73 len = strlen(fstr);
74 if (!pool)
75 str = (char *) malloc(len + 1);
76 else
77 str = (char *) mem_Alloc(pool, len + 1);
78
79 for (f=fstr, t=str; *f; f++) {
80 if (isalnum(*f)) *t++ = *f;
81 else if (*f == '.' || *f == '/') *t++ = '_';
82 }
83 *t = 0;
84 return str;
85} // idstr
86
87
88/*
89 * lNewBlock()
90 *
91 */
92
93static TokenBlock *lNewBlock(TokenStream *fTok, MemoryPool *pool)
94{
95 TokenBlock *lBlock;
96
97 if (!pool)
98 lBlock = (TokenBlock *) malloc(sizeof(TokenBlock) + 256);
99 else
100 lBlock = (TokenBlock *) mem_Alloc(pool, sizeof(TokenBlock) + 256);
101 lBlock->count = 0;
102 lBlock->current = 0;
103 lBlock->data = (unsigned char *) lBlock + sizeof(TokenBlock);
104 lBlock->max = 256;
105 lBlock->next = NULL;
106 if (fTok->head) {
107 fTok->current->next = lBlock;
108 } else {
109 fTok->head = lBlock;
110 }
111 fTok->current = lBlock;
112 return lBlock;
113} // lNewBlock
114
115/*
116 * lAddByte()
117 *
118 */
119
120static void lAddByte(TokenStream *fTok, unsigned char fVal)
121{
122 TokenBlock *lBlock;
123 lBlock = fTok->current;
124 if (lBlock->count >= lBlock->max)
125 lBlock = lNewBlock(fTok, 0);
126 lBlock->data[lBlock->count++] = fVal;
127} // lAddByte
128
129
130
131/*
132 * lReadByte() - Get the next byte from a stream.
133 *
134 */
135
136static int lReadByte(TokenStream *pTok)
137{
138 TokenBlock *lBlock;
139 int lval = -1;
140
141 lBlock = pTok->current;
142 if (lBlock) {
143 if (lBlock->current >= lBlock->count) {
144 lBlock = lBlock->next;
145 if (lBlock)
146 lBlock->current = 0;
147 pTok->current = lBlock;
148 }
149 if (lBlock)
150 lval = lBlock->data[lBlock->current++];
151 }
152 return lval;
153} // lReadByte
154
155/////////////////////////////////////// Global Functions://////////////////////////////////////
156
157/*
158 * NewTokenStream()
159 *
160 */
161
162TokenStream *NewTokenStream(const char *name, MemoryPool *pool)
163{
164 TokenStream *pTok;
165
166 if (!pool)
167 pTok = (TokenStream *) malloc(sizeof(TokenStream));
168 else
169 pTok = (TokenStream*)mem_Alloc(pool, sizeof(TokenStream));
170 pTok->next = NULL;
171 pTok->name = idstr(name, pool);
172 pTok->head = NULL;
173 pTok->current = NULL;
174 lNewBlock(pTok, pool);
175 return pTok;
176} // NewTokenStream
177
178/*
179 * DeleteTokenStream()
180 *
181 */
182
183void DeleteTokenStream(TokenStream *pTok)
184{
185 TokenBlock *pBlock, *nBlock;
186
187 if (pTok) {
188 pBlock = pTok->head;
189 while (pBlock) {
190 nBlock = pBlock->next;
191 free(pBlock);
192 pBlock = nBlock;
193 }
194 if (pTok->name)
195 free(pTok->name);
196 free(pTok);
197 }
198} // DeleteTokenStream
199
200/*
201 * RecordToken() - Add a token to the end of a list for later playback or printout.
202 *
203 */
204
205void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
206{
207 const char *s;
alokp@chromium.orgbcfba4c2010-08-09 22:30:49 +0000208 char *str=NULL;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209
210 if (token > 256)
211 lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80));
212 else
213 lAddByte(pTok, (unsigned char)(token & 0x7f));
214 switch (token) {
215 case CPP_IDENTIFIER:
216 case CPP_TYPEIDENTIFIER:
217 case CPP_STRCONSTANT:
218 s = GetAtomString(atable, yylvalpp->sc_ident);
219 while (*s)
220 lAddByte(pTok, (unsigned char) *s++);
221 lAddByte(pTok, 0);
222 break;
223 case CPP_FLOATCONSTANT:
224 case CPP_INTCONSTANT:
225 str=yylvalpp->symbol_name;
226 while (*str){
227 lAddByte(pTok,(unsigned char) *str);
228 *str++;
229 }
230 lAddByte(pTok, 0);
231 break;
232 case '(':
233 lAddByte(pTok, (unsigned char)(yylvalpp->sc_int ? 1 : 0));
234 default:
235 break;
236 }
237} // RecordToken
238
239/*
240 * RewindTokenStream() - Reset a token stream in preperation for reading.
241 *
242 */
243
244void RewindTokenStream(TokenStream *pTok)
245{
246 if (pTok->head) {
247 pTok->current = pTok->head;
248 pTok->current->current = 0;
249 }
250} // RewindTokenStream
251
252/*
253 * ReadToken() - Read the next token from a stream.
254 *
255 */
256
257int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
258{
259 char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
260 char string_val[MAX_STRING_LEN + 1];
261 int ltoken, len;
262 char ch;
263
264 ltoken = lReadByte(pTok);
265 if (ltoken >= 0) {
266 if (ltoken > 127)
267 ltoken += 128;
268 switch (ltoken) {
269 case CPP_IDENTIFIER:
270 case CPP_TYPEIDENTIFIER:
271 len = 0;
272 ch = lReadByte(pTok);
273 while ((ch >= 'a' && ch <= 'z') ||
274 (ch >= 'A' && ch <= 'Z') ||
275 (ch >= '0' && ch <= '9') ||
276 ch == '_')
277 {
278 if (len < MAX_SYMBOL_NAME_LEN) {
279 symbol_name[len] = ch;
280 len++;
281 ch = lReadByte(pTok);
282 }
283 }
284 symbol_name[len] = '\0';
285 assert(ch == '\0');
286 yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
287 return CPP_IDENTIFIER;
288 break;
289 case CPP_STRCONSTANT:
290 len = 0;
291 while ((ch = lReadByte(pTok)) != 0)
292 if (len < MAX_STRING_LEN)
293 string_val[len++] = ch;
294 string_val[len] = 0;
295 yylvalpp->sc_ident = LookUpAddString(atable, string_val);
296 break;
297 case CPP_FLOATCONSTANT:
298 len = 0;
299 ch = lReadByte(pTok);
300 while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
301 {
302 if (len < MAX_SYMBOL_NAME_LEN) {
303 symbol_name[len] = ch;
304 len++;
305 ch = lReadByte(pTok);
306 }
307 }
308 symbol_name[len] = '\0';
309 assert(ch == '\0');
310 strcpy(yylvalpp->symbol_name,symbol_name);
311 yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name);
312 break;
313 case CPP_INTCONSTANT:
314 len = 0;
315 ch = lReadByte(pTok);
316 while ((ch >= '0' && ch <= '9'))
317 {
318 if (len < MAX_SYMBOL_NAME_LEN) {
319 symbol_name[len] = ch;
320 len++;
321 ch = lReadByte(pTok);
322 }
323 }
324 symbol_name[len] = '\0';
325 assert(ch == '\0');
326 strcpy(yylvalpp->symbol_name,symbol_name);
327 yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
328 break;
329 case '(':
330 yylvalpp->sc_int = lReadByte(pTok);
331 break;
332 }
333 return ltoken;
334 }
335 return EOF_SY;
336} // ReadToken
337
338typedef struct TokenInputSrc {
339 InputSrc base;
340 TokenStream *tokens;
341 int (*final)(CPPStruct *);
342} TokenInputSrc;
343
344static int scan_token(TokenInputSrc *in, yystypepp * yylvalpp)
345{
346 int token = ReadToken(in->tokens, yylvalpp);
347 int (*final)(CPPStruct *);
348 cpp->tokenLoc->file = cpp->currentInput->name;
349 cpp->tokenLoc->line = cpp->currentInput->line;
350 if (token == '\n') {
351 in->base.line++;
352 return token;
353 }
354 if (token > 0) return token;
355 cpp->currentInput = in->base.prev;
356 final = in->final;
357 free(in);
358 if (final && !final(cpp)) return -1;
359 return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
360}
361
362int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(CPPStruct *))
363{
364 TokenInputSrc *in = malloc(sizeof(TokenInputSrc));
365 memset(in, 0, sizeof(TokenInputSrc));
366 in->base.name = name;
367 in->base.prev = cpp->currentInput;
368 in->base.scan = (int (*)(InputSrc *, yystypepp *))scan_token;
369 in->base.line = 1;
370 in->tokens = ts;
371 in->final = final;
372 RewindTokenStream(ts);
373 cpp->currentInput = &in->base;
374 return 1;
375}
376
377typedef struct UngotToken {
378 InputSrc base;
379 int token;
380 yystypepp lval;
381} UngotToken;
382
383static int reget_token(UngotToken *t, yystypepp * yylvalpp)
384{
385 int token = t->token;
386 *yylvalpp = t->lval;
387 cpp->currentInput = t->base.prev;
388 free(t);
389 return token;
390}
391
392void UngetToken(int token, yystypepp * yylvalpp) {
393 UngotToken *t = malloc(sizeof(UngotToken));
394 memset(t, 0, sizeof(UngotToken));
395 t->token = token;
396 t->lval = *yylvalpp;
397 t->base.scan = (void *)reget_token;
398 t->base.prev = cpp->currentInput;
399 t->base.name = cpp->currentInput->name;
400 t->base.line = cpp->currentInput->line;
401 cpp->currentInput = &t->base;
402}
403
404
405void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
406 int token;
407 char str[100];
408
409 if (fp == 0) fp = stdout;
410 RewindTokenStream(s);
411 while ((token = ReadToken(s, yylvalpp)) > 0) {
412 switch (token) {
413 case CPP_IDENTIFIER:
414 case CPP_TYPEIDENTIFIER:
415 sprintf(str, "%s ", GetAtomString(atable, yylvalpp->sc_ident));
416 break;
417 case CPP_STRCONSTANT:
418 sprintf(str, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident));
419 break;
420 case CPP_FLOATCONSTANT:
421 //printf("%g9.6 ", yylvalpp->sc_fval);
422 break;
423 case CPP_INTCONSTANT:
424 //printf("%d ", yylvalpp->sc_int);
425 break;
426 default:
427 if (token >= 127)
428 sprintf(str, "%s ", GetAtomString(atable, token));
429 else
430 sprintf(str, "%c", token);
431 break;
432 }
433 CPPDebugLogMsg(str);
434 }
435}
436
437///////////////////////////////////////////////////////////////////////////////////////////////
438/////////////////////////////////////// End of tokens.c ///////////////////////////////////////
439///////////////////////////////////////////////////////////////////////////////////////////////