blob: 6dc179736a27ae7c5560c8e7c67886e9e074b053 [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// scanner.c
46//
47
alokp@chromium.org43668cd2010-10-20 20:55:53 +000048#include <assert.h>
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000049#include <stdarg.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53
54#if 0
55 #include <ieeefp.h>
alokp@chromium.org43668cd2010-10-20 20:55:53 +000056#else
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000057 #define isinff(x) (((*(int *)&(x) & 0x7f800000L)==0x7f800000L) && \
58 ((*(int *)&(x) & 0x007fffffL)==0000000000L))
59#endif
60
daniel@transgaming.come6842292010-04-20 18:52:50 +000061#include "compiler/preprocessor/slglobals.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000062
63
64typedef struct StringInputSrc {
65 InputSrc base;
66 char *p;
67} StringInputSrc;
68
69static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
70{
71 return EOF;
72} // eof_scan
73
74static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {}
75
76static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop };
77
78static int byte_scan(InputSrc *, yystypepp * yylvalpp);
79
80#define EOL_SY '\n'
81
alokp@chromium.org01b666f2010-07-16 19:27:45 +000082#if defined(_MSC_VER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000083 #define DBG_BREAKPOINT() __asm int 3
alokp@chromium.org01b666f2010-07-16 19:27:45 +000084#elif defined(_M_AMD64)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000085 #define DBG_BREAKPOINT() assert(!"Dbg_Breakpoint");
alokp@chromium.org01b666f2010-07-16 19:27:45 +000086#else
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000087 #define DBG_BREAKPOINT()
alokp@chromium.org01b666f2010-07-16 19:27:45 +000088#endif
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000089
alokp@chromium.org01b666f2010-07-16 19:27:45 +000090#if defined(_MSC_VER) && !defined(_M_AMD64)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000091 __int64 RDTSC ( void ) {
92
93 __int64 v;
94
95 __asm __emit 0x0f
96 __asm __emit 0x31
97 __asm mov dword ptr v, eax
98 __asm mov dword ptr v+4, edx
99
100 return v;
101 }
102#endif
103
104
105int InitScanner(CPPStruct *cpp)
106{
107 // Add various atoms needed by the CPP line scanner:
108 if (!InitCPP())
109 return 0;
110
111 cpp->mostRecentToken = 0;
112 cpp->tokenLoc = &cpp->ltokenLoc;
113
114 cpp->ltokenLoc.file = 0;
115 cpp->ltokenLoc.line = 0;
116
117 cpp->currentInput = &eof_inputsrc;
118 cpp->previous_token = '\n';
daniel@transgaming.comdec19e22010-04-29 03:35:42 +0000119 cpp->pastFirstStatement = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000120
121 return 1;
122} // InitScanner
123
124int FreeScanner(void)
125{
126 return (FreeCPP());
127}
128
129/*
130 * str_getch()
131 * takes care of reading from multiple strings.
132 * returns the next-char from the input stream.
133 * returns EOF when the complete shader is parsed.
134 */
135static int str_getch(StringInputSrc *in)
136{
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000137 for(;;){
138 if (*in->p){
139 if (*in->p == '\n') {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000140 in->base.line++;
141 IncLineNumber();
142 }
143 return *in->p++;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000144 }
145 if(++(cpp->PaWhichStr) < cpp->PaArgc){
146 free(in);
147 SetStringNumber(cpp->PaWhichStr);
148 SetLineNumber(1);
149 ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
150 in=(StringInputSrc*)cpp->currentInput;
151 continue;
152 }
153 else{
154 cpp->currentInput = in->base.prev;
155 cpp->PaWhichStr=0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000156 free(in);
157 return EOF;
158 }
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000159 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000160} // str_getch
161
162static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
163 if (in->p[-1] == ch)in->p--;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000164 else {
165 *(in->p)='\0'; //this would take care of shifting to the previous string.
166 cpp->PaWhichStr--;
167 }
168 if (ch == '\n') {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000169 in->base.line--;
170 DecLineNumber();
171 }
172} // str_ungetch
173
alokp@chromium.org07620a52010-09-23 17:53:56 +0000174int ScanFromString(const char *s)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000175{
176
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000177 StringInputSrc *in = malloc(sizeof(StringInputSrc));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000178 memset(in, 0, sizeof(StringInputSrc));
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000179 in->p = s;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000180 in->base.line = 1;
181 in->base.scan = byte_scan;
182 in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
183 in->base.ungetch = (void (*)(InputSrc *, int, yystypepp *))str_ungetch;
184 in->base.prev = cpp->currentInput;
185 cpp->currentInput = &in->base;
186
187 return 1;
188} // ScanFromString;
189
190
191///////////////////////////////////////////////////////////////////////////////////////////////
192/////////////////////////////////// Floating point constants: /////////////////////////////////
193///////////////////////////////////////////////////////////////////////////////////////////////
194/*
195 * lBuildFloatValue() - Quick and dirty conversion to floating point. Since all
196 * we need is single precision this should be quite precise.
197 */
198
199static float lBuildFloatValue(const char *str, int len, int exp)
200{
201 double val, expval, ten;
202 int ii, llen, absexp;
203 float rv;
204
205 val = 0.0;
206 llen = len;
207 for (ii = 0; ii < len; ii++)
208 val = val*10.0 + (str[ii] - '0');
209 if (exp != 0) {
210 absexp = exp > 0 ? exp : -exp;
211 expval = 1.0f;
212 ten = 10.0;
213 while (absexp) {
214 if (absexp & 1)
215 expval *= ten;
216 ten *= ten;
217 absexp >>= 1;
218 }
219 if (exp >= 0) {
220 val *= expval;
221 } else {
222 val /= expval;
223 }
224 }
225 rv = (float)val;
226 if (isinff(rv)) {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000227 CPPErrorToInfoLog(" ERROR___FP_CONST_OVERFLOW");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228 }
229 return rv;
230} // lBuildFloatValue
231
232
233/*
234 * lFloatConst() - Scan a floating point constant. Assumes that the scanner
235 * has seen at least one digit, followed by either a decimal '.' or the
236 * letter 'e'.
237 */
238
239static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
240{
241 int HasDecimal, declen, exp, ExpSign;
242 int str_len;
243 float lval;
244
245 HasDecimal = 0;
246 declen = 0;
247 exp = 0;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000248
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000249 str_len=len;
250 if (ch == '.') {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000251 str[len++]=ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000252 HasDecimal = 1;
253 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
254 while (ch >= '0' && ch <= '9') {
255 if (len < MAX_SYMBOL_NAME_LEN) {
256 declen++;
257 if (len > 0 || ch != '0') {
258 str[len] = ch;
259 len++;str_len++;
260 }
261 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
262 } else {
263 CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
264 len = 1,str_len=1;
265 }
266 }
267 }
268
269 // Exponent:
270
271 if (ch == 'e' || ch == 'E') {
272 ExpSign = 1;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000273 str[len++]=ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000274 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
275 if (ch == '+') {
276 str[len++]=ch;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000277 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000278 } else if (ch == '-') {
279 ExpSign = -1;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000280 str[len++]=ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000281 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
282 }
283 if (ch >= '0' && ch <= '9') {
284 while (ch >= '0' && ch <= '9') {
285 exp = exp*10 + ch - '0';
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000286 str[len++]=ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000287 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
288 }
289 } else {
290 CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT");
291 }
292 exp *= ExpSign;
293 }
294
295 if (len == 0) {
296 lval = 0.0f;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000297 strcpy(str,"0.0");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000298 } else {
299 str[len]='\0';
300 lval = lBuildFloatValue(str, str_len, exp - declen);
301 }
302 // Suffix:
303
304 yylvalpp->sc_fval = lval;
305 strcpy(yylvalpp->symbol_name,str);
306 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
307 return CPP_FLOATCONSTANT;
308} // lFloatConst
309
310///////////////////////////////////////////////////////////////////////////////////////////////
311///////////////////////////////////////// Normal Scanner //////////////////////////////////////
312///////////////////////////////////////////////////////////////////////////////////////////////
313
314static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
315{
316 char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
317 char string_val[MAX_STRING_LEN + 1];
318 int AlreadyComplained;
319 int len, ch, ii, ival = 0;
320
321 for (;;) {
322 yylvalpp->sc_int = 0;
323 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000324
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000325 while (ch == ' ' || ch == '\t' || ch == '\r') {
326 yylvalpp->sc_int = 1;
327 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
328 }
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000329
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000330 cpp->ltokenLoc.file = cpp->currentInput->name;
331 cpp->ltokenLoc.line = cpp->currentInput->line;
332 len = 0;
333 switch (ch) {
334 default:
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000335 return ch; // Single character token
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000336 case EOF:
337 return -1;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000338 case 'A': case 'B': case 'C': case 'D': case 'E':
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000339 case 'F': case 'G': case 'H': case 'I': case 'J':
340 case 'K': case 'L': case 'M': case 'N': case 'O':
341 case 'P': case 'Q': case 'R': case 'S': case 'T':
342 case 'U': case 'V': case 'W': case 'X': case 'Y':
343 case 'Z': case '_':
344 case 'a': case 'b': case 'c': case 'd': case 'e':
345 case 'f': case 'g': case 'h': case 'i': case 'j':
346 case 'k': case 'l': case 'm': case 'n': case 'o':
347 case 'p': case 'q': case 'r': case 's': case 't':
348 case 'u': case 'v': case 'w': case 'x': case 'y':
349 case 'z':
350 do {
351 if (len < MAX_SYMBOL_NAME_LEN) {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000352 symbol_name[len++] = ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000353 }
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000354 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000355 } while ((ch >= 'a' && ch <= 'z') ||
356 (ch >= 'A' && ch <= 'Z') ||
357 (ch >= '0' && ch <= '9') ||
358 ch == '_');
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000359 assert(len <= MAX_SYMBOL_NAME_LEN);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000360 symbol_name[len] = '\0';
361 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
362 yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
363 return CPP_IDENTIFIER;
364 break;
365 case '0':
366 yylvalpp->symbol_name[len++] = ch;
367 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
368 if (ch == 'x' || ch == 'X') {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000369 yylvalpp->symbol_name[len++] = ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000370 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
371 if ((ch >= '0' && ch <= '9') ||
372 (ch >= 'A' && ch <= 'F') ||
373 (ch >= 'a' && ch <= 'f'))
374 {
375 AlreadyComplained = 0;
376 ival = 0;
377 do {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000378 yylvalpp->symbol_name[len++] = ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000379 if (ival <= 0x0fffffff) {
380 if (ch >= '0' && ch <= '9') {
381 ii = ch - '0';
382 } else if (ch >= 'A' && ch <= 'F') {
383 ii = ch - 'A' + 10;
384 } else {
385 ii = ch - 'a' + 10;
386 }
387 ival = (ival << 4) | ii;
388 } else {
389 if (!AlreadyComplained)
390 CPPErrorToInfoLog("ERROR___HEX_CONST_OVERFLOW");
391 AlreadyComplained = 1;
392 }
393 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
394 } while ((ch >= '0' && ch <= '9') ||
395 (ch >= 'A' && ch <= 'F') ||
396 (ch >= 'a' && ch <= 'f'));
397 } else {
398 CPPErrorToInfoLog("ERROR___ERROR_IN_HEX_CONSTANT");
399 }
400 yylvalpp->symbol_name[len] = '\0';
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000401 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
402 yylvalpp->sc_int = ival;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000403 return CPP_INTCONSTANT;
404 } else if (ch >= '0' && ch <= '7') { // octal integer constants
405 AlreadyComplained = 0;
406 ival = 0;
407 do {
408 yylvalpp->symbol_name[len++] = ch;
409 if (ival <= 0x1fffffff) {
410 ii = ch - '0';
411 ival = (ival << 3) | ii;
412 } else {
413 if (!AlreadyComplained)
414 CPPErrorToInfoLog("ERROR___OCT_CONST_OVERFLOW");
415 AlreadyComplained = 1;
416 }
417 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
418 } while (ch >= '0' && ch <= '7');
419 if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E')
420 return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
421 yylvalpp->symbol_name[len] = '\0';
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000422 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
423 yylvalpp->sc_int = ival;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000424 return CPP_INTCONSTANT;
425 } else {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000426 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
427 ch = '0';
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000428 }
429 // Fall through...
430 case '1': case '2': case '3': case '4':
431 case '5': case '6': case '7': case '8': case '9':
432 do {
433 if (len < MAX_SYMBOL_NAME_LEN) {
434 if (len > 0 || ch != '0') {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000435 yylvalpp->symbol_name[len++] = ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000436 }
437 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
438 }
439 } while (ch >= '0' && ch <= '9');
440 if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') {
441 return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
442 } else {
443 yylvalpp->symbol_name[len] = '\0';
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000444 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000445 ival = 0;
446 AlreadyComplained = 0;
447 for (ii = 0; ii < len; ii++) {
448 ch = yylvalpp->symbol_name[ii] - '0';
449 if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
450 if (!AlreadyComplained)
451 CPPErrorToInfoLog("ERROR___INTEGER_CONST_OVERFLOW");
452 AlreadyComplained = 1;
453 }
454 ival = ival*10 + ch;
455 }
456 yylvalpp->sc_int = ival;
457 if(ival==0)
458 strcpy(yylvalpp->symbol_name,"0");
459 return CPP_INTCONSTANT;
460 }
461 break;
462 case '-':
463 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
464 if (ch == '-') {
465 return CPP_DEC_OP;
466 } else if (ch == '=') {
467 return CPP_SUB_ASSIGN;
468 } else {
469 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
470 return '-';
471 }
472 case '+':
473 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
474 if (ch == '+') {
475 return CPP_INC_OP;
476 } else if (ch == '=') {
477 return CPP_ADD_ASSIGN;
478 } else {
479 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
480 return '+';
481 }
482 case '*':
483 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
484 if (ch == '=') {
485 return CPP_MUL_ASSIGN;
486 } else {
487 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
488 return '*';
489 }
490 case '%':
491 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
492 if (ch == '=') {
493 return CPP_MOD_ASSIGN;
494 } else if (ch == '>'){
495 return CPP_RIGHT_BRACE;
496 } else {
497 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
498 return '%';
499 }
500 case ':':
501 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
502 if (ch == '>') {
503 return CPP_RIGHT_BRACKET;
504 } else {
505 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
506 return ':';
507 }
508 case '^':
509 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
510 if (ch == '^') {
511 return CPP_XOR_OP;
512 } else {
513 if (ch == '=')
514 return CPP_XOR_ASSIGN;
515 else{
516 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
517 return '^';
518 }
519 }
520
521 case '=':
522 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
523 if (ch == '=') {
524 return CPP_EQ_OP;
525 } else {
526 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
527 return '=';
528 }
529 case '!':
530 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
531 if (ch == '=') {
532 return CPP_NE_OP;
533 } else {
534 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
535 return '!';
536 }
537 case '|':
538 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
539 if (ch == '|') {
540 return CPP_OR_OP;
541 } else {
542 if (ch == '=')
543 return CPP_OR_ASSIGN;
544 else{
545 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
546 return '|';
547 }
548 }
549 case '&':
550 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
551 if (ch == '&') {
552 return CPP_AND_OP;
553 } else {
554 if (ch == '=')
555 return CPP_AND_ASSIGN;
556 else{
557 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
558 return '&';
559 }
560 }
561 case '<':
562 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
563 if (ch == '<') {
564 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
565 if(ch == '=')
566 return CPP_LEFT_ASSIGN;
567 else{
568 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
569 return CPP_LEFT_OP;
570 }
571 } else {
572 if (ch == '=') {
573 return CPP_LE_OP;
574 } else {
575 if (ch == '%')
576 return CPP_LEFT_BRACE;
577 else if (ch == ':')
578 return CPP_LEFT_BRACKET;
579 else{
580 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
581 return '<';
582 }
583 }
584 }
585 case '>':
586 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
587 if (ch == '>') {
588 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
589 if(ch == '=')
590 return CPP_RIGHT_ASSIGN;
591 else{
592 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
593 return CPP_RIGHT_OP;
594 }
595 } else {
596 if (ch == '=') {
597 return CPP_GE_OP;
598 } else {
599 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
600 return '>';
601 }
602 }
603 case '.':
604 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
605 if (ch >= '0' && ch <= '9') {
606 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
607 return lFloatConst(yylvalpp->symbol_name, 0, '.', yylvalpp);
608 } else {
609 if (ch == '.') {
610 return -1; // Special EOF hack
611 } else {
612 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
613 return '.';
614 }
615 }
616 case '/':
617 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
618 if (ch == '/') {
619 do {
620 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
621 } while (ch != '\n' && ch != EOF);
622 if (ch == EOF)
623 return -1;
624 return '\n';
625 } else if (ch == '*') {
626 int nlcount = 0;
627 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
628 do {
629 while (ch != '*') {
630 if (ch == '\n') nlcount++;
631 if (ch == EOF) {
632 CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
633 return -1;
634 }
635 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
636 }
637 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
638 if (ch == EOF) {
639 CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
640 return -1;
641 }
642 } while (ch != '/');
643 if (nlcount) {
644 return '\n';
645 }
646 // Go try it again...
647 } else if (ch == '=') {
648 return CPP_DIV_ASSIGN;
649 } else {
650 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
651 return '/';
652 }
653 break;
654 case '"':
655 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
656 while (ch != '"' && ch != '\n' && ch != EOF) {
657 if (ch == '\\') {
daniel@transgaming.comedff8dc2010-05-14 17:30:27 +0000658 CPPErrorToInfoLog("The line continuation character (\\) is not part of the OpenGL ES Shading Language");
659 return -1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000660 }
661 if (len < MAX_STRING_LEN) {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000662 string_val[len++] = ch;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000663 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
664 }
665 };
666 string_val[len] = '\0';
667 if (ch == '"') {
668 yylvalpp->sc_ident = LookUpAddString(atable, string_val);
669 return CPP_STRCONSTANT;
670 } else {
671 CPPErrorToInfoLog("ERROR___CPP_EOL_IN_STRING");
672 return ERROR_SY;
673 }
674 }
675 }
676} // byte_scan
677
678int yylex_CPP(char* buf, int maxSize)
679{
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000680 yystypepp yylvalpp;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000681 int token = '\n';
682
683 for(;;) {
684
685 char* tokenString = 0;
686 token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000687 if(check_EOF(token))
688 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000689 if (token == '#') {
690 if (cpp->previous_token == '\n'|| cpp->previous_token == 0) {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000691 token = readCPPline(&yylvalpp);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000692 if(check_EOF(token))
693 return 0;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000694 continue;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000695 } else {
696 CPPErrorToInfoLog("preprocessor command must not be preceded by any other statement in that line");
697 return 0;
698 }
699 }
700 cpp->previous_token = token;
701 // expand macros
702 if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) {
daniel@transgaming.comdec19e22010-04-29 03:35:42 +0000703 cpp->pastFirstStatement = 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000704 continue;
705 }
706
707 if (token == '\n')
708 continue;
709
710 if (token == CPP_IDENTIFIER) {
daniel@transgaming.comdec19e22010-04-29 03:35:42 +0000711 cpp->pastFirstStatement = 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000712 tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
713 } else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){
daniel@transgaming.comdec19e22010-04-29 03:35:42 +0000714 cpp->pastFirstStatement = 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000715 tokenString = yylvalpp.symbol_name;
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000716 } else {
daniel@transgaming.comdec19e22010-04-29 03:35:42 +0000717 cpp->pastFirstStatement = 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000718 tokenString = GetStringOfAtom(atable,token);
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000719 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000720
721 if (tokenString) {
722 if ((signed)strlen(tokenString) >= maxSize) {
723 cpp->tokensBeforeEOF = 1;
724 return maxSize;
725 } else if (strlen(tokenString) > 0) {
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000726 strcpy(buf, tokenString);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000727 cpp->tokensBeforeEOF = 1;
728 return (int)strlen(tokenString);
729 }
730
731 return 0;
732 }
733 }
734
735 return 0;
736} // yylex
737
738//Checks if the token just read is EOF or not.
739int check_EOF(int token)
740{
741 if(token==-1){
742 if(cpp->ifdepth >0){
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000743 CPPErrorToInfoLog("#endif missing!! Compilation stopped");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000744 cpp->CompileError=1;
745 }
746 return 1;
747 }
748 return 0;
749}
750
751///////////////////////////////////////////////////////////////////////////////////////////////
752/////////////////////////////////////// End of scanner.c //////////////////////////////////////
753///////////////////////////////////////////////////////////////////////////////////////////////
754