i965: Fix array indexing of arrays of matrices.
[mesa.git] / src / glsl / glsl_lexer.lpp
1 %{
2 /*
3 * Copyright © 2008, 2009 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24 #include <ctype.h>
25 #include "ast.h"
26 #include "glsl_parser_extras.h"
27 #include "glsl_parser.h"
28
29 #define YY_USER_ACTION \
30 do { \
31 yylloc->source = 0; \
32 yylloc->first_column = yycolumn + 1; \
33 yylloc->first_line = yylineno + 1; \
34 yycolumn += yyleng; \
35 } while(0);
36
37 #define YY_USER_INIT yylineno = 0; yycolumn = 0;
38
39 #define TOKEN_OR_IDENTIFIER(version, token) \
40 do { \
41 if (yyextra->language_version >= version) { \
42 return token; \
43 } else { \
44 yylval->identifier = strdup(yytext); \
45 return IDENTIFIER; \
46 } \
47 } while (0)
48
49 /* Handle reserved words in GLSL ES (version 100) */
50 #define TOKEN_OR_IDENTIFIER_ES(version, token) \
51 do { \
52 if (yyextra->es_shader) { \
53 return token; \
54 } else { \
55 TOKEN_OR_IDENTIFIER(version, token); \
56 } \
57 } while (0)
58
59 #define RESERVED_WORD(version, token) \
60 do { \
61 if (yyextra->language_version >= version) { \
62 return token; \
63 } else { \
64 _mesa_glsl_error(yylloc, yyextra, \
65 "Illegal use of reserved word `%s'", yytext); \
66 return ERROR_TOK; \
67 } \
68 } while (0)
69 %}
70
71 %option bison-bridge bison-locations reentrant noyywrap
72 %option nounput noyy_top_state
73 %option never-interactive
74 %option prefix="_mesa_glsl_"
75 %option extra-type="struct _mesa_glsl_parse_state *"
76
77 %x PP PRAGMA
78
79 DEC_INT [1-9][0-9]*
80 HEX_INT 0[xX][0-9a-fA-F]+
81 OCT_INT 0[0-7]*
82 INT ({DEC_INT}|{HEX_INT}|{OCT_INT})
83 SPC [ \t]*
84 SPCP [ \t]+
85 HASH ^{SPC}#{SPC}
86 %%
87
88 [ \r\t]+ ;
89
90 /* Preprocessor tokens. */
91 ^[ \t]*#[ \t]*$ ;
92 ^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; }
93 ^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; }
94 {HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
95 /* Eat characters until the first digit is
96 * encountered
97 */
98 char *ptr = yytext;
99 while (!isdigit(*ptr))
100 ptr++;
101
102 /* Subtract one from the line number because
103 * yylineno is zero-based instead of
104 * one-based.
105 */
106 yylineno = strtol(ptr, &ptr, 0) - 1;
107 yylloc->source = strtol(ptr, NULL, 0);
108 }
109 {HASH}line{SPCP}{INT}{SPC}$ {
110 /* Eat characters until the first digit is
111 * encountered
112 */
113 char *ptr = yytext;
114 while (!isdigit(*ptr))
115 ptr++;
116
117 /* Subtract one from the line number because
118 * yylineno is zero-based instead of
119 * one-based.
120 */
121 yylineno = strtol(ptr, &ptr, 0) - 1;
122 }
123 ^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) {
124 BEGIN PP;
125 return PRAGMA_DEBUG_ON;
126 }
127 ^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}off{SPC}\) {
128 BEGIN PP;
129 return PRAGMA_DEBUG_OFF;
130 }
131 ^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}on{SPC}\) {
132 BEGIN PP;
133 return PRAGMA_OPTIMIZE_ON;
134 }
135 ^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}off{SPC}\) {
136 BEGIN PP;
137 return PRAGMA_OPTIMIZE_OFF;
138 }
139 ^{SPC}#{SPC}pragma{SPCP} { BEGIN PRAGMA; }
140
141 <PRAGMA>\n { BEGIN 0; yylineno++; yycolumn = 0; }
142 <PRAGMA>. { }
143
144 <PP>\/\/[^\n]* { }
145 <PP>[ \t\r]* { }
146 <PP>: return COLON;
147 <PP>[_a-zA-Z][_a-zA-Z0-9]* {
148 yylval->identifier = strdup(yytext);
149 return IDENTIFIER;
150 }
151 <PP>[1-9][0-9]* {
152 yylval->n = strtol(yytext, NULL, 10);
153 return INTCONSTANT;
154 }
155 <PP>\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
156
157 \n { yylineno++; yycolumn = 0; }
158
159 attribute return ATTRIBUTE;
160 const return CONST_TOK;
161 bool return BOOL_TOK;
162 float return FLOAT_TOK;
163 int return INT_TOK;
164
165 break return BREAK;
166 continue return CONTINUE;
167 do return DO;
168 while return WHILE;
169 else return ELSE;
170 for return FOR;
171 if return IF;
172 discard return DISCARD;
173 return return RETURN;
174
175 bvec2 return BVEC2;
176 bvec3 return BVEC3;
177 bvec4 return BVEC4;
178 ivec2 return IVEC2;
179 ivec3 return IVEC3;
180 ivec4 return IVEC4;
181 vec2 return VEC2;
182 vec3 return VEC3;
183 vec4 return VEC4;
184 mat2 return MAT2X2;
185 mat3 return MAT3X3;
186 mat4 return MAT4X4;
187 mat2x2 TOKEN_OR_IDENTIFIER(120, MAT2X2);
188 mat2x3 TOKEN_OR_IDENTIFIER(120, MAT2X3);
189 mat2x4 TOKEN_OR_IDENTIFIER(120, MAT2X4);
190 mat3x2 TOKEN_OR_IDENTIFIER(120, MAT3X2);
191 mat3x3 TOKEN_OR_IDENTIFIER(120, MAT3X3);
192 mat3x4 TOKEN_OR_IDENTIFIER(120, MAT3X4);
193 mat4x2 TOKEN_OR_IDENTIFIER(120, MAT4X2);
194 mat4x3 TOKEN_OR_IDENTIFIER(120, MAT4X3);
195 mat4x4 TOKEN_OR_IDENTIFIER(120, MAT4X4);
196
197 in return IN_TOK;
198 out return OUT_TOK;
199 inout return INOUT_TOK;
200 uniform return UNIFORM;
201 varying return VARYING;
202 centroid TOKEN_OR_IDENTIFIER(120, CENTROID);
203 invariant TOKEN_OR_IDENTIFIER_ES(120, INVARIANT);
204
205 flat TOKEN_OR_IDENTIFIER_ES(130, FLAT);
206 smooth TOKEN_OR_IDENTIFIER(130, SMOOTH);
207 noperspective TOKEN_OR_IDENTIFIER(130, NOPERSPECTIVE);
208
209 sampler1D return SAMPLER1D;
210 sampler2D return SAMPLER2D;
211 sampler3D return SAMPLER3D;
212 samplerCube return SAMPLERCUBE;
213 sampler1DShadow return SAMPLER1DSHADOW;
214 sampler2DShadow return SAMPLER2DSHADOW;
215
216 struct return STRUCT;
217 void return VOID_TOK;
218
219 layout {
220 if ((yyextra->language_version >= 140)
221 || (yyextra->ARB_fragment_coord_conventions_enable)){
222 return LAYOUT_TOK;
223 } else {
224 yylval->identifier = strdup(yytext);
225 return IDENTIFIER;
226 }
227 }
228
229 \+\+ return INC_OP;
230 -- return DEC_OP;
231 \<= return LE_OP;
232 >= return GE_OP;
233 == return EQ_OP;
234 != return NE_OP;
235 && return AND_OP;
236 \|\| return OR_OP;
237 "^^" return XOR_OP;
238
239 \*= return MUL_ASSIGN;
240 \/= return DIV_ASSIGN;
241 \+= return ADD_ASSIGN;
242 \%= return MOD_ASSIGN;
243 \<\<= return LEFT_ASSIGN;
244 >>= return RIGHT_ASSIGN;
245 &= return AND_ASSIGN;
246 ^= return XOR_ASSIGN;
247 \|= return OR_ASSIGN;
248 -= return SUB_ASSIGN;
249
250 [1-9][0-9]* {
251 yylval->n = strtol(yytext, NULL, 10);
252 return INTCONSTANT;
253 }
254 0[xX][0-9a-fA-F]+ {
255 yylval->n = strtol(yytext + 2, NULL, 16);
256 return INTCONSTANT;
257 }
258 0[0-7]* {
259 yylval->n = strtol(yytext, NULL, 8);
260 return INTCONSTANT;
261 }
262
263 [0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
264 yylval->real = strtod(yytext, NULL);
265 return FLOATCONSTANT;
266 }
267 \.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
268 yylval->real = strtod(yytext, NULL);
269 return FLOATCONSTANT;
270 }
271 [0-9]+\.([eE][+-]?[0-9]+)?[fF]? {
272 yylval->real = strtod(yytext, NULL);
273 return FLOATCONSTANT;
274 }
275 [0-9]+[eE][+-]?[0-9]+[fF]? {
276 yylval->real = strtod(yytext, NULL);
277 return FLOATCONSTANT;
278 }
279 [0-9]+[fF] {
280 yylval->real = strtod(yytext, NULL);
281 return FLOATCONSTANT;
282 }
283
284 true {
285 yylval->n = 1;
286 return BOOLCONSTANT;
287 }
288 false {
289 yylval->n = 0;
290 return BOOLCONSTANT;
291 }
292
293
294 /* Reserved words in GLSL 1.10. */
295 asm RESERVED_WORD(999, ASM);
296 class RESERVED_WORD(999, CLASS);
297 union RESERVED_WORD(999, UNION);
298 enum RESERVED_WORD(999, ENUM);
299 typedef RESERVED_WORD(999, TYPEDEF);
300 template RESERVED_WORD(999, TEMPLATE);
301 this RESERVED_WORD(999, THIS);
302 packed RESERVED_WORD(999, PACKED_TOK);
303 goto RESERVED_WORD(999, GOTO);
304 switch RESERVED_WORD(130, SWITCH);
305 default RESERVED_WORD(130, DEFAULT);
306 inline RESERVED_WORD(999, INLINE_TOK);
307 noinline RESERVED_WORD(999, NOINLINE);
308 volatile RESERVED_WORD(999, VOLATILE);
309 public RESERVED_WORD(999, PUBLIC_TOK);
310 static RESERVED_WORD(999, STATIC);
311 extern RESERVED_WORD(999, EXTERN);
312 external RESERVED_WORD(999, EXTERNAL);
313 interface RESERVED_WORD(999, INTERFACE);
314 long RESERVED_WORD(999, LONG_TOK);
315 short RESERVED_WORD(999, SHORT_TOK);
316 double RESERVED_WORD(999, DOUBLE_TOK);
317 half RESERVED_WORD(999, HALF);
318 fixed RESERVED_WORD(999, FIXED_TOK);
319 unsigned RESERVED_WORD(999, UNSIGNED);
320 input RESERVED_WORD(999, INPUT_TOK);
321 output RESERVED_WORD(999, OUTPUT);
322 hvec2 RESERVED_WORD(999, HVEC2);
323 hvec3 RESERVED_WORD(999, HVEC3);
324 hvec4 RESERVED_WORD(999, HVEC4);
325 dvec2 RESERVED_WORD(999, DVEC2);
326 dvec3 RESERVED_WORD(999, DVEC3);
327 dvec4 RESERVED_WORD(999, DVEC4);
328 fvec2 RESERVED_WORD(999, FVEC2);
329 fvec3 RESERVED_WORD(999, FVEC3);
330 fvec4 RESERVED_WORD(999, FVEC4);
331 sampler2DRect return SAMPLER2DRECT;
332 sampler3DRect RESERVED_WORD(999, SAMPLER3DRECT);
333 sampler2DRectShadow return SAMPLER2DRECTSHADOW;
334 sizeof RESERVED_WORD(999, SIZEOF);
335 cast RESERVED_WORD(999, CAST);
336 namespace RESERVED_WORD(999, NAMESPACE);
337 using RESERVED_WORD(999, USING);
338
339 /* Additional reserved words in GLSL 1.20. */
340 lowp TOKEN_OR_IDENTIFIER_ES(120, LOWP);
341 mediump TOKEN_OR_IDENTIFIER_ES(120, MEDIUMP);
342 highp TOKEN_OR_IDENTIFIER_ES(120, HIGHP);
343 precision TOKEN_OR_IDENTIFIER_ES(120, PRECISION);
344
345 /* Additional reserved words in GLSL 1.30. */
346 common TOKEN_OR_IDENTIFIER(130, COMMON);
347 partition TOKEN_OR_IDENTIFIER(130, PARTITION);
348 active TOKEN_OR_IDENTIFIER(130, ACTIVE);
349 superp TOKEN_OR_IDENTIFIER_ES(130, SUPERP);
350 samplerBuffer TOKEN_OR_IDENTIFIER(130, SAMPLERBUFFER);
351 filter TOKEN_OR_IDENTIFIER(130, FILTER);
352 image1D TOKEN_OR_IDENTIFIER(130, IMAGE1D);
353 image2D TOKEN_OR_IDENTIFIER(130, IMAGE2D);
354 image3D TOKEN_OR_IDENTIFIER(130, IMAGE3D);
355 imageCube TOKEN_OR_IDENTIFIER(130, IMAGECUBE);
356 iimage1D TOKEN_OR_IDENTIFIER(130, IIMAGE1D);
357 iimage2D TOKEN_OR_IDENTIFIER(130, IIMAGE2D);
358 iimage3D TOKEN_OR_IDENTIFIER(130, IIMAGE3D);
359 iimageCube TOKEN_OR_IDENTIFIER(130, IIMAGECUBE);
360 uimage1D TOKEN_OR_IDENTIFIER(130, UIMAGE1D);
361 uimage2D TOKEN_OR_IDENTIFIER(130, UIMAGE2D);
362 uimage3D TOKEN_OR_IDENTIFIER(130, UIMAGE3D);
363 uimageCube TOKEN_OR_IDENTIFIER(130, UIMAGECUBE);
364 image1DArray TOKEN_OR_IDENTIFIER(130, IMAGE1DARRAY);
365 image2DArray TOKEN_OR_IDENTIFIER(130, IMAGE2DARRAY);
366 iimage1DArray TOKEN_OR_IDENTIFIER(130, IIMAGE1DARRAY);
367 iimage2DArray TOKEN_OR_IDENTIFIER(130, IIMAGE2DARRAY);
368 uimage1DArray TOKEN_OR_IDENTIFIER(130, UIMAGE1DARRAY);
369 uimage2DArray TOKEN_OR_IDENTIFIER(130, UIMAGE2DARRAY);
370 image1DShadow TOKEN_OR_IDENTIFIER(130, IMAGE1DSHADOW);
371 image2DShadow TOKEN_OR_IDENTIFIER(130, IMAGE2DSHADOW);
372 imageBuffer TOKEN_OR_IDENTIFIER(130, IMAGEBUFFER);
373 iimageBuffer TOKEN_OR_IDENTIFIER(130, IIMAGEBUFFER);
374 uimageBuffer TOKEN_OR_IDENTIFIER(130, UIMAGEBUFFER);
375 row_major TOKEN_OR_IDENTIFIER(130, ROW_MAJOR);
376
377 [_a-zA-Z][_a-zA-Z0-9]* {
378 struct _mesa_glsl_parse_state *state = yyextra;
379 void *ctx = state;
380 yylval->identifier = talloc_strdup(ctx, yytext);
381 return IDENTIFIER;
382 }
383
384 . { return yytext[0]; }
385
386 %%
387
388 void
389 _mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string)
390 {
391 yylex_init_extra(state, & state->scanner);
392 yy_scan_string(string, state->scanner);
393 }
394
395 void
396 _mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
397 {
398 yylex_destroy(state->scanner);
399 }