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