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 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 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
+= 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 ((strlen (integral
) + strlen (fractional
) + strlen (
738 exponent
) + 3) * sizeof (char)));
741 slang_alloc_free (exponent
);
742 slang_alloc_free (fractional
);
743 slang_alloc_free (integral
);
744 slang_info_log_memory (C
->L
);
748 slang_string_copy (whole
, integral
);
749 slang_string_concat (whole
, ".");
750 slang_string_concat (whole
, fractional
);
751 slang_string_concat (whole
, "E");
752 slang_string_concat (whole
, exponent
);
754 *number
= (float) (atof (whole
));
756 slang_alloc_free (whole
);
757 slang_alloc_free (exponent
);
758 slang_alloc_free (fractional
);
759 slang_alloc_free (integral
);
763 /* revision number - increment after each change affecting emitted output */
766 static int check_revision (slang_parse_ctx
*C
)
768 if (*C
->I
!= REVISION
)
770 slang_info_log_error (C
->L
, "internal compiler error");
777 static int parse_statement (slang_parse_ctx
*, slang_operation
*, slang_variable_scope
*,
778 slang_struct_scope
*, slang_function_scope
*);
779 static int parse_expression (slang_parse_ctx
*, slang_operation
*, slang_variable_scope
*,
780 slang_struct_scope
*, slang_function_scope
*);
783 #define TYPE_QUALIFIER_NONE 0
784 #define TYPE_QUALIFIER_CONST 1
785 #define TYPE_QUALIFIER_ATTRIBUTE 2
786 #define TYPE_QUALIFIER_VARYING 3
787 #define TYPE_QUALIFIER_UNIFORM 4
788 #define TYPE_QUALIFIER_FIXEDOUTPUT 5
789 #define TYPE_QUALIFIER_FIXEDINPUT 6
791 static int parse_type_qualifier (slang_parse_ctx
*C
, slang_type_qualifier
*qual
)
795 case TYPE_QUALIFIER_NONE
:
796 *qual
= slang_qual_none
;
798 case TYPE_QUALIFIER_CONST
:
799 *qual
= slang_qual_const
;
801 case TYPE_QUALIFIER_ATTRIBUTE
:
802 *qual
= slang_qual_attribute
;
804 case TYPE_QUALIFIER_VARYING
:
805 *qual
= slang_qual_varying
;
807 case TYPE_QUALIFIER_UNIFORM
:
808 *qual
= slang_qual_uniform
;
810 case TYPE_QUALIFIER_FIXEDOUTPUT
:
811 *qual
= slang_qual_fixedoutput
;
813 case TYPE_QUALIFIER_FIXEDINPUT
:
814 *qual
= slang_qual_fixedinput
;
823 #define TYPE_SPECIFIER_VOID 0
824 #define TYPE_SPECIFIER_BOOL 1
825 #define TYPE_SPECIFIER_BVEC2 2
826 #define TYPE_SPECIFIER_BVEC3 3
827 #define TYPE_SPECIFIER_BVEC4 4
828 #define TYPE_SPECIFIER_INT 5
829 #define TYPE_SPECIFIER_IVEC2 6
830 #define TYPE_SPECIFIER_IVEC3 7
831 #define TYPE_SPECIFIER_IVEC4 8
832 #define TYPE_SPECIFIER_FLOAT 9
833 #define TYPE_SPECIFIER_VEC2 10
834 #define TYPE_SPECIFIER_VEC3 11
835 #define TYPE_SPECIFIER_VEC4 12
836 #define TYPE_SPECIFIER_MAT2 13
837 #define TYPE_SPECIFIER_MAT3 14
838 #define TYPE_SPECIFIER_MAT4 15
839 #define TYPE_SPECIFIER_SAMPLER1D 16
840 #define TYPE_SPECIFIER_SAMPLER2D 17
841 #define TYPE_SPECIFIER_SAMPLER3D 18
842 #define TYPE_SPECIFIER_SAMPLERCUBE 19
843 #define TYPE_SPECIFIER_SAMPLER1DSHADOW 20
844 #define TYPE_SPECIFIER_SAMPLER2DSHADOW 21
845 #define TYPE_SPECIFIER_STRUCT 22
846 #define TYPE_SPECIFIER_TYPENAME 23
848 /* structure field */
851 #define FIELD_ARRAY 2
853 static int parse_type_specifier (slang_parse_ctx
*C
, slang_type_specifier
*spec
,
854 slang_struct_scope
*structs
, slang_variable_scope
*scope
, slang_function_scope
*funcs
)
858 case TYPE_SPECIFIER_VOID
:
859 spec
->type
= slang_spec_void
;
861 case TYPE_SPECIFIER_BOOL
:
862 spec
->type
= slang_spec_bool
;
864 case TYPE_SPECIFIER_BVEC2
:
865 spec
->type
= slang_spec_bvec2
;
867 case TYPE_SPECIFIER_BVEC3
:
868 spec
->type
= slang_spec_bvec3
;
870 case TYPE_SPECIFIER_BVEC4
:
871 spec
->type
= slang_spec_bvec4
;
873 case TYPE_SPECIFIER_INT
:
874 spec
->type
= slang_spec_int
;
876 case TYPE_SPECIFIER_IVEC2
:
877 spec
->type
= slang_spec_ivec2
;
879 case TYPE_SPECIFIER_IVEC3
:
880 spec
->type
= slang_spec_ivec3
;
882 case TYPE_SPECIFIER_IVEC4
:
883 spec
->type
= slang_spec_ivec4
;
885 case TYPE_SPECIFIER_FLOAT
:
886 spec
->type
= slang_spec_float
;
888 case TYPE_SPECIFIER_VEC2
:
889 spec
->type
= slang_spec_vec2
;
891 case TYPE_SPECIFIER_VEC3
:
892 spec
->type
= slang_spec_vec3
;
894 case TYPE_SPECIFIER_VEC4
:
895 spec
->type
= slang_spec_vec4
;
897 case TYPE_SPECIFIER_MAT2
:
898 spec
->type
= slang_spec_mat2
;
900 case TYPE_SPECIFIER_MAT3
:
901 spec
->type
= slang_spec_mat3
;
903 case TYPE_SPECIFIER_MAT4
:
904 spec
->type
= slang_spec_mat4
;
906 case TYPE_SPECIFIER_SAMPLER1D
:
907 spec
->type
= slang_spec_sampler1D
;
909 case TYPE_SPECIFIER_SAMPLER2D
:
910 spec
->type
= slang_spec_sampler2D
;
912 case TYPE_SPECIFIER_SAMPLER3D
:
913 spec
->type
= slang_spec_sampler3D
;
915 case TYPE_SPECIFIER_SAMPLERCUBE
:
916 spec
->type
= slang_spec_samplerCube
;
918 case TYPE_SPECIFIER_SAMPLER1DSHADOW
:
919 spec
->type
= slang_spec_sampler1DShadow
;
921 case TYPE_SPECIFIER_SAMPLER2DSHADOW
:
922 spec
->type
= slang_spec_sampler2DShadow
;
924 case TYPE_SPECIFIER_STRUCT
:
925 spec
->type
= slang_spec_struct
;
928 if (!parse_identifier (C
, &name
))
930 if (*name
!= '\0' && slang_struct_scope_find (structs
, name
, 0) != NULL
)
932 slang_info_log_error (C
->L
, "%s: duplicate type name", name
);
933 slang_alloc_free (name
);
936 spec
->_struct
= (slang_struct
*) slang_alloc_malloc (sizeof (slang_struct
));
937 if (spec
->_struct
== NULL
)
939 slang_alloc_free (name
);
940 slang_info_log_memory (C
->L
);
943 if (!slang_struct_construct_a (spec
->_struct
))
945 slang_alloc_free (spec
->_struct
);
946 spec
->_struct
= NULL
;
947 slang_alloc_free (name
);
948 slang_info_log_memory (C
->L
);
951 spec
->_struct
->name
= name
;
952 spec
->_struct
->structs
->outer_scope
= structs
;
956 slang_type_specifier sp
;
957 slang_type_specifier_construct (&sp
);
958 if (!parse_type_specifier (C
, &sp
, spec
->_struct
->structs
, scope
, funcs
))
960 slang_type_specifier_destruct (&sp
);
966 spec
->_struct
->fields
->variables
= (slang_variable
*) slang_alloc_realloc (
967 spec
->_struct
->fields
->variables
,
968 spec
->_struct
->fields
->num_variables
* sizeof (slang_variable
),
969 (spec
->_struct
->fields
->num_variables
+ 1) * sizeof (slang_variable
));
970 if (spec
->_struct
->fields
->variables
== NULL
)
972 slang_type_specifier_destruct (&sp
);
973 slang_info_log_memory (C
->L
);
976 var
= spec
->_struct
->fields
->variables
+ spec
->_struct
->fields
->num_variables
;
977 spec
->_struct
->fields
->num_variables
++;
978 slang_variable_construct (var
);
979 if (!slang_type_specifier_copy (&var
->type
.specifier
, &sp
))
981 slang_type_specifier_destruct (&sp
);
984 if (!parse_identifier (C
, &var
->name
))
986 slang_type_specifier_destruct (&sp
);
994 var
->array_size
= (slang_operation
*) slang_alloc_malloc (sizeof (
996 if (var
->array_size
== NULL
)
998 slang_type_specifier_destruct (&sp
);
999 slang_info_log_memory (C
->L
);
1002 if (!slang_operation_construct_a (var
->array_size
))
1004 slang_alloc_free (var
->array_size
);
1005 var
->array_size
= NULL
;
1006 slang_type_specifier_destruct (&sp
);
1007 slang_info_log_memory (C
->L
);
1010 if (!parse_expression (C
, var
->array_size
, scope
, structs
, funcs
))
1012 slang_type_specifier_destruct (&sp
);
1020 while (*C
->I
++ != FIELD_NONE
);
1022 while (*C
->I
++ != FIELD_NONE
);
1023 if (*spec
->_struct
->name
!= '\0')
1026 structs
->structs
= (slang_struct
*) slang_alloc_realloc (structs
->structs
,
1027 structs
->num_structs
* sizeof (slang_struct
),
1028 (structs
->num_structs
+ 1) * sizeof (slang_struct
));
1029 if (structs
->structs
== NULL
)
1031 slang_info_log_memory (C
->L
);
1034 s
= structs
->structs
+ structs
->num_structs
;
1035 if (!slang_struct_construct_a (s
))
1037 structs
->num_structs
++;
1038 if (!slang_struct_copy (s
, spec
->_struct
))
1042 case TYPE_SPECIFIER_TYPENAME
:
1043 spec
->type
= slang_spec_struct
;
1047 if (!parse_identifier (C
, &name
))
1049 stru
= slang_struct_scope_find (structs
, name
, 1);
1052 slang_info_log_error (C
->L
, "%s: undeclared type name", name
);
1053 slang_alloc_free (name
);
1056 slang_alloc_free (name
);
1057 spec
->_struct
= (slang_struct
*) slang_alloc_malloc (sizeof (slang_struct
));
1058 if (spec
->_struct
== NULL
)
1060 slang_info_log_memory (C
->L
);
1063 if (!slang_struct_construct_a (spec
->_struct
))
1065 slang_alloc_free (spec
->_struct
);
1066 spec
->_struct
= NULL
;
1069 if (!slang_struct_copy (spec
->_struct
, stru
))
1079 static int parse_fully_specified_type (slang_parse_ctx
*C
, slang_fully_specified_type
*type
,
1080 slang_struct_scope
*structs
, slang_variable_scope
*scope
, slang_function_scope
*funcs
)
1082 if (!parse_type_qualifier (C
, &type
->qualifier
))
1084 return parse_type_specifier (C
, &type
->specifier
, structs
, scope
, funcs
);
1089 #define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1
1090 #define OP_BLOCK_BEGIN_NEW_SCOPE 2
1091 #define OP_DECLARE 3
1094 #define OP_CONTINUE 6
1095 #define OP_DISCARD 7
1097 #define OP_EXPRESSION 9
1102 #define OP_PUSH_VOID 14
1103 #define OP_PUSH_BOOL 15
1104 #define OP_PUSH_INT 16
1105 #define OP_PUSH_FLOAT 17
1106 #define OP_PUSH_IDENTIFIER 18
1107 #define OP_SEQUENCE 19
1108 #define OP_ASSIGN 20
1109 #define OP_ADDASSIGN 21
1110 #define OP_SUBASSIGN 22
1111 #define OP_MULASSIGN 23
1112 #define OP_DIVASSIGN 24
1113 /*#define OP_MODASSIGN 25*/
1114 /*#define OP_LSHASSIGN 26*/
1115 /*#define OP_RSHASSIGN 27*/
1116 /*#define OP_ORASSIGN 28*/
1117 /*#define OP_XORASSIGN 29*/
1118 /*#define OP_ANDASSIGN 30*/
1119 #define OP_SELECT 31
1120 #define OP_LOGICALOR 32
1121 #define OP_LOGICALXOR 33
1122 #define OP_LOGICALAND 34
1123 /*#define OP_BITOR 35*/
1124 /*#define OP_BITXOR 36*/
1125 /*#define OP_BITAND 37*/
1127 #define OP_NOTEQUAL 39
1129 #define OP_GREATER 41
1130 #define OP_LESSEQUAL 42
1131 #define OP_GREATEREQUAL 43
1132 /*#define OP_LSHIFT 44*/
1133 /*#define OP_RSHIFT 45*/
1135 #define OP_SUBTRACT 47
1136 #define OP_MULTIPLY 48
1137 #define OP_DIVIDE 49
1138 /*#define OP_MODULUS 50*/
1139 #define OP_PREINCREMENT 51
1140 #define OP_PREDECREMENT 52
1143 /*#define OP_COMPLEMENT 55*/
1145 #define OP_SUBSCRIPT 57
1148 #define OP_POSTINCREMENT 60
1149 #define OP_POSTDECREMENT 61
1151 static int parse_child_operation (slang_parse_ctx
*C
, slang_operation
*oper
, int statement
,
1152 slang_variable_scope
*scope
, slang_struct_scope
*structs
, slang_function_scope
*funcs
)
1154 oper
->children
= (slang_operation
*) slang_alloc_realloc (oper
->children
,
1155 oper
->num_children
* sizeof (slang_operation
),
1156 (oper
->num_children
+ 1) * sizeof (slang_operation
));
1157 if (oper
->children
== NULL
)
1159 slang_info_log_memory (C
->L
);
1162 if (!slang_operation_construct_a (oper
->children
+ oper
->num_children
))
1164 slang_info_log_memory (C
->L
);
1167 oper
->num_children
++;
1169 return parse_statement (C
, oper
->children
+ oper
->num_children
- 1, scope
, structs
, funcs
);
1170 return parse_expression (C
, oper
->children
+ oper
->num_children
- 1, scope
, structs
, funcs
);
1173 static int parse_declaration (slang_parse_ctx
*C
, slang_variable_scope
*, slang_struct_scope
*,
1174 slang_function_scope
*);
1176 static int parse_statement (slang_parse_ctx
*C
, slang_operation
*oper
, slang_variable_scope
*scope
,
1177 slang_struct_scope
*structs
, slang_function_scope
*funcs
)
1179 oper
->locals
->outer_scope
= scope
;
1182 case OP_BLOCK_BEGIN_NO_NEW_SCOPE
:
1183 oper
->type
= slang_oper_block_no_new_scope
;
1184 while (*C
->I
!= OP_END
)
1185 if (!parse_child_operation (C
, oper
, 1, scope
, structs
, funcs
))
1189 case OP_BLOCK_BEGIN_NEW_SCOPE
:
1190 oper
->type
= slang_oper_block_new_scope
;
1191 while (*C
->I
!= OP_END
)
1192 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1197 oper
->type
= slang_oper_variable_decl
;
1199 const unsigned int first_var
= scope
->num_variables
;
1200 if (!parse_declaration (C
, scope
, structs
, funcs
))
1202 if (first_var
< scope
->num_variables
)
1204 const unsigned int num_vars
= scope
->num_variables
- first_var
;
1206 oper
->children
= (slang_operation
*) slang_alloc_malloc (num_vars
* sizeof (
1208 if (oper
->children
== NULL
)
1210 slang_info_log_memory (C
->L
);
1213 for (i
= 0; i
< num_vars
; i
++)
1214 if (!slang_operation_construct_a (oper
->children
+ i
))
1217 for (j
= 0; j
< i
; j
++)
1218 slang_operation_destruct (oper
->children
+ j
);
1219 slang_alloc_free (oper
->children
);
1220 oper
->children
= NULL
;
1221 slang_info_log_memory (C
->L
);
1224 oper
->num_children
= num_vars
;
1225 for (i
= first_var
; i
< scope
->num_variables
; i
++)
1227 slang_operation
*o
= oper
->children
+ i
- first_var
;
1228 o
->type
= slang_oper_identifier
;
1229 o
->locals
->outer_scope
= scope
;
1230 o
->identifier
= slang_string_duplicate (scope
->variables
[i
].name
);
1231 if (o
->identifier
== NULL
)
1233 slang_info_log_memory (C
->L
);
1241 oper
->type
= slang_oper_asm
;
1242 if (!parse_identifier (C
, &oper
->identifier
))
1244 while (*C
->I
!= OP_END
)
1245 if (!parse_child_operation (C
, oper
, 0, scope
, structs
, funcs
))
1250 oper
->type
= slang_oper_break
;
1253 oper
->type
= slang_oper_continue
;
1256 oper
->type
= slang_oper_discard
;
1259 oper
->type
= slang_oper_return
;
1260 if (!parse_child_operation (C
, oper
, 0, scope
, structs
, funcs
))
1264 oper
->type
= slang_oper_expression
;
1265 if (!parse_child_operation (C
, oper
, 0, scope
, structs
, funcs
))
1269 oper
->type
= slang_oper_if
;
1270 if (!parse_child_operation (C
, oper
, 0, scope
, structs
, funcs
))
1272 if (!parse_child_operation (C
, oper
, 1, scope
, structs
, funcs
))
1274 if (!parse_child_operation (C
, oper
, 1, scope
, structs
, funcs
))
1278 oper
->type
= slang_oper_while
;
1279 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1281 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1285 oper
->type
= slang_oper_do
;
1286 if (!parse_child_operation (C
, oper
, 1, scope
, structs
, funcs
))
1288 if (!parse_child_operation (C
, oper
, 0, scope
, structs
, funcs
))
1292 oper
->type
= slang_oper_for
;
1293 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1295 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1297 if (!parse_child_operation (C
, oper
, 0, oper
->locals
, structs
, funcs
))
1299 if (!parse_child_operation (C
, oper
, 1, oper
->locals
, structs
, funcs
))
1308 static int handle_trinary_expression (slang_parse_ctx
*C
, slang_operation
*op
,
1309 slang_operation
**ops
, unsigned int *num_ops
)
1311 op
->num_children
= 3;
1312 op
->children
= (slang_operation
*) slang_alloc_malloc (3 * sizeof (slang_operation
));
1313 if (op
->children
== NULL
)
1315 slang_info_log_memory (C
->L
);
1318 op
->children
[0] = (*ops
)[*num_ops
- 4];
1319 op
->children
[1] = (*ops
)[*num_ops
- 3];
1320 op
->children
[2] = (*ops
)[*num_ops
- 2];
1321 (*ops
)[*num_ops
- 4] = (*ops
)[*num_ops
- 1];
1323 *ops
= (slang_operation
*) slang_alloc_realloc (*ops
, (*num_ops
+ 3) * sizeof (slang_operation
),
1324 *num_ops
* sizeof (slang_operation
));
1327 slang_info_log_memory (C
->L
);
1333 static int handle_binary_expression (slang_parse_ctx
*C
, slang_operation
*op
,
1334 slang_operation
**ops
, unsigned int *num_ops
)
1336 op
->num_children
= 2;
1337 op
->children
= (slang_operation
*) slang_alloc_malloc (2 * sizeof (slang_operation
));
1338 if (op
->children
== NULL
)
1340 slang_info_log_memory (C
->L
);
1343 op
->children
[0] = (*ops
)[*num_ops
- 3];
1344 op
->children
[1] = (*ops
)[*num_ops
- 2];
1345 (*ops
)[*num_ops
- 3] = (*ops
)[*num_ops
- 1];
1347 *ops
= (slang_operation
*) slang_alloc_realloc (*ops
, (*num_ops
+ 2) * sizeof (slang_operation
),
1348 *num_ops
* sizeof (slang_operation
));
1351 slang_info_log_memory (C
->L
);
1357 static int handle_unary_expression (slang_parse_ctx
*C
, slang_operation
*op
,
1358 slang_operation
**ops
, unsigned int *num_ops
)
1360 op
->num_children
= 1;
1361 op
->children
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
1362 if (op
->children
== NULL
)
1364 slang_info_log_memory (C
->L
);
1367 op
->children
[0] = (*ops
)[*num_ops
- 2];
1368 (*ops
)[*num_ops
- 2] = (*ops
)[*num_ops
- 1];
1370 *ops
= (slang_operation
*) slang_alloc_realloc (*ops
, (*num_ops
+ 1) * sizeof (slang_operation
),
1371 *num_ops
* sizeof (slang_operation
));
1374 slang_info_log_memory (C
->L
);
1380 static int is_constructor_name (const char *name
, slang_struct_scope
*structs
)
1382 if (slang_type_specifier_type_from_string (name
) != slang_spec_void
)
1384 return slang_struct_scope_find (structs
, name
, 1) != NULL
;
1387 static int parse_expression (slang_parse_ctx
*C
, slang_operation
*oper
, slang_variable_scope
*scope
,
1388 slang_struct_scope
*structs
, slang_function_scope
*funcs
)
1390 slang_operation
*ops
= NULL
;
1391 unsigned int num_ops
= 0;
1394 while (*C
->I
!= OP_END
)
1396 slang_operation
*op
;
1397 const unsigned int op_code
= *C
->I
++;
1398 ops
= (slang_operation
*) slang_alloc_realloc (ops
,
1399 num_ops
* sizeof (slang_operation
), (num_ops
+ 1) * sizeof (slang_operation
));
1402 slang_info_log_memory (C
->L
);
1406 if (!slang_operation_construct_a (op
))
1408 slang_info_log_memory (C
->L
);
1412 op
->locals
->outer_scope
= scope
;
1416 op
->type
= slang_oper_void
;
1419 op
->type
= slang_oper_literal_bool
;
1420 if (!parse_number (C
, &number
))
1422 op
->literal
= (float) number
;
1425 op
->type
= slang_oper_literal_int
;
1426 if (!parse_number (C
, &number
))
1428 op
->literal
= (float) number
;
1431 op
->type
= slang_oper_literal_float
;
1432 if (!parse_float (C
, &op
->literal
))
1435 case OP_PUSH_IDENTIFIER
:
1436 op
->type
= slang_oper_identifier
;
1437 if (!parse_identifier (C
, &op
->identifier
))
1441 op
->type
= slang_oper_sequence
;
1442 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1446 op
->type
= slang_oper_assign
;
1447 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1451 op
->type
= slang_oper_addassign
;
1452 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1456 op
->type
= slang_oper_subassign
;
1457 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1461 op
->type
= slang_oper_mulassign
;
1462 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1466 op
->type
= slang_oper_divassign
;
1467 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1470 /*case OP_MODASSIGN:*/
1471 /*case OP_LSHASSIGN:*/
1472 /*case OP_RSHASSIGN:*/
1473 /*case OP_ORASSIGN:*/
1474 /*case OP_XORASSIGN:*/
1475 /*case OP_ANDASSIGN:*/
1477 op
->type
= slang_oper_select
;
1478 if (!handle_trinary_expression (C
, op
, &ops
, &num_ops
))
1482 op
->type
= slang_oper_logicalor
;
1483 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1487 op
->type
= slang_oper_logicalxor
;
1488 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1492 op
->type
= slang_oper_logicaland
;
1493 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1500 op
->type
= slang_oper_equal
;
1501 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1505 op
->type
= slang_oper_notequal
;
1506 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1510 op
->type
= slang_oper_less
;
1511 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1515 op
->type
= slang_oper_greater
;
1516 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1520 op
->type
= slang_oper_lessequal
;
1521 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1524 case OP_GREATEREQUAL
:
1525 op
->type
= slang_oper_greaterequal
;
1526 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1532 op
->type
= slang_oper_add
;
1533 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1537 op
->type
= slang_oper_subtract
;
1538 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1542 op
->type
= slang_oper_multiply
;
1543 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1547 op
->type
= slang_oper_divide
;
1548 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1551 /*case OP_MODULUS:*/
1552 case OP_PREINCREMENT
:
1553 op
->type
= slang_oper_preincrement
;
1554 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1557 case OP_PREDECREMENT
:
1558 op
->type
= slang_oper_predecrement
;
1559 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1563 op
->type
= slang_oper_plus
;
1564 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1568 op
->type
= slang_oper_minus
;
1569 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1573 op
->type
= slang_oper_not
;
1574 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1577 /*case OP_COMPLEMENT:*/
1579 op
->type
= slang_oper_subscript
;
1580 if (!handle_binary_expression (C
, op
, &ops
, &num_ops
))
1584 op
->type
= slang_oper_call
;
1585 if (!parse_identifier (C
, &op
->identifier
))
1587 while (*C
->I
!= OP_END
)
1588 if (!parse_child_operation (C
, op
, 0, scope
, structs
, funcs
))
1591 if (!C
->parsing_builtin
&&
1592 !slang_function_scope_find_by_name (funcs
, op
->identifier
, 1) &&
1593 !is_constructor_name (op
->identifier
, structs
))
1595 slang_info_log_error (C
->L
, "%s: undeclared function name", op
->identifier
);
1600 op
->type
= slang_oper_field
;
1601 if (!parse_identifier (C
, &op
->identifier
))
1603 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1606 case OP_POSTINCREMENT
:
1607 op
->type
= slang_oper_postincrement
;
1608 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1611 case OP_POSTDECREMENT
:
1612 op
->type
= slang_oper_postdecrement
;
1613 if (!handle_unary_expression (C
, op
, &ops
, &num_ops
))
1622 slang_alloc_free (ops
);
1626 /* parameter qualifier */
1627 #define PARAM_QUALIFIER_IN 0
1628 #define PARAM_QUALIFIER_OUT 1
1629 #define PARAM_QUALIFIER_INOUT 2
1631 /* function parameter array presence */
1632 #define PARAMETER_ARRAY_NOT_PRESENT 0
1633 #define PARAMETER_ARRAY_PRESENT 1
1635 static int parse_parameter_declaration (slang_parse_ctx
*C
, slang_variable
*param
,
1636 slang_struct_scope
*structs
, slang_variable_scope
*scope
, slang_function_scope
*funcs
)
1638 slang_storage_aggregate agg
;
1639 if (!parse_type_qualifier (C
, ¶m
->type
.qualifier
))
1643 case PARAM_QUALIFIER_IN
:
1644 if (param
->type
.qualifier
!= slang_qual_const
&& param
->type
.qualifier
!= slang_qual_none
)
1646 slang_info_log_error (C
->L
, "invalid type qualifier");
1650 case PARAM_QUALIFIER_OUT
:
1651 if (param
->type
.qualifier
== slang_qual_none
)
1652 param
->type
.qualifier
= slang_qual_out
;
1655 slang_info_log_error (C
->L
, "invalid type qualifier");
1659 case PARAM_QUALIFIER_INOUT
:
1660 if (param
->type
.qualifier
== slang_qual_none
)
1661 param
->type
.qualifier
= slang_qual_inout
;
1664 slang_info_log_error (C
->L
, "invalid type qualifier");
1671 if (!parse_type_specifier (C
, ¶m
->type
.specifier
, structs
, scope
, funcs
))
1673 if (!parse_identifier (C
, ¶m
->name
))
1675 if (*C
->I
++ == PARAMETER_ARRAY_PRESENT
)
1677 param
->array_size
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
1678 if (param
->array_size
== NULL
)
1680 slang_info_log_memory (C
->L
);
1683 if (!slang_operation_construct_a (param
->array_size
))
1685 slang_alloc_free (param
->array_size
);
1686 param
->array_size
= NULL
;
1687 slang_info_log_memory (C
->L
);
1690 if (!parse_expression (C
, param
->array_size
, scope
, structs
, funcs
))
1693 slang_storage_aggregate_construct (&agg
);
1694 if (!_slang_aggregate_variable (&agg
, ¶m
->type
.specifier
, param
->array_size
, funcs
,
1697 slang_storage_aggregate_destruct (&agg
);
1700 slang_storage_aggregate_destruct (&agg
);
1705 #define FUNCTION_ORDINARY 0
1706 #define FUNCTION_CONSTRUCTOR 1
1707 #define FUNCTION_OPERATOR 2
1709 /* function parameter */
1710 #define PARAMETER_NONE 0
1711 #define PARAMETER_NEXT 1
1714 #define OPERATOR_ASSIGN 1
1715 #define OPERATOR_ADDASSIGN 2
1716 #define OPERATOR_SUBASSIGN 3
1717 #define OPERATOR_MULASSIGN 4
1718 #define OPERATOR_DIVASSIGN 5
1719 /*#define OPERATOR_MODASSIGN 6*/
1720 /*#define OPERATOR_LSHASSIGN 7*/
1721 /*#define OPERATOR_RSHASSIGN 8*/
1722 /*#define OPERATOR_ANDASSIGN 9*/
1723 /*#define OPERATOR_XORASSIGN 10*/
1724 /*#define OPERATOR_ORASSIGN 11*/
1725 #define OPERATOR_LOGICALXOR 12
1726 /*#define OPERATOR_BITOR 13*/
1727 /*#define OPERATOR_BITXOR 14*/
1728 /*#define OPERATOR_BITAND 15*/
1729 #define OPERATOR_EQUAL 16
1730 #define OPERATOR_NOTEQUAL 17
1731 #define OPERATOR_LESS 18
1732 #define OPERATOR_GREATER 19
1733 #define OPERATOR_LESSEQUAL 20
1734 #define OPERATOR_GREATEREQUAL 21
1735 /*#define OPERATOR_LSHIFT 22*/
1736 /*#define OPERATOR_RSHIFT 23*/
1737 #define OPERATOR_MULTIPLY 24
1738 #define OPERATOR_DIVIDE 25
1739 /*#define OPERATOR_MODULUS 26*/
1740 #define OPERATOR_INCREMENT 27
1741 #define OPERATOR_DECREMENT 28
1742 #define OPERATOR_PLUS 29
1743 #define OPERATOR_MINUS 30
1744 /*#define OPERATOR_COMPLEMENT 31*/
1745 #define OPERATOR_NOT 32
1747 static const struct {
1748 unsigned int o_code
;
1750 } operator_names
[] = {
1751 { OPERATOR_INCREMENT
, "++" },
1752 { OPERATOR_ADDASSIGN
, "+=" },
1753 { OPERATOR_PLUS
, "+" },
1754 { OPERATOR_DECREMENT
, "--" },
1755 { OPERATOR_SUBASSIGN
, "-=" },
1756 { OPERATOR_MINUS
, "-" },
1757 { OPERATOR_NOTEQUAL
, "!=" },
1758 { OPERATOR_NOT
, "!" },
1759 { OPERATOR_MULASSIGN
, "*=" },
1760 { OPERATOR_MULTIPLY
, "*" },
1761 { OPERATOR_DIVASSIGN
, "/=" },
1762 { OPERATOR_DIVIDE
, "/" },
1763 { OPERATOR_LESSEQUAL
, "<=" },
1764 /*{ OPERATOR_LSHASSIGN, "<<=" },*/
1765 /*{ OPERATOR_LSHIFT, "<<" },*/
1766 { OPERATOR_LESS
, "<" },
1767 { OPERATOR_GREATEREQUAL
, ">=" },
1768 /*{ OPERATOR_RSHASSIGN, ">>=" },*/
1769 /*{ OPERATOR_RSHIFT, ">>" },*/
1770 { OPERATOR_GREATER
, ">" },
1771 { OPERATOR_EQUAL
, "==" },
1772 { OPERATOR_ASSIGN
, "=" },
1773 /*{ OPERATOR_MODASSIGN, "%=" },*/
1774 /*{ OPERATOR_MODULUS, "%" },*/
1775 /*{ OPERATOR_ANDASSIGN, "&=" },*/
1776 /*{ OPERATOR_BITAND, "&" },*/
1777 /*{ OPERATOR_ORASSIGN, "|=" },*/
1778 /*{ OPERATOR_BITOR, "|" },*/
1779 /*{ OPERATOR_COMPLEMENT, "~" },*/
1780 /*{ OPERATOR_XORASSIGN, "^=" },*/
1781 { OPERATOR_LOGICALXOR
, "^^" }/*,*/
1782 /*{ OPERATOR_BITXOR, "^" }*/
1785 static int parse_operator_name (slang_parse_ctx
*C
, char **pname
)
1788 for (i
= 0; i
< sizeof (operator_names
) / sizeof (*operator_names
); i
++)
1789 if (operator_names
[i
].o_code
== (unsigned int) (*C
->I
))
1791 *pname
= slang_string_duplicate (operator_names
[i
].o_name
);
1794 slang_info_log_memory (C
->L
);
1803 static int parse_function_prototype (slang_parse_ctx
*C
, slang_function
*func
,
1804 slang_struct_scope
*structs
, slang_variable_scope
*scope
, slang_function_scope
*funcs
)
1806 if (!parse_fully_specified_type (C
, &func
->header
.type
, structs
, scope
, funcs
))
1810 case FUNCTION_ORDINARY
:
1811 func
->kind
= slang_func_ordinary
;
1812 if (!parse_identifier (C
, &func
->header
.name
))
1815 case FUNCTION_CONSTRUCTOR
:
1816 func
->kind
= slang_func_constructor
;
1817 if (func
->header
.type
.specifier
.type
== slang_spec_struct
)
1819 func
->header
.name
= slang_string_duplicate (
1820 type_specifier_type_names
[func
->header
.type
.specifier
.type
]);
1821 if (func
->header
.name
== NULL
)
1823 slang_info_log_memory (C
->L
);
1827 case FUNCTION_OPERATOR
:
1828 func
->kind
= slang_func_operator
;
1829 if (!parse_operator_name (C
, &func
->header
.name
))
1835 func
->parameters
->outer_scope
= scope
;
1836 while (*C
->I
++ == PARAMETER_NEXT
)
1838 func
->parameters
->variables
= (slang_variable
*) slang_alloc_realloc (
1839 func
->parameters
->variables
,
1840 func
->parameters
->num_variables
* sizeof (slang_variable
),
1841 (func
->parameters
->num_variables
+ 1) * sizeof (slang_variable
));
1842 if (func
->parameters
->variables
== NULL
)
1844 slang_info_log_memory (C
->L
);
1847 slang_variable_construct (func
->parameters
->variables
+ func
->parameters
->num_variables
);
1848 func
->parameters
->num_variables
++;
1849 if (!parse_parameter_declaration (C
, func
->parameters
->variables
+
1850 func
->parameters
->num_variables
- 1, structs
, scope
, funcs
))
1853 func
->param_count
= func
->parameters
->num_variables
;
1857 static int parse_function_definition (slang_parse_ctx
*C
, slang_function
*func
,
1858 slang_struct_scope
*structs
, slang_variable_scope
*scope
, slang_function_scope
*funcs
)
1860 if (!parse_function_prototype (C
, func
, structs
, scope
, funcs
))
1862 func
->body
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
1863 if (func
->body
== NULL
)
1865 slang_info_log_memory (C
->L
);
1868 if (!slang_operation_construct_a (func
->body
))
1870 slang_alloc_free (func
->body
);
1872 slang_info_log_memory (C
->L
);
1875 if (!parse_statement (C
, func
->body
, func
->parameters
, structs
, funcs
))
1880 /* init declarator list */
1881 #define DECLARATOR_NONE 0
1882 #define DECLARATOR_NEXT 1
1884 /* variable declaration */
1885 #define VARIABLE_NONE 0
1886 #define VARIABLE_IDENTIFIER 1
1887 #define VARIABLE_INITIALIZER 2
1888 #define VARIABLE_ARRAY_EXPLICIT 3
1889 #define VARIABLE_ARRAY_UNKNOWN 4
1891 static int parse_init_declarator (slang_parse_ctx
*C
, const slang_fully_specified_type
*type
,
1892 slang_variable_scope
*vars
, slang_struct_scope
*structs
, slang_function_scope
*funcs
)
1894 slang_variable
*var
;
1896 if (*C
->I
++ == VARIABLE_NONE
)
1898 vars
->variables
= (slang_variable
*) slang_alloc_realloc (vars
->variables
,
1899 vars
->num_variables
* sizeof (slang_variable
),
1900 (vars
->num_variables
+ 1) * sizeof (slang_variable
));
1901 if (vars
->variables
== NULL
)
1903 slang_info_log_memory (C
->L
);
1906 var
= vars
->variables
+ vars
->num_variables
;
1907 vars
->num_variables
++;
1908 slang_variable_construct (var
);
1909 var
->type
.qualifier
= type
->qualifier
;
1910 if (!parse_identifier (C
, &var
->name
))
1915 if (!slang_type_specifier_copy (&var
->type
.specifier
, &type
->specifier
))
1918 case VARIABLE_INITIALIZER
:
1919 if (!slang_type_specifier_copy (&var
->type
.specifier
, &type
->specifier
))
1921 var
->initializer
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
1922 if (var
->initializer
== NULL
)
1924 slang_info_log_memory (C
->L
);
1927 if (!slang_operation_construct_a (var
->initializer
))
1929 slang_alloc_free (var
->initializer
);
1930 var
->initializer
= NULL
;
1931 slang_info_log_memory (C
->L
);
1934 if (!parse_expression (C
, var
->initializer
, vars
, structs
, funcs
))
1937 case VARIABLE_ARRAY_UNKNOWN
:
1938 var
->type
.specifier
.type
= slang_spec_array
;
1939 var
->type
.specifier
._array
= (slang_type_specifier
*) slang_alloc_malloc (sizeof (
1940 slang_type_specifier
));
1941 if (var
->type
.specifier
._array
== NULL
)
1943 slang_info_log_memory (C
->L
);
1946 slang_type_specifier_construct (var
->type
.specifier
._array
);
1947 if (!slang_type_specifier_copy (var
->type
.specifier
._array
, &type
->specifier
))
1950 case VARIABLE_ARRAY_EXPLICIT
:
1951 var
->type
.specifier
.type
= slang_spec_array
;
1952 var
->type
.specifier
._array
= (slang_type_specifier
*) slang_alloc_malloc (sizeof (
1953 slang_type_specifier
));
1954 if (var
->type
.specifier
._array
== NULL
)
1956 slang_info_log_memory (C
->L
);
1959 slang_type_specifier_construct (var
->type
.specifier
._array
);
1960 if (!slang_type_specifier_copy (var
->type
.specifier
._array
, &type
->specifier
))
1962 var
->array_size
= (slang_operation
*) slang_alloc_malloc (sizeof (slang_operation
));
1963 if (var
->array_size
== NULL
)
1965 slang_info_log_memory (C
->L
);
1968 if (!slang_operation_construct_a (var
->array_size
))
1970 slang_alloc_free (var
->array_size
);
1971 var
->array_size
= NULL
;
1972 slang_info_log_memory (C
->L
);
1975 if (!parse_expression (C
, var
->array_size
, vars
, structs
, funcs
))
1981 if (!(var
->type
.specifier
.type
== slang_spec_array
&& var
->array_size
== NULL
))
1983 slang_storage_aggregate agg
;
1985 slang_storage_aggregate_construct (&agg
);
1986 if (!_slang_aggregate_variable (&agg
, &var
->type
.specifier
, var
->array_size
, funcs
,
1989 slang_storage_aggregate_destruct (&agg
);
1992 slang_storage_aggregate_destruct (&agg
);
1997 static int parse_init_declarator_list (slang_parse_ctx
*C
, slang_variable_scope
*vars
,
1998 slang_struct_scope
*structs
, slang_function_scope
*funcs
)
2000 slang_fully_specified_type type
;
2002 slang_fully_specified_type_construct (&type
);
2003 if (!parse_fully_specified_type (C
, &type
, structs
, vars
, funcs
))
2005 slang_fully_specified_type_destruct (&type
);
2010 if (!parse_init_declarator (C
, &type
, vars
, structs
, funcs
))
2012 slang_fully_specified_type_destruct (&type
);
2016 while (*C
->I
++ == DECLARATOR_NEXT
);
2017 slang_fully_specified_type_destruct (&type
);
2021 static int parse_function (slang_parse_ctx
*C
, int definition
, slang_struct_scope
*structs
,
2022 slang_function_scope
*funcs
, slang_variable_scope
*scope
, slang_function
**parsed_func_ret
)
2024 slang_function parsed_func
, *found_func
;
2026 /* parse function definition/declaration */
2027 slang_function_construct (&parsed_func
);
2030 if (!parse_function_definition (C
, &parsed_func
, structs
, scope
, funcs
))
2032 slang_function_destruct (&parsed_func
);
2038 if (!parse_function_prototype (C
, &parsed_func
, structs
, scope
, funcs
))
2040 slang_function_destruct (&parsed_func
);
2045 /* find a function with a prototype matching the parsed one - only the current scope
2046 is being searched to allow built-in function overriding */
2047 found_func
= slang_function_scope_find (funcs
, &parsed_func
, 0);
2048 if (found_func
== NULL
)
2050 /* add the parsed function to the function list */
2051 funcs
->functions
= (slang_function
*) slang_alloc_realloc (funcs
->functions
,
2052 funcs
->num_functions
* sizeof (slang_function
), (funcs
->num_functions
+ 1) * sizeof (
2054 if (funcs
->functions
== NULL
)
2056 slang_info_log_memory (C
->L
);
2057 slang_function_destruct (&parsed_func
);
2060 funcs
->functions
[funcs
->num_functions
] = parsed_func
;
2061 funcs
->num_functions
++;
2063 /* return the newly parsed function */
2064 *parsed_func_ret
= funcs
->functions
+ funcs
->num_functions
- 1;
2068 /* TODO: check function return type qualifiers and specifiers */
2071 /* destroy the existing function declaration and replace it with the new one */
2072 if (found_func
->body
!= NULL
)
2074 slang_info_log_error (C
->L
, "%s: function already has a body",
2075 parsed_func
.header
.name
);
2076 slang_function_destruct (&parsed_func
);
2079 slang_function_destruct (found_func
);
2080 *found_func
= parsed_func
;
2084 /* another declaration of the same function prototype - ignore it */
2085 slang_function_destruct (&parsed_func
);
2088 /* return the found function */
2089 *parsed_func_ret
= found_func
;
2092 /* assemble the parsed function */
2096 const int y
= 61; /* core 437 */
2098 slang_assembly_file file
;
2099 slang_assembly_name_space space
;
2102 slang_assembly_file_construct (&file
);
2103 space
.funcs
= funcs
;
2104 space
.structs
= structs
;
2110 if (!_slang_assemble_function (&file
, *parsed_func_ret
, &space
))
2112 slang_assembly_file_destruct (&file
);
2117 _slang_execute (&file
);
2118 slang_assembly_file_destruct (&file
);
2126 #define DECLARATION_FUNCTION_PROTOTYPE 1
2127 #define DECLARATION_INIT_DECLARATOR_LIST 2
2129 static int parse_declaration (slang_parse_ctx
*C
, slang_variable_scope
*scope
,
2130 slang_struct_scope
*structs
, slang_function_scope
*funcs
)
2132 slang_function
*dummy_func
;
2136 case DECLARATION_INIT_DECLARATOR_LIST
:
2137 if (!parse_init_declarator_list (C
, scope
, structs
, funcs
))
2140 case DECLARATION_FUNCTION_PROTOTYPE
:
2141 if (!parse_function (C
, 0, structs
, funcs
, scope
, &dummy_func
))
2150 /* external declaration */
2151 #define EXTERNAL_NULL 0
2152 #define EXTERNAL_FUNCTION_DEFINITION 1
2153 #define EXTERNAL_DECLARATION 2
2155 static int parse_translation_unit (slang_parse_ctx
*C
, slang_translation_unit
*unit
)
2157 while (*C
->I
!= EXTERNAL_NULL
)
2159 slang_function
*func
;
2163 case EXTERNAL_FUNCTION_DEFINITION
:
2164 if (!parse_function (C
, 1, &unit
->structs
, &unit
->functions
, &unit
->globals
, &func
))
2167 case EXTERNAL_DECLARATION
:
2168 if (!parse_declaration (C
, &unit
->globals
, &unit
->structs
, &unit
->functions
))
2179 static int compile_binary (const byte
*prod
, slang_translation_unit
*unit
, slang_unit_type type
,
2180 slang_info_log
*log
, slang_translation_unit
*builtins
)
2184 /* set-up parse context */
2187 C
.parsing_builtin
= builtins
== NULL
;
2189 if (!check_revision (&C
))
2192 /* create translation unit object */
2193 slang_translation_unit_construct (unit
);
2196 if (builtins
!= NULL
)
2198 /* link to built-in functions */
2199 builtins
[1].functions
.outer_scope
= &builtins
[0].functions
;
2200 builtins
[2].functions
.outer_scope
= &builtins
[1].functions
;
2201 unit
->functions
.outer_scope
= &builtins
[2].functions
;
2203 /* link to built-in variables - core unit does not define any */
2204 builtins
[2].globals
.outer_scope
= &builtins
[1].globals
;
2205 unit
->globals
.outer_scope
= &builtins
[2].globals
;
2207 /* link to built-in structure typedefs - only in common unit */
2208 unit
->structs
.outer_scope
= &builtins
[1].structs
;
2211 /* parse translation unit */
2212 if (!parse_translation_unit (&C
, unit
))
2214 slang_translation_unit_destruct (unit
);
2221 static int compile_with_grammar (grammar id
, const char *source
, slang_translation_unit
*unit
,
2222 slang_unit_type type
, slang_info_log
*log
, slang_translation_unit
*builtins
)
2225 unsigned int size
, start
, version
;
2227 /* retrieve version */
2228 if (!_slang_preprocess_version (source
, &version
, &start
, log
))
2231 /* check the syntax */
2232 if (!grammar_fast_check (id
, (const byte
*) source
+ start
, &prod
, &size
, 65536))
2236 grammar_get_last_error ( (unsigned char*) buf
, 1024, (int*) &pos
);
2237 slang_info_log_error (log
, buf
);
2241 if (!compile_binary (prod
, unit
, type
, log
, builtins
))
2243 grammar_alloc_free (prod
);
2247 grammar_alloc_free (prod
);
2251 static const char *slang_shader_syn
=
2252 #include "library/slang_shader_syn.h"
2255 static const byte slang_core_gc_bin
[] = {
2256 #include "library/slang_core_gc_bin.h"
2259 static const byte slang_common_builtin_gc_bin
[] = {
2260 #include "library/slang_common_builtin_gc_bin.h"
2263 static const byte slang_fragment_builtin_gc_bin
[] = {
2264 #include "library/slang_fragment_builtin_gc_bin.h"
2267 static const byte slang_vertex_builtin_gc_bin
[] = {
2268 #include "library/slang_vertex_builtin_gc_bin.h"
2271 int _slang_compile (const char *source
, slang_translation_unit
*unit
, slang_unit_type type
,
2272 slang_info_log
*log
)
2275 slang_translation_unit builtin_units
[3];
2276 slang_translation_unit
*builtins
= NULL
;
2278 /* load slang grammar */
2279 id
= grammar_load_from_text ((const byte
*) slang_shader_syn
);
2284 grammar_get_last_error ( (unsigned char*) buf
, 1024, (int*) &pos
);
2285 slang_info_log_error (log
, buf
);
2289 /* set shader type - the syntax is slightly different for different shaders */
2290 if (type
== slang_unit_fragment_shader
|| type
== slang_unit_fragment_builtin
)
2291 grammar_set_reg8 (id
, (const byte
*) "shader_type", 1);
2293 grammar_set_reg8 (id
, (const byte
*) "shader_type", 2);
2295 /* enable language extensions */
2296 grammar_set_reg8 (id
, (const byte
*) "parsing_builtin", 1);
2298 /* if parsing user-specified shader, load built-in library */
2299 if (type
== slang_unit_fragment_shader
|| type
== slang_unit_vertex_shader
)
2301 if (!compile_binary (slang_core_gc_bin
, builtin_units
,
2302 slang_unit_fragment_builtin
, log
, NULL
))
2304 grammar_destroy (id
);
2307 if (!compile_binary (slang_common_builtin_gc_bin
, builtin_units
+ 1,
2308 slang_unit_fragment_builtin
, log
, NULL
))
2310 slang_translation_unit_destruct (builtin_units
);
2311 grammar_destroy (id
);
2314 if (type
== slang_unit_fragment_shader
)
2316 if (!compile_binary (slang_fragment_builtin_gc_bin
, builtin_units
+ 2,
2317 slang_unit_fragment_builtin
, log
, NULL
))
2319 slang_translation_unit_destruct (builtin_units
);
2320 slang_translation_unit_destruct (builtin_units
+ 1);
2321 grammar_destroy (id
);
2325 else if (type
== slang_unit_vertex_shader
)
2327 if (!compile_binary (slang_vertex_builtin_gc_bin
, builtin_units
+ 2,
2328 slang_unit_vertex_builtin
, log
, NULL
))
2330 slang_translation_unit_destruct (builtin_units
);
2331 slang_translation_unit_destruct (builtin_units
+ 1);
2332 grammar_destroy (id
);
2337 /* disable language extensions */
2338 grammar_set_reg8 (id
, (const byte
*) "parsing_builtin", 0);
2339 builtins
= builtin_units
;
2342 /* compile the actual shader - pass-in built-in library for external shader */
2343 if (!compile_with_grammar (id
, source
, unit
, type
, log
, builtins
))
2345 if (type
== slang_unit_fragment_shader
|| type
== slang_unit_vertex_shader
)
2347 slang_translation_unit_destruct (builtin_units
);
2348 slang_translation_unit_destruct (builtin_units
+ 1);
2349 slang_translation_unit_destruct (builtin_units
+ 2);
2351 grammar_destroy (id
);
2355 /* destroy built-in library */
2356 if (type
== slang_unit_fragment_shader
|| type
== slang_unit_vertex_shader
)
2358 slang_translation_unit_destruct (builtin_units
);
2359 slang_translation_unit_destruct (builtin_units
+ 1);
2360 slang_translation_unit_destruct (builtin_units
+ 2);
2362 grammar_destroy (id
);