blob: baa07dec0f0fc7914774fd546120e204782db142 [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){
alokp@chromium.orgac231892010-10-14 16:09:09 +0000227 lAddByte(pTok, (unsigned char) *str++);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228 }
229 lAddByte(pTok, 0);
230 break;
231 case '(':
232 lAddByte(pTok, (unsigned char)(yylvalpp->sc_int ? 1 : 0));
233 default:
234 break;
235 }
236} // RecordToken
237
238/*
239 * RewindTokenStream() - Reset a token stream in preperation for reading.
240 *
241 */
242
243void RewindTokenStream(TokenStream *pTok)
244{
245 if (pTok->head) {
246 pTok->current = pTok->head;
247 pTok->current->current = 0;
248 }
249} // RewindTokenStream
250
251/*
252 * ReadToken() - Read the next token from a stream.
253 *
254 */
255
256int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
257{
258 char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
259 char string_val[MAX_STRING_LEN + 1];
260 int ltoken, len;
261 char ch;
262
263 ltoken = lReadByte(pTok);
264 if (ltoken >= 0) {
265 if (ltoken > 127)
266 ltoken += 128;
267 switch (ltoken) {
268 case CPP_IDENTIFIER:
269 case CPP_TYPEIDENTIFIER:
270 len = 0;
271 ch = lReadByte(pTok);
272 while ((ch >= 'a' && ch <= 'z') ||
273 (ch >= 'A' && ch <= 'Z') ||
274 (ch >= '0' && ch <= '9') ||
275 ch == '_')
276 {
277 if (len < MAX_SYMBOL_NAME_LEN) {
278 symbol_name[len] = ch;
279 len++;
280 ch = lReadByte(pTok);
281 }
282 }
283 symbol_name[len] = '\0';
284 assert(ch == '\0');
285 yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
286 return CPP_IDENTIFIER;
287 break;
288 case CPP_STRCONSTANT:
289 len = 0;
290 while ((ch = lReadByte(pTok)) != 0)
291 if (len < MAX_STRING_LEN)
292 string_val[len++] = ch;
293 string_val[len] = 0;
294 yylvalpp->sc_ident = LookUpAddString(atable, string_val);
295 break;
296 case CPP_FLOATCONSTANT:
297 len = 0;
298 ch = lReadByte(pTok);
299 while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
300 {
301 if (len < MAX_SYMBOL_NAME_LEN) {
302 symbol_name[len] = ch;
303 len++;
304 ch = lReadByte(pTok);
305 }
306 }
307 symbol_name[len] = '\0';
308 assert(ch == '\0');
309 strcpy(yylvalpp->symbol_name,symbol_name);
310 yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name);
311 break;
312 case CPP_INTCONSTANT:
313 len = 0;
314 ch = lReadByte(pTok);
315 while ((ch >= '0' && ch <= '9'))
316 {
317 if (len < MAX_SYMBOL_NAME_LEN) {
318 symbol_name[len] = ch;
319 len++;
320 ch = lReadByte(pTok);
321 }
322 }
323 symbol_name[len] = '\0';
324 assert(ch == '\0');
325 strcpy(yylvalpp->symbol_name,symbol_name);
326 yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
327 break;
328 case '(':
329 yylvalpp->sc_int = lReadByte(pTok);
330 break;
331 }
332 return ltoken;
333 }
334 return EOF_SY;
335} // ReadToken
336
337typedef struct TokenInputSrc {
338 InputSrc base;
339 TokenStream *tokens;
340 int (*final)(CPPStruct *);
341} TokenInputSrc;
342
343static int scan_token(TokenInputSrc *in, yystypepp * yylvalpp)
344{
345 int token = ReadToken(in->tokens, yylvalpp);
346 int (*final)(CPPStruct *);
347 cpp->tokenLoc->file = cpp->currentInput->name;
348 cpp->tokenLoc->line = cpp->currentInput->line;
349 if (token == '\n') {
350 in->base.line++;
351 return token;
352 }
353 if (token > 0) return token;
354 cpp->currentInput = in->base.prev;
355 final = in->final;
356 free(in);
357 if (final && !final(cpp)) return -1;
358 return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
359}
360
361int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(CPPStruct *))
362{
363 TokenInputSrc *in = malloc(sizeof(TokenInputSrc));
364 memset(in, 0, sizeof(TokenInputSrc));
365 in->base.name = name;
366 in->base.prev = cpp->currentInput;
367 in->base.scan = (int (*)(InputSrc *, yystypepp *))scan_token;
368 in->base.line = 1;
369 in->tokens = ts;
370 in->final = final;
371 RewindTokenStream(ts);
372 cpp->currentInput = &in->base;
373 return 1;
374}
375
376typedef struct UngotToken {
377 InputSrc base;
378 int token;
379 yystypepp lval;
380} UngotToken;
381
382static int reget_token(UngotToken *t, yystypepp * yylvalpp)
383{
384 int token = t->token;
385 *yylvalpp = t->lval;
386 cpp->currentInput = t->base.prev;
387 free(t);
388 return token;
389}
390
391void UngetToken(int token, yystypepp * yylvalpp) {
392 UngotToken *t = malloc(sizeof(UngotToken));
393 memset(t, 0, sizeof(UngotToken));
394 t->token = token;
395 t->lval = *yylvalpp;
396 t->base.scan = (void *)reget_token;
397 t->base.prev = cpp->currentInput;
398 t->base.name = cpp->currentInput->name;
399 t->base.line = cpp->currentInput->line;
400 cpp->currentInput = &t->base;
401}
402
403
404void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
405 int token;
406 char str[100];
407
408 if (fp == 0) fp = stdout;
409 RewindTokenStream(s);
410 while ((token = ReadToken(s, yylvalpp)) > 0) {
411 switch (token) {
412 case CPP_IDENTIFIER:
413 case CPP_TYPEIDENTIFIER:
414 sprintf(str, "%s ", GetAtomString(atable, yylvalpp->sc_ident));
415 break;
416 case CPP_STRCONSTANT:
417 sprintf(str, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident));
418 break;
419 case CPP_FLOATCONSTANT:
420 //printf("%g9.6 ", yylvalpp->sc_fval);
421 break;
422 case CPP_INTCONSTANT:
423 //printf("%d ", yylvalpp->sc_int);
424 break;
425 default:
426 if (token >= 127)
427 sprintf(str, "%s ", GetAtomString(atable, token));
428 else
429 sprintf(str, "%c", token);
430 break;
431 }
432 CPPDebugLogMsg(str);
433 }
434}
435
436///////////////////////////////////////////////////////////////////////////////////////////////
437/////////////////////////////////////// End of tokens.c ///////////////////////////////////////
438///////////////////////////////////////////////////////////////////////////////////////////////