📄 slang_assemble_typeinfo.c
字号:
/*
* Mesa 3-D graphics library
* Version: 6.5
*
* Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* \file slang_assemble_typeinfo.c
* slang type info
* \author Michal Krol
*/
#include "imports.h"
#include "slang_assemble.h"
#include "slang_compile.h"
/*
* slang_type_specifier
*/
GLvoid slang_type_specifier_ctr (slang_type_specifier *self)
{
self->type = slang_spec_void;
self->_struct = NULL;
self->_array = NULL;
}
GLvoid slang_type_specifier_dtr (slang_type_specifier *self)
{
if (self->_struct != NULL)
{
slang_struct_destruct (self->_struct);
slang_alloc_free (self->_struct);
}
if (self->_array != NULL)
{
slang_type_specifier_dtr (self->_array);
slang_alloc_free (self->_array);
}
}
GLboolean slang_type_specifier_copy (slang_type_specifier *x, const slang_type_specifier *y)
{
slang_type_specifier z;
slang_type_specifier_ctr (&z);
z.type = y->type;
if (z.type == slang_spec_struct)
{
z._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
if (z._struct == NULL)
{
slang_type_specifier_dtr (&z);
return GL_FALSE;
}
if (!slang_struct_construct (z._struct))
{
slang_alloc_free (z._struct);
slang_type_specifier_dtr (&z);
return GL_FALSE;
}
if (!slang_struct_copy (z._struct, y->_struct))
{
slang_type_specifier_dtr (&z);
return GL_FALSE;
}
}
else if (z.type == slang_spec_array)
{
z._array = (slang_type_specifier *) slang_alloc_malloc (sizeof (slang_type_specifier));
if (z._array == NULL)
{
slang_type_specifier_dtr (&z);
return GL_FALSE;
}
slang_type_specifier_ctr (z._array);
if (!slang_type_specifier_copy (z._array, y->_array))
{
slang_type_specifier_dtr (&z);
return GL_FALSE;
}
}
slang_type_specifier_dtr (x);
*x = z;
return GL_TRUE;
}
GLboolean slang_type_specifier_equal (const slang_type_specifier *x, const slang_type_specifier *y)
{
if (x->type != y->type)
return 0;
if (x->type == slang_spec_struct)
return slang_struct_equal (x->_struct, y->_struct);
if (x->type == slang_spec_array)
return slang_type_specifier_equal (x->_array, y->_array);
return 1;
}
/* slang_assembly_typeinfo */
GLboolean slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)
{
slang_type_specifier_ctr (&ti->spec);
ti->array_len = 0;
return GL_TRUE;
}
GLvoid slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti)
{
slang_type_specifier_dtr (&ti->spec);
}
/* _slang_typeof_operation() */
static GLboolean typeof_existing_function (const char *name, slang_operation *params,
GLuint num_params, slang_assembly_name_space *space, slang_type_specifier *spec,
slang_atom_pool *atoms)
{
slang_atom atom;
GLboolean exists;
atom = slang_atom_pool_atom (atoms, name);
if (!_slang_typeof_function (atom, params, num_params, space, spec, &exists, atoms))
return GL_FALSE;
return exists;
}
GLboolean _slang_typeof_operation (slang_assemble_ctx *A, slang_operation *op,
slang_assembly_typeinfo *ti)
{
return _slang_typeof_operation_ (op, &A->space, ti, A->atoms);
}
GLboolean _slang_typeof_operation_ (slang_operation *op, slang_assembly_name_space *space,
slang_assembly_typeinfo *ti, slang_atom_pool *atoms)
{
ti->can_be_referenced = GL_FALSE;
ti->is_swizzled = GL_FALSE;
switch (op->type)
{
case slang_oper_block_no_new_scope:
case slang_oper_block_new_scope:
case slang_oper_variable_decl:
case slang_oper_asm:
case slang_oper_break:
case slang_oper_continue:
case slang_oper_discard:
case slang_oper_return:
case slang_oper_if:
case slang_oper_while:
case slang_oper_do:
case slang_oper_for:
case slang_oper_void:
ti->spec.type = slang_spec_void;
break;
case slang_oper_expression:
case slang_oper_assign:
case slang_oper_addassign:
case slang_oper_subassign:
case slang_oper_mulassign:
case slang_oper_divassign:
case slang_oper_preincrement:
case slang_oper_predecrement:
if (!_slang_typeof_operation_ (op->children, space, ti, atoms))
return 0;
break;
case slang_oper_literal_bool:
case slang_oper_logicalor:
case slang_oper_logicalxor:
case slang_oper_logicaland:
case slang_oper_equal:
case slang_oper_notequal:
case slang_oper_less:
case slang_oper_greater:
case slang_oper_lessequal:
case slang_oper_greaterequal:
case slang_oper_not:
ti->spec.type = slang_spec_bool;
break;
case slang_oper_literal_int:
ti->spec.type = slang_spec_int;
break;
case slang_oper_literal_float:
ti->spec.type = slang_spec_float;
break;
case slang_oper_identifier:
{
slang_variable *var;
var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE);
if (var == NULL)
return GL_FALSE;
if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier))
return GL_FALSE;
ti->can_be_referenced = GL_TRUE;
ti->array_len = var->array_len;
}
break;
case slang_oper_sequence:
/* TODO: check [0] and [1] if they match */
if (!_slang_typeof_operation_ (&op->children[1], space, ti, atoms))
return GL_FALSE;
ti->can_be_referenced = GL_FALSE;
ti->is_swizzled = GL_FALSE;
break;
/*case slang_oper_modassign:*/
/*case slang_oper_lshassign:*/
/*case slang_oper_rshassign:*/
/*case slang_oper_orassign:*/
/*case slang_oper_xorassign:*/
/*case slang_oper_andassign:*/
case slang_oper_select:
/* TODO: check [1] and [2] if they match */
if (!_slang_typeof_operation_ (&op->children[1], space, ti, atoms))
return GL_FALSE;
ti->can_be_referenced = GL_FALSE;
ti->is_swizzled = GL_FALSE;
break;
/*case slang_oper_bitor:*/
/*case slang_oper_bitxor:*/
/*case slang_oper_bitand:*/
/*case slang_oper_lshift:*/
/*case slang_oper_rshift:*/
case slang_oper_add:
if (!typeof_existing_function ("+", op->children, 2, space, &ti->spec, atoms))
return GL_FALSE;
break;
case slang_oper_subtract:
if (!typeof_existing_function ("-", op->children, 2, space, &ti->spec, atoms))
return GL_FALSE;
break;
case slang_oper_multiply:
if (!typeof_existing_function ("*", op->children, 2, space, &ti->spec, atoms))
return GL_FALSE;
break;
case slang_oper_divide:
if (!typeof_existing_function ("/", op->children, 2, space, &ti->spec, atoms))
return GL_FALSE;
break;
/*case slang_oper_modulus:*/
case slang_oper_plus:
if (!_slang_typeof_operation_ (op->children, space, ti, atoms))
return GL_FALSE;
ti->can_be_referenced = GL_FALSE;
ti->is_swizzled = GL_FALSE;
break;
case slang_oper_minus:
if (!typeof_existing_function ("-", op->children, 1, space, &ti->spec, atoms))
return GL_FALSE;
break;
/*case slang_oper_complement:*/
case slang_oper_subscript:
{
slang_assembly_typeinfo _ti;
if (!slang_assembly_typeinfo_construct (&_ti))
return GL_FALSE;
if (!_slang_typeof_operation_ (op->children, space, &_ti, atoms))
{
slang_assembly_typeinfo_destruct (&_ti);
return GL_FALSE;
}
ti->can_be_referenced = _ti.can_be_referenced;
if (_ti.spec.type == slang_spec_array)
{
if (!slang_type_specifier_copy (&ti->spec, _ti.spec._array))
{
slang_assembly_typeinfo_destruct (&_ti);
return GL_FALSE;
}
}
else
{
if (!_slang_type_is_vector (_ti.spec.type) && !_slang_type_is_matrix (_ti.spec.type))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -