2 * Mesa 3-D graphics library
5 * Copyright (C) 2005-2006 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_assemble_typeinfo.c
32 #include "slang_utility.h"
33 #include "slang_assemble_typeinfo.h"
35 /* slang_assembly_typeinfo */
37 GLboolean
slang_assembly_typeinfo_construct (slang_assembly_typeinfo
*ti
)
39 if (!slang_type_specifier_construct (&ti
->spec
))
45 GLvoid
slang_assembly_typeinfo_destruct (slang_assembly_typeinfo
*ti
)
47 slang_type_specifier_destruct (&ti
->spec
);
50 /* _slang_typeof_operation() */
52 static GLboolean
typeof_existing_function (const char *name
, slang_operation
*params
,
53 GLuint num_params
, slang_assembly_name_space
*space
, slang_type_specifier
*spec
,
54 slang_atom_pool
*atoms
)
59 atom
= slang_atom_pool_atom (atoms
, name
);
60 if (!_slang_typeof_function (atom
, params
, num_params
, space
, spec
, &exists
, atoms
))
65 GLboolean
_slang_typeof_operation (slang_assemble_ctx
*A
, slang_operation
*op
,
66 slang_assembly_typeinfo
*ti
)
68 return _slang_typeof_operation_ (op
, &A
->space
, ti
, A
->atoms
);
71 GLboolean
_slang_typeof_operation_ (slang_operation
*op
, slang_assembly_name_space
*space
,
72 slang_assembly_typeinfo
*ti
, slang_atom_pool
*atoms
)
74 ti
->can_be_referenced
= GL_FALSE
;
75 ti
->is_swizzled
= GL_FALSE
;
79 case slang_oper_block_no_new_scope
:
80 case slang_oper_block_new_scope
:
81 case slang_oper_variable_decl
:
83 case slang_oper_break
:
84 case slang_oper_continue
:
85 case slang_oper_discard
:
86 case slang_oper_return
:
88 case slang_oper_while
:
92 ti
->spec
.type
= slang_spec_void
;
94 case slang_oper_expression
:
95 case slang_oper_assign
:
96 case slang_oper_addassign
:
97 case slang_oper_subassign
:
98 case slang_oper_mulassign
:
99 case slang_oper_divassign
:
100 case slang_oper_preincrement
:
101 case slang_oper_predecrement
:
102 if (!_slang_typeof_operation_ (op
->children
, space
, ti
, atoms
))
105 case slang_oper_literal_bool
:
106 case slang_oper_logicalor
:
107 case slang_oper_logicalxor
:
108 case slang_oper_logicaland
:
109 case slang_oper_equal
:
110 case slang_oper_notequal
:
111 case slang_oper_less
:
112 case slang_oper_greater
:
113 case slang_oper_lessequal
:
114 case slang_oper_greaterequal
:
116 ti
->spec
.type
= slang_spec_bool
;
118 case slang_oper_literal_int
:
119 ti
->spec
.type
= slang_spec_int
;
121 case slang_oper_literal_float
:
122 ti
->spec
.type
= slang_spec_float
;
124 case slang_oper_identifier
:
128 var
= _slang_locate_variable (op
->locals
, op
->a_id
, GL_TRUE
);
131 if (!slang_type_specifier_copy (&ti
->spec
, &var
->type
.specifier
))
133 ti
->can_be_referenced
= GL_TRUE
;
134 ti
->array_len
= var
->array_len
;
137 case slang_oper_sequence
:
138 /* TODO: check [0] and [1] if they match */
139 if (!_slang_typeof_operation_ (&op
->children
[1], space
, ti
, atoms
))
141 ti
->can_be_referenced
= GL_FALSE
;
142 ti
->is_swizzled
= GL_FALSE
;
144 /*case slang_oper_modassign:*/
145 /*case slang_oper_lshassign:*/
146 /*case slang_oper_rshassign:*/
147 /*case slang_oper_orassign:*/
148 /*case slang_oper_xorassign:*/
149 /*case slang_oper_andassign:*/
150 case slang_oper_select
:
151 /* TODO: check [1] and [2] if they match */
152 if (!_slang_typeof_operation_ (&op
->children
[1], space
, ti
, atoms
))
154 ti
->can_be_referenced
= GL_FALSE
;
155 ti
->is_swizzled
= GL_FALSE
;
157 /*case slang_oper_bitor:*/
158 /*case slang_oper_bitxor:*/
159 /*case slang_oper_bitand:*/
160 /*case slang_oper_lshift:*/
161 /*case slang_oper_rshift:*/
163 if (!typeof_existing_function ("+", op
->children
, 2, space
, &ti
->spec
, atoms
))
166 case slang_oper_subtract
:
167 if (!typeof_existing_function ("-", op
->children
, 2, space
, &ti
->spec
, atoms
))
170 case slang_oper_multiply
:
171 if (!typeof_existing_function ("*", op
->children
, 2, space
, &ti
->spec
, atoms
))
174 case slang_oper_divide
:
175 if (!typeof_existing_function ("/", op
->children
, 2, space
, &ti
->spec
, atoms
))
178 /*case slang_oper_modulus:*/
179 case slang_oper_plus
:
180 if (!_slang_typeof_operation_ (op
->children
, space
, ti
, atoms
))
182 ti
->can_be_referenced
= GL_FALSE
;
183 ti
->is_swizzled
= GL_FALSE
;
185 case slang_oper_minus
:
186 if (!typeof_existing_function ("-", op
->children
, 1, space
, &ti
->spec
, atoms
))
189 /*case slang_oper_complement:*/
190 case slang_oper_subscript
:
192 slang_assembly_typeinfo _ti
;
194 if (!slang_assembly_typeinfo_construct (&_ti
))
196 if (!_slang_typeof_operation_ (op
->children
, space
, &_ti
, atoms
))
198 slang_assembly_typeinfo_destruct (&_ti
);
201 ti
->can_be_referenced
= _ti
.can_be_referenced
;
202 if (_ti
.spec
.type
== slang_spec_array
)
204 if (!slang_type_specifier_copy (&ti
->spec
, _ti
.spec
._array
))
206 slang_assembly_typeinfo_destruct (&_ti
);
212 if (!_slang_type_is_vector (_ti
.spec
.type
) && !_slang_type_is_matrix (_ti
.spec
.type
))
214 slang_assembly_typeinfo_destruct (&_ti
);
217 ti
->spec
.type
= _slang_type_base (_ti
.spec
.type
);
219 slang_assembly_typeinfo_destruct (&_ti
);
222 case slang_oper_call
:
226 if (!_slang_typeof_function (op
->a_id
, op
->children
, op
->num_children
, space
, &ti
->spec
,
231 slang_struct
*s
= slang_struct_scope_find (space
->structs
, op
->a_id
, GL_TRUE
);
234 ti
->spec
.type
= slang_spec_struct
;
235 ti
->spec
._struct
= (slang_struct
*) slang_alloc_malloc (sizeof (slang_struct
));
236 if (ti
->spec
._struct
== NULL
)
238 if (!slang_struct_construct (ti
->spec
._struct
))
240 slang_alloc_free (ti
->spec
._struct
);
241 ti
->spec
._struct
= NULL
;
244 if (!slang_struct_copy (ti
->spec
._struct
, s
))
250 slang_type_specifier_type type
;
252 name
= slang_atom_pool_id (atoms
, op
->a_id
);
253 type
= slang_type_specifier_type_from_string (name
);
254 if (type
== slang_spec_void
)
256 ti
->spec
.type
= type
;
261 case slang_oper_field
:
263 slang_assembly_typeinfo _ti
;
265 if (!slang_assembly_typeinfo_construct (&_ti
))
267 if (!_slang_typeof_operation_ (op
->children
, space
, &_ti
, atoms
))
269 slang_assembly_typeinfo_destruct (&_ti
);
272 if (_ti
.spec
.type
== slang_spec_struct
)
274 slang_variable
*field
;
276 field
= _slang_locate_variable (_ti
.spec
._struct
->fields
, op
->a_id
, GL_FALSE
);
279 slang_assembly_typeinfo_destruct (&_ti
);
282 if (!slang_type_specifier_copy (&ti
->spec
, &field
->type
.specifier
))
284 slang_assembly_typeinfo_destruct (&_ti
);
287 ti
->can_be_referenced
= _ti
.can_be_referenced
;
293 slang_type_specifier_type base
;
295 /* determine the swizzle of the field expression */
296 if (!_slang_type_is_vector (_ti
.spec
.type
))
298 slang_assembly_typeinfo_destruct (&_ti
);
301 rows
= _slang_type_dim (_ti
.spec
.type
);
302 swizzle
= slang_atom_pool_id (atoms
, op
->a_id
);
303 if (!_slang_is_swizzle (swizzle
, rows
, &ti
->swz
))
305 slang_assembly_typeinfo_destruct (&_ti
);
308 ti
->is_swizzled
= GL_TRUE
;
309 ti
->can_be_referenced
= _ti
.can_be_referenced
&& _slang_is_swizzle_mask (&ti
->swz
,
315 /* swizzle the swizzle */
316 _slang_multiply_swizzles (&swz
, &_ti
.swz
, &ti
->swz
);
319 base
= _slang_type_base (_ti
.spec
.type
);
320 switch (ti
->swz
.num_components
)
323 ti
->spec
.type
= base
;
328 case slang_spec_float
:
329 ti
->spec
.type
= slang_spec_vec2
;
332 ti
->spec
.type
= slang_spec_ivec2
;
334 case slang_spec_bool
:
335 ti
->spec
.type
= slang_spec_bvec2
;
344 case slang_spec_float
:
345 ti
->spec
.type
= slang_spec_vec3
;
348 ti
->spec
.type
= slang_spec_ivec3
;
350 case slang_spec_bool
:
351 ti
->spec
.type
= slang_spec_bvec3
;
360 case slang_spec_float
:
361 ti
->spec
.type
= slang_spec_vec4
;
364 ti
->spec
.type
= slang_spec_ivec4
;
366 case slang_spec_bool
:
367 ti
->spec
.type
= slang_spec_bvec4
;
377 slang_assembly_typeinfo_destruct (&_ti
);
380 case slang_oper_postincrement
:
381 case slang_oper_postdecrement
:
382 if (!_slang_typeof_operation_ (op
->children
, space
, ti
, atoms
))
384 ti
->can_be_referenced
= GL_FALSE
;
385 ti
->is_swizzled
= GL_FALSE
;
394 /* _slang_typeof_function() */
396 GLboolean
_slang_typeof_function (slang_atom a_name
, slang_operation
*params
, GLuint num_params
,
397 slang_assembly_name_space
*space
, slang_type_specifier
*spec
, GLboolean
*exists
,
398 slang_atom_pool
*atoms
)
402 fun
= _slang_locate_function (space
->funcs
, a_name
, params
, num_params
, space
, atoms
);
403 *exists
= fun
!= NULL
;
406 return slang_type_specifier_copy (spec
, &fun
->header
.type
.specifier
);
409 /* _slang_type_is_matrix() */
411 GLboolean
_slang_type_is_matrix (slang_type_specifier_type ty
)
415 case slang_spec_mat2
:
416 case slang_spec_mat3
:
417 case slang_spec_mat4
:
424 /* _slang_type_is_vector() */
426 GLboolean
_slang_type_is_vector (slang_type_specifier_type ty
)
430 case slang_spec_vec2
:
431 case slang_spec_vec3
:
432 case slang_spec_vec4
:
433 case slang_spec_ivec2
:
434 case slang_spec_ivec3
:
435 case slang_spec_ivec4
:
436 case slang_spec_bvec2
:
437 case slang_spec_bvec3
:
438 case slang_spec_bvec4
:
445 /* _slang_type_base_of_vector() */
447 slang_type_specifier_type
_slang_type_base (slang_type_specifier_type ty
)
451 case slang_spec_float
:
452 case slang_spec_vec2
:
453 case slang_spec_vec3
:
454 case slang_spec_vec4
:
455 return slang_spec_float
;
457 case slang_spec_ivec2
:
458 case slang_spec_ivec3
:
459 case slang_spec_ivec4
:
460 return slang_spec_int
;
461 case slang_spec_bool
:
462 case slang_spec_bvec2
:
463 case slang_spec_bvec3
:
464 case slang_spec_bvec4
:
465 return slang_spec_bool
;
466 case slang_spec_mat2
:
467 return slang_spec_vec2
;
468 case slang_spec_mat3
:
469 return slang_spec_vec3
;
470 case slang_spec_mat4
:
471 return slang_spec_vec4
;
473 return slang_spec_void
;
477 /* _slang_type_dim */
479 GLuint
_slang_type_dim (slang_type_specifier_type ty
)
483 case slang_spec_float
:
485 case slang_spec_bool
:
487 case slang_spec_vec2
:
488 case slang_spec_ivec2
:
489 case slang_spec_bvec2
:
490 case slang_spec_mat2
:
492 case slang_spec_vec3
:
493 case slang_spec_ivec3
:
494 case slang_spec_bvec3
:
495 case slang_spec_mat3
:
497 case slang_spec_vec4
:
498 case slang_spec_ivec4
:
499 case slang_spec_bvec4
:
500 case slang_spec_mat4
: