Merge commit 'origin/master' into glsl-pp-rework-2
[mesa.git] / src / mesa / shader / slang / slang_compile.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
5 * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file slang_compile.c
27 * slang front-end compiler
28 * \author Michal Krol
29 */
30
31 #include "main/imports.h"
32 #include "main/context.h"
33 #include "shader/program.h"
34 #include "shader/programopt.h"
35 #include "shader/prog_optimize.h"
36 #include "shader/prog_print.h"
37 #include "shader/prog_parameter.h"
38 #include "shader/grammar/grammar_mesa.h"
39 #include "../../glsl/pp/sl_pp_context.h"
40 #include "../../glsl/pp/sl_pp_purify.h"
41 #include "../../glsl/pp/sl_pp_version.h"
42 #include "../../glsl/pp/sl_pp_process.h"
43 #include "slang_codegen.h"
44 #include "slang_compile.h"
45 #include "slang_storage.h"
46 #include "slang_emit.h"
47 #include "slang_log.h"
48 #include "slang_mem.h"
49 #include "slang_vartable.h"
50 #include "slang_simplify.h"
51
52 #include "slang_print.h"
53
54 /*
55 * This is a straightforward implementation of the slang front-end
56 * compiler. Lots of error-checking functionality is missing but
57 * every well-formed shader source should compile successfully and
58 * execute as expected. However, some semantically ill-formed shaders
59 * may be accepted resulting in undefined behaviour.
60 */
61
62
63 /** re-defined below, should be the same though */
64 #define TYPE_SPECIFIER_COUNT 32
65
66
67 /**
68 * Check if the given identifier is legal.
69 */
70 static GLboolean
71 legal_identifier(slang_atom name)
72 {
73 /* "gl_" is a reserved prefix */
74 if (_mesa_strncmp((char *) name, "gl_", 3) == 0) {
75 return GL_FALSE;
76 }
77 return GL_TRUE;
78 }
79
80
81 /*
82 * slang_code_unit
83 */
84
85 GLvoid
86 _slang_code_unit_ctr(slang_code_unit * self,
87 struct slang_code_object_ * object)
88 {
89 _slang_variable_scope_ctr(&self->vars);
90 _slang_function_scope_ctr(&self->funs);
91 _slang_struct_scope_ctr(&self->structs);
92 self->object = object;
93 }
94
95 GLvoid
96 _slang_code_unit_dtr(slang_code_unit * self)
97 {
98 slang_variable_scope_destruct(&self->vars);
99 slang_function_scope_destruct(&self->funs);
100 slang_struct_scope_destruct(&self->structs);
101 }
102
103 /*
104 * slang_code_object
105 */
106
107 GLvoid
108 _slang_code_object_ctr(slang_code_object * self)
109 {
110 GLuint i;
111
112 for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
113 _slang_code_unit_ctr(&self->builtin[i], self);
114 _slang_code_unit_ctr(&self->unit, self);
115 slang_atom_pool_construct(&self->atompool);
116 }
117
118 GLvoid
119 _slang_code_object_dtr(slang_code_object * self)
120 {
121 GLuint i;
122
123 for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
124 _slang_code_unit_dtr(&self->builtin[i]);
125 _slang_code_unit_dtr(&self->unit);
126 slang_atom_pool_destruct(&self->atompool);
127 }
128
129
130 /* slang_parse_ctx */
131
132 typedef struct slang_parse_ctx_
133 {
134 const byte *I;
135 slang_info_log *L;
136 int parsing_builtin;
137 GLboolean global_scope; /**< Is object being declared a global? */
138 slang_atom_pool *atoms;
139 slang_unit_type type; /**< Vertex vs. Fragment */
140 GLuint version; /**< user-specified (or default) #version */
141 } slang_parse_ctx;
142
143 /* slang_output_ctx */
144
145 typedef struct slang_output_ctx_
146 {
147 slang_variable_scope *vars;
148 slang_function_scope *funs;
149 slang_struct_scope *structs;
150 struct gl_program *program;
151 struct gl_sl_pragmas *pragmas;
152 slang_var_table *vartable;
153 GLuint default_precision[TYPE_SPECIFIER_COUNT];
154 GLboolean allow_precision;
155 GLboolean allow_invariant;
156 GLboolean allow_centroid;
157 GLboolean allow_array_types; /* float[] syntax */
158 } slang_output_ctx;
159
160 /* _slang_compile() */
161
162
163 /* Debugging aid, print file/line where parsing error is detected */
164 #define RETURN0 \
165 do { \
166 if (0) \
167 printf("slang error at %s:%d\n", __FILE__, __LINE__); \
168 return 0; \
169 } while (0)
170
171
172 static void
173 parse_identifier_str(slang_parse_ctx * C, char **id)
174 {
175 *id = (char *) C->I;
176 C->I += _mesa_strlen(*id) + 1;
177 }
178
179 static slang_atom
180 parse_identifier(slang_parse_ctx * C)
181 {
182 const char *id;
183
184 id = (const char *) C->I;
185 C->I += _mesa_strlen(id) + 1;
186 return slang_atom_pool_atom(C->atoms, id);
187 }
188
189 static int
190 is_hex_digit(char c)
191 {
192 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
193 }
194
195 static int
196 parse_general_number(slang_parse_ctx *ctx, float *number)
197 {
198 char *flt = NULL;
199
200 if (*ctx->I == '0') {
201 int value = 0;
202 const byte *pi;
203
204 if (ctx->I[1] == 'x' || ctx->I[1] == 'X') {
205 ctx->I += 2;
206 if (!is_hex_digit(*ctx->I)) {
207 return 0;
208 }
209 do {
210 int digit;
211
212 if (*ctx->I >= '0' && *ctx->I <= '9') {
213 digit = (int)(*ctx->I - '0');
214 } else if (*ctx->I >= 'a' && *ctx->I <= 'f') {
215 digit = (int)(*ctx->I - 'a') + 10;
216 } else {
217 digit = (int)(*ctx->I - 'A') + 10;
218 }
219 value = value * 0x10 + digit;
220 ctx->I++;
221 } while (is_hex_digit(*ctx->I));
222 if (*ctx->I != '\0') {
223 return 0;
224 }
225 ctx->I++;
226 *number = (float)value;
227 return 1;
228 }
229
230 pi = ctx->I;
231 pi++;
232 while (*pi >= '0' && *pi <= '7') {
233 int digit;
234
235 digit = (int)(*pi - '0');
236 value = value * 010 + digit;
237 pi++;
238 }
239 if (*pi == '\0') {
240 pi++;
241 ctx->I = pi;
242 *number = (float)value;
243 return 1;
244 }
245 }
246
247 parse_identifier_str(ctx, &flt);
248 flt = strdup(flt);
249 if (!flt) {
250 return 0;
251 }
252 if (flt[strlen(flt) - 1] == 'f' || flt[strlen(flt) - 1] == 'F') {
253 flt[strlen(flt) - 1] = '\0';
254 }
255 *number = (float)_mesa_strtod(flt, (char **)NULL);
256 free(flt);
257
258 return 1;
259 }
260
261 static int
262 parse_number(slang_parse_ctx * C, int *number)
263 {
264 const int radix = (int) (*C->I++);
265
266 if (radix == 1) {
267 float f = 0.0f;
268
269 parse_general_number(C, &f);
270 *number = (int)f;
271 } else {
272 *number = 0;
273 while (*C->I != '\0') {
274 int digit;
275 if (*C->I >= '0' && *C->I <= '9')
276 digit = (int) (*C->I - '0');
277 else if (*C->I >= 'A' && *C->I <= 'Z')
278 digit = (int) (*C->I - 'A') + 10;
279 else
280 digit = (int) (*C->I - 'a') + 10;
281 *number = *number * radix + digit;
282 C->I++;
283 }
284 C->I++;
285 }
286 if (*number > 65535)
287 slang_info_log_warning(C->L, "%d: literal integer overflow.", *number);
288 return 1;
289 }
290
291 static int
292 parse_float(slang_parse_ctx * C, float *number)
293 {
294 if (*C->I == 1) {
295 C->I++;
296 parse_general_number(C, number);
297 } else {
298 char *integral = NULL;
299 char *fractional = NULL;
300 char *exponent = NULL;
301 char *whole = NULL;
302
303 parse_identifier_str(C, &integral);
304 parse_identifier_str(C, &fractional);
305 parse_identifier_str(C, &exponent);
306
307 whole = (char *) _slang_alloc((_mesa_strlen(integral) +
308 _mesa_strlen(fractional) +
309 _mesa_strlen(exponent) + 3) * sizeof(char));
310 if (whole == NULL) {
311 slang_info_log_memory(C->L);
312 RETURN0;
313 }
314
315 slang_string_copy(whole, integral);
316 slang_string_concat(whole, ".");
317 slang_string_concat(whole, fractional);
318 slang_string_concat(whole, "E");
319 slang_string_concat(whole, exponent);
320
321 *number = (float) (_mesa_strtod(whole, (char **) NULL));
322
323 _slang_free(whole);
324 }
325
326 return 1;
327 }
328
329 /* revision number - increment after each change affecting emitted output */
330 #define REVISION 5
331
332 static int
333 check_revision(slang_parse_ctx * C)
334 {
335 if (*C->I != REVISION) {
336 slang_info_log_error(C->L, "Internal compiler error.");
337 RETURN0;
338 }
339 C->I++;
340 return 1;
341 }
342
343 static int parse_statement(slang_parse_ctx *, slang_output_ctx *,
344 slang_operation *);
345 static int parse_expression(slang_parse_ctx *, slang_output_ctx *,
346 slang_operation *);
347 static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *,
348 slang_type_specifier *);
349 static int
350 parse_type_array_size(slang_parse_ctx *C,
351 slang_output_ctx *O,
352 GLint *array_len);
353
354 static GLboolean
355 parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len)
356 {
357 slang_operation array_size;
358 slang_name_space space;
359 GLboolean result;
360
361 if (!slang_operation_construct(&array_size))
362 return GL_FALSE;
363 if (!parse_expression(C, O, &array_size)) {
364 slang_operation_destruct(&array_size);
365 return GL_FALSE;
366 }
367
368 space.funcs = O->funs;
369 space.structs = O->structs;
370 space.vars = O->vars;
371
372 /* evaluate compile-time expression which is array size */
373 _slang_simplify(&array_size, &space, C->atoms);
374
375 if (array_size.type == SLANG_OPER_LITERAL_INT) {
376 result = GL_TRUE;
377 *len = (GLint) array_size.literal[0];
378 } else if (array_size.type == SLANG_OPER_IDENTIFIER) {
379 slang_variable *var = _slang_variable_locate(array_size.locals, array_size.a_id, GL_TRUE);
380 if (!var) {
381 slang_info_log_error(C->L, "undefined variable '%s'",
382 (char *) array_size.a_id);
383 result = GL_FALSE;
384 } else if (var->type.qualifier == SLANG_QUAL_CONST &&
385 var->type.specifier.type == SLANG_SPEC_INT) {
386 if (var->initializer &&
387 var->initializer->type == SLANG_OPER_LITERAL_INT) {
388 *len = (GLint) var->initializer->literal[0];
389 result = GL_TRUE;
390 } else {
391 slang_info_log_error(C->L, "unable to parse array size declaration");
392 result = GL_FALSE;
393 }
394 } else {
395 slang_info_log_error(C->L, "unable to parse array size declaration");
396 result = GL_FALSE;
397 }
398 } else {
399 result = GL_FALSE;
400 }
401
402 slang_operation_destruct(&array_size);
403 return result;
404 }
405
406 static GLboolean
407 calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O,
408 slang_variable * var)
409 {
410 slang_storage_aggregate agg;
411
412 if (!slang_storage_aggregate_construct(&agg))
413 return GL_FALSE;
414 if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len,
415 O->funs, O->structs, O->vars, C->atoms)) {
416 slang_storage_aggregate_destruct(&agg);
417 return GL_FALSE;
418 }
419 var->size = _slang_sizeof_aggregate(&agg);
420 slang_storage_aggregate_destruct(&agg);
421 return GL_TRUE;
422 }
423
424 static void
425 promote_type_to_array(slang_parse_ctx *C,
426 slang_fully_specified_type *type,
427 GLint array_len)
428 {
429 slang_type_specifier *baseType =
430 slang_type_specifier_new(type->specifier.type, NULL, NULL);
431
432 type->specifier.type = SLANG_SPEC_ARRAY;
433 type->specifier._array = baseType;
434 type->array_len = array_len;
435 }
436
437
438 static GLboolean
439 convert_to_array(slang_parse_ctx * C, slang_variable * var,
440 const slang_type_specifier * sp)
441 {
442 /* sized array - mark it as array, copy the specifier to the array element
443 * and parse the expression */
444 var->type.specifier.type = SLANG_SPEC_ARRAY;
445 var->type.specifier._array = (slang_type_specifier *)
446 _slang_alloc(sizeof(slang_type_specifier));
447 if (var->type.specifier._array == NULL) {
448 slang_info_log_memory(C->L);
449 return GL_FALSE;
450 }
451 slang_type_specifier_ctr(var->type.specifier._array);
452 return slang_type_specifier_copy(var->type.specifier._array, sp);
453 }
454
455 /* structure field */
456 #define FIELD_NONE 0
457 #define FIELD_NEXT 1
458 #define FIELD_ARRAY 2
459
460 static GLboolean
461 parse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O,
462 slang_variable * var, slang_atom a_name,
463 const slang_type_specifier * sp,
464 GLuint array_len)
465 {
466 var->a_name = a_name;
467 if (var->a_name == SLANG_ATOM_NULL)
468 return GL_FALSE;
469
470 switch (*C->I++) {
471 case FIELD_NONE:
472 if (array_len != -1) {
473 if (!convert_to_array(C, var, sp))
474 return GL_FALSE;
475 var->array_len = array_len;
476 }
477 else {
478 if (!slang_type_specifier_copy(&var->type.specifier, sp))
479 return GL_FALSE;
480 }
481 break;
482 case FIELD_ARRAY:
483 if (array_len != -1)
484 return GL_FALSE;
485 if (!convert_to_array(C, var, sp))
486 return GL_FALSE;
487 if (!parse_array_len(C, O, &var->array_len))
488 return GL_FALSE;
489 break;
490 default:
491 return GL_FALSE;
492 }
493
494 return calculate_var_size(C, O, var);
495 }
496
497 static int
498 parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O,
499 slang_struct * st, slang_type_specifier * sp)
500 {
501 slang_output_ctx o = *O;
502 GLint array_len;
503
504 o.structs = st->structs;
505 if (!parse_type_specifier(C, &o, sp))
506 RETURN0;
507 if (!parse_type_array_size(C, &o, &array_len))
508 RETURN0;
509
510 do {
511 slang_atom a_name;
512 slang_variable *var = slang_variable_scope_grow(st->fields);
513 if (!var) {
514 slang_info_log_memory(C->L);
515 RETURN0;
516 }
517 a_name = parse_identifier(C);
518 if (_slang_variable_locate(st->fields, a_name, GL_FALSE)) {
519 slang_info_log_error(C->L, "duplicate field '%s'", (char *) a_name);
520 RETURN0;
521 }
522
523 if (!parse_struct_field_var(C, &o, var, a_name, sp, array_len))
524 RETURN0;
525 }
526 while (*C->I++ != FIELD_NONE);
527
528 return 1;
529 }
530
531 static int
532 parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st)
533 {
534 slang_atom a_name;
535 const char *name;
536
537 /* parse struct name (if any) and make sure it is unique in current scope */
538 a_name = parse_identifier(C);
539 if (a_name == SLANG_ATOM_NULL)
540 RETURN0;
541
542 name = slang_atom_pool_id(C->atoms, a_name);
543 if (name[0] != '\0'
544 && slang_struct_scope_find(O->structs, a_name, 0) != NULL) {
545 slang_info_log_error(C->L, "%s: duplicate type name.", name);
546 RETURN0;
547 }
548
549 /* set-up a new struct */
550 *st = (slang_struct *) _slang_alloc(sizeof(slang_struct));
551 if (*st == NULL) {
552 slang_info_log_memory(C->L);
553 RETURN0;
554 }
555 if (!slang_struct_construct(*st)) {
556 _slang_free(*st);
557 *st = NULL;
558 slang_info_log_memory(C->L);
559 RETURN0;
560 }
561 (**st).a_name = a_name;
562 (**st).structs->outer_scope = O->structs;
563
564 /* parse individual struct fields */
565 do {
566 slang_type_specifier sp;
567
568 slang_type_specifier_ctr(&sp);
569 if (!parse_struct_field(C, O, *st, &sp)) {
570 slang_type_specifier_dtr(&sp);
571 RETURN0;
572 }
573 slang_type_specifier_dtr(&sp);
574 }
575 while (*C->I++ != FIELD_NONE);
576
577 /* if named struct, copy it to current scope */
578 if (name[0] != '\0') {
579 slang_struct *s;
580
581 O->structs->structs =
582 (slang_struct *) _slang_realloc(O->structs->structs,
583 O->structs->num_structs
584 * sizeof(slang_struct),
585 (O->structs->num_structs + 1)
586 * sizeof(slang_struct));
587 if (O->structs->structs == NULL) {
588 slang_info_log_memory(C->L);
589 RETURN0;
590 }
591 s = &O->structs->structs[O->structs->num_structs];
592 if (!slang_struct_construct(s))
593 RETURN0;
594 O->structs->num_structs++;
595 if (!slang_struct_copy(s, *st))
596 RETURN0;
597 }
598
599 return 1;
600 }
601
602
603 /* invariant qualifer */
604 #define TYPE_VARIANT 90
605 #define TYPE_INVARIANT 91
606
607 static int
608 parse_type_variant(slang_parse_ctx * C, slang_type_variant *variant)
609 {
610 GLuint invariant = *C->I++;
611 switch (invariant) {
612 case TYPE_VARIANT:
613 *variant = SLANG_VARIANT;
614 return 1;
615 case TYPE_INVARIANT:
616 *variant = SLANG_INVARIANT;
617 return 1;
618 default:
619 RETURN0;
620 }
621 }
622
623
624 /* centroid qualifer */
625 #define TYPE_CENTER 95
626 #define TYPE_CENTROID 96
627
628 static int
629 parse_type_centroid(slang_parse_ctx * C, slang_type_centroid *centroid)
630 {
631 GLuint c = *C->I++;
632 switch (c) {
633 case TYPE_CENTER:
634 *centroid = SLANG_CENTER;
635 return 1;
636 case TYPE_CENTROID:
637 *centroid = SLANG_CENTROID;
638 return 1;
639 default:
640 RETURN0;
641 }
642 }
643
644
645 /* type qualifier */
646 #define TYPE_QUALIFIER_NONE 0
647 #define TYPE_QUALIFIER_CONST 1
648 #define TYPE_QUALIFIER_ATTRIBUTE 2
649 #define TYPE_QUALIFIER_VARYING 3
650 #define TYPE_QUALIFIER_UNIFORM 4
651 #define TYPE_QUALIFIER_FIXEDOUTPUT 5
652 #define TYPE_QUALIFIER_FIXEDINPUT 6
653
654 static int
655 parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual)
656 {
657 GLuint qualifier = *C->I++;
658 switch (qualifier) {
659 case TYPE_QUALIFIER_NONE:
660 *qual = SLANG_QUAL_NONE;
661 break;
662 case TYPE_QUALIFIER_CONST:
663 *qual = SLANG_QUAL_CONST;
664 break;
665 case TYPE_QUALIFIER_ATTRIBUTE:
666 *qual = SLANG_QUAL_ATTRIBUTE;
667 break;
668 case TYPE_QUALIFIER_VARYING:
669 *qual = SLANG_QUAL_VARYING;
670 break;
671 case TYPE_QUALIFIER_UNIFORM:
672 *qual = SLANG_QUAL_UNIFORM;
673 break;
674 case TYPE_QUALIFIER_FIXEDOUTPUT:
675 *qual = SLANG_QUAL_FIXEDOUTPUT;
676 break;
677 case TYPE_QUALIFIER_FIXEDINPUT:
678 *qual = SLANG_QUAL_FIXEDINPUT;
679 break;
680 default:
681 RETURN0;
682 }
683 return 1;
684 }
685
686 /* type specifier */
687 #define TYPE_SPECIFIER_VOID 0
688 #define TYPE_SPECIFIER_BOOL 1
689 #define TYPE_SPECIFIER_BVEC2 2
690 #define TYPE_SPECIFIER_BVEC3 3
691 #define TYPE_SPECIFIER_BVEC4 4
692 #define TYPE_SPECIFIER_INT 5
693 #define TYPE_SPECIFIER_IVEC2 6
694 #define TYPE_SPECIFIER_IVEC3 7
695 #define TYPE_SPECIFIER_IVEC4 8
696 #define TYPE_SPECIFIER_FLOAT 9
697 #define TYPE_SPECIFIER_VEC2 10
698 #define TYPE_SPECIFIER_VEC3 11
699 #define TYPE_SPECIFIER_VEC4 12
700 #define TYPE_SPECIFIER_MAT2 13
701 #define TYPE_SPECIFIER_MAT3 14
702 #define TYPE_SPECIFIER_MAT4 15
703 #define TYPE_SPECIFIER_SAMPLER1D 16
704 #define TYPE_SPECIFIER_SAMPLER2D 17
705 #define TYPE_SPECIFIER_SAMPLER3D 18
706 #define TYPE_SPECIFIER_SAMPLERCUBE 19
707 #define TYPE_SPECIFIER_SAMPLER1DSHADOW 20
708 #define TYPE_SPECIFIER_SAMPLER2DSHADOW 21
709 #define TYPE_SPECIFIER_SAMPLER2DRECT 22
710 #define TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23
711 #define TYPE_SPECIFIER_STRUCT 24
712 #define TYPE_SPECIFIER_TYPENAME 25
713 #define TYPE_SPECIFIER_MAT23 26
714 #define TYPE_SPECIFIER_MAT32 27
715 #define TYPE_SPECIFIER_MAT24 28
716 #define TYPE_SPECIFIER_MAT42 29
717 #define TYPE_SPECIFIER_MAT34 30
718 #define TYPE_SPECIFIER_MAT43 31
719 #define TYPE_SPECIFIER_COUNT 32
720
721 static int
722 parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O,
723 slang_type_specifier * spec)
724 {
725 switch (*C->I++) {
726 case TYPE_SPECIFIER_VOID:
727 spec->type = SLANG_SPEC_VOID;
728 break;
729 case TYPE_SPECIFIER_BOOL:
730 spec->type = SLANG_SPEC_BOOL;
731 break;
732 case TYPE_SPECIFIER_BVEC2:
733 spec->type = SLANG_SPEC_BVEC2;
734 break;
735 case TYPE_SPECIFIER_BVEC3:
736 spec->type = SLANG_SPEC_BVEC3;
737 break;
738 case TYPE_SPECIFIER_BVEC4:
739 spec->type = SLANG_SPEC_BVEC4;
740 break;
741 case TYPE_SPECIFIER_INT:
742 spec->type = SLANG_SPEC_INT;
743 break;
744 case TYPE_SPECIFIER_IVEC2:
745 spec->type = SLANG_SPEC_IVEC2;
746 break;
747 case TYPE_SPECIFIER_IVEC3:
748 spec->type = SLANG_SPEC_IVEC3;
749 break;
750 case TYPE_SPECIFIER_IVEC4:
751 spec->type = SLANG_SPEC_IVEC4;
752 break;
753 case TYPE_SPECIFIER_FLOAT:
754 spec->type = SLANG_SPEC_FLOAT;
755 break;
756 case TYPE_SPECIFIER_VEC2:
757 spec->type = SLANG_SPEC_VEC2;
758 break;
759 case TYPE_SPECIFIER_VEC3:
760 spec->type = SLANG_SPEC_VEC3;
761 break;
762 case TYPE_SPECIFIER_VEC4:
763 spec->type = SLANG_SPEC_VEC4;
764 break;
765 case TYPE_SPECIFIER_MAT2:
766 spec->type = SLANG_SPEC_MAT2;
767 break;
768 case TYPE_SPECIFIER_MAT3:
769 spec->type = SLANG_SPEC_MAT3;
770 break;
771 case TYPE_SPECIFIER_MAT4:
772 spec->type = SLANG_SPEC_MAT4;
773 break;
774 case TYPE_SPECIFIER_MAT23:
775 spec->type = SLANG_SPEC_MAT23;
776 break;
777 case TYPE_SPECIFIER_MAT32:
778 spec->type = SLANG_SPEC_MAT32;
779 break;
780 case TYPE_SPECIFIER_MAT24:
781 spec->type = SLANG_SPEC_MAT24;
782 break;
783 case TYPE_SPECIFIER_MAT42:
784 spec->type = SLANG_SPEC_MAT42;
785 break;
786 case TYPE_SPECIFIER_MAT34:
787 spec->type = SLANG_SPEC_MAT34;
788 break;
789 case TYPE_SPECIFIER_MAT43:
790 spec->type = SLANG_SPEC_MAT43;
791 break;
792 case TYPE_SPECIFIER_SAMPLER1D:
793 spec->type = SLANG_SPEC_SAMPLER1D;
794 break;
795 case TYPE_SPECIFIER_SAMPLER2D:
796 spec->type = SLANG_SPEC_SAMPLER2D;
797 break;
798 case TYPE_SPECIFIER_SAMPLER3D:
799 spec->type = SLANG_SPEC_SAMPLER3D;
800 break;
801 case TYPE_SPECIFIER_SAMPLERCUBE:
802 spec->type = SLANG_SPEC_SAMPLERCUBE;
803 break;
804 case TYPE_SPECIFIER_SAMPLER2DRECT:
805 spec->type = SLANG_SPEC_SAMPLER2DRECT;
806 break;
807 case TYPE_SPECIFIER_SAMPLER1DSHADOW:
808 spec->type = SLANG_SPEC_SAMPLER1DSHADOW;
809 break;
810 case TYPE_SPECIFIER_SAMPLER2DSHADOW:
811 spec->type = SLANG_SPEC_SAMPLER2DSHADOW;
812 break;
813 case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW:
814 spec->type = SLANG_SPEC_SAMPLER2DRECTSHADOW;
815 break;
816 case TYPE_SPECIFIER_STRUCT:
817 spec->type = SLANG_SPEC_STRUCT;
818 if (!parse_struct(C, O, &spec->_struct))
819 RETURN0;
820 break;
821 case TYPE_SPECIFIER_TYPENAME:
822 spec->type = SLANG_SPEC_STRUCT;
823 {
824 slang_atom a_name;
825 slang_struct *stru;
826
827 a_name = parse_identifier(C);
828 if (a_name == NULL)
829 RETURN0;
830
831 stru = slang_struct_scope_find(O->structs, a_name, 1);
832 if (stru == NULL) {
833 slang_info_log_error(C->L, "undeclared type name '%s'",
834 slang_atom_pool_id(C->atoms, a_name));
835 RETURN0;
836 }
837
838 spec->_struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
839 if (spec->_struct == NULL) {
840 slang_info_log_memory(C->L);
841 RETURN0;
842 }
843 if (!slang_struct_construct(spec->_struct)) {
844 _slang_free(spec->_struct);
845 spec->_struct = NULL;
846 RETURN0;
847 }
848 if (!slang_struct_copy(spec->_struct, stru))
849 RETURN0;
850 }
851 break;
852 default:
853 RETURN0;
854 }
855 return 1;
856 }
857
858 #define TYPE_SPECIFIER_NONARRAY 0
859 #define TYPE_SPECIFIER_ARRAY 1
860
861 static int
862 parse_type_array_size(slang_parse_ctx *C,
863 slang_output_ctx *O,
864 GLint *array_len)
865 {
866 GLuint size;
867
868 switch (*C->I++) {
869 case TYPE_SPECIFIER_NONARRAY:
870 *array_len = -1; /* -1 = not an array */
871 break;
872 case TYPE_SPECIFIER_ARRAY:
873 if (!parse_array_len(C, O, &size))
874 RETURN0;
875 *array_len = (GLint) size;
876 break;
877 default:
878 assert(0);
879 RETURN0;
880 }
881 return 1;
882 }
883
884 #define PRECISION_DEFAULT 0
885 #define PRECISION_LOW 1
886 #define PRECISION_MEDIUM 2
887 #define PRECISION_HIGH 3
888
889 static int
890 parse_type_precision(slang_parse_ctx *C,
891 slang_type_precision *precision)
892 {
893 GLint prec = *C->I++;
894 switch (prec) {
895 case PRECISION_DEFAULT:
896 *precision = SLANG_PREC_DEFAULT;
897 return 1;
898 case PRECISION_LOW:
899 *precision = SLANG_PREC_LOW;
900 return 1;
901 case PRECISION_MEDIUM:
902 *precision = SLANG_PREC_MEDIUM;
903 return 1;
904 case PRECISION_HIGH:
905 *precision = SLANG_PREC_HIGH;
906 return 1;
907 default:
908 RETURN0;
909 }
910 }
911
912 static int
913 parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
914 slang_fully_specified_type * type)
915 {
916 if (!parse_type_variant(C, &type->variant))
917 RETURN0;
918
919 if (!parse_type_centroid(C, &type->centroid))
920 RETURN0;
921
922 if (!parse_type_qualifier(C, &type->qualifier))
923 RETURN0;
924
925 if (!parse_type_precision(C, &type->precision))
926 RETURN0;
927
928 if (!parse_type_specifier(C, O, &type->specifier))
929 RETURN0;
930
931 if (!parse_type_array_size(C, O, &type->array_len))
932 RETURN0;
933
934 if (!O->allow_invariant && type->variant == SLANG_INVARIANT) {
935 slang_info_log_error(C->L,
936 "'invariant' keyword not allowed (perhaps set #version 120)");
937 RETURN0;
938 }
939
940 if (!O->allow_centroid && type->centroid == SLANG_CENTROID) {
941 slang_info_log_error(C->L,
942 "'centroid' keyword not allowed (perhaps set #version 120)");
943 RETURN0;
944 }
945 else if (type->centroid == SLANG_CENTROID &&
946 type->qualifier != SLANG_QUAL_VARYING) {
947 slang_info_log_error(C->L,
948 "'centroid' keyword only allowed for varying vars");
949 RETURN0;
950 }
951
952
953 /* need this?
954 if (type->qualifier != SLANG_QUAL_VARYING &&
955 type->variant == SLANG_INVARIANT) {
956 slang_info_log_error(C->L,
957 "invariant qualifer only allowed for varying vars");
958 RETURN0;
959 }
960 */
961
962 if (O->allow_precision) {
963 if (type->precision == SLANG_PREC_DEFAULT) {
964 assert(type->specifier.type < TYPE_SPECIFIER_COUNT);
965 /* use the default precision for this datatype */
966 type->precision = O->default_precision[type->specifier.type];
967 }
968 }
969 else {
970 /* only default is allowed */
971 if (type->precision != SLANG_PREC_DEFAULT) {
972 slang_info_log_error(C->L, "precision qualifiers not allowed");
973 RETURN0;
974 }
975 }
976
977 if (!O->allow_array_types && type->array_len >= 0) {
978 slang_info_log_error(C->L, "first-class array types not allowed");
979 RETURN0;
980 }
981
982 if (type->array_len >= 0) {
983 /* convert type to array type (ex: convert "int" to "array of int" */
984 promote_type_to_array(C, type, type->array_len);
985 }
986
987 return 1;
988 }
989
990 /* operation */
991 #define OP_END 0
992 #define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1
993 #define OP_BLOCK_BEGIN_NEW_SCOPE 2
994 #define OP_DECLARE 3
995 #define OP_ASM 4
996 #define OP_BREAK 5
997 #define OP_CONTINUE 6
998 #define OP_DISCARD 7
999 #define OP_RETURN 8
1000 #define OP_EXPRESSION 9
1001 #define OP_IF 10
1002 #define OP_WHILE 11
1003 #define OP_DO 12
1004 #define OP_FOR 13
1005 #define OP_PUSH_VOID 14
1006 #define OP_PUSH_BOOL 15
1007 #define OP_PUSH_INT 16
1008 #define OP_PUSH_FLOAT 17
1009 #define OP_PUSH_IDENTIFIER 18
1010 #define OP_SEQUENCE 19
1011 #define OP_ASSIGN 20
1012 #define OP_ADDASSIGN 21
1013 #define OP_SUBASSIGN 22
1014 #define OP_MULASSIGN 23
1015 #define OP_DIVASSIGN 24
1016 /*#define OP_MODASSIGN 25*/
1017 /*#define OP_LSHASSIGN 26*/
1018 /*#define OP_RSHASSIGN 27*/
1019 /*#define OP_ORASSIGN 28*/
1020 /*#define OP_XORASSIGN 29*/
1021 /*#define OP_ANDASSIGN 30*/
1022 #define OP_SELECT 31
1023 #define OP_LOGICALOR 32
1024 #define OP_LOGICALXOR 33
1025 #define OP_LOGICALAND 34
1026 /*#define OP_BITOR 35*/
1027 /*#define OP_BITXOR 36*/
1028 /*#define OP_BITAND 37*/
1029 #define OP_EQUAL 38
1030 #define OP_NOTEQUAL 39
1031 #define OP_LESS 40
1032 #define OP_GREATER 41
1033 #define OP_LESSEQUAL 42
1034 #define OP_GREATEREQUAL 43
1035 /*#define OP_LSHIFT 44*/
1036 /*#define OP_RSHIFT 45*/
1037 #define OP_ADD 46
1038 #define OP_SUBTRACT 47
1039 #define OP_MULTIPLY 48
1040 #define OP_DIVIDE 49
1041 /*#define OP_MODULUS 50*/
1042 #define OP_PREINCREMENT 51
1043 #define OP_PREDECREMENT 52
1044 #define OP_PLUS 53
1045 #define OP_MINUS 54
1046 /*#define OP_COMPLEMENT 55*/
1047 #define OP_NOT 56
1048 #define OP_SUBSCRIPT 57
1049 #define OP_CALL 58
1050 #define OP_FIELD 59
1051 #define OP_POSTINCREMENT 60
1052 #define OP_POSTDECREMENT 61
1053 #define OP_PRECISION 62
1054 #define OP_METHOD 63
1055
1056
1057 /**
1058 * When parsing a compound production, this function is used to parse the
1059 * children.
1060 * For example, a while-loop compound will have two children, the
1061 * while condition expression and the loop body. So, this function will
1062 * be called twice to parse those two sub-expressions.
1063 * \param C the parsing context
1064 * \param O the output context
1065 * \param oper the operation we're parsing
1066 * \param statement indicates whether parsing a statement, or expression
1067 * \return 1 if success, 0 if error
1068 */
1069 static int
1070 parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O,
1071 slang_operation * oper, GLboolean statement)
1072 {
1073 slang_operation *ch;
1074
1075 /* grow child array */
1076 ch = slang_operation_grow(&oper->num_children, &oper->children);
1077 if (statement)
1078 return parse_statement(C, O, ch);
1079 return parse_expression(C, O, ch);
1080 }
1081
1082 static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O);
1083
1084 static int
1085 parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
1086 slang_operation * oper)
1087 {
1088 int op;
1089
1090 oper->locals->outer_scope = O->vars;
1091
1092 op = *C->I++;
1093 switch (op) {
1094 case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
1095 /* parse child statements, do not create new variable scope */
1096 oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
1097 while (*C->I != OP_END)
1098 if (!parse_child_operation(C, O, oper, GL_TRUE))
1099 RETURN0;
1100 C->I++;
1101 break;
1102 case OP_BLOCK_BEGIN_NEW_SCOPE:
1103 /* parse child statements, create new variable scope */
1104 {
1105 slang_output_ctx o = *O;
1106
1107 oper->type = SLANG_OPER_BLOCK_NEW_SCOPE;
1108 o.vars = oper->locals;
1109 while (*C->I != OP_END)
1110 if (!parse_child_operation(C, &o, oper, GL_TRUE))
1111 RETURN0;
1112 C->I++;
1113 }
1114 break;
1115 case OP_DECLARE:
1116 /* local variable declaration, individual declarators are stored as
1117 * children identifiers
1118 */
1119 oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
1120 {
1121 const unsigned int first_var = O->vars->num_variables;
1122
1123 /* parse the declaration, note that there can be zero or more
1124 * than one declarators
1125 */
1126 if (!parse_declaration(C, O))
1127 RETURN0;
1128 if (first_var < O->vars->num_variables) {
1129 const unsigned int num_vars = O->vars->num_variables - first_var;
1130 unsigned int i;
1131 assert(oper->num_children == 0);
1132 oper->num_children = num_vars;
1133 oper->children = slang_operation_new(num_vars);
1134 if (oper->children == NULL) {
1135 slang_info_log_memory(C->L);
1136 RETURN0;
1137 }
1138 for (i = first_var; i < O->vars->num_variables; i++) {
1139 slang_operation *o = &oper->children[i - first_var];
1140 slang_variable *var = O->vars->variables[i];
1141 o->type = SLANG_OPER_VARIABLE_DECL;
1142 o->locals->outer_scope = O->vars;
1143 o->a_id = var->a_name;
1144
1145 /* new/someday...
1146 calculate_var_size(C, O, var);
1147 */
1148
1149 if (!legal_identifier(o->a_id)) {
1150 slang_info_log_error(C->L, "illegal variable name '%s'",
1151 (char *) o->a_id);
1152 RETURN0;
1153 }
1154 }
1155 }
1156 }
1157 break;
1158 case OP_ASM:
1159 /* the __asm statement, parse the mnemonic and all its arguments
1160 * as expressions
1161 */
1162 oper->type = SLANG_OPER_ASM;
1163 oper->a_id = parse_identifier(C);
1164 if (oper->a_id == SLANG_ATOM_NULL)
1165 RETURN0;
1166 while (*C->I != OP_END) {
1167 if (!parse_child_operation(C, O, oper, GL_FALSE))
1168 RETURN0;
1169 }
1170 C->I++;
1171 break;
1172 case OP_BREAK:
1173 oper->type = SLANG_OPER_BREAK;
1174 break;
1175 case OP_CONTINUE:
1176 oper->type = SLANG_OPER_CONTINUE;
1177 break;
1178 case OP_DISCARD:
1179 oper->type = SLANG_OPER_DISCARD;
1180 break;
1181 case OP_RETURN:
1182 oper->type = SLANG_OPER_RETURN;
1183 if (!parse_child_operation(C, O, oper, GL_FALSE))
1184 RETURN0;
1185 break;
1186 case OP_EXPRESSION:
1187 oper->type = SLANG_OPER_EXPRESSION;
1188 if (!parse_child_operation(C, O, oper, GL_FALSE))
1189 RETURN0;
1190 break;
1191 case OP_IF:
1192 oper->type = SLANG_OPER_IF;
1193 if (!parse_child_operation(C, O, oper, GL_FALSE))
1194 RETURN0;
1195 if (!parse_child_operation(C, O, oper, GL_TRUE))
1196 RETURN0;
1197 if (!parse_child_operation(C, O, oper, GL_TRUE))
1198 RETURN0;
1199 break;
1200 case OP_WHILE:
1201 {
1202 slang_output_ctx o = *O;
1203
1204 oper->type = SLANG_OPER_WHILE;
1205 o.vars = oper->locals;
1206 if (!parse_child_operation(C, &o, oper, GL_TRUE))
1207 RETURN0;
1208 if (!parse_child_operation(C, &o, oper, GL_TRUE))
1209 RETURN0;
1210 }
1211 break;
1212 case OP_DO:
1213 oper->type = SLANG_OPER_DO;
1214 if (!parse_child_operation(C, O, oper, GL_TRUE))
1215 RETURN0;
1216 if (!parse_child_operation(C, O, oper, GL_FALSE))
1217 RETURN0;
1218 break;
1219 case OP_FOR:
1220 {
1221 slang_output_ctx o = *O;
1222
1223 oper->type = SLANG_OPER_FOR;
1224 o.vars = oper->locals;
1225 if (!parse_child_operation(C, &o, oper, GL_TRUE))
1226 RETURN0;
1227 if (!parse_child_operation(C, &o, oper, GL_TRUE))
1228 RETURN0;
1229 if (!parse_child_operation(C, &o, oper, GL_FALSE))
1230 RETURN0;
1231 if (!parse_child_operation(C, &o, oper, GL_TRUE))
1232 RETURN0;
1233 }
1234 break;
1235 case OP_PRECISION:
1236 {
1237 /* set default precision for a type in this scope */
1238 /* ignored at this time */
1239 int prec_qual = *C->I++;
1240 int datatype = *C->I++;
1241 (void) prec_qual;
1242 (void) datatype;
1243 }
1244 break;
1245 default:
1246 /*printf("Unexpected operation %d\n", op);*/
1247 RETURN0;
1248 }
1249 return 1;
1250 }
1251
1252 static int
1253 handle_nary_expression(slang_parse_ctx * C, slang_operation * op,
1254 slang_operation ** ops, unsigned int *total_ops,
1255 unsigned int n)
1256 {
1257 unsigned int i;
1258
1259 op->children = slang_operation_new(n);
1260 if (op->children == NULL) {
1261 slang_info_log_memory(C->L);
1262 RETURN0;
1263 }
1264 op->num_children = n;
1265
1266 for (i = 0; i < n; i++) {
1267 slang_operation_destruct(&op->children[i]);
1268 op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
1269 }
1270
1271 (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
1272 *total_ops -= n;
1273
1274 *ops = (slang_operation *)
1275 _slang_realloc(*ops,
1276 (*total_ops + n) * sizeof(slang_operation),
1277 *total_ops * sizeof(slang_operation));
1278 if (*ops == NULL) {
1279 slang_info_log_memory(C->L);
1280 RETURN0;
1281 }
1282 return 1;
1283 }
1284
1285 static int
1286 is_constructor_name(const char *name, slang_atom a_name,
1287 slang_struct_scope * structs)
1288 {
1289 if (slang_type_specifier_type_from_string(name) != SLANG_SPEC_VOID)
1290 return 1;
1291 return slang_struct_scope_find(structs, a_name, 1) != NULL;
1292 }
1293
1294 #define FUNCTION_CALL_NONARRAY 0
1295 #define FUNCTION_CALL_ARRAY 1
1296
1297 static int
1298 parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
1299 slang_operation * oper)
1300 {
1301 slang_operation *ops = NULL;
1302 unsigned int num_ops = 0;
1303 int number;
1304
1305 while (*C->I != OP_END) {
1306 slang_operation *op;
1307 const unsigned int op_code = *C->I++;
1308
1309 /* allocate default operation, becomes a no-op if not used */
1310 ops = (slang_operation *)
1311 _slang_realloc(ops,
1312 num_ops * sizeof(slang_operation),
1313 (num_ops + 1) * sizeof(slang_operation));
1314 if (ops == NULL) {
1315 slang_info_log_memory(C->L);
1316 RETURN0;
1317 }
1318 op = &ops[num_ops];
1319 if (!slang_operation_construct(op)) {
1320 slang_info_log_memory(C->L);
1321 RETURN0;
1322 }
1323 num_ops++;
1324 op->locals->outer_scope = O->vars;
1325
1326 switch (op_code) {
1327 case OP_PUSH_VOID:
1328 op->type = SLANG_OPER_VOID;
1329 break;
1330 case OP_PUSH_BOOL:
1331 op->type = SLANG_OPER_LITERAL_BOOL;
1332 if (!parse_number(C, &number))
1333 RETURN0;
1334 op->literal[0] =
1335 op->literal[1] =
1336 op->literal[2] =
1337 op->literal[3] = (GLfloat) number;
1338 op->literal_size = 1;
1339 break;
1340 case OP_PUSH_INT:
1341 op->type = SLANG_OPER_LITERAL_INT;
1342 if (!parse_number(C, &number))
1343 RETURN0;
1344 op->literal[0] =
1345 op->literal[1] =
1346 op->literal[2] =
1347 op->literal[3] = (GLfloat) number;
1348 op->literal_size = 1;
1349 break;
1350 case OP_PUSH_FLOAT:
1351 op->type = SLANG_OPER_LITERAL_FLOAT;
1352 if (!parse_float(C, &op->literal[0]))
1353 RETURN0;
1354 op->literal[1] =
1355 op->literal[2] =
1356 op->literal[3] = op->literal[0];
1357 op->literal_size = 1;
1358 break;
1359 case OP_PUSH_IDENTIFIER:
1360 op->type = SLANG_OPER_IDENTIFIER;
1361 op->a_id = parse_identifier(C);
1362 if (op->a_id == SLANG_ATOM_NULL)
1363 RETURN0;
1364 break;
1365 case OP_SEQUENCE:
1366 op->type = SLANG_OPER_SEQUENCE;
1367 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1368 RETURN0;
1369 break;
1370 case OP_ASSIGN:
1371 op->type = SLANG_OPER_ASSIGN;
1372 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1373 RETURN0;
1374 break;
1375 case OP_ADDASSIGN:
1376 op->type = SLANG_OPER_ADDASSIGN;
1377 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1378 RETURN0;
1379 break;
1380 case OP_SUBASSIGN:
1381 op->type = SLANG_OPER_SUBASSIGN;
1382 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1383 RETURN0;
1384 break;
1385 case OP_MULASSIGN:
1386 op->type = SLANG_OPER_MULASSIGN;
1387 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1388 RETURN0;
1389 break;
1390 case OP_DIVASSIGN:
1391 op->type = SLANG_OPER_DIVASSIGN;
1392 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1393 RETURN0;
1394 break;
1395 /*case OP_MODASSIGN: */
1396 /*case OP_LSHASSIGN: */
1397 /*case OP_RSHASSIGN: */
1398 /*case OP_ORASSIGN: */
1399 /*case OP_XORASSIGN: */
1400 /*case OP_ANDASSIGN: */
1401 case OP_SELECT:
1402 op->type = SLANG_OPER_SELECT;
1403 if (!handle_nary_expression(C, op, &ops, &num_ops, 3))
1404 RETURN0;
1405 break;
1406 case OP_LOGICALOR:
1407 op->type = SLANG_OPER_LOGICALOR;
1408 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1409 RETURN0;
1410 break;
1411 case OP_LOGICALXOR:
1412 op->type = SLANG_OPER_LOGICALXOR;
1413 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1414 RETURN0;
1415 break;
1416 case OP_LOGICALAND:
1417 op->type = SLANG_OPER_LOGICALAND;
1418 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1419 RETURN0;
1420 break;
1421 /*case OP_BITOR: */
1422 /*case OP_BITXOR: */
1423 /*case OP_BITAND: */
1424 case OP_EQUAL:
1425 op->type = SLANG_OPER_EQUAL;
1426 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1427 RETURN0;
1428 break;
1429 case OP_NOTEQUAL:
1430 op->type = SLANG_OPER_NOTEQUAL;
1431 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1432 RETURN0;
1433 break;
1434 case OP_LESS:
1435 op->type = SLANG_OPER_LESS;
1436 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1437 RETURN0;
1438 break;
1439 case OP_GREATER:
1440 op->type = SLANG_OPER_GREATER;
1441 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1442 RETURN0;
1443 break;
1444 case OP_LESSEQUAL:
1445 op->type = SLANG_OPER_LESSEQUAL;
1446 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1447 RETURN0;
1448 break;
1449 case OP_GREATEREQUAL:
1450 op->type = SLANG_OPER_GREATEREQUAL;
1451 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1452 RETURN0;
1453 break;
1454 /*case OP_LSHIFT: */
1455 /*case OP_RSHIFT: */
1456 case OP_ADD:
1457 op->type = SLANG_OPER_ADD;
1458 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1459 RETURN0;
1460 break;
1461 case OP_SUBTRACT:
1462 op->type = SLANG_OPER_SUBTRACT;
1463 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1464 RETURN0;
1465 break;
1466 case OP_MULTIPLY:
1467 op->type = SLANG_OPER_MULTIPLY;
1468 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1469 RETURN0;
1470 break;
1471 case OP_DIVIDE:
1472 op->type = SLANG_OPER_DIVIDE;
1473 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1474 RETURN0;
1475 break;
1476 /*case OP_MODULUS: */
1477 case OP_PREINCREMENT:
1478 op->type = SLANG_OPER_PREINCREMENT;
1479 if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1480 RETURN0;
1481 break;
1482 case OP_PREDECREMENT:
1483 op->type = SLANG_OPER_PREDECREMENT;
1484 if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1485 RETURN0;
1486 break;
1487 case OP_PLUS:
1488 op->type = SLANG_OPER_PLUS;
1489 if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1490 RETURN0;
1491 break;
1492 case OP_MINUS:
1493 op->type = SLANG_OPER_MINUS;
1494 if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1495 RETURN0;
1496 break;
1497 case OP_NOT:
1498 op->type = SLANG_OPER_NOT;
1499 if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1500 RETURN0;
1501 break;
1502 /*case OP_COMPLEMENT: */
1503 case OP_SUBSCRIPT:
1504 op->type = SLANG_OPER_SUBSCRIPT;
1505 if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1506 RETURN0;
1507 break;
1508 case OP_METHOD:
1509 op->type = SLANG_OPER_METHOD;
1510 op->a_obj = parse_identifier(C);
1511 if (op->a_obj == SLANG_ATOM_NULL)
1512 RETURN0;
1513
1514 op->a_id = parse_identifier(C);
1515 if (op->a_id == SLANG_ATOM_NULL)
1516 RETURN0;
1517
1518 assert(*C->I == OP_END);
1519 C->I++;
1520
1521 while (*C->I != OP_END)
1522 if (!parse_child_operation(C, O, op, GL_FALSE))
1523 RETURN0;
1524 C->I++;
1525 #if 0
1526 /* don't lookup the method (not yet anyway) */
1527 if (!C->parsing_builtin
1528 && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
1529 const char *id;
1530
1531 id = slang_atom_pool_id(C->atoms, op->a_id);
1532 if (!is_constructor_name(id, op->a_id, O->structs)) {
1533 slang_info_log_error(C->L, "%s: undeclared function name.", id);
1534 RETURN0;
1535 }
1536 }
1537 #endif
1538 break;
1539 case OP_CALL:
1540 {
1541 GLboolean array_constructor = GL_FALSE;
1542 GLint array_constructor_size = 0;
1543
1544 op->type = SLANG_OPER_CALL;
1545 op->a_id = parse_identifier(C);
1546 if (op->a_id == SLANG_ATOM_NULL)
1547 RETURN0;
1548 switch (*C->I++) {
1549 case FUNCTION_CALL_NONARRAY:
1550 /* Nothing to do. */
1551 break;
1552 case FUNCTION_CALL_ARRAY:
1553 /* Calling an array constructor. For example:
1554 * float[3](1.1, 2.2, 3.3);
1555 */
1556 if (!O->allow_array_types) {
1557 slang_info_log_error(C->L,
1558 "array constructors not allowed "
1559 "in this GLSL version");
1560 RETURN0;
1561 }
1562 else {
1563 /* parse the array constructor size */
1564 slang_operation array_size;
1565 array_constructor = GL_TRUE;
1566 slang_operation_construct(&array_size);
1567 if (!parse_expression(C, O, &array_size)) {
1568 slang_operation_destruct(&array_size);
1569 return GL_FALSE;
1570 }
1571 if (array_size.type != SLANG_OPER_LITERAL_INT) {
1572 slang_info_log_error(C->L,
1573 "constructor array size is not an integer");
1574 slang_operation_destruct(&array_size);
1575 RETURN0;
1576 }
1577 array_constructor_size = (int) array_size.literal[0];
1578 op->array_constructor = GL_TRUE;
1579 slang_operation_destruct(&array_size);
1580 }
1581 break;
1582 default:
1583 assert(0);
1584 RETURN0;
1585 }
1586 while (*C->I != OP_END)
1587 if (!parse_child_operation(C, O, op, GL_FALSE))
1588 RETURN0;
1589 C->I++;
1590
1591 if (array_constructor &&
1592 array_constructor_size != op->num_children) {
1593 slang_info_log_error(C->L, "number of parameters to array"
1594 " constructor does not match array size");
1595 RETURN0;
1596 }
1597
1598 if (!C->parsing_builtin
1599 && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
1600 const char *id;
1601
1602 id = slang_atom_pool_id(C->atoms, op->a_id);
1603 if (!is_constructor_name(id, op->a_id, O->structs)) {
1604 slang_info_log_error(C->L, "%s: undeclared function name.", id);
1605 RETURN0;
1606 }
1607 }
1608 }
1609 break;
1610 case OP_FIELD:
1611 op->type = SLANG_OPER_FIELD;
1612 op->a_id = parse_identifier(C);
1613 if (op->a_id == SLANG_ATOM_NULL)
1614 RETURN0;
1615 if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1616 RETURN0;
1617 break;
1618 case OP_POSTINCREMENT:
1619 op->type = SLANG_OPER_POSTINCREMENT;
1620 if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1621 RETURN0;
1622 break;
1623 case OP_POSTDECREMENT:
1624 op->type = SLANG_OPER_POSTDECREMENT;
1625 if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1626 RETURN0;
1627 break;
1628 default:
1629 RETURN0;
1630 }
1631 }
1632 C->I++;
1633
1634 slang_operation_destruct(oper);
1635 *oper = *ops; /* struct copy */
1636 _slang_free(ops);
1637
1638 return 1;
1639 }
1640
1641 /* parameter qualifier */
1642 #define PARAM_QUALIFIER_IN 0
1643 #define PARAM_QUALIFIER_OUT 1
1644 #define PARAM_QUALIFIER_INOUT 2
1645
1646 /* function parameter array presence */
1647 #define PARAMETER_ARRAY_NOT_PRESENT 0
1648 #define PARAMETER_ARRAY_PRESENT 1
1649
1650 static int
1651 parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
1652 slang_variable * param)
1653 {
1654 int param_qual, precision_qual;
1655
1656 /* parse and validate the parameter's type qualifiers (there can be
1657 * two at most) because not all combinations are valid
1658 */
1659 if (!parse_type_qualifier(C, &param->type.qualifier))
1660 RETURN0;
1661
1662 param_qual = *C->I++;
1663 switch (param_qual) {
1664 case PARAM_QUALIFIER_IN:
1665 if (param->type.qualifier != SLANG_QUAL_CONST
1666 && param->type.qualifier != SLANG_QUAL_NONE) {
1667 slang_info_log_error(C->L, "Invalid type qualifier.");
1668 RETURN0;
1669 }
1670 break;
1671 case PARAM_QUALIFIER_OUT:
1672 if (param->type.qualifier == SLANG_QUAL_NONE)
1673 param->type.qualifier = SLANG_QUAL_OUT;
1674 else {
1675 slang_info_log_error(C->L, "Invalid type qualifier.");
1676 RETURN0;
1677 }
1678 break;
1679 case PARAM_QUALIFIER_INOUT:
1680 if (param->type.qualifier == SLANG_QUAL_NONE)
1681 param->type.qualifier = SLANG_QUAL_INOUT;
1682 else {
1683 slang_info_log_error(C->L, "Invalid type qualifier.");
1684 RETURN0;
1685 }
1686 break;
1687 default:
1688 RETURN0;
1689 }
1690
1691 /* parse precision qualifier (lowp, mediump, highp */
1692 precision_qual = *C->I++;
1693 /* ignored at this time */
1694 (void) precision_qual;
1695
1696 /* parse parameter's type specifier and name */
1697 if (!parse_type_specifier(C, O, &param->type.specifier))
1698 RETURN0;
1699 if (!parse_type_array_size(C, O, &param->type.array_len))
1700 RETURN0;
1701 param->a_name = parse_identifier(C);
1702 if (param->a_name == SLANG_ATOM_NULL)
1703 RETURN0;
1704
1705 /* first-class array
1706 */
1707 if (param->type.array_len >= 0) {
1708 slang_type_specifier p;
1709
1710 slang_type_specifier_ctr(&p);
1711 if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
1712 slang_type_specifier_dtr(&p);
1713 RETURN0;
1714 }
1715 if (!convert_to_array(C, param, &p)) {
1716 slang_type_specifier_dtr(&p);
1717 RETURN0;
1718 }
1719 slang_type_specifier_dtr(&p);
1720 param->array_len = param->type.array_len;
1721 }
1722
1723 /* if the parameter is an array, parse its size (the size must be
1724 * explicitly defined
1725 */
1726 if (*C->I++ == PARAMETER_ARRAY_PRESENT) {
1727 slang_type_specifier p;
1728
1729 if (param->type.array_len >= 0) {
1730 slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
1731 RETURN0;
1732 }
1733 slang_type_specifier_ctr(&p);
1734 if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
1735 slang_type_specifier_dtr(&p);
1736 RETURN0;
1737 }
1738 if (!convert_to_array(C, param, &p)) {
1739 slang_type_specifier_dtr(&p);
1740 RETURN0;
1741 }
1742 slang_type_specifier_dtr(&p);
1743 if (!parse_array_len(C, O, &param->array_len))
1744 RETURN0;
1745 }
1746
1747 #if 0
1748 /* calculate the parameter size */
1749 if (!calculate_var_size(C, O, param))
1750 RETURN0;
1751 #endif
1752 /* TODO: allocate the local address here? */
1753 return 1;
1754 }
1755
1756 /* function type */
1757 #define FUNCTION_ORDINARY 0
1758 #define FUNCTION_CONSTRUCTOR 1
1759 #define FUNCTION_OPERATOR 2
1760
1761 /* function parameter */
1762 #define PARAMETER_NONE 0
1763 #define PARAMETER_NEXT 1
1764
1765 /* operator type */
1766 #define OPERATOR_ADDASSIGN 1
1767 #define OPERATOR_SUBASSIGN 2
1768 #define OPERATOR_MULASSIGN 3
1769 #define OPERATOR_DIVASSIGN 4
1770 /*#define OPERATOR_MODASSIGN 5*/
1771 /*#define OPERATOR_LSHASSIGN 6*/
1772 /*#define OPERATOR_RSHASSIGN 7*/
1773 /*#define OPERATOR_ANDASSIGN 8*/
1774 /*#define OPERATOR_XORASSIGN 9*/
1775 /*#define OPERATOR_ORASSIGN 10*/
1776 #define OPERATOR_LOGICALXOR 11
1777 /*#define OPERATOR_BITOR 12*/
1778 /*#define OPERATOR_BITXOR 13*/
1779 /*#define OPERATOR_BITAND 14*/
1780 #define OPERATOR_LESS 15
1781 #define OPERATOR_GREATER 16
1782 #define OPERATOR_LESSEQUAL 17
1783 #define OPERATOR_GREATEREQUAL 18
1784 /*#define OPERATOR_LSHIFT 19*/
1785 /*#define OPERATOR_RSHIFT 20*/
1786 #define OPERATOR_MULTIPLY 21
1787 #define OPERATOR_DIVIDE 22
1788 /*#define OPERATOR_MODULUS 23*/
1789 #define OPERATOR_INCREMENT 24
1790 #define OPERATOR_DECREMENT 25
1791 #define OPERATOR_PLUS 26
1792 #define OPERATOR_MINUS 27
1793 /*#define OPERATOR_COMPLEMENT 28*/
1794 #define OPERATOR_NOT 29
1795
1796 static const struct
1797 {
1798 unsigned int o_code;
1799 const char *o_name;
1800 } operator_names[] = {
1801 {OPERATOR_INCREMENT, "++"},
1802 {OPERATOR_ADDASSIGN, "+="},
1803 {OPERATOR_PLUS, "+"},
1804 {OPERATOR_DECREMENT, "--"},
1805 {OPERATOR_SUBASSIGN, "-="},
1806 {OPERATOR_MINUS, "-"},
1807 {OPERATOR_NOT, "!"},
1808 {OPERATOR_MULASSIGN, "*="},
1809 {OPERATOR_MULTIPLY, "*"},
1810 {OPERATOR_DIVASSIGN, "/="},
1811 {OPERATOR_DIVIDE, "/"},
1812 {OPERATOR_LESSEQUAL, "<="},
1813 /*{ OPERATOR_LSHASSIGN, "<<=" }, */
1814 /*{ OPERATOR_LSHIFT, "<<" }, */
1815 {OPERATOR_LESS, "<"},
1816 {OPERATOR_GREATEREQUAL, ">="},
1817 /*{ OPERATOR_RSHASSIGN, ">>=" }, */
1818 /*{ OPERATOR_RSHIFT, ">>" }, */
1819 {OPERATOR_GREATER, ">"},
1820 /*{ OPERATOR_MODASSIGN, "%=" }, */
1821 /*{ OPERATOR_MODULUS, "%" }, */
1822 /*{ OPERATOR_ANDASSIGN, "&=" }, */
1823 /*{ OPERATOR_BITAND, "&" }, */
1824 /*{ OPERATOR_ORASSIGN, "|=" }, */
1825 /*{ OPERATOR_BITOR, "|" }, */
1826 /*{ OPERATOR_COMPLEMENT, "~" }, */
1827 /*{ OPERATOR_XORASSIGN, "^=" }, */
1828 {OPERATOR_LOGICALXOR, "^^"},
1829 /*{ OPERATOR_BITXOR, "^" } */
1830 };
1831
1832 static slang_atom
1833 parse_operator_name(slang_parse_ctx * C)
1834 {
1835 unsigned int i;
1836
1837 for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) {
1838 if (operator_names[i].o_code == (unsigned int) (*C->I)) {
1839 slang_atom atom =
1840 slang_atom_pool_atom(C->atoms, operator_names[i].o_name);
1841 if (atom == SLANG_ATOM_NULL) {
1842 slang_info_log_memory(C->L);
1843 RETURN0;
1844 }
1845 C->I++;
1846 return atom;
1847 }
1848 }
1849 RETURN0;
1850 }
1851
1852
1853 static int
1854 parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
1855 slang_function * func)
1856 {
1857 GLuint functype;
1858 /* parse function type and name */
1859 if (!parse_fully_specified_type(C, O, &func->header.type))
1860 RETURN0;
1861
1862 functype = *C->I++;
1863 switch (functype) {
1864 case FUNCTION_ORDINARY:
1865 func->kind = SLANG_FUNC_ORDINARY;
1866 func->header.a_name = parse_identifier(C);
1867 if (func->header.a_name == SLANG_ATOM_NULL)
1868 RETURN0;
1869 break;
1870 case FUNCTION_CONSTRUCTOR:
1871 func->kind = SLANG_FUNC_CONSTRUCTOR;
1872 if (func->header.type.specifier.type == SLANG_SPEC_STRUCT)
1873 RETURN0;
1874 func->header.a_name =
1875 slang_atom_pool_atom(C->atoms,
1876 slang_type_specifier_type_to_string
1877 (func->header.type.specifier.type));
1878 if (func->header.a_name == SLANG_ATOM_NULL) {
1879 slang_info_log_memory(C->L);
1880 RETURN0;
1881 }
1882 break;
1883 case FUNCTION_OPERATOR:
1884 func->kind = SLANG_FUNC_OPERATOR;
1885 func->header.a_name = parse_operator_name(C);
1886 if (func->header.a_name == SLANG_ATOM_NULL)
1887 RETURN0;
1888 break;
1889 default:
1890 RETURN0;
1891 }
1892
1893 if (!legal_identifier(func->header.a_name)) {
1894 slang_info_log_error(C->L, "illegal function name '%s'",
1895 (char *) func->header.a_name);
1896 RETURN0;
1897 }
1898
1899 /* parse function parameters */
1900 while (*C->I++ == PARAMETER_NEXT) {
1901 slang_variable *p = slang_variable_scope_grow(func->parameters);
1902 if (!p) {
1903 slang_info_log_memory(C->L);
1904 RETURN0;
1905 }
1906 if (!parse_parameter_declaration(C, O, p))
1907 RETURN0;
1908 }
1909
1910 /* if the function returns a value, append a hidden __retVal 'out'
1911 * parameter that corresponds to the return value.
1912 */
1913 if (_slang_function_has_return_value(func)) {
1914 slang_variable *p = slang_variable_scope_grow(func->parameters);
1915 slang_atom a_retVal = slang_atom_pool_atom(C->atoms, "__retVal");
1916 assert(a_retVal);
1917 p->a_name = a_retVal;
1918 p->type = func->header.type;
1919 p->type.qualifier = SLANG_QUAL_OUT;
1920 }
1921
1922 /* function formal parameters and local variables share the same
1923 * scope, so save the information about param count in a seperate
1924 * place also link the scope to the global variable scope so when a
1925 * given identifier is not found here, the search process continues
1926 * in the global space
1927 */
1928 func->param_count = func->parameters->num_variables;
1929 func->parameters->outer_scope = O->vars;
1930
1931 return 1;
1932 }
1933
1934 static int
1935 parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
1936 slang_function * func)
1937 {
1938 slang_output_ctx o = *O;
1939
1940 if (!parse_function_prototype(C, O, func))
1941 RETURN0;
1942
1943 /* create function's body operation */
1944 func->body = (slang_operation *) _slang_alloc(sizeof(slang_operation));
1945 if (func->body == NULL) {
1946 slang_info_log_memory(C->L);
1947 RETURN0;
1948 }
1949 if (!slang_operation_construct(func->body)) {
1950 _slang_free(func->body);
1951 func->body = NULL;
1952 slang_info_log_memory(C->L);
1953 RETURN0;
1954 }
1955
1956 /* to parse the body the parse context is modified in order to
1957 * capture parsed variables into function's local variable scope
1958 */
1959 C->global_scope = GL_FALSE;
1960 o.vars = func->parameters;
1961 if (!parse_statement(C, &o, func->body))
1962 RETURN0;
1963
1964 C->global_scope = GL_TRUE;
1965 return 1;
1966 }
1967
1968 static GLboolean
1969 initialize_global(slang_assemble_ctx * A, slang_variable * var)
1970 {
1971 slang_operation op_id, op_assign;
1972 GLboolean result;
1973
1974 /* construct the left side of assignment */
1975 if (!slang_operation_construct(&op_id))
1976 return GL_FALSE;
1977 op_id.type = SLANG_OPER_IDENTIFIER;
1978 op_id.a_id = var->a_name;
1979
1980 /* put the variable into operation's scope */
1981 op_id.locals->variables =
1982 (slang_variable **) _slang_alloc(sizeof(slang_variable *));
1983 if (op_id.locals->variables == NULL) {
1984 slang_operation_destruct(&op_id);
1985 return GL_FALSE;
1986 }
1987 op_id.locals->num_variables = 1;
1988 op_id.locals->variables[0] = var;
1989
1990 /* construct the assignment expression */
1991 if (!slang_operation_construct(&op_assign)) {
1992 op_id.locals->num_variables = 0;
1993 slang_operation_destruct(&op_id);
1994 return GL_FALSE;
1995 }
1996 op_assign.type = SLANG_OPER_ASSIGN;
1997 op_assign.children =
1998 (slang_operation *) _slang_alloc(2 * sizeof(slang_operation));
1999 if (op_assign.children == NULL) {
2000 slang_operation_destruct(&op_assign);
2001 op_id.locals->num_variables = 0;
2002 slang_operation_destruct(&op_id);
2003 return GL_FALSE;
2004 }
2005 op_assign.num_children = 2;
2006 op_assign.children[0] = op_id;
2007 op_assign.children[1] = *var->initializer;
2008
2009 result = 1;
2010
2011 /* carefully destroy the operations */
2012 op_assign.num_children = 0;
2013 _slang_free(op_assign.children);
2014 op_assign.children = NULL;
2015 slang_operation_destruct(&op_assign);
2016 op_id.locals->num_variables = 0;
2017 slang_operation_destruct(&op_id);
2018
2019 if (!result)
2020 return GL_FALSE;
2021
2022 return GL_TRUE;
2023 }
2024
2025 /* init declarator list */
2026 #define DECLARATOR_NONE 0
2027 #define DECLARATOR_NEXT 1
2028
2029 /* variable declaration */
2030 #define VARIABLE_NONE 0
2031 #define VARIABLE_IDENTIFIER 1
2032 #define VARIABLE_INITIALIZER 2
2033 #define VARIABLE_ARRAY_EXPLICIT 3
2034 #define VARIABLE_ARRAY_UNKNOWN 4
2035
2036
2037 /**
2038 * Parse the initializer for a variable declaration.
2039 */
2040 static int
2041 parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
2042 const slang_fully_specified_type * type)
2043 {
2044 GET_CURRENT_CONTEXT(ctx); /* a hack */
2045 slang_variable *var;
2046 slang_atom a_name;
2047
2048 /* empty init declatator (without name, e.g. "float ;") */
2049 if (*C->I++ == VARIABLE_NONE)
2050 return 1;
2051
2052 a_name = parse_identifier(C);
2053
2054 /* check if name is already in this scope */
2055 if (_slang_variable_locate(O->vars, a_name, GL_FALSE)) {
2056 slang_info_log_error(C->L,
2057 "declaration of '%s' conflicts with previous declaration",
2058 (char *) a_name);
2059 RETURN0;
2060 }
2061
2062 /* make room for the new variable and initialize it */
2063 var = slang_variable_scope_grow(O->vars);
2064 if (!var) {
2065 slang_info_log_memory(C->L);
2066 RETURN0;
2067 }
2068
2069 /* copy the declarator type qualifier/etc info, parse the identifier */
2070 var->type.qualifier = type->qualifier;
2071 var->type.centroid = type->centroid;
2072 var->type.precision = type->precision;
2073 var->type.variant = type->variant;
2074 var->type.array_len = type->array_len;
2075 var->a_name = a_name;
2076 if (var->a_name == SLANG_ATOM_NULL)
2077 RETURN0;
2078
2079 switch (*C->I++) {
2080 case VARIABLE_NONE:
2081 /* simple variable declarator - just copy the specifier */
2082 if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
2083 RETURN0;
2084 break;
2085 case VARIABLE_INITIALIZER:
2086 /* initialized variable - copy the specifier and parse the expression */
2087 if (0 && type->array_len >= 0) {
2088 /* The type was something like "float[4]" */
2089 convert_to_array(C, var, &type->specifier);
2090 var->array_len = type->array_len;
2091 }
2092 else {
2093 if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
2094 RETURN0;
2095 }
2096 var->initializer =
2097 (slang_operation *) _slang_alloc(sizeof(slang_operation));
2098 if (var->initializer == NULL) {
2099 slang_info_log_memory(C->L);
2100 RETURN0;
2101 }
2102 if (!slang_operation_construct(var->initializer)) {
2103 _slang_free(var->initializer);
2104 var->initializer = NULL;
2105 slang_info_log_memory(C->L);
2106 RETURN0;
2107 }
2108 if (!parse_expression(C, O, var->initializer))
2109 RETURN0;
2110 break;
2111 case VARIABLE_ARRAY_UNKNOWN:
2112 /* unsized array - mark it as array and copy the specifier to
2113 * the array element
2114 */
2115 if (type->array_len >= 0) {
2116 slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
2117 RETURN0;
2118 }
2119 if (!convert_to_array(C, var, &type->specifier))
2120 return GL_FALSE;
2121 break;
2122 case VARIABLE_ARRAY_EXPLICIT:
2123 if (type->array_len >= 0) {
2124 /* the user is trying to do something like: float[2] x[3]; */
2125 slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
2126 RETURN0;
2127 }
2128 if (!convert_to_array(C, var, &type->specifier))
2129 return GL_FALSE;
2130 if (!parse_array_len(C, O, &var->array_len))
2131 return GL_FALSE;
2132 break;
2133 default:
2134 RETURN0;
2135 }
2136
2137 /* allocate global address space for a variable with a known size */
2138 if (C->global_scope
2139 && !(var->type.specifier.type == SLANG_SPEC_ARRAY
2140 && var->array_len == 0)) {
2141 if (!calculate_var_size(C, O, var))
2142 return GL_FALSE;
2143 }
2144
2145 /* emit code for global var decl */
2146 if (C->global_scope) {
2147 slang_assemble_ctx A;
2148 memset(&A, 0, sizeof(slang_assemble_ctx));
2149 A.atoms = C->atoms;
2150 A.space.funcs = O->funs;
2151 A.space.structs = O->structs;
2152 A.space.vars = O->vars;
2153 A.program = O->program;
2154 A.pragmas = O->pragmas;
2155 A.vartable = O->vartable;
2156 A.log = C->L;
2157 A.curFuncEndLabel = NULL;
2158 A.EmitContReturn = ctx->Shader.EmitContReturn;
2159 if (!_slang_codegen_global_variable(&A, var, C->type))
2160 RETURN0;
2161 }
2162
2163 /* initialize global variable */
2164 if (C->global_scope) {
2165 if (var->initializer != NULL) {
2166 slang_assemble_ctx A;
2167 memset(&A, 0, sizeof(slang_assemble_ctx));
2168 A.atoms = C->atoms;
2169 A.space.funcs = O->funs;
2170 A.space.structs = O->structs;
2171 A.space.vars = O->vars;
2172 if (!initialize_global(&A, var))
2173 RETURN0;
2174 }
2175 }
2176 return 1;
2177 }
2178
2179 /**
2180 * Parse a list of variable declarations. Each variable may have an
2181 * initializer.
2182 */
2183 static int
2184 parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O)
2185 {
2186 slang_fully_specified_type type;
2187
2188 /* parse the fully specified type, common to all declarators */
2189 if (!slang_fully_specified_type_construct(&type))
2190 RETURN0;
2191 if (!parse_fully_specified_type(C, O, &type)) {
2192 slang_fully_specified_type_destruct(&type);
2193 RETURN0;
2194 }
2195
2196 /* parse declarators, pass-in the parsed type */
2197 do {
2198 if (!parse_init_declarator(C, O, &type)) {
2199 slang_fully_specified_type_destruct(&type);
2200 RETURN0;
2201 }
2202 }
2203 while (*C->I++ == DECLARATOR_NEXT);
2204
2205 slang_fully_specified_type_destruct(&type);
2206 return 1;
2207 }
2208
2209
2210 /**
2211 * Parse a function definition or declaration.
2212 * \param C parsing context
2213 * \param O output context
2214 * \param definition if non-zero expect a definition, else a declaration
2215 * \param parsed_func_ret returns the parsed function
2216 * \return GL_TRUE if success, GL_FALSE if failure
2217 */
2218 static GLboolean
2219 parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
2220 slang_function ** parsed_func_ret)
2221 {
2222 slang_function parsed_func, *found_func;
2223
2224 /* parse function definition/declaration */
2225 if (!slang_function_construct(&parsed_func))
2226 return GL_FALSE;
2227 if (definition) {
2228 if (!parse_function_definition(C, O, &parsed_func)) {
2229 slang_function_destruct(&parsed_func);
2230 return GL_FALSE;
2231 }
2232 }
2233 else {
2234 if (!parse_function_prototype(C, O, &parsed_func)) {
2235 slang_function_destruct(&parsed_func);
2236 return GL_FALSE;
2237 }
2238 }
2239
2240 /* find a function with a prototype matching the parsed one - only
2241 * the current scope is being searched to allow built-in function
2242 * overriding
2243 */
2244 found_func = slang_function_scope_find(O->funs, &parsed_func, 0);
2245 if (found_func == NULL) {
2246 /* New function, add it to the function list */
2247 O->funs->functions =
2248 (slang_function *) _slang_realloc(O->funs->functions,
2249 O->funs->num_functions
2250 * sizeof(slang_function),
2251 (O->funs->num_functions + 1)
2252 * sizeof(slang_function));
2253 if (O->funs->functions == NULL) {
2254 /* Make sure that there are no functions marked, as the
2255 * allocation is currently NULL, in order to avoid
2256 * a potental segfault as we clean up later.
2257 */
2258 O->funs->num_functions = 0;
2259
2260 slang_info_log_memory(C->L);
2261 slang_function_destruct(&parsed_func);
2262 return GL_FALSE;
2263 }
2264 O->funs->functions[O->funs->num_functions] = parsed_func;
2265 O->funs->num_functions++;
2266
2267 /* return the newly parsed function */
2268 *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
2269 }
2270 else {
2271 /* previously defined or declared */
2272 /* TODO: check function return type qualifiers and specifiers */
2273 if (definition) {
2274 if (found_func->body != NULL) {
2275 slang_info_log_error(C->L, "%s: function already has a body.",
2276 slang_atom_pool_id(C->atoms,
2277 parsed_func.header.
2278 a_name));
2279 slang_function_destruct(&parsed_func);
2280 return GL_FALSE;
2281 }
2282
2283 /* destroy the existing function declaration and replace it
2284 * with the new one
2285 */
2286 slang_function_destruct(found_func);
2287 *found_func = parsed_func;
2288 }
2289 else {
2290 /* another declaration of the same function prototype - ignore it */
2291 slang_function_destruct(&parsed_func);
2292 }
2293
2294 /* return the found function */
2295 *parsed_func_ret = found_func;
2296 }
2297
2298 return GL_TRUE;
2299 }
2300
2301 /* declaration */
2302 #define DECLARATION_FUNCTION_PROTOTYPE 1
2303 #define DECLARATION_INIT_DECLARATOR_LIST 2
2304
2305 static int
2306 parse_declaration(slang_parse_ctx * C, slang_output_ctx * O)
2307 {
2308 switch (*C->I++) {
2309 case DECLARATION_INIT_DECLARATOR_LIST:
2310 if (!parse_init_declarator_list(C, O))
2311 RETURN0;
2312 break;
2313 case DECLARATION_FUNCTION_PROTOTYPE:
2314 {
2315 slang_function *dummy_func;
2316
2317 if (!parse_function(C, O, 0, &dummy_func))
2318 RETURN0;
2319 }
2320 break;
2321 default:
2322 RETURN0;
2323 }
2324 return 1;
2325 }
2326
2327 static int
2328 parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O)
2329 {
2330 int precision, type;
2331
2332 if (!O->allow_precision) {
2333 slang_info_log_error(C->L, "syntax error at \"precision\"");
2334 RETURN0;
2335 }
2336
2337 precision = *C->I++;
2338 switch (precision) {
2339 case PRECISION_LOW:
2340 case PRECISION_MEDIUM:
2341 case PRECISION_HIGH:
2342 /* OK */
2343 break;
2344 default:
2345 _mesa_problem(NULL, "unexpected precision %d at %s:%d\n",
2346 precision, __FILE__, __LINE__);
2347 RETURN0;
2348 }
2349
2350 type = *C->I++;
2351 switch (type) {
2352 case TYPE_SPECIFIER_FLOAT:
2353 case TYPE_SPECIFIER_INT:
2354 case TYPE_SPECIFIER_SAMPLER1D:
2355 case TYPE_SPECIFIER_SAMPLER2D:
2356 case TYPE_SPECIFIER_SAMPLER3D:
2357 case TYPE_SPECIFIER_SAMPLERCUBE:
2358 case TYPE_SPECIFIER_SAMPLER1DSHADOW:
2359 case TYPE_SPECIFIER_SAMPLER2DSHADOW:
2360 case TYPE_SPECIFIER_SAMPLER2DRECT:
2361 case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW:
2362 /* OK */
2363 break;
2364 default:
2365 _mesa_problem(NULL, "unexpected type %d at %s:%d\n",
2366 type, __FILE__, __LINE__);
2367 RETURN0;
2368 }
2369
2370 assert(type < TYPE_SPECIFIER_COUNT);
2371 O->default_precision[type] = precision;
2372
2373 return 1;
2374 }
2375
2376
2377 /**
2378 * Initialize the default precision for all types.
2379 * XXX this info isn't used yet.
2380 */
2381 static void
2382 init_default_precision(slang_output_ctx *O, slang_unit_type type)
2383 {
2384 GLuint i;
2385 for (i = 0; i < TYPE_SPECIFIER_COUNT; i++) {
2386 #if FEATURE_es2_glsl
2387 O->default_precision[i] = PRECISION_LOW;
2388 #else
2389 O->default_precision[i] = PRECISION_HIGH;
2390 #endif
2391 }
2392
2393 if (type == SLANG_UNIT_VERTEX_SHADER) {
2394 O->default_precision[TYPE_SPECIFIER_FLOAT] = PRECISION_HIGH;
2395 O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_HIGH;
2396 }
2397 else {
2398 O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_MEDIUM;
2399 }
2400 }
2401
2402
2403 static int
2404 parse_invariant(slang_parse_ctx * C, slang_output_ctx * O)
2405 {
2406 if (O->allow_invariant) {
2407 slang_atom *a = parse_identifier(C);
2408 /* XXX not doing anything with this var yet */
2409 /*printf("ID: %s\n", (char*) a);*/
2410 return a ? 1 : 0;
2411 }
2412 else {
2413 slang_info_log_error(C->L, "syntax error at \"invariant\"");
2414 RETURN0;
2415 }
2416 }
2417
2418
2419 /* external declaration or default precision specifier */
2420 #define EXTERNAL_NULL 0
2421 #define EXTERNAL_FUNCTION_DEFINITION 1
2422 #define EXTERNAL_DECLARATION 2
2423 #define DEFAULT_PRECISION 3
2424 #define INVARIANT_STMT 4
2425
2426
2427 static GLboolean
2428 parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
2429 struct gl_shader *shader)
2430 {
2431 GET_CURRENT_CONTEXT(ctx);
2432 slang_output_ctx o;
2433 GLboolean success;
2434 GLuint maxRegs;
2435 slang_function *mainFunc = NULL;
2436
2437 if (unit->type == SLANG_UNIT_FRAGMENT_BUILTIN ||
2438 unit->type == SLANG_UNIT_FRAGMENT_SHADER) {
2439 maxRegs = ctx->Const.FragmentProgram.MaxTemps;
2440 }
2441 else {
2442 assert(unit->type == SLANG_UNIT_VERTEX_BUILTIN ||
2443 unit->type == SLANG_UNIT_VERTEX_SHADER);
2444 maxRegs = ctx->Const.VertexProgram.MaxTemps;
2445 }
2446
2447 /* setup output context */
2448 o.funs = &unit->funs;
2449 o.structs = &unit->structs;
2450 o.vars = &unit->vars;
2451 o.program = shader ? shader->Program : NULL;
2452 o.pragmas = shader ? &shader->Pragmas : NULL;
2453 o.vartable = _slang_new_var_table(maxRegs);
2454 _slang_push_var_table(o.vartable);
2455
2456 /* allow 'invariant' keyword? */
2457 #if FEATURE_es2_glsl
2458 o.allow_invariant = GL_TRUE;
2459 #else
2460 o.allow_invariant = (C->version >= 120) ? GL_TRUE : GL_FALSE;
2461 #endif
2462
2463 /* allow 'centroid' keyword? */
2464 o.allow_centroid = (C->version >= 120) ? GL_TRUE : GL_FALSE;
2465
2466 /* allow 'lowp/mediump/highp' keywords? */
2467 #if FEATURE_es2_glsl
2468 o.allow_precision = GL_TRUE;
2469 #else
2470 o.allow_precision = (C->version >= 120) ? GL_TRUE : GL_FALSE;
2471 #endif
2472 init_default_precision(&o, unit->type);
2473
2474 /* allow 'float[]' keyword? */
2475 o.allow_array_types = (C->version >= 120) ? GL_TRUE : GL_FALSE;
2476
2477 /* parse individual functions and declarations */
2478 while (*C->I != EXTERNAL_NULL) {
2479 switch (*C->I++) {
2480 case EXTERNAL_FUNCTION_DEFINITION:
2481 {
2482 slang_function *func;
2483 success = parse_function(C, &o, 1, &func);
2484 if (success &&
2485 _mesa_strcmp((char *) func->header.a_name, "main") == 0) {
2486 /* found main() */
2487 mainFunc = func;
2488 }
2489 }
2490 break;
2491 case EXTERNAL_DECLARATION:
2492 success = parse_declaration(C, &o);
2493 break;
2494 case DEFAULT_PRECISION:
2495 success = parse_default_precision(C, &o);
2496 break;
2497 case INVARIANT_STMT:
2498 success = parse_invariant(C, &o);
2499 break;
2500 default:
2501 success = GL_FALSE;
2502 }
2503
2504 if (!success) {
2505 /* xxx free codegen */
2506 _slang_pop_var_table(o.vartable);
2507 return GL_FALSE;
2508 }
2509 }
2510 C->I++;
2511
2512 if (mainFunc) {
2513 /* assemble (generate code) for main() */
2514 slang_assemble_ctx A;
2515 memset(&A, 0, sizeof(slang_assemble_ctx));
2516 A.atoms = C->atoms;
2517 A.space.funcs = o.funs;
2518 A.space.structs = o.structs;
2519 A.space.vars = o.vars;
2520 A.program = o.program;
2521 A.pragmas = &shader->Pragmas;
2522 A.vartable = o.vartable;
2523 A.EmitContReturn = ctx->Shader.EmitContReturn;
2524 A.log = C->L;
2525
2526 /* main() takes no parameters */
2527 if (mainFunc->param_count > 0) {
2528 slang_info_log_error(A.log, "main() takes no arguments");
2529 return GL_FALSE;
2530 }
2531
2532 _slang_codegen_function(&A, mainFunc);
2533
2534 shader->Main = GL_TRUE; /* this shader defines main() */
2535
2536 shader->UnresolvedRefs = A.UnresolvedRefs;
2537 }
2538
2539 _slang_pop_var_table(o.vartable);
2540 _slang_delete_var_table(o.vartable);
2541
2542 return GL_TRUE;
2543 }
2544
2545 static GLboolean
2546 compile_binary(const byte * prod, slang_code_unit * unit,
2547 GLuint version,
2548 slang_unit_type type, slang_info_log * infolog,
2549 slang_code_unit * builtin, slang_code_unit * downlink,
2550 struct gl_shader *shader)
2551 {
2552 slang_parse_ctx C;
2553
2554 unit->type = type;
2555
2556 /* setup parse context */
2557 C.I = prod;
2558 C.L = infolog;
2559 C.parsing_builtin = (builtin == NULL);
2560 C.global_scope = GL_TRUE;
2561 C.atoms = &unit->object->atompool;
2562 C.type = type;
2563 C.version = version;
2564
2565 if (!check_revision(&C))
2566 return GL_FALSE;
2567
2568 if (downlink != NULL) {
2569 unit->vars.outer_scope = &downlink->vars;
2570 unit->funs.outer_scope = &downlink->funs;
2571 unit->structs.outer_scope = &downlink->structs;
2572 }
2573
2574 /* parse translation unit */
2575 return parse_code_unit(&C, unit, shader);
2576 }
2577
2578 static GLboolean
2579 compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
2580 slang_unit_type type, slang_info_log * infolog,
2581 slang_code_unit * builtin,
2582 struct gl_shader *shader,
2583 const struct gl_extensions *extensions,
2584 struct gl_sl_pragmas *pragmas)
2585 {
2586 struct sl_pp_context context;
2587 struct sl_pp_token_info *tokens;
2588 byte *prod;
2589 GLuint size;
2590 unsigned int version;
2591 unsigned int maxVersion;
2592 int result;
2593 struct sl_pp_purify_options options;
2594 char *outbuf;
2595 struct sl_pp_token_info *intokens;
2596 unsigned int tokens_eaten;
2597
2598 memset(&options, 0, sizeof(options));
2599 if (sl_pp_purify(source, &options, &outbuf)) {
2600 slang_info_log_error(infolog, "unable to preprocess the source");
2601 return GL_FALSE;
2602 }
2603
2604 if (sl_pp_context_init(&context)) {
2605 slang_info_log_error(infolog, "out of memory");
2606 free(outbuf);
2607 return GL_FALSE;
2608 }
2609
2610 if (sl_pp_tokenise(&context, outbuf, &intokens)) {
2611 slang_info_log_error(infolog, "%s", context.error_msg);
2612 sl_pp_context_destroy(&context);
2613 free(outbuf);
2614 return GL_FALSE;
2615 }
2616
2617 free(outbuf);
2618
2619 if (sl_pp_version(&context, intokens, &version, &tokens_eaten)) {
2620 slang_info_log_error(infolog, "%s", context.error_msg);
2621 sl_pp_context_destroy(&context);
2622 free(intokens);
2623 return GL_FALSE;
2624 }
2625
2626 if (sl_pp_process(&context, &intokens[tokens_eaten], &tokens)) {
2627 slang_info_log_error(infolog, "%s", context.error_msg);
2628 sl_pp_context_destroy(&context);
2629 free(intokens);
2630 return GL_FALSE;
2631 }
2632
2633 free(intokens);
2634
2635 /* For the time being we care about only a handful of tokens. */
2636 {
2637 const struct sl_pp_token_info *src = tokens;
2638 struct sl_pp_token_info *dst = tokens;
2639
2640 while (src->token != SL_PP_EOF) {
2641 switch (src->token) {
2642 case SL_PP_COMMA:
2643 case SL_PP_SEMICOLON:
2644 case SL_PP_LBRACE:
2645 case SL_PP_RBRACE:
2646 case SL_PP_LPAREN:
2647 case SL_PP_RPAREN:
2648 case SL_PP_LBRACKET:
2649 case SL_PP_RBRACKET:
2650 case SL_PP_DOT:
2651 case SL_PP_INCREMENT:
2652 case SL_PP_ADDASSIGN:
2653 case SL_PP_PLUS:
2654 case SL_PP_DECREMENT:
2655 case SL_PP_SUBASSIGN:
2656 case SL_PP_MINUS:
2657 case SL_PP_BITNOT:
2658 case SL_PP_NOTEQUAL:
2659 case SL_PP_NOT:
2660 case SL_PP_MULASSIGN:
2661 case SL_PP_STAR:
2662 case SL_PP_DIVASSIGN:
2663 case SL_PP_SLASH:
2664 case SL_PP_MODASSIGN:
2665 case SL_PP_MODULO:
2666 case SL_PP_LSHIFTASSIGN:
2667 case SL_PP_LSHIFT:
2668 case SL_PP_LESSEQUAL:
2669 case SL_PP_LESS:
2670 case SL_PP_RSHIFTASSIGN:
2671 case SL_PP_RSHIFT:
2672 case SL_PP_GREATEREQUAL:
2673 case SL_PP_GREATER:
2674 case SL_PP_EQUAL:
2675 case SL_PP_ASSIGN:
2676 case SL_PP_AND:
2677 case SL_PP_BITANDASSIGN:
2678 case SL_PP_BITAND:
2679 case SL_PP_XOR:
2680 case SL_PP_BITXORASSIGN:
2681 case SL_PP_BITXOR:
2682 case SL_PP_OR:
2683 case SL_PP_BITORASSIGN:
2684 case SL_PP_BITOR:
2685 case SL_PP_QUESTION:
2686 case SL_PP_COLON:
2687 case SL_PP_IDENTIFIER:
2688 case SL_PP_NUMBER:
2689 *dst++ = *src++;
2690 break;
2691
2692 default:
2693 src++;
2694 }
2695 }
2696
2697 /* The end of stream token. */
2698 *dst = *src;
2699 }
2700
2701 #if FEATURE_ARB_shading_language_120
2702 maxVersion = 120;
2703 #elif FEATURE_es2_glsl
2704 maxVersion = 100;
2705 #else
2706 maxVersion = 110;
2707 #endif
2708
2709 if (version > maxVersion ||
2710 (version != 100 && version != 110 && version != 120)) {
2711 slang_info_log_error(infolog,
2712 "language version %.2f is not supported.",
2713 version * 0.01);
2714 sl_pp_context_destroy(&context);
2715 free(tokens);
2716 return GL_FALSE;
2717 }
2718
2719 /* Finally check the syntax and generate its binary representation. */
2720 result = grammar_fast_check(id, &context, tokens, &prod, &size, 65536);
2721
2722 sl_pp_context_destroy(&context);
2723 free(tokens);
2724
2725 if (!result) {
2726 char buf[1024];
2727 GLint pos;
2728
2729 grammar_get_last_error((byte *) (buf), sizeof(buf), &pos);
2730 slang_info_log_error(infolog, buf);
2731 /* syntax error (possibly in library code) */
2732 #if 0
2733 {
2734 int line, col;
2735 char *s;
2736 s = (char *) _mesa_find_line_column((const GLubyte *) source,
2737 (const GLubyte *) source + pos,
2738 &line, &col);
2739 printf("Error on line %d, col %d: %s\n", line, col, s);
2740 }
2741 #endif
2742 return GL_FALSE;
2743 }
2744
2745 /* Syntax is okay - translate it to internal representation. */
2746 if (!compile_binary(prod, unit, version, type, infolog, builtin,
2747 &builtin[SLANG_BUILTIN_TOTAL - 1],
2748 shader)) {
2749 grammar_alloc_free(prod);
2750 return GL_FALSE;
2751 }
2752 grammar_alloc_free(prod);
2753 return GL_TRUE;
2754 }
2755
2756 LONGSTRING static const char *slang_shader_syn =
2757 #include "library/slang_shader_syn.h"
2758 ;
2759
2760 static const byte slang_core_gc[] = {
2761 #include "library/slang_core_gc.h"
2762 };
2763
2764 static const byte slang_120_core_gc[] = {
2765 #include "library/slang_120_core_gc.h"
2766 };
2767
2768 static const byte slang_120_fragment_gc[] = {
2769 #include "library/slang_builtin_120_fragment_gc.h"
2770 };
2771
2772 static const byte slang_common_builtin_gc[] = {
2773 #include "library/slang_common_builtin_gc.h"
2774 };
2775
2776 static const byte slang_fragment_builtin_gc[] = {
2777 #include "library/slang_fragment_builtin_gc.h"
2778 };
2779
2780 static const byte slang_vertex_builtin_gc[] = {
2781 #include "library/slang_vertex_builtin_gc.h"
2782 };
2783
2784 static GLboolean
2785 compile_object(grammar * id, const char *source, slang_code_object * object,
2786 slang_unit_type type, slang_info_log * infolog,
2787 struct gl_shader *shader,
2788 const struct gl_extensions *extensions,
2789 struct gl_sl_pragmas *pragmas)
2790 {
2791 slang_code_unit *builtins = NULL;
2792 GLuint base_version = 110;
2793
2794 /* load GLSL grammar */
2795 *id = grammar_load_from_text((const byte *) (slang_shader_syn));
2796 if (*id == 0) {
2797 byte buf[1024];
2798 int pos;
2799
2800 grammar_get_last_error(buf, 1024, &pos);
2801 slang_info_log_error(infolog, (const char *) (buf));
2802 return GL_FALSE;
2803 }
2804
2805 /* set shader type - the syntax is slightly different for different shaders */
2806 if (type == SLANG_UNIT_FRAGMENT_SHADER
2807 || type == SLANG_UNIT_FRAGMENT_BUILTIN)
2808 grammar_set_reg8(*id, (const byte *) "shader_type", 1);
2809 else
2810 grammar_set_reg8(*id, (const byte *) "shader_type", 2);
2811
2812 /* enable language extensions */
2813 grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1);
2814
2815 /* if parsing user-specified shader, load built-in library */
2816 if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_VERTEX_SHADER) {
2817 /* compile core functionality first */
2818 if (!compile_binary(slang_core_gc,
2819 &object->builtin[SLANG_BUILTIN_CORE],
2820 base_version,
2821 SLANG_UNIT_FRAGMENT_BUILTIN, infolog,
2822 NULL, NULL, NULL))
2823 return GL_FALSE;
2824
2825 #if FEATURE_ARB_shading_language_120
2826 if (!compile_binary(slang_120_core_gc,
2827 &object->builtin[SLANG_BUILTIN_120_CORE],
2828 120,
2829 SLANG_UNIT_FRAGMENT_BUILTIN, infolog,
2830 NULL, &object->builtin[SLANG_BUILTIN_CORE], NULL))
2831 return GL_FALSE;
2832 #endif
2833
2834 /* compile common functions and variables, link to core */
2835 if (!compile_binary(slang_common_builtin_gc,
2836 &object->builtin[SLANG_BUILTIN_COMMON],
2837 #if FEATURE_ARB_shading_language_120
2838 120,
2839 #else
2840 base_version,
2841 #endif
2842 SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
2843 #if FEATURE_ARB_shading_language_120
2844 &object->builtin[SLANG_BUILTIN_120_CORE],
2845 #else
2846 &object->builtin[SLANG_BUILTIN_CORE],
2847 #endif
2848 NULL))
2849 return GL_FALSE;
2850
2851 /* compile target-specific functions and variables, link to common */
2852 if (type == SLANG_UNIT_FRAGMENT_SHADER) {
2853 if (!compile_binary(slang_fragment_builtin_gc,
2854 &object->builtin[SLANG_BUILTIN_TARGET],
2855 base_version,
2856 SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
2857 &object->builtin[SLANG_BUILTIN_COMMON], NULL))
2858 return GL_FALSE;
2859 #if FEATURE_ARB_shading_language_120
2860 if (!compile_binary(slang_120_fragment_gc,
2861 &object->builtin[SLANG_BUILTIN_TARGET],
2862 120,
2863 SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
2864 &object->builtin[SLANG_BUILTIN_COMMON], NULL))
2865 return GL_FALSE;
2866 #endif
2867 }
2868 else if (type == SLANG_UNIT_VERTEX_SHADER) {
2869 if (!compile_binary(slang_vertex_builtin_gc,
2870 &object->builtin[SLANG_BUILTIN_TARGET],
2871 base_version,
2872 SLANG_UNIT_VERTEX_BUILTIN, infolog, NULL,
2873 &object->builtin[SLANG_BUILTIN_COMMON], NULL))
2874 return GL_FALSE;
2875 }
2876
2877 /* disable language extensions */
2878 #if NEW_SLANG /* allow-built-ins */
2879 grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1);
2880 #else
2881 grammar_set_reg8(*id, (const byte *) "parsing_builtin", 0);
2882 #endif
2883 builtins = object->builtin;
2884 }
2885
2886 /* compile the actual shader - pass-in built-in library for external shader */
2887 return compile_with_grammar(*id, source, &object->unit, type, infolog,
2888 builtins, shader, extensions, pragmas);
2889 }
2890
2891
2892 static GLboolean
2893 compile_shader(GLcontext *ctx, slang_code_object * object,
2894 slang_unit_type type, slang_info_log * infolog,
2895 struct gl_shader *shader)
2896 {
2897 GLboolean success;
2898 grammar id = 0;
2899
2900 #if 0 /* for debug */
2901 _mesa_printf("********* COMPILE SHADER ***********\n");
2902 _mesa_printf("%s\n", shader->Source);
2903 _mesa_printf("************************************\n");
2904 #endif
2905
2906 assert(shader->Program);
2907
2908 _slang_code_object_dtr(object);
2909 _slang_code_object_ctr(object);
2910
2911 success = compile_object(&id, shader->Source, object, type, infolog, shader,
2912 &ctx->Extensions, &shader->Pragmas);
2913 if (id != 0)
2914 grammar_destroy(id);
2915 if (!success)
2916 return GL_FALSE;
2917
2918 return GL_TRUE;
2919 }
2920
2921
2922
2923 GLboolean
2924 _slang_compile(GLcontext *ctx, struct gl_shader *shader)
2925 {
2926 GLboolean success;
2927 slang_info_log info_log;
2928 slang_code_object obj;
2929 slang_unit_type type;
2930
2931 if (shader->Type == GL_VERTEX_SHADER) {
2932 type = SLANG_UNIT_VERTEX_SHADER;
2933 }
2934 else {
2935 assert(shader->Type == GL_FRAGMENT_SHADER);
2936 type = SLANG_UNIT_FRAGMENT_SHADER;
2937 }
2938
2939 if (!shader->Source)
2940 return GL_FALSE;
2941
2942 ctx->Shader.MemPool = _slang_new_mempool(1024*1024);
2943
2944 shader->Main = GL_FALSE;
2945
2946 if (!shader->Program) {
2947 GLenum progTarget;
2948 if (shader->Type == GL_VERTEX_SHADER)
2949 progTarget = GL_VERTEX_PROGRAM_ARB;
2950 else
2951 progTarget = GL_FRAGMENT_PROGRAM_ARB;
2952 shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
2953 shader->Program->Parameters = _mesa_new_parameter_list();
2954 shader->Program->Varying = _mesa_new_parameter_list();
2955 shader->Program->Attributes = _mesa_new_parameter_list();
2956 }
2957
2958 slang_info_log_construct(&info_log);
2959 _slang_code_object_ctr(&obj);
2960
2961 success = compile_shader(ctx, &obj, type, &info_log, shader);
2962
2963 /* free shader's prev info log */
2964 if (shader->InfoLog) {
2965 _mesa_free(shader->InfoLog);
2966 shader->InfoLog = NULL;
2967 }
2968
2969 if (info_log.text) {
2970 /* copy info-log string to shader object */
2971 shader->InfoLog = _mesa_strdup(info_log.text);
2972 }
2973
2974 if (info_log.error_flag) {
2975 success = GL_FALSE;
2976 }
2977
2978 slang_info_log_destruct(&info_log);
2979 _slang_code_object_dtr(&obj);
2980
2981 _slang_delete_mempool((slang_mempool *) ctx->Shader.MemPool);
2982 ctx->Shader.MemPool = NULL;
2983
2984 /* remove any reads of output registers */
2985 #if 0
2986 printf("Pre-remove output reads:\n");
2987 _mesa_print_program(shader->Program);
2988 #endif
2989 _mesa_remove_output_reads(shader->Program, PROGRAM_OUTPUT);
2990 if (shader->Type == GL_VERTEX_SHADER) {
2991 /* and remove writes to varying vars in vertex programs */
2992 _mesa_remove_output_reads(shader->Program, PROGRAM_VARYING);
2993 }
2994 #if 0
2995 printf("Post-remove output reads:\n");
2996 _mesa_print_program(shader->Program);
2997 #endif
2998
2999 shader->CompileStatus = success;
3000
3001 if (success) {
3002 if (shader->Pragmas.Optimize &&
3003 (ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
3004 _mesa_optimize_program(ctx, shader->Program);
3005 }
3006 }
3007
3008 if (ctx->Shader.Flags & GLSL_LOG) {
3009 _mesa_write_shader_to_file(shader);
3010 }
3011
3012 return success;
3013 }
3014