blob: fbf89ae916ab093e4ee5c23672f90cea64d8d821 [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) {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000278 symbol_name[len++] = ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279 ch = lReadByte(pTok);
280 }
281 }
282 symbol_name[len] = '\0';
283 assert(ch == '\0');
284 yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
285 return CPP_IDENTIFIER;
286 break;
287 case CPP_STRCONSTANT:
288 len = 0;
289 while ((ch = lReadByte(pTok)) != 0)
290 if (len < MAX_STRING_LEN)
291 string_val[len++] = ch;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000292 string_val[len] = '\0';
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000293 yylvalpp->sc_ident = LookUpAddString(atable, string_val);
294 break;
295 case CPP_FLOATCONSTANT:
296 len = 0;
297 ch = lReadByte(pTok);
298 while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
299 {
300 if (len < MAX_SYMBOL_NAME_LEN) {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000301 symbol_name[len++] = ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000302 ch = lReadByte(pTok);
303 }
304 }
305 symbol_name[len] = '\0';
306 assert(ch == '\0');
307 strcpy(yylvalpp->symbol_name,symbol_name);
308 yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name);
309 break;
310 case CPP_INTCONSTANT:
311 len = 0;
312 ch = lReadByte(pTok);
313 while ((ch >= '0' && ch <= '9'))
314 {
315 if (len < MAX_SYMBOL_NAME_LEN) {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000316 symbol_name[len++] = ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000317 ch = lReadByte(pTok);
318 }
319 }
320 symbol_name[len] = '\0';
321 assert(ch == '\0');
322 strcpy(yylvalpp->symbol_name,symbol_name);
323 yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
324 break;
325 case '(':
326 yylvalpp->sc_int = lReadByte(pTok);
327 break;
328 }
329 return ltoken;
330 }
331 return EOF_SY;
332} // ReadToken
333
334typedef struct TokenInputSrc {
335 InputSrc base;
336 TokenStream *tokens;
337 int (*final)(CPPStruct *);
338} TokenInputSrc;
339
340static int scan_token(TokenInputSrc *in, yystypepp * yylvalpp)
341{
342 int token = ReadToken(in->tokens, yylvalpp);
343 int (*final)(CPPStruct *);
344 cpp->tokenLoc->file = cpp->currentInput->name;
345 cpp->tokenLoc->line = cpp->currentInput->line;
346 if (token == '\n') {
347 in->base.line++;
348 return token;
349 }
350 if (token > 0) return token;
351 cpp->currentInput = in->base.prev;
352 final = in->final;
353 free(in);
354 if (final && !final(cpp)) return -1;
355 return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
356}
357
358int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(CPPStruct *))
359{
360 TokenInputSrc *in = malloc(sizeof(TokenInputSrc));
361 memset(in, 0, sizeof(TokenInputSrc));
362 in->base.name = name;
363 in->base.prev = cpp->currentInput;
364 in->base.scan = (int (*)(InputSrc *, yystypepp *))scan_token;
365 in->base.line = 1;
366 in->tokens = ts;
367 in->final = final;
368 RewindTokenStream(ts);
369 cpp->currentInput = &in->base;
370 return 1;
371}
372
373typedef struct UngotToken {
374 InputSrc base;
375 int token;
376 yystypepp lval;
377} UngotToken;
378
379static int reget_token(UngotToken *t, yystypepp * yylvalpp)
380{
381 int token = t->token;
382 *yylvalpp = t->lval;
383 cpp->currentInput = t->base.prev;
384 free(t);
385 return token;
386}
387
388void UngetToken(int token, yystypepp * yylvalpp) {
389 UngotToken *t = malloc(sizeof(UngotToken));
390 memset(t, 0, sizeof(UngotToken));
391 t->token = token;
392 t->lval = *yylvalpp;
393 t->base.scan = (void *)reget_token;
394 t->base.prev = cpp->currentInput;
395 t->base.name = cpp->currentInput->name;
396 t->base.line = cpp->currentInput->line;
397 cpp->currentInput = &t->base;
398}
399
400
401void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
402 int token;
403 char str[100];
404
405 if (fp == 0) fp = stdout;
406 RewindTokenStream(s);
407 while ((token = ReadToken(s, yylvalpp)) > 0) {
408 switch (token) {
409 case CPP_IDENTIFIER:
410 case CPP_TYPEIDENTIFIER:
411 sprintf(str, "%s ", GetAtomString(atable, yylvalpp->sc_ident));
412 break;
413 case CPP_STRCONSTANT:
414 sprintf(str, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident));
415 break;
416 case CPP_FLOATCONSTANT:
417 //printf("%g9.6 ", yylvalpp->sc_fval);
418 break;
419 case CPP_INTCONSTANT:
420 //printf("%d ", yylvalpp->sc_int);
421 break;
422 default:
423 if (token >= 127)
424 sprintf(str, "%s ", GetAtomString(atable, token));
425 else
426 sprintf(str, "%c", token);
427 break;
428 }
429 CPPDebugLogMsg(str);
430 }
431}
432
433///////////////////////////////////////////////////////////////////////////////////////////////
434/////////////////////////////////////// End of tokens.c ///////////////////////////////////////
435///////////////////////////////////////////////////////////////////////////////////////////////