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_assemble.h"
33 #include "slang_compile.h"
36 * slang_type_specifier
39 GLvoid
slang_type_specifier_ctr (slang_type_specifier
*self
)
41 self
->type
= slang_spec_void
;
46 GLvoid
slang_type_specifier_dtr (slang_type_specifier
*self
)
48 if (self
->_struct
!= NULL
)
50 slang_struct_destruct (self
->_struct
);
51 slang_alloc_free (self
->_struct
);
53 if (self
->_array
!= NULL
)
55 slang_type_specifier_dtr (self
->_array
);
56 slang_alloc_free (self
->_array
);
60 GLboolean
slang_type_specifier_copy (slang_type_specifier
*x
, const slang_type_specifier
*y
)
62 slang_type_specifier z
;
64 slang_type_specifier_ctr (&z
);
66 if (z
.type
== slang_spec_struct
)
68 z
._struct
= (slang_struct
*) slang_alloc_malloc (sizeof (slang_struct
));
69 if (z
._struct
== NULL
)
71 slang_type_specifier_dtr (&z
);
74 if (!slang_struct_construct (z
._struct
))
76 slang_alloc_free (z
._struct
);
77 slang_type_specifier_dtr (&z
);
80 if (!slang_struct_copy (z
._struct
, y
->_struct
))
82 slang_type_specifier_dtr (&z
);
86 else if (z
.type
== slang_spec_array
)
88 z
._array
= (slang_type_specifier
*) slang_alloc_malloc (sizeof (slang_type_specifier
));
91 slang_type_specifier_dtr (&z
);
94 slang_type_specifier_ctr (z
._array
);
95 if (!slang_type_specifier_copy (z
._array
, y
->_array
))
97 slang_type_specifier_dtr (&z
);
101 slang_type_specifier_dtr (x
);
106 GLboolean
slang_type_specifier_equal (const slang_type_specifier
*x
, const slang_type_specifier
*y
)
108 if (x
->type
!= y
->type
)
110 if (x
->type
== slang_spec_struct
)
111 return slang_struct_equal (x
->_struct
, y
->_struct
);
112 if (x
->type
== slang_spec_array
)
113 return slang_type_specifier_equal (x
->_array
, y
->_array
);
117 /* slang_assembly_typeinfo */
119 GLboolean
slang_assembly_typeinfo_construct (slang_assembly_typeinfo
*ti
)
121 slang_type_specifier_ctr (&ti
->spec
);
126 GLvoid
slang_assembly_typeinfo_destruct (slang_assembly_typeinfo
*ti
)
128 slang_type_specifier_dtr (&ti
->spec
);
131 /* _slang_typeof_operation() */
133 static GLboolean
typeof_existing_function (const char *name
, slang_operation
*params
,
134 GLuint num_params
, slang_assembly_name_space
*space
, slang_type_specifier
*spec
,
135 slang_atom_pool
*atoms
)
140 atom
= slang_atom_pool_atom (atoms
, name
);
141 if (!_slang_typeof_function (atom
, params
, num_params
, space
, spec
, &exists
, atoms
))
146 GLboolean
_slang_typeof_operation (slang_assemble_ctx
*A
, slang_operation
*op
,
147 slang_assembly_typeinfo
*ti
)
149 return _slang_typeof_operation_ (op
, &A
->space
, ti
, A
->atoms
);
152 GLboolean
_slang_typeof_operation_ (slang_operation
*op
, slang_assembly_name_space
*space
,
153 slang_assembly_typeinfo
*ti
, slang_atom_pool
*atoms
)
155 ti
->can_be_referenced
= GL_FALSE
;
156 ti
->is_swizzled
= GL_FALSE
;
160 case slang_oper_block_no_new_scope
:
161 case slang_oper_block_new_scope
:
162 case slang_oper_variable_decl
:
164 case slang_oper_break
:
165 case slang_oper_continue
:
166 case slang_oper_discard
:
167 case slang_oper_return
:
169 case slang_oper_while
:
172 case slang_oper_void
:
173 ti
->spec
.type
= slang_spec_void
;
175 case slang_oper_expression
:
176 case slang_oper_assign
:
177 case slang_oper_addassign
:
178 case slang_oper_subassign
:
179 case slang_oper_mulassign
:
180 case slang_oper_divassign
:
181 case slang_oper_preincrement
:
182 case slang_oper_predecrement
:
183 if (!_slang_typeof_operation_ (op
->children
, space
, ti
, atoms
))
186 case slang_oper_literal_bool
:
187 case slang_oper_logicalor
:
188 case slang_oper_logicalxor
:
189 case slang_oper_logicaland
:
190 case slang_oper_equal
:
191 case slang_oper_notequal
:
192 case slang_oper_less
:
193 case slang_oper_greater
:
194 case slang_oper_lessequal
:
195 case slang_oper_greaterequal
:
197 ti
->spec
.type
= slang_spec_bool
;
199 case slang_oper_literal_int
:
200 ti
->spec
.type
= slang_spec_int
;
202 case slang_oper_literal_float
:
203 ti
->spec
.type
= slang_spec_float
;
205 case slang_oper_identifier
:
209 var
= _slang_locate_variable (op
->locals
, op
->a_id
, GL_TRUE
);
212 if (!slang_type_specifier_copy (&ti
->spec
, &var
->type
.specifier
))
214 ti
->can_be_referenced
= GL_TRUE
;
215 ti
->array_len
= var
->array_len
;
218 case slang_oper_sequence
:
219 /* TODO: check [0] and [1] if they match */
220 if (!_slang_typeof_operation_ (&op
->children
[1], space
, ti
, atoms
))
222 ti
->can_be_referenced
= GL_FALSE
;
223 ti
->is_swizzled
= GL_FALSE
;
225 /*case slang_oper_modassign:*/
226 /*case slang_oper_lshassign:*/
227 /*case slang_oper_rshassign:*/
228 /*case slang_oper_orassign:*/
229 /*case slang_oper_xorassign:*/
230 /*case slang_oper_andassign:*/
231 case slang_oper_select
:
232 /* TODO: check [1] and [2] if they match */
233 if (!_slang_typeof_operation_ (&op
->children
[1], space
, ti
, atoms
))
235 ti
->can_be_referenced
= GL_FALSE
;
236 ti
->is_swizzled
= GL_FALSE
;
238 /*case slang_oper_bitor:*/
239 /*case slang_oper_bitxor:*/
240 /*case slang_oper_bitand:*/
241 /*case slang_oper_lshift:*/
242 /*case slang_oper_rshift:*/
244 if (!typeof_existing_function ("+", op
->children
, 2, space
, &ti
->spec
, atoms
))
247 case slang_oper_subtract
:
248 if (!typeof_existing_function ("-", op
->children
, 2, space
, &ti
->spec
, atoms
))
251 case slang_oper_multiply
:
252 if (!typeof_existing_function ("*", op
->children
, 2, space
, &ti
->spec
, atoms
))
255 case slang_oper_divide
:
256 if (!typeof_existing_function ("/", op
->children
, 2, space
, &ti
->spec
, atoms
))
259 /*case slang_oper_modulus:*/
260 case slang_oper_plus
:
261 if (!_slang_typeof_operation_ (op
->children
, space
, ti
, atoms
))
263 ti
->can_be_referenced
= GL_FALSE
;
264 ti
->is_swizzled
= GL_FALSE
;
266 case slang_oper_minus
:
267 if (!typeof_existing_function ("-", op
->children
, 1, space
, &ti
->spec
, atoms
))
270 /*case slang_oper_complement:*/
271 case slang_oper_subscript
:
273 slang_assembly_typeinfo _ti
;
275 if (!slang_assembly_typeinfo_construct (&_ti
))
277 if (!_slang_typeof_operation_ (op
->children
, space
, &_ti
, atoms
))
279 slang_assembly_typeinfo_destruct (&_ti
);
282 ti
->can_be_referenced
= _ti
.can_be_referenced
;
283 if (_ti
.spec
.type
== slang_spec_array
)
285 if (!slang_type_specifier_copy (&ti
->spec
, _ti
.spec
._array
))
287 slang_assembly_typeinfo_destruct (&_ti
);
293 if (!_slang_type_is_vector (_ti
.spec
.type
) && !_slang_type_is_matrix (_ti
.spec
.type
))
295 slang_assembly_typeinfo_destruct (&_ti
);
298 ti
->spec
.type
= _slang_type_base (_ti
.spec
.type
);
300 slang_assembly_typeinfo_destruct (&_ti
);
303 case slang_oper_call
:
307 if (!_slang_typeof_function (op
->a_id
, op
->children
, op
->num_children
, space
, &ti
->spec
,
312 slang_struct
*s
= slang_struct_scope_find (space
->structs
, op
->a_id
, GL_TRUE
);
315 ti
->spec
.type
= slang_spec_struct
;
316 ti
->spec
._struct
= (slang_struct
*) slang_alloc_malloc (sizeof (slang_struct
));
317 if (ti
->spec
._struct
== NULL
)
319 if (!slang_struct_construct (ti
->spec
._struct
))
321 slang_alloc_free (ti
->spec
._struct
);
322 ti
->spec
._struct
= NULL
;
325 if (!slang_struct_copy (ti
->spec
._struct
, s
))
331 slang_type_specifier_type type
;
333 name
= slang_atom_pool_id (atoms
, op
->a_id
);
334 type
= slang_type_specifier_type_from_string (name
);
335 if (type
== slang_spec_void
)
337 ti
->spec
.type
= type
;
342 case slang_oper_field
:
344 slang_assembly_typeinfo _ti
;
346 if (!slang_assembly_typeinfo_construct (&_ti
))
348 if (!_slang_typeof_operation_ (op
->children
, space
, &_ti
, atoms
))
350 slang_assembly_typeinfo_destruct (&_ti
);
353 if (_ti
.spec
.type
== slang_spec_struct
)
355 slang_variable
*field
;
357 field
= _slang_locate_variable (_ti
.spec
._struct
->fields
, op
->a_id
, GL_FALSE
);
360 slang_assembly_typeinfo_destruct (&_ti
);
363 if (!slang_type_specifier_copy (&ti
->spec
, &field
->type
.specifier
))
365 slang_assembly_typeinfo_destruct (&_ti
);
368 ti
->can_be_referenced
= _ti
.can_be_referenced
;
374 slang_type_specifier_type base
;
376 /* determine the swizzle of the field expression */
377 if (!_slang_type_is_vector (_ti
.spec
.type
))
379 slang_assembly_typeinfo_destruct (&_ti
);
382 rows
= _slang_type_dim (_ti
.spec
.type
);
383 swizzle
= slang_atom_pool_id (atoms
, op
->a_id
);
384 if (!_slang_is_swizzle (swizzle
, rows
, &ti
->swz
))
386 slang_assembly_typeinfo_destruct (&_ti
);
389 ti
->is_swizzled
= GL_TRUE
;
390 ti
->can_be_referenced
= _ti
.can_be_referenced
&& _slang_is_swizzle_mask (&ti
->swz
,
396 /* swizzle the swizzle */
397 _slang_multiply_swizzles (&swz
, &_ti
.swz
, &ti
->swz
);
400 base
= _slang_type_base (_ti
.spec
.type
);
401 switch (ti
->swz
.num_components
)
404 ti
->spec
.type
= base
;
409 case slang_spec_float
:
410 ti
->spec
.type
= slang_spec_vec2
;
413 ti
->spec
.type
= slang_spec_ivec2
;
415 case slang_spec_bool
:
416 ti
->spec
.type
= slang_spec_bvec2
;
425 case slang_spec_float
:
426 ti
->spec
.type
= slang_spec_vec3
;
429 ti
->spec
.type
= slang_spec_ivec3
;
431 case slang_spec_bool
:
432 ti
->spec
.type
= slang_spec_bvec3
;
441 case slang_spec_float
:
442 ti
->spec
.type
= slang_spec_vec4
;
445 ti
->spec
.type
= slang_spec_ivec4
;
447 case slang_spec_bool
:
448 ti
->spec
.type
= slang_spec_bvec4
;
458 slang_assembly_typeinfo_destruct (&_ti
);
461 case slang_oper_postincrement
:
462 case slang_oper_postdecrement
:
463 if (!_slang_typeof_operation_ (op
->children
, space
, ti
, atoms
))
465 ti
->can_be_referenced
= GL_FALSE
;
466 ti
->is_swizzled
= GL_FALSE
;
475 /* _slang_typeof_function() */
477 GLboolean
_slang_typeof_function (slang_atom a_name
, slang_operation
*params
, GLuint num_params
,
478 slang_assembly_name_space
*space
, slang_type_specifier
*spec
, GLboolean
*exists
,
479 slang_atom_pool
*atoms
)
483 fun
= _slang_locate_function (space
->funcs
, a_name
, params
, num_params
, space
, atoms
);
484 *exists
= fun
!= NULL
;
487 return slang_type_specifier_copy (spec
, &fun
->header
.type
.specifier
);
490 /* _slang_type_is_matrix() */
492 GLboolean
_slang_type_is_matrix (slang_type_specifier_type ty
)
496 case slang_spec_mat2
:
497 case slang_spec_mat3
:
498 case slang_spec_mat4
:
505 /* _slang_type_is_vector() */
507 GLboolean
_slang_type_is_vector (slang_type_specifier_type ty
)
511 case slang_spec_vec2
:
512 case slang_spec_vec3
:
513 case slang_spec_vec4
:
514 case slang_spec_ivec2
:
515 case slang_spec_ivec3
:
516 case slang_spec_ivec4
:
517 case slang_spec_bvec2
:
518 case slang_spec_bvec3
:
519 case slang_spec_bvec4
:
526 /* _slang_type_base_of_vector() */
528 slang_type_specifier_type
_slang_type_base (slang_type_specifier_type ty
)
532 case slang_spec_float
:
533 case slang_spec_vec2
:
534 case slang_spec_vec3
:
535 case slang_spec_vec4
:
536 return slang_spec_float
;
538 case slang_spec_ivec2
:
539 case slang_spec_ivec3
:
540 case slang_spec_ivec4
:
541 return slang_spec_int
;
542 case slang_spec_bool
:
543 case slang_spec_bvec2
:
544 case slang_spec_bvec3
:
545 case slang_spec_bvec4
:
546 return slang_spec_bool
;
547 case slang_spec_mat2
:
548 return slang_spec_vec2
;
549 case slang_spec_mat3
:
550 return slang_spec_vec3
;
551 case slang_spec_mat4
:
552 return slang_spec_vec4
;
554 return slang_spec_void
;
558 /* _slang_type_dim */
560 GLuint
_slang_type_dim (slang_type_specifier_type ty
)
564 case slang_spec_float
:
566 case slang_spec_bool
:
568 case slang_spec_vec2
:
569 case slang_spec_ivec2
:
570 case slang_spec_bvec2
:
571 case slang_spec_mat2
:
573 case slang_spec_vec3
:
574 case slang_spec_ivec3
:
575 case slang_spec_bvec3
:
576 case slang_spec_mat3
:
578 case slang_spec_vec4
:
579 case slang_spec_ivec4
:
580 case slang_spec_bvec4
:
581 case slang_spec_mat4
: