2 * Mesa 3-D graphics library
5 * Copyright (C) 2005 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
26 * \file slang_compile.c
27 * slang front-end compiler
32 #include "grammar_mesa.h"
33 #include "slang_utility.h"
34 #include "slang_compile.h"
35 #include "slang_preprocess.h"
36 #include "slang_storage.h"
37 #include "slang_assemble.h"
38 #include "slang_execute.h"
41 This is a straightforward implementation of the slang front-end compiler.
42 Lots of error-checking functionality is missing but every well-formed shader source should
43 compile successfully and execute as expected. However, some semantically ill-formed shaders
44 may be accepted resulting in undefined behaviour.
47 static void slang_variable_construct (slang_variable
*);
48 static int slang_variable_copy (slang_variable
*, const slang_variable
*);
49 static void slang_struct_destruct (slang_struct
*);
50 static int slang_struct_equal (const slang_struct
*, const slang_struct
*);
51 static void slang_variable_destruct (slang_variable
*);
53 /* slang_type_specifier_type */
55 /* these must match with slang_type_specifier_type enum */
56 static const char *type_specifier_type_names
[] = {
82 slang_type_specifier_type
slang_type_specifier_type_from_string (const char *name
)
84 const char **p
= type_specifier_type_names
;
87 if (slang_string_compare (*p
, name
) == 0)
88 return (slang_type_specifier_type
) (p
- type_specifier_type_names
);
91 return slang_spec_void
;
94 /* slang_type_specifier */
96 void slang_type_specifier_construct (slang_type_specifier
*spec
)
98 spec
->type
= slang_spec_void
;
103 void slang_type_specifier_destruct (slang_type_specifier
*spec
)
105 if (spec
->_struct
!= NULL
)
107 slang_struct_destruct (spec
->_struct
);
108 slang_alloc_free (spec
->_struct
);
110 if (spec
->_array
!= NULL
)
112 slang_type_specifier_destruct (spec
->_array
);
113 slang_alloc_free (spec
->_array
);
117 int slang_type_specifier_copy (slang_type_specifier
*x
, const slang_type_specifier
*y
)
119 slang_type_specifier_destruct (x
);
120 slang_type_specifier_construct (x
);
122 if (x
->type
== slang_spec_struct
)
124 x
->_struct
= (slang_struct
*) slang_alloc_malloc (sizeof (slang_struct
));
125 if (x
->_struct
== NULL
)
127 if (!slang_struct_construct_a (x
->_struct
))
129 slang_alloc_free (x
->_struct
);
133 return slang_struct_copy (x
->_struct
, y
->_struct
);
135 if (x
->type
== slang_spec_array
)
137 x
->_array
= (slang_type_specifier
*) slang_alloc_malloc (sizeof (slang_type_specifier
));
138 if (x
->_array
== NULL
)
140 slang_type_specifier_construct (x
->_array
);
141 return slang_type_specifier_copy (x
->_array
, y
->_array
);
146 int slang_type_specifier_equal (const slang_type_specifier
*x
, const slang_type_specifier
*y
)
148 if (x
->type
!= y
->type
)
150 if (x
->type
== slang_spec_struct
)
151 return slang_struct_equal (x
->_struct
, y
->_struct
);
152 if (x
->type
== slang_spec_array
)
153 return slang_type_specifier_equal (x
->_array
, y
->_array
);
157 /* slang_fully_specified_type */
159 static void slang_fully_specified_type_construct (slang_fully_specified_type
*type
)
161 type
->qualifier
= slang_qual_none
;
162 slang_type_specifier_construct (&type
->specifier
);
165 static void slang_fully_specified_type_destruct (slang_fully_specified_type
*type
)
167 slang_type_specifier_destruct (&type
->specifier
);
170 static int slang_fully_specified_type_copy (slang_fully_specified_type
*x
,
171 const slang_fully_specified_type
*y
)
173 slang_fully_specified_type_construct (x
);
174 slang_fully_specified_type_destruct (x
);
175 x
->qualifier
= y
->qualifier
;
176 return slang_type_specifier_copy (&x
->specifier
, &y
->specifier
);
179 /* slang_variable_scope */
181 static void slang_variable_scope_construct (slang_variable_scope
*scope
)
183 scope
->variables
= NULL
;
184 scope
->num_variables
= 0;
185 scope
->outer_scope
= NULL
;
188 static void slang_variable_scope_destruct (slang_variable_scope
*scope
)
191 for (i
= 0; i
< scope
->num_variables
; i
++)
192 slang_variable_destruct (scope
->variables
+ i
);
193 slang_alloc_free (scope
->variables
);
196 static int slang_variable_scope_copy (slang_variable_scope
*x
, const slang_variable_scope
*y
)
199 slang_variable_scope_destruct (x
);
200 slang_variable_scope_construct (x
);
201 x
->variables
= (slang_variable
*) slang_alloc_malloc (y
->num_variables
* sizeof (
203 if (x
->variables
== NULL
)
205 x
->num_variables
= y
->num_variables
;
206 for (i
= 0; i
< x
->num_variables
; i
++)
207 slang_variable_construct (x
->variables
+ i
);
208 for (i
= 0; i
< x
->num_variables
; i
++)
209 if (!slang_variable_copy (x
->variables
+ i
, y
->variables
+ i
))
211 x
->outer_scope
= y
->outer_scope
;
215 /* slang_operation */
217 int slang_operation_construct_a (slang_operation
*oper
)
219 oper
->type
= slang_oper_none
;
220 oper
->children
= NULL
;
221 oper
->num_children
= 0;
222 oper
->literal
= (float) 0;
223 oper
->identifier
= NULL
;
224 oper
->locals
= (slang_variable_scope
*) slang_alloc_malloc (sizeof (slang_variable_scope
));
225 if (oper
->locals
== NULL
)
227 slang_variable_scope_construct (oper
->locals
);
231 void slang_operation_destruct (slang_operation
*oper
)
234 for (i
= 0; i
< oper
->num_children
; i
++)
235 slang_operation_destruct (oper
->children
+ i
);
236 slang_alloc_free (oper
->children
);
237 slang_alloc_free (oper
->identifier
);
238 slang_variable_scope_destruct (oper
->locals
);
239 slang_alloc_free (oper
->locals
);
242 static int slang_operation_copy (slang_operation
*x
, const slang_operation
*y
)
245 for (i
= 0; i
< x
->num_children
; i
++)
246 slang_operation_destruct (x
->children
+ i
);
247 slang_alloc_free (x
->children
);
249 slang_alloc_free (x
->identifier
);
250 x
->identifier
= NULL
;
251 slang_variable_scope_destruct (x
->locals
);
252 slang_variable_scope_construct (x
->locals
);
255 x
->children
= (slang_operation
*) slang_alloc_malloc (y
->num_children
* sizeof (
257 if (x
->children
== NULL
)
259 for (i
= 0; i
< y
->num_children
; i
++)
260 if (!slang_operation_construct_a (x
->children
+ i
))
263 for (j
= 0; j
< i
; j
++)
264 slang_operation_destruct (x
->children
+ j
);
265 slang_alloc_free (x
->children
);
269 x
->num_children
= y
->num_children
;
270 for (i
= 0; i
< x
->num_children
; i
++)
271 if (!slang_operation_copy (x
->children
+ i
, y
->children
+ i
))
273 x
->literal
= y
->literal
;
274 if (y
->identifier
!= NULL
)
276 x
->identifier
= slang_string_duplicate (y
->identifier
);
277 if (x
->identifier
== NULL
)
280 if (!slang_variable_scope_copy (x
->locals
, y
->locals
))
287 static void slang_variable_construct (slang_variable
*var
)
289 slang_fully_specified_type_construct (&var
->type
);
291 var
->array_size
= NULL
;
292 var
->initializer
= NULL
;
296 static void slang_variable_destruct (slang_variable
*var
)
298 slang_fully_specified_type_destruct (&var
->type
);
299 slang_alloc_free (var
->name
);
300 if (var
->array_size
!= NULL
)
302 slang_operation_destruct (var
->array_size
);
303 slang_alloc_free (var
->array_size
);
305 if (var
->initializer
!= NULL
)
307 slang_operation_destruct (var
->initializer
);
308 slang_alloc_free (var
->initializer
);
312 static int slang_variable_copy (slang_variable
*x
, const slang_variable
*y
)
314 slang_variable_destruct (x
);
315 slang_variable_construct (x
);
316 if (!slang_fully_specified_type_copy (&x
->type
, &y
->type
))
320 x
->name
= slang_string_duplicate (y
->name
);
324 if (y
->array_size
!= NULL
)
326 x
->array_size
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
327 if (x
->array_size
== NULL
)
329 if (!slang_operation_construct_a (x
->array_size
))
331 slang_alloc_free (x
->array_size
);
332 x
->array_size
= NULL
;
335 if (!slang_operation_copy (x
->array_size
, y
->array_size
))
338 if (y
->initializer
!= NULL
)
340 x
->initializer
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
341 if (x
->initializer
== NULL
)
343 if (!slang_operation_construct_a (x
->initializer
))
345 slang_alloc_free (x
->initializer
);
346 x
->initializer
= NULL
;
349 if (!slang_operation_copy (x
->initializer
, y
->initializer
))
355 slang_variable
*_slang_locate_variable (slang_variable_scope
*scope
, const char *name
, int all
)
358 for (i
= 0; i
< scope
->num_variables
; i
++)
359 if (slang_string_compare (name
, scope
->variables
[i
].name
) == 0)
360 return scope
->variables
+ i
;
361 if (all
&& scope
->outer_scope
!= NULL
)
362 return _slang_locate_variable (scope
->outer_scope
, name
, 1);
366 /* slang_struct_scope */
368 static void slang_struct_scope_construct (slang_struct_scope
*scope
)
370 scope
->structs
= NULL
;
371 scope
->num_structs
= 0;
372 scope
->outer_scope
= NULL
;
375 static void slang_struct_scope_destruct (slang_struct_scope
*scope
)
378 for (i
= 0; i
< scope
->num_structs
; i
++)
379 slang_struct_destruct (scope
->structs
+ i
);
380 slang_alloc_free (scope
->structs
);
383 static int slang_struct_scope_copy (slang_struct_scope
*x
, const slang_struct_scope
*y
)
386 slang_struct_scope_destruct (x
);
387 slang_struct_scope_construct (x
);
388 x
->structs
= (slang_struct
*) slang_alloc_malloc (y
->num_structs
* sizeof (slang_struct
));
389 if (x
->structs
== NULL
)
391 x
->num_structs
= y
->num_structs
;
392 for (i
= 0; i
< x
->num_structs
; i
++)
395 if (!slang_struct_construct_a (x
->structs
+ i
))
397 for (j
= 0; j
< i
; j
++)
398 slang_struct_destruct (x
->structs
+ j
);
399 slang_alloc_free (x
->structs
);
404 for (i
= 0; i
< x
->num_structs
; i
++)
405 if (!slang_struct_copy (x
->structs
+ i
, y
->structs
+ i
))
407 x
->outer_scope
= y
->outer_scope
;
411 slang_struct
*slang_struct_scope_find (slang_struct_scope
*stru
, const char *name
, int all_scopes
)
414 for (i
= 0; i
< stru
->num_structs
; i
++)
415 if (slang_string_compare (name
, stru
->structs
[i
].name
) == 0)
416 return stru
->structs
+ i
;
417 if (all_scopes
&& stru
->outer_scope
!= NULL
)
418 return slang_struct_scope_find (stru
->outer_scope
, name
, 1);
424 int slang_struct_construct_a (slang_struct
*stru
)
427 stru
->fields
= (slang_variable_scope
*) slang_alloc_malloc (sizeof (slang_variable_scope
));
428 if (stru
->fields
== NULL
)
430 slang_variable_scope_construct (stru
->fields
);
431 stru
->structs
= (slang_struct_scope
*) slang_alloc_malloc (sizeof (slang_struct_scope
));
432 if (stru
->structs
== NULL
)
434 slang_variable_scope_destruct (stru
->fields
);
435 slang_alloc_free (stru
->fields
);
438 slang_struct_scope_construct (stru
->structs
);
442 static void slang_struct_destruct (slang_struct
*stru
)
444 slang_alloc_free (stru
->name
);
445 slang_variable_scope_destruct (stru
->fields
);
446 slang_alloc_free (stru
->fields
);
447 slang_struct_scope_destruct (stru
->structs
);
448 slang_alloc_free (stru
->structs
);
451 int slang_struct_copy (slang_struct
*x
, const slang_struct
*y
)
453 slang_alloc_free (x
->name
);
455 slang_variable_scope_destruct (x
->fields
);
456 slang_variable_scope_construct (x
->fields
);
457 slang_struct_scope_destruct (x
->structs
);
458 slang_struct_scope_construct (x
->structs
);
461 x
->name
= slang_string_duplicate (y
->name
);
465 if (!slang_variable_scope_copy (x
->fields
, y
->fields
))
467 if (!slang_struct_scope_copy (x
->structs
, y
->structs
))
472 static int slang_struct_equal (const slang_struct
*x
, const slang_struct
*y
)
475 if (x
->fields
->num_variables
!= y
->fields
->num_variables
)
477 for (i
= 0; i
< x
->fields
->num_variables
; i
++)
479 slang_variable
*varx
= x
->fields
->variables
+ i
;
480 slang_variable
*vary
= y
->fields
->variables
+ i
;
481 if (slang_string_compare (varx
->name
, vary
->name
) != 0)
483 if (!slang_type_specifier_equal (&varx
->type
.specifier
, &vary
->type
.specifier
))
485 if (varx
->type
.specifier
.type
== slang_spec_array
)
487 /* TODO compare array sizes */
495 static void slang_function_construct (slang_function
*func
)
497 func
->kind
= slang_func_ordinary
;
498 slang_variable_construct (&func
->header
);
499 func
->parameters
= (slang_variable_scope
*) slang_alloc_malloc (sizeof (slang_variable_scope
));
500 slang_variable_scope_construct (func
->parameters
);
505 static void slang_function_destruct (slang_function
*func
)
507 slang_variable_destruct (&func
->header
);
508 slang_variable_scope_destruct (func
->parameters
);
509 slang_alloc_free (func
->parameters
);
510 if (func
->body
!= NULL
)
512 slang_operation_destruct (func
->body
);
513 slang_alloc_free (func
->body
);
517 /* slang_function_scope */
519 static void slang_function_scope_construct (slang_function_scope
*scope
)
521 scope
->functions
= NULL
;
522 scope
->num_functions
= 0;
523 scope
->outer_scope
= NULL
;
526 static void slang_function_scope_destruct (slang_function_scope
*scope
)
529 for (i
= 0; i
< scope
->num_functions
; i
++)
530 slang_function_destruct (scope
->functions
+ i
);
531 slang_alloc_free (scope
->functions
);
534 static int slang_function_scope_find_by_name (slang_function_scope
*funcs
, const char *name
,
538 for (i
= 0; i
< funcs
->num_functions
; i
++)
539 if (slang_string_compare (name
, funcs
->functions
[i
].header
.name
) == 0)
541 if (all_scopes
&& funcs
->outer_scope
!= NULL
)
542 return slang_function_scope_find_by_name (funcs
->outer_scope
, name
, 1);
546 static slang_function
*slang_function_scope_find (slang_function_scope
*funcs
, slang_function
*fun
,
550 for (i
= 0; i
< funcs
->num_functions
; i
++)
552 slang_function
*f
= funcs
->functions
+ i
;
554 if (slang_string_compare (fun
->header
.name
, f
->header
.name
) != 0)
556 if (fun
->param_count
!= f
->param_count
)
558 for (j
= 0; j
< fun
->param_count
; j
++)
560 if (!slang_type_specifier_equal (&fun
->parameters
->variables
[j
].type
.specifier
,
561 &f
->parameters
->variables
[j
].type
.specifier
))
566 if (j
== fun
->param_count
)
569 if (all_scopes
&& funcs
->outer_scope
!= NULL
)
570 return slang_function_scope_find (funcs
->outer_scope
, fun
, 1);
574 /* slang_translation_unit */
576 void slang_translation_unit_construct (slang_translation_unit
*unit
)
578 slang_variable_scope_construct (&unit
->globals
);
579 slang_function_scope_construct (&unit
->functions
);
580 slang_struct_scope_construct (&unit
->structs
);
583 void slang_translation_unit_destruct (slang_translation_unit
*unit
)
585 slang_variable_scope_destruct (&unit
->globals
);
586 slang_function_scope_destruct (&unit
->functions
);
587 slang_struct_scope_destruct (&unit
->structs
);
592 static char *out_of_memory
= "error: out of memory\n";
594 void slang_info_log_construct (slang_info_log
*log
)
597 log
->dont_free_text
= 0;
600 void slang_info_log_destruct (slang_info_log
*log
)
602 if (!log
->dont_free_text
)
603 slang_alloc_free (log
->text
);
606 static int slang_info_log_message (slang_info_log
*log
, const char *prefix
, const char *msg
)
608 unsigned int new_size
;
609 if (log
->dont_free_text
)
611 new_size
= slang_string_length (prefix
) + 3 + slang_string_length (msg
);
612 if (log
->text
!= NULL
)
614 log
->text
= (char *) slang_alloc_realloc (log
->text
, slang_string_length (log
->text
) + 1,
615 new_size
+ slang_string_length (log
->text
) + 1);
619 log
->text
= (char *) slang_alloc_malloc (new_size
+ 1);
620 if (log
->text
!= NULL
)
623 if (log
->text
== NULL
)
625 slang_string_concat (log
->text
, prefix
);
626 slang_string_concat (log
->text
, ": ");
627 slang_string_concat (log
->text
, msg
);
628 slang_string_concat (log
->text
, "\n");
632 int slang_info_log_error (slang_info_log
*log
, const char *msg
, ...)
638 _mesa_vsprintf (buf
, msg
, va
);
639 if (slang_info_log_message (log
, "error", buf
))
641 slang_info_log_memory (log
);
646 int slang_info_log_warning (slang_info_log
*log
, const char *msg
, ...)
652 _mesa_vsprintf (buf
, msg
, va
);
653 if (slang_info_log_message (log
, "warning", buf
))
655 slang_info_log_memory (log
);
660 void slang_info_log_memory (slang_info_log
*log
)
662 if (!slang_info_log_message (log
, "error", "out of memory"))
664 log
->dont_free_text
= 1;
665 log
->text
= out_of_memory
;
669 /* slang_parse_ctx */
671 typedef struct slang_parse_ctx_
678 /* _slang_compile() */
680 static int parse_identifier (slang_parse_ctx
*C
, char **id
)
682 *id
= slang_string_duplicate ((const char *) C
->I
);
685 slang_info_log_memory (C
->L
);
688 C
->I
+= _mesa_strlen ((const char *) C
->I
) + 1;
692 static int parse_number (slang_parse_ctx
*C
, int *number
)
694 const int radix
= (int) (*C
->I
++);
696 while (*C
->I
!= '\0')
699 if (*C
->I
>= '0' && *C
->I
<= '9')
700 digit
= (int) (*C
->I
- '0');
701 else if (*C
->I
>= 'A' && *C
->I
<= 'Z')
702 digit
= (int) (*C
->I
- 'A') + 10;
704 digit
= (int) (*C
->I
- 'a') + 10;
705 *number
= *number
* radix
+ digit
;
710 slang_info_log_warning (C
->L
, "%d: literal integer overflow", *number
);
714 static int parse_float (slang_parse_ctx
*C
, float *number
)
716 char *integral
= NULL
;
717 char *fractional
= NULL
;
718 char *exponent
= NULL
;
721 if (!parse_identifier (C
, &integral
))
724 if (!parse_identifier (C
, &fractional
))
726 slang_alloc_free (integral
);
730 if (!parse_identifier (C
, &exponent
))
732 slang_alloc_free (fractional
);
733 slang_alloc_free (integral
);
737 whole
= (char *) (slang_alloc_malloc ((_mesa_strlen (integral
) +
738 _mesa_strlen (fractional
) + _mesa_strlen (exponent
) + 3) *
742 slang_alloc_free (exponent
);
743 slang_alloc_free (fractional
);
744 slang_alloc_free (integral
);
745 slang_info_log_memory (C
->L
);
749 slang_string_copy (whole
, integral
);
750 slang_string_concat (whole
, ".");
751 slang_string_concat (whole
, fractional
);
752 slang_string_concat (whole
, "E");
753 slang_string_concat (whole
, exponent
);
755 *number
= (float) (_mesa_strtod(whole
, (char **)NULL
));
757 slang_alloc_free (whole
);
758 slang_alloc_free (exponent
);
759 slang_alloc_free (fractional
);
760 slang_alloc_free (integral
);
764 /* revision number - increment after each change affecting emitted output */
767 static int check_revision (slang_parse_ctx
*C
)
769 if (*C
->I
!= REVISION
)
771 slang_info_log_error (C
->L
, "internal compiler error");
778 static int parse_statement (slang_parse_ctx
*, slang_operation
*, slang_variable_scope
*,
779 slang_struct_scope
*, slang_function_scope
*);
780 static int parse_expression (slang_parse_ctx
*, slang_operation
*, slang_variable_scope
*,
781 slang_struct_scope
*, slang_function_scope
*);
784 #define TYPE_QUALIFIER_NONE 0
785 #define TYPE_QUALIFIER_CONST 1
786 #define TYPE_QUALIFIER_ATTRIBUTE 2
787 #define TYPE_QUALIFIER_VARYING 3
788 #define TYPE_QUALIFIER_UNIFORM 4
789 #define TYPE_QUALIFIER_FIXEDOUTPUT 5
790 #define TYPE_QUALIFIER_FIXEDINPUT 6
792 static int parse_type_qualifier (slang_parse_ctx
*C
, slang_type_qualifier
*qual
)
796 case TYPE_QUALIFIER_NONE
:
797 *qual
= slang_qual_none
;
799 case TYPE_QUALIFIER_CONST
:
800 *qual
= slang_qual_const
;
802 case TYPE_QUALIFIER_ATTRIBUTE
:
803 *qual
= slang_qual_attribute
;
805 case TYPE_QUALIFIER_VARYING
:
806 *qual
= slang_qual_varying
;
808 case TYPE_QUALIFIER_UNIFORM
:
809 *qual
= slang_qual_uniform
;
811 case TYPE_QUALIFIER_FIXEDOUTPUT
:
812 *qual
= slang_qual_fixedoutput
;
814 case TYPE_QUALIFIER_FIXEDINPUT
:
815 *qual
= slang_qual_fixedinput
;
824 #define TYPE_SPECIFIER_VOID 0
825 #define TYPE_SPECIFIER_BOOL 1
826 #define TYPE_SPECIFIER_BVEC2 2
827 #define TYPE_SPECIFIER_BVEC3 3
828 #define TYPE_SPECIFIER_BVEC4 4
829 #define TYPE_SPECIFIER_INT 5
830 #define TYPE_SPECIFIER_IVEC2 6
831 #define TYPE_SPECIFIER_IVEC3 7
832 #define TYPE_SPECIFIER_IVEC4 8
833 #define TYPE_SPECIFIER_FLOAT 9
834 #define TYPE_SPECIFIER_VEC2 10
835 #define TYPE_SPECIFIER_VEC3 11
836 #define TYPE_SPECIFIER_VEC4 12
837 #define TYPE_SPECIFIER_MAT2 13
838 #define TYPE_SPECIFIER_MAT3 14
839 #define TYPE_SPECIFIER_MAT4 15
840 #define TYPE_SPECIFIER_SAMPLER1D 16
841 #define TYPE_SPECIFIER_SAMPLER2D 17
842 #define TYPE_SPECIFIER_SAMPLER3D 18
843 #define TYPE_SPECIFIER_SAMPLERCUBE 19
844 #define TYPE_SPECIFIER_SAMPLER1DSHADOW 20
845 #define TYPE_SPECIFIER_SAMPLER2DSHADOW 21
846 #define TYPE_SPECIFIER_STRUCT 22
847 #define TYPE_SPECIFIER_TYPENAME 23
849 /* structure field */
852 #define FIELD_ARRAY 2
854 static int parse_type_specifier (slang_parse_ctx
*C
, slang_type_specifier
*spec
,
855 slang_struct_scope
*structs
, slang_variable_scope
*scope
, slang_function_scope
*funcs
)
859 case TYPE_SPECIFIER_VOID
:
860 spec
->type
= slang_spec_void
;
862 case TYPE_SPECIFIER_BOOL
:
863 spec
->type
= slang_spec_bool
;
865 case TYPE_SPECIFIER_BVEC2
:
866 spec
->type
= slang_spec_bvec2
;
868 case TYPE_SPECIFIER_BVEC3
:
869 spec
->type
= slang_spec_bvec3
;
871 case TYPE_SPECIFIER_BVEC4
:
872 spec
->type
= slang_spec_bvec4
;
874 case TYPE_SPECIFIER_INT
:
875 spec
->type
= slang_spec_int
;
877 case TYPE_SPECIFIER_IVEC2
:
878 spec
->type
= slang_spec_ivec2
;
880 case TYPE_SPECIFIER_IVEC3
:
881 spec
->type
= slang_spec_ivec3
;
883 case TYPE_SPECIFIER_IVEC4
:
884 spec
->type
= slang_spec_ivec4
;
886 case TYPE_SPECIFIER_FLOAT
:
887 spec
->type
= slang_spec_float
;
889 case TYPE_SPECIFIER_VEC2
:
890 spec
->type
= slang_spec_vec2
;
892 case TYPE_SPECIFIER_VEC3
:
893 spec
->type
= slang_spec_vec3
;
895 case TYPE_SPECIFIER_VEC4
:
896 spec
->type
= slang_spec_vec4
;
898 case TYPE_SPECIFIER_MAT2
:
899 spec
->type
= slang_spec_mat2
;
901 case TYPE_SPECIFIER_MAT3
:
902 spec
->type
= slang_spec_mat3
;
904 case TYPE_SPECIFIER_MAT4
:
905 spec
->type
= slang_spec_mat4
;
907 case TYPE_SPECIFIER_SAMPLER1D
:
908 spec
->type
= slang_spec_sampler1D
;
910 case TYPE_SPECIFIER_SAMPLER2D
:
911 spec
->type
= slang_spec_sampler2D
;
913 case TYPE_SPECIFIER_SAMPLER3D
:
914 spec
->type
= slang_spec_sampler3D
;
916 case TYPE_SPECIFIER_SAMPLERCUBE
:
917 spec
->type
= slang_spec_samplerCube
;
919 case TYPE_SPECIFIER_SAMPLER1DSHADOW
:
920 spec
->type
= slang_spec_sampler1DShadow
;
922 case TYPE_SPECIFIER_SAMPLER2DSHADOW
:
923 spec
->type
= slang_spec_sampler2DShadow
;
925 case TYPE_SPECIFIER_STRUCT
:
926 spec
->type
= slang_spec_struct
;
929 if (!parse_identifier (C
, &name
))
931 if (*name
!= '\0' && slang_struct_scope_find (structs
, name
, 0) != NULL
)
933 slang_info_log_error (C
->L
, "%s: duplicate type name", name
);
934 slang_alloc_free (name
);
937 spec
->_struct
= (slang_struct
*) slang_alloc_malloc (sizeof (slang_struct
));
938 if (spec
->_struct
== NULL
)
940 slang_alloc_free (name
);
941 slang_info_log_memory (C
->L
);
944 if (!slang_struct_construct_a (spec
->_struct
))
946 slang_alloc_free (spec
->_struct
);
947 spec
->_struct
= NULL
;
948 slang_alloc_free (name
);
949 slang_info_log_memory (C
->L
);
952 spec
->_struct
->name
= name
;
953 spec
->_struct
->structs
->outer_scope
= structs
;
957 slang_type_specifier sp
;
958 slang_type_specifier_construct (&sp
);
959 if (!parse_type_specifier (C
, &sp
, spec
->_struct
->structs
, scope
, funcs
))
961 slang_type_specifier_destruct (&sp
);
967 spec
->_struct
->fields
->variables
= (slang_variable
*) slang_alloc_realloc (
968 spec
->_struct
->fields
->variables
,
969 spec
->_struct
->fields
->num_variables
* sizeof (slang_variable
),
970 (spec
->_struct
->fields
->num_variables
+ 1) * sizeof (slang_variable
));
971 if (spec
->_struct
->fields
->variables
== NULL
)
973 slang_type_specifier_destruct (&sp
);
974 slang_info_log_memory (C
->L
);
977 var
= spec
->_struct
->fields
->variables
+ spec
->_struct
->fields
->num_variables
;
978 spec
->_struct
->fields
->num_variables
++;
979 slang_variable_construct (var
);
980 if (!slang_type_specifier_copy (&var
->type
.specifier
, &sp
))
982 slang_type_specifier_destruct (&sp
);
985 if (!parse_identifier (C
, &var
->name
))
987 slang_type_specifier_destruct (&sp
);
995 var
->array_size
= (slang_operation
*) slang_alloc_malloc (sizeof (
997 if (var
->array_size
== NULL
)
999 slang_type_specifier_destruct (&sp
);
1000 slang_info_log_memory (C
->L
);
1003 if (!slang_operation_construct_a (var
->array_size
))
1005 slang_alloc_free (var
->array_size
);
1006 var
->array_size
= NULL
;
1007 slang_type_specifier_destruct (&sp
);
1008 slang_info_log_memory (C
->L
);
1011 if (!parse_expression (C
, var
->array_size
, scope
, structs
, funcs
))
1013 slang_type_specifier_destruct (&sp
);
1021 while (*C
->I
++ != FIELD_NONE
);
1023 while (*C
->I
++ != FIELD_NONE
);
1024 if (*spec
->_struct
->name
!= '\0')
1027 structs
->structs
= (slang_struct
*) slang_alloc_realloc (structs
->structs
,
1028 structs
->num_structs
* sizeof (slang_struct
),
1029 (structs
->num_structs
+ 1) * sizeof (slang_struct
));
1030 if (structs
->structs
== NULL
)
1032 slang_info_log_memory (C
->L
);
1035 s
= structs
->structs
+ structs
->num_structs
;
1036 if (!slang_struct_construct_a (s
))
1038 structs
->num_structs
++;
1039 if (!slang_struct_copy (s
, spec
->_struct
))
1043 case TYPE_SPECIFIER_TYPENAME
:
1044 spec
->type
= slang_spec_struct
;
1048 if (!parse_identifier (C
, &name
))
1050 stru
= slang_struct_scope_find (structs
, name
, 1);
1053 slang_info_log_error (C
->L
, "%s: undeclared type name", name
);
1054 slang_alloc_free (name
);
1057 slang_alloc_free (name
);
1058 spec
->_struct
= (slang_struct
*) slang_alloc_malloc (sizeof (slang_struct
));
1059 if (spec
->_struct
== NULL
)
1061 slang_info_log_memory (C
->L
);
1064 if (!slang_struct_construct_a (spec
->_struct
))
1066 slang_alloc_free (spec
->_struct
);
1067 spec
->_struct
= NULL
;
1070 if (!slang_struct_copy (spec
->_struct
, stru
))
1080 static int parse_fully_specified_type (slang_parse_ctx
*C
, slang_fully_specified_type
*type
,
1081 slang_struct_scope
*structs
, slang_variable_scope
*scope
, slang_function_scope
*funcs
)
1083 if (!parse_type_qualifier (C
, &type
->qualifier
))
1085 return parse_type_specifier (C
, &type
->specifier
, structs
, scope
, funcs
);
1090 #define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1
1091 #define OP_BLOCK_BEGIN_NEW_SCOPE 2
1092 #define OP_DECLARE 3
1095 #define OP_CONTINUE 6
1096 #define OP_DISCARD 7
1098 #define OP_EXPRESSION 9
1103 #define OP_PUSH_VOID 14
1104 #define OP_PUSH_BOOL 15
1105 #define OP_PUSH_INT 16
1106 #define OP_PUSH_FLOAT 17
1107 #define OP_PUSH_IDENTIFIER 18
1108 #define OP_SEQUENCE 19
1109 #define OP_ASSIGN 20
1110 #define OP_ADDASSIGN 21
1111 #define OP_SUBASSIGN 22
1112 #define OP_MULASSIGN 23
1113 #define OP_DIVASSIGN 24
1114 /*#define OP_MODASSIGN 25*/
1115 /*#define OP_LSHASSIGN 26*/
1116 /*#define OP_RSHASSIGN 27*/
1117 /*#define OP_ORASSIGN 28*/
1118 /*#define OP_XORASSIGN 29*/
1119 /*#define OP_ANDASSIGN 30*/
1120 #define OP_SELECT 31
1121 #define OP_LOGICALOR 32
1122 #define OP_LOGICALXOR 33
1123 #define OP_LOGICALAND 34
1124 /*#define OP_BITOR 35*/
1125 /*#define OP_BITXOR 36*/
1126 /*#define OP_BITAND 37*/
1128 #define OP_NOTEQUAL 39
1130 #define OP_GREATER 41
1131 #define OP_LESSEQUAL 42
1132 #define OP_GREATEREQUAL 43
1133 /*#define OP_LSHIFT 44*/
1134 /*#define OP_RSHIFT 45*/
1136 #define OP_SUBTRACT 47
1137 #define OP_MULTIPLY 48
1138 #define OP_DIVIDE 49
1139 /*#define OP_MODULUS 50*/
1140 #define OP_PREINCREMENT 51
1141 #define OP_PREDECREMENT 52
1144 /*#define OP_COMPLEMENT 55*/
1146 #define OP_SUBSCRIPT 57
1149 #define OP_POSTINCREMENT 60
1150 #define OP_POSTDECREMENT 61
1152 static int parse_child_operation (slang_parse_ctx
*C
, slang_operation
*oper
, int statement
,
1153 slang_variable_scope
*scope
, slang_struct_scope
*structs
, slang_function_scope
*funcs
)
1155 oper
->children
= (slang_operation
*) slang_alloc_realloc (oper
->children
,
1156 oper
->num_children
* sizeof (slang_operation
),
1157 (oper
->num_children
+ 1) * sizeof (slang_operation
));
1158 if (oper
->children
== NULL
)
1160 slang_info_log_memory (C
->L
);
1163 if (!slang_operation_construct_a (oper
->children
+ oper
->num_children
))
1165 slang_info_log_memory (C
->L
);
1168 oper
->num_children
++;
1170 return parse_statement (C
, oper
->children
+ oper
->num_children
- 1, scope
, structs
, funcs
);
1171 return parse_expression (C
, oper
->children
+ oper
->num_children
- 1, scope
, structs
, funcs
);
1174 static int parse_declaration (slang_parse_ctx
*C
, slang_variable_scope
*, slang_struct_scope
*,
1175 slang_function_scope
*);
1177 static int parse_statement (slang_parse_ctx
*C
, slang_operation
*oper
, slang_variable_scope
*scope
,
1178 slang_struct_scope
*structs
, slang_function_scope
*funcs
)
1180 oper
->locals
->outer_scope
= scope
;
1183 case OP_BLOCK_BEGIN_NO_NEW_SCOPE
:
1184 oper
->type
= slang_oper_block_no_new_scope
;
1185 while (*C
->I
!= OP_END
)
1186 if (!parse_child_operation (C
, oper
, 1, scope
, structs
, funcs
))
1190 case OP_BLOCK_BEGIN_NEW_SCOPE
:
1191 oper
->type
= slang_oper_block_new_scope
;
1192 while (*C
->I
!= OP_END
)
1193 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1198 oper
->type
= slang_oper_variable_decl
;
1200 const unsigned int first_var
= scope
->num_variables
;
1201 if (!parse_declaration (C
, scope
, structs
, funcs
))
1203 if (first_var
< scope
->num_variables
)
1205 const unsigned int num_vars
= scope
->num_variables
- first_var
;
1207 oper
->children
= (slang_operation
*) slang_alloc_malloc (num_vars
* sizeof (
1209 if (oper
->children
== NULL
)
1211 slang_info_log_memory (C
->L
);
1214 for (i
= 0; i
< num_vars
; i
++)
1215 if (!slang_operation_construct_a (oper
->children
+ i
))
1218 for (j
= 0; j
< i
; j
++)
1219 slang_operation_destruct (oper
->children
+ j
);
1220 slang_alloc_free (oper
->children
);
1221 oper
->children
= NULL
;
1222 slang_info_log_memory (C
->L
);
1225 oper
->num_children
= num_vars
;
1226 for (i
= first_var
; i
< scope
->num_variables
; i
++)
1228 slang_operation
*o
= oper
->children
+ i
- first_var
;
1229 o
->type
= slang_oper_identifier
;
1230 o
->locals
->outer_scope
= scope
;
1231 o
->identifier
= slang_string_duplicate (scope
->variables
[i
].name
);
1232 if (o
->identifier
== NULL
)
1234 slang_info_log_memory (C
->L
);
1242 oper
->type
= slang_oper_asm
;
1243 if (!parse_identifier (C
, &oper
->identifier
))
1245 while (*C
->I
!= OP_END
)
1246 if (!parse_child_operation (C
, oper
, 0, scope
, structs
, funcs
))
1251 oper
->type
= slang_oper_break
;
1254 oper
->type
= slang_oper_continue
;
1257 oper
->type
= slang_oper_discard
;
1260 oper
->type
= slang_oper_return
;
1261 if (!parse_child_operation (C
, oper
, 0, scope
, structs
, funcs
))
1265 oper
->type
= slang_oper_expression
;
1266 if (!parse_child_operation (C
, oper
, 0, scope
, structs
, funcs
))
1270 oper
->type
= slang_oper_if
;
1271 if (!parse_child_operation (C
, oper
, 0, scope
, structs
, funcs
))
1273 if (!parse_child_operation (C
, oper
, 1, scope
, structs
, funcs
))
1275 if (!parse_child_operation (C
, oper
, 1, scope
, structs
, funcs
))
1279 oper
->type
= slang_oper_while
;
1280 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1282 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1286 oper
->type
= slang_oper_do
;
1287 if (!parse_child_operation (C
, oper
, 1, scope
, structs
, funcs
))
1289 if (!parse_child_operation (C
, oper
, 0, scope
, structs
, funcs
))
1293 oper
->type
= slang_oper_for
;
1294 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1296 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1298 if (!parse_child_operation (C
, oper
, 0, oper
->locals
, structs
, funcs
))
1300 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1309 static int handle_trinary_expression (slang_parse_ctx
*C
, slang_operation
*op
,
1310 slang_operation
**ops
, unsigned int *num_ops
)
1312 op
->num_children
= 3;
1313 op
->children
= (slang_operation
*) slang_alloc_malloc (3 * sizeof (slang_operation
));
1314 if (op
->children
== NULL
)
1316 slang_info_log_memory (C
->L
);
1319 op
->children
[0] = (*ops
)[*num_ops
- 4];
1320 op
->children
[1] = (*ops
)[*num_ops
- 3];
1321 op
->children
[2] = (*ops
)[*num_ops
- 2];
1322 (*ops
)[*num_ops
- 4] = (*ops
)[*num_ops
- 1];
1324 *ops
= (slang_operation
*) slang_alloc_realloc (*ops
, (*num_ops
+ 3) * sizeof (slang_operation
),
1325 *num_ops
* sizeof (slang_operation
));
1328 slang_info_log_memory (C
->L
);
1334 static int handle_binary_expression (slang_parse_ctx
*C
, slang_operation
*op
,
1335 slang_operation
**ops
, unsigned int *num_ops
)
1337 op
->num_children
= 2;
1338 op
->children
= (slang_operation
*) slang_alloc_malloc (2 * sizeof (slang_operation
));
1339 if (op
->children
== NULL
)
1341 slang_info_log_memory (C
->L
);
1344 op
->children
[0] = (*ops
)[*num_ops
- 3];
1345 op
->children
[1] = (*ops
)[*num_ops
- 2];
1346 (*ops
)[*num_ops
- 3] = (*ops
)[*num_ops
- 1];
1348 *ops
= (slang_operation
*) slang_alloc_realloc (*ops
, (*num_ops
+ 2) * sizeof (slang_operation
),
1349 *num_ops
* sizeof (slang_operation
));
1352 slang_info_log_memory (C
->L
);
1358 static int handle_unary_expression (slang_parse_ctx
*C
, slang_operation
*op
,
1359 slang_operation
**ops
, unsigned int *num_ops
)
1361 op
->num_children
= 1;
1362 op
->children
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
1363 if (op
->children
== NULL
)
1365 slang_info_log_memory (C
->L
);
1368 op
->children
[0] = (*ops
)[*num_ops
- 2];
1369 (*ops
)[*num_ops
- 2] = (*ops
)[*num_ops
- 1];
1371 *ops
= (slang_operation
*) slang_alloc_realloc (*ops
, (*num_ops
+ 1) * sizeof (slang_operation
),
1372 *num_ops
* sizeof (slang_operation
));
1375 slang_info_log_memory (C
->L
);
1381 static int is_constructor_name (const char *name
, slang_struct_scope
*structs
)
1383 if (slang_type_specifier_type_from_string (name
) != slang_spec_void
)
1385 return slang_struct_scope_find (structs
, name
, 1) != NULL
;
1388 static int parse_expression (slang_parse_ctx
*C
, slang_operation
*oper
, slang_variable_scope
*scope
,
1389 slang_struct_scope
*structs
, slang_function_scope
*funcs
)
1391 slang_operation
*ops
= NULL
;
1392 unsigned int num_ops
= 0;
1395 while (*C
->I
!= OP_END
)
1397 slang_operation
*op
;
1398 const unsigned int op_code
= *C
->I
++;
1399 ops
= (slang_operation
*) slang_alloc_realloc (ops
,
1400 num_ops
* sizeof (slang_operation
), (num_ops
+ 1) * sizeof (slang_operation
));
1403 slang_info_log_memory (C
->L
);
1407 if (!slang_operation_construct_a (op
))
1409 slang_info_log_memory (C
->L
);
1413 op
->locals
->outer_scope
= scope
;
1417 op
->type
= slang_oper_void
;
1420 op
->type
= slang_oper_literal_bool
;
1421 if (!parse_number (C
, &number
))
1423 op
->literal
= (float) number
;
1426 op
->type
= slang_oper_literal_int
;
1427 if (!parse_number (C
, &number
))
1429 op
->literal
= (float) number
;
1432 op
->type
= slang_oper_literal_float
;
1433 if (!parse_float (C
, &op
->literal
))
1436 case OP_PUSH_IDENTIFIER
:
1437 op
->type
= slang_oper_identifier
;
1438 if (!parse_identifier (C
, &op
->identifier
))
1442 op
->type
= slang_oper_sequence
;
1443 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1447 op
->type
= slang_oper_assign
;
1448 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1452 op
->type
= slang_oper_addassign
;
1453 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1457 op
->type
= slang_oper_subassign
;
1458 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1462 op
->type
= slang_oper_mulassign
;
1463 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1467 op
->type
= slang_oper_divassign
;
1468 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1471 /*case OP_MODASSIGN:*/
1472 /*case OP_LSHASSIGN:*/
1473 /*case OP_RSHASSIGN:*/
1474 /*case OP_ORASSIGN:*/
1475 /*case OP_XORASSIGN:*/
1476 /*case OP_ANDASSIGN:*/
1478 op
->type
= slang_oper_select
;
1479 if (!handle_trinary_expression (C
, op
, &ops
, &num_ops
))
1483 op
->type
= slang_oper_logicalor
;
1484 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1488 op
->type
= slang_oper_logicalxor
;
1489 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1493 op
->type
= slang_oper_logicaland
;
1494 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1501 op
->type
= slang_oper_equal
;
1502 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1506 op
->type
= slang_oper_notequal
;
1507 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1511 op
->type
= slang_oper_less
;
1512 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1516 op
->type
= slang_oper_greater
;
1517 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1521 op
->type
= slang_oper_lessequal
;
1522 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1525 case OP_GREATEREQUAL
:
1526 op
->type
= slang_oper_greaterequal
;
1527 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1533 op
->type
= slang_oper_add
;
1534 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1538 op
->type
= slang_oper_subtract
;
1539 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1543 op
->type
= slang_oper_multiply
;
1544 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1548 op
->type
= slang_oper_divide
;
1549 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1552 /*case OP_MODULUS:*/
1553 case OP_PREINCREMENT
:
1554 op
->type
= slang_oper_preincrement
;
1555 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1558 case OP_PREDECREMENT
:
1559 op
->type
= slang_oper_predecrement
;
1560 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1564 op
->type
= slang_oper_plus
;
1565 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1569 op
->type
= slang_oper_minus
;
1570 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1574 op
->type
= slang_oper_not
;
1575 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1578 /*case OP_COMPLEMENT:*/
1580 op
->type
= slang_oper_subscript
;
1581 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1585 op
->type
= slang_oper_call
;
1586 if (!parse_identifier (C
, &op
->identifier
))
1588 while (*C
->I
!= OP_END
)
1589 if (!parse_child_operation (C
, op
, 0, scope
, structs
, funcs
))
1592 if (!C
->parsing_builtin
&&
1593 !slang_function_scope_find_by_name (funcs
, op
->identifier
, 1) &&
1594 !is_constructor_name (op
->identifier
, structs
))
1596 slang_info_log_error (C
->L
, "%s: undeclared function name", op
->identifier
);
1601 op
->type
= slang_oper_field
;
1602 if (!parse_identifier (C
, &op
->identifier
))
1604 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1607 case OP_POSTINCREMENT
:
1608 op
->type
= slang_oper_postincrement
;
1609 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1612 case OP_POSTDECREMENT
:
1613 op
->type
= slang_oper_postdecrement
;
1614 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1623 slang_alloc_free (ops
);
1627 /* parameter qualifier */
1628 #define PARAM_QUALIFIER_IN 0
1629 #define PARAM_QUALIFIER_OUT 1
1630 #define PARAM_QUALIFIER_INOUT 2
1632 /* function parameter array presence */
1633 #define PARAMETER_ARRAY_NOT_PRESENT 0
1634 #define PARAMETER_ARRAY_PRESENT 1
1636 static int parse_parameter_declaration (slang_parse_ctx
*C
, slang_variable
*param
,
1637 slang_struct_scope
*structs
, slang_variable_scope
*scope
, slang_function_scope
*funcs
)
1639 slang_storage_aggregate agg
;
1640 if (!parse_type_qualifier (C
, ¶m
->type
.qualifier
))
1644 case PARAM_QUALIFIER_IN
:
1645 if (param
->type
.qualifier
!= slang_qual_const
&& param
->type
.qualifier
!= slang_qual_none
)
1647 slang_info_log_error (C
->L
, "invalid type qualifier");
1651 case PARAM_QUALIFIER_OUT
:
1652 if (param
->type
.qualifier
== slang_qual_none
)
1653 param
->type
.qualifier
= slang_qual_out
;
1656 slang_info_log_error (C
->L
, "invalid type qualifier");
1660 case PARAM_QUALIFIER_INOUT
:
1661 if (param
->type
.qualifier
== slang_qual_none
)
1662 param
->type
.qualifier
= slang_qual_inout
;
1665 slang_info_log_error (C
->L
, "invalid type qualifier");
1672 if (!parse_type_specifier (C
, ¶m
->type
.specifier
, structs
, scope
, funcs
))
1674 if (!parse_identifier (C
, ¶m
->name
))
1676 if (*C
->I
++ == PARAMETER_ARRAY_PRESENT
)
1678 param
->array_size
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
1679 if (param
->array_size
== NULL
)
1681 slang_info_log_memory (C
->L
);
1684 if (!slang_operation_construct_a (param
->array_size
))
1686 slang_alloc_free (param
->array_size
);
1687 param
->array_size
= NULL
;
1688 slang_info_log_memory (C
->L
);
1691 if (!parse_expression (C
, param
->array_size
, scope
, structs
, funcs
))
1694 slang_storage_aggregate_construct (&agg
);
1695 if (!_slang_aggregate_variable (&agg
, ¶m
->type
.specifier
, param
->array_size
, funcs
,
1698 slang_storage_aggregate_destruct (&agg
);
1701 slang_storage_aggregate_destruct (&agg
);
1706 #define FUNCTION_ORDINARY 0
1707 #define FUNCTION_CONSTRUCTOR 1
1708 #define FUNCTION_OPERATOR 2
1710 /* function parameter */
1711 #define PARAMETER_NONE 0
1712 #define PARAMETER_NEXT 1
1715 #define OPERATOR_ASSIGN 1
1716 #define OPERATOR_ADDASSIGN 2
1717 #define OPERATOR_SUBASSIGN 3
1718 #define OPERATOR_MULASSIGN 4
1719 #define OPERATOR_DIVASSIGN 5
1720 /*#define OPERATOR_MODASSIGN 6*/
1721 /*#define OPERATOR_LSHASSIGN 7*/
1722 /*#define OPERATOR_RSHASSIGN 8*/
1723 /*#define OPERATOR_ANDASSIGN 9*/
1724 /*#define OPERATOR_XORASSIGN 10*/
1725 /*#define OPERATOR_ORASSIGN 11*/
1726 #define OPERATOR_LOGICALXOR 12
1727 /*#define OPERATOR_BITOR 13*/
1728 /*#define OPERATOR_BITXOR 14*/
1729 /*#define OPERATOR_BITAND 15*/
1730 #define OPERATOR_EQUAL 16
1731 #define OPERATOR_NOTEQUAL 17
1732 #define OPERATOR_LESS 18
1733 #define OPERATOR_GREATER 19
1734 #define OPERATOR_LESSEQUAL 20
1735 #define OPERATOR_GREATEREQUAL 21
1736 /*#define OPERATOR_LSHIFT 22*/
1737 /*#define OPERATOR_RSHIFT 23*/
1738 #define OPERATOR_MULTIPLY 24
1739 #define OPERATOR_DIVIDE 25
1740 /*#define OPERATOR_MODULUS 26*/
1741 #define OPERATOR_INCREMENT 27
1742 #define OPERATOR_DECREMENT 28
1743 #define OPERATOR_PLUS 29
1744 #define OPERATOR_MINUS 30
1745 /*#define OPERATOR_COMPLEMENT 31*/
1746 #define OPERATOR_NOT 32
1748 static const struct {
1749 unsigned int o_code
;
1751 } operator_names
[] = {
1752 { OPERATOR_INCREMENT
, "++" },
1753 { OPERATOR_ADDASSIGN
, "+=" },
1754 { OPERATOR_PLUS
, "+" },
1755 { OPERATOR_DECREMENT
, "--" },
1756 { OPERATOR_SUBASSIGN
, "-=" },
1757 { OPERATOR_MINUS
, "-" },
1758 { OPERATOR_NOTEQUAL
, "!=" },
1759 { OPERATOR_NOT
, "!" },
1760 { OPERATOR_MULASSIGN
, "*=" },
1761 { OPERATOR_MULTIPLY
, "*" },
1762 { OPERATOR_DIVASSIGN
, "/=" },
1763 { OPERATOR_DIVIDE
, "/" },
1764 { OPERATOR_LESSEQUAL
, "<=" },
1765 /*{ OPERATOR_LSHASSIGN, "<<=" },*/
1766 /*{ OPERATOR_LSHIFT, "<<" },*/
1767 { OPERATOR_LESS
, "<" },
1768 { OPERATOR_GREATEREQUAL
, ">=" },
1769 /*{ OPERATOR_RSHASSIGN, ">>=" },*/
1770 /*{ OPERATOR_RSHIFT, ">>" },*/
1771 { OPERATOR_GREATER
, ">" },
1772 { OPERATOR_EQUAL
, "==" },
1773 { OPERATOR_ASSIGN
, "=" },
1774 /*{ OPERATOR_MODASSIGN, "%=" },*/
1775 /*{ OPERATOR_MODULUS, "%" },*/
1776 /*{ OPERATOR_ANDASSIGN, "&=" },*/
1777 /*{ OPERATOR_BITAND, "&" },*/
1778 /*{ OPERATOR_ORASSIGN, "|=" },*/
1779 /*{ OPERATOR_BITOR, "|" },*/
1780 /*{ OPERATOR_COMPLEMENT, "~" },*/
1781 /*{ OPERATOR_XORASSIGN, "^=" },*/
1782 { OPERATOR_LOGICALXOR
, "^^" }/*,*/
1783 /*{ OPERATOR_BITXOR, "^" }*/
1786 static int parse_operator_name (slang_parse_ctx
*C
, char **pname
)
1789 for (i
= 0; i
< sizeof (operator_names
) / sizeof (*operator_names
); i
++)
1790 if (operator_names
[i
].o_code
== (unsigned int) (*C
->I
))
1792 *pname
= slang_string_duplicate (operator_names
[i
].o_name
);
1795 slang_info_log_memory (C
->L
);
1804 static int parse_function_prototype (slang_parse_ctx
*C
, slang_function
*func
,
1805 slang_struct_scope
*structs
, slang_variable_scope
*scope
, slang_function_scope
*funcs
)
1807 if (!parse_fully_specified_type (C
, &func
->header
.type
, structs
, scope
, funcs
))
1811 case FUNCTION_ORDINARY
:
1812 func
->kind
= slang_func_ordinary
;
1813 if (!parse_identifier (C
, &func
->header
.name
))
1816 case FUNCTION_CONSTRUCTOR
:
1817 func
->kind
= slang_func_constructor
;
1818 if (func
->header
.type
.specifier
.type
== slang_spec_struct
)
1820 func
->header
.name
= slang_string_duplicate (
1821 type_specifier_type_names
[func
->header
.type
.specifier
.type
]);
1822 if (func
->header
.name
== NULL
)
1824 slang_info_log_memory (C
->L
);
1828 case FUNCTION_OPERATOR
:
1829 func
->kind
= slang_func_operator
;
1830 if (!parse_operator_name (C
, &func
->header
.name
))
1836 func
->parameters
->outer_scope
= scope
;
1837 while (*C
->I
++ == PARAMETER_NEXT
)
1839 func
->parameters
->variables
= (slang_variable
*) slang_alloc_realloc (
1840 func
->parameters
->variables
,
1841 func
->parameters
->num_variables
* sizeof (slang_variable
),
1842 (func
->parameters
->num_variables
+ 1) * sizeof (slang_variable
));
1843 if (func
->parameters
->variables
== NULL
)
1845 slang_info_log_memory (C
->L
);
1848 slang_variable_construct (func
->parameters
->variables
+ func
->parameters
->num_variables
);
1849 func
->parameters
->num_variables
++;
1850 if (!parse_parameter_declaration (C
, func
->parameters
->variables
+
1851 func
->parameters
->num_variables
- 1, structs
, scope
, funcs
))
1854 func
->param_count
= func
->parameters
->num_variables
;
1858 static int parse_function_definition (slang_parse_ctx
*C
, slang_function
*func
,
1859 slang_struct_scope
*structs
, slang_variable_scope
*scope
, slang_function_scope
*funcs
)
1861 if (!parse_function_prototype (C
, func
, structs
, scope
, funcs
))
1863 func
->body
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
1864 if (func
->body
== NULL
)
1866 slang_info_log_memory (C
->L
);
1869 if (!slang_operation_construct_a (func
->body
))
1871 slang_alloc_free (func
->body
);
1873 slang_info_log_memory (C
->L
);
1876 if (!parse_statement (C
, func
->body
, func
->parameters
, structs
, funcs
))
1881 /* init declarator list */
1882 #define DECLARATOR_NONE 0
1883 #define DECLARATOR_NEXT 1
1885 /* variable declaration */
1886 #define VARIABLE_NONE 0
1887 #define VARIABLE_IDENTIFIER 1
1888 #define VARIABLE_INITIALIZER 2
1889 #define VARIABLE_ARRAY_EXPLICIT 3
1890 #define VARIABLE_ARRAY_UNKNOWN 4
1892 static int parse_init_declarator (slang_parse_ctx
*C
, const slang_fully_specified_type
*type
,
1893 slang_variable_scope
*vars
, slang_struct_scope
*structs
, slang_function_scope
*funcs
)
1895 slang_variable
*var
;
1897 if (*C
->I
++ == VARIABLE_NONE
)
1899 vars
->variables
= (slang_variable
*) slang_alloc_realloc (vars
->variables
,
1900 vars
->num_variables
* sizeof (slang_variable
),
1901 (vars
->num_variables
+ 1) * sizeof (slang_variable
));
1902 if (vars
->variables
== NULL
)
1904 slang_info_log_memory (C
->L
);
1907 var
= vars
->variables
+ vars
->num_variables
;
1908 vars
->num_variables
++;
1909 slang_variable_construct (var
);
1910 var
->type
.qualifier
= type
->qualifier
;
1911 if (!parse_identifier (C
, &var
->name
))
1916 if (!slang_type_specifier_copy (&var
->type
.specifier
, &type
->specifier
))
1919 case VARIABLE_INITIALIZER
:
1920 if (!slang_type_specifier_copy (&var
->type
.specifier
, &type
->specifier
))
1922 var
->initializer
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
1923 if (var
->initializer
== NULL
)
1925 slang_info_log_memory (C
->L
);
1928 if (!slang_operation_construct_a (var
->initializer
))
1930 slang_alloc_free (var
->initializer
);
1931 var
->initializer
= NULL
;
1932 slang_info_log_memory (C
->L
);
1935 if (!parse_expression (C
, var
->initializer
, vars
, structs
, funcs
))
1938 case VARIABLE_ARRAY_UNKNOWN
:
1939 var
->type
.specifier
.type
= slang_spec_array
;
1940 var
->type
.specifier
._array
= (slang_type_specifier
*) slang_alloc_malloc (sizeof (
1941 slang_type_specifier
));
1942 if (var
->type
.specifier
._array
== NULL
)
1944 slang_info_log_memory (C
->L
);
1947 slang_type_specifier_construct (var
->type
.specifier
._array
);
1948 if (!slang_type_specifier_copy (var
->type
.specifier
._array
, &type
->specifier
))
1951 case VARIABLE_ARRAY_EXPLICIT
:
1952 var
->type
.specifier
.type
= slang_spec_array
;
1953 var
->type
.specifier
._array
= (slang_type_specifier
*) slang_alloc_malloc (sizeof (
1954 slang_type_specifier
));
1955 if (var
->type
.specifier
._array
== NULL
)
1957 slang_info_log_memory (C
->L
);
1960 slang_type_specifier_construct (var
->type
.specifier
._array
);
1961 if (!slang_type_specifier_copy (var
->type
.specifier
._array
, &type
->specifier
))
1963 var
->array_size
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
1964 if (var
->array_size
== NULL
)
1966 slang_info_log_memory (C
->L
);
1969 if (!slang_operation_construct_a (var
->array_size
))
1971 slang_alloc_free (var
->array_size
);
1972 var
->array_size
= NULL
;
1973 slang_info_log_memory (C
->L
);
1976 if (!parse_expression (C
, var
->array_size
, vars
, structs
, funcs
))
1982 if (!(var
->type
.specifier
.type
== slang_spec_array
&& var
->array_size
== NULL
))
1984 slang_storage_aggregate agg
;
1986 slang_storage_aggregate_construct (&agg
);
1987 if (!_slang_aggregate_variable (&agg
, &var
->type
.specifier
, var
->array_size
, funcs
,
1990 slang_storage_aggregate_destruct (&agg
);
1993 slang_storage_aggregate_destruct (&agg
);
1998 static int parse_init_declarator_list (slang_parse_ctx
*C
, slang_variable_scope
*vars
,
1999 slang_struct_scope
*structs
, slang_function_scope
*funcs
)
2001 slang_fully_specified_type type
;
2003 slang_fully_specified_type_construct (&type
);
2004 if (!parse_fully_specified_type (C
, &type
, structs
, vars
, funcs
))
2006 slang_fully_specified_type_destruct (&type
);
2011 if (!parse_init_declarator (C
, &type
, vars
, structs
, funcs
))
2013 slang_fully_specified_type_destruct (&type
);
2017 while (*C
->I
++ == DECLARATOR_NEXT
);
2018 slang_fully_specified_type_destruct (&type
);
2022 static int parse_function (slang_parse_ctx
*C
, int definition
, slang_struct_scope
*structs
,
2023 slang_function_scope
*funcs
, slang_variable_scope
*scope
, slang_function
**parsed_func_ret
)
2025 slang_function parsed_func
, *found_func
;
2027 /* parse function definition/declaration */
2028 slang_function_construct (&parsed_func
);
2031 if (!parse_function_definition (C
, &parsed_func
, structs
, scope
, funcs
))
2033 slang_function_destruct (&parsed_func
);
2039 if (!parse_function_prototype (C
, &parsed_func
, structs
, scope
, funcs
))
2041 slang_function_destruct (&parsed_func
);
2046 /* find a function with a prototype matching the parsed one - only the current scope
2047 is being searched to allow built-in function overriding */
2048 found_func
= slang_function_scope_find (funcs
, &parsed_func
, 0);
2049 if (found_func
== NULL
)
2051 /* add the parsed function to the function list */
2052 funcs
->functions
= (slang_function
*) slang_alloc_realloc (funcs
->functions
,
2053 funcs
->num_functions
* sizeof (slang_function
), (funcs
->num_functions
+ 1) * sizeof (
2055 if (funcs
->functions
== NULL
)
2057 slang_info_log_memory (C
->L
);
2058 slang_function_destruct (&parsed_func
);
2061 funcs
->functions
[funcs
->num_functions
] = parsed_func
;
2062 funcs
->num_functions
++;
2064 /* return the newly parsed function */
2065 *parsed_func_ret
= funcs
->functions
+ funcs
->num_functions
- 1;
2069 /* TODO: check function return type qualifiers and specifiers */
2072 /* destroy the existing function declaration and replace it with the new one */
2073 if (found_func
->body
!= NULL
)
2075 slang_info_log_error (C
->L
, "%s: function already has a body",
2076 parsed_func
.header
.name
);
2077 slang_function_destruct (&parsed_func
);
2080 slang_function_destruct (found_func
);
2081 *found_func
= parsed_func
;
2085 /* another declaration of the same function prototype - ignore it */
2086 slang_function_destruct (&parsed_func
);
2089 /* return the found function */
2090 *parsed_func_ret
= found_func
;
2093 /* assemble the parsed function */
2096 slang_assembly_file file
;
2097 slang_assembly_name_space space
;
2099 slang_assembly_file_construct (&file
);
2100 space
.funcs
= funcs
;
2101 space
.structs
= structs
;
2104 (**parsed_func_ret
).address
= file
.count
;
2105 if (!_slang_assemble_function (&file
, *parsed_func_ret
, &space
))
2107 slang_assembly_file_destruct (&file
);
2115 #define DECLARATION_FUNCTION_PROTOTYPE 1
2116 #define DECLARATION_INIT_DECLARATOR_LIST 2
2118 static int parse_declaration (slang_parse_ctx
*C
, slang_variable_scope
*scope
,
2119 slang_struct_scope
*structs
, slang_function_scope
*funcs
)
2121 slang_function
*dummy_func
;
2125 case DECLARATION_INIT_DECLARATOR_LIST
:
2126 if (!parse_init_declarator_list (C
, scope
, structs
, funcs
))
2129 case DECLARATION_FUNCTION_PROTOTYPE
:
2130 if (!parse_function (C
, 0, structs
, funcs
, scope
, &dummy_func
))
2139 /* external declaration */
2140 #define EXTERNAL_NULL 0
2141 #define EXTERNAL_FUNCTION_DEFINITION 1
2142 #define EXTERNAL_DECLARATION 2
2144 static int parse_translation_unit (slang_parse_ctx
*C
, slang_translation_unit
*unit
)
2146 while (*C
->I
!= EXTERNAL_NULL
)
2148 slang_function
*func
;
2152 case EXTERNAL_FUNCTION_DEFINITION
:
2153 if (!parse_function (C
, 1, &unit
->structs
, &unit
->functions
, &unit
->globals
, &func
))
2156 case EXTERNAL_DECLARATION
:
2157 if (!parse_declaration (C
, &unit
->globals
, &unit
->structs
, &unit
->functions
))
2168 static int compile_binary (const byte
*prod
, slang_translation_unit
*unit
, slang_unit_type type
,
2169 slang_info_log
*log
, slang_translation_unit
*builtins
)
2173 /* set-up parse context */
2176 C
.parsing_builtin
= builtins
== NULL
;
2178 if (!check_revision (&C
))
2181 /* create translation unit object */
2182 slang_translation_unit_construct (unit
);
2185 if (builtins
!= NULL
)
2187 /* link to built-in functions */
2188 builtins
[1].functions
.outer_scope
= &builtins
[0].functions
;
2189 builtins
[2].functions
.outer_scope
= &builtins
[1].functions
;
2190 unit
->functions
.outer_scope
= &builtins
[2].functions
;
2192 /* link to built-in variables - core unit does not define any */
2193 builtins
[2].globals
.outer_scope
= &builtins
[1].globals
;
2194 unit
->globals
.outer_scope
= &builtins
[2].globals
;
2196 /* link to built-in structure typedefs - only in common unit */
2197 unit
->structs
.outer_scope
= &builtins
[1].structs
;
2200 /* parse translation unit */
2201 if (!parse_translation_unit (&C
, unit
))
2203 slang_translation_unit_destruct (unit
);
2210 static int compile_with_grammar (grammar id
, const char *source
, slang_translation_unit
*unit
,
2211 slang_unit_type type
, slang_info_log
*log
, slang_translation_unit
*builtins
)
2214 unsigned int size
, start
, version
;
2216 /* retrieve version */
2217 if (!_slang_preprocess_version (source
, &version
, &start
, log
))
2220 /* check the syntax */
2221 if (!grammar_fast_check (id
, (const byte
*) source
+ start
, &prod
, &size
, 65536))
2225 grammar_get_last_error ( (unsigned char*) buf
, 1024, (int*) &pos
);
2226 slang_info_log_error (log
, buf
);
2230 if (!compile_binary (prod
, unit
, type
, log
, builtins
))
2232 grammar_alloc_free (prod
);
2236 grammar_alloc_free (prod
);
2240 static const char *slang_shader_syn
=
2241 #include "library/slang_shader_syn.h"
2244 static const byte slang_core_gc
[] = {
2245 #include "library/slang_core_gc.h"
2248 static const byte slang_common_builtin_gc
[] = {
2249 #include "library/slang_common_builtin_gc.h"
2252 static const byte slang_fragment_builtin_gc
[] = {
2253 #include "library/slang_fragment_builtin_gc.h"
2256 static const byte slang_vertex_builtin_gc
[] = {
2257 #include "library/slang_vertex_builtin_gc.h"
2260 int compile (grammar
*id
, slang_translation_unit builtin_units
[3], int compiled
[3],
2261 const char *source
, slang_translation_unit
*unit
, slang_unit_type type
, slang_info_log
*log
)
2263 slang_translation_unit
*builtins
= NULL
;
2265 /* load slang grammar */
2266 *id
= grammar_load_from_text ((const byte
*) (slang_shader_syn
));
2272 grammar_get_last_error (buf
, 1024, &pos
);
2273 slang_info_log_error (log
, (const char *) (buf
));
2277 /* set shader type - the syntax is slightly different for different shaders */
2278 if (type
== slang_unit_fragment_shader
|| type
== slang_unit_fragment_builtin
)
2279 grammar_set_reg8 (*id
, (const byte
*) "shader_type", 1);
2281 grammar_set_reg8 (*id
, (const byte
*) "shader_type", 2);
2283 /* enable language extensions */
2284 grammar_set_reg8 (*id
, (const byte
*) "parsing_builtin", 1);
2286 /* if parsing user-specified shader, load built-in library */
2287 if (type
== slang_unit_fragment_shader
|| type
== slang_unit_vertex_shader
)
2289 if (!compile_binary (slang_core_gc
, &builtin_units
[0], slang_unit_fragment_builtin
, log
,
2294 if (!compile_binary (slang_common_builtin_gc
, &builtin_units
[1],
2295 slang_unit_fragment_builtin
, log
, NULL
))
2299 if (type
== slang_unit_fragment_shader
)
2301 if (!compile_binary (slang_fragment_builtin_gc
, &builtin_units
[2],
2302 slang_unit_fragment_builtin
, log
, NULL
))
2305 else if (type
== slang_unit_vertex_shader
)
2307 if (!compile_binary (slang_vertex_builtin_gc
, &builtin_units
[2],
2308 slang_unit_vertex_builtin
, log
, NULL
))
2313 /* disable language extensions */
2314 grammar_set_reg8 (*id
, (const byte
*) "parsing_builtin", 0);
2315 builtins
= builtin_units
;
2318 /* compile the actual shader - pass-in built-in library for external shader */
2319 if (!compile_with_grammar (*id
, source
, unit
, type
, log
, builtins
))
2325 int _slang_compile (const char *source
, slang_translation_unit
*unit
, slang_unit_type type
,
2326 slang_info_log
*log
)
2330 slang_translation_unit builtin_units
[3];
2331 int compiled
[3] = { 0 };
2333 success
= compile (&id
, builtin_units
, compiled
, source
, unit
, type
, log
);
2335 /* destroy built-in library */
2336 if (type
== slang_unit_fragment_shader
|| type
== slang_unit_vertex_shader
)
2340 for (i
= 0; i
< 3; i
++)
2341 if (compiled
[i
] != 0)
2342 slang_translation_unit_destruct (&builtin_units
[i
]);
2345 grammar_destroy (id
);