📄 slang_typeinfo.c
字号:
return GL_TRUE; } return GL_FALSE; }}GLboolean_slang_typeof_operation(const slang_assemble_ctx * A, slang_operation * op, slang_typeinfo * ti){ return _slang_typeof_operation_(op, &A->space, ti, A->atoms, A->log);}/** * Determine the return type of an operation. * \param op the operation node * \param space the namespace to use * \param ti the returned type * \param atoms atom pool * \return GL_TRUE for success, GL_FALSE if failure */GLboolean_slang_typeof_operation_(slang_operation * op, const slang_name_space * space, slang_typeinfo * ti, slang_atom_pool * atoms, slang_info_log *log){ 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_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, log)) return GL_FALSE; break; case SLANG_OPER_LITERAL_BOOL: if (op->literal_size == 1) ti->spec.type = SLANG_SPEC_BOOL; else if (op->literal_size == 2) ti->spec.type = SLANG_SPEC_BVEC2; else if (op->literal_size == 3) ti->spec.type = SLANG_SPEC_BVEC3; else if (op->literal_size == 4) ti->spec.type = SLANG_SPEC_BVEC4; else { _mesa_problem(NULL, "Unexpected bool literal_size %d in _slang_typeof_operation()", op->literal_size); ti->spec.type = SLANG_SPEC_BOOL; } break; 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: if (op->literal_size == 1) ti->spec.type = SLANG_SPEC_INT; else if (op->literal_size == 2) ti->spec.type = SLANG_SPEC_IVEC2; else if (op->literal_size == 3) ti->spec.type = SLANG_SPEC_IVEC3; else if (op->literal_size == 4) ti->spec.type = SLANG_SPEC_IVEC4; else { _mesa_problem(NULL, "Unexpected int literal_size %d in _slang_typeof_operation()", op->literal_size); ti->spec.type = SLANG_SPEC_INT; } break; case SLANG_OPER_LITERAL_FLOAT: if (op->literal_size == 1) ti->spec.type = SLANG_SPEC_FLOAT; else if (op->literal_size == 2) ti->spec.type = SLANG_SPEC_VEC2; else if (op->literal_size == 3) ti->spec.type = SLANG_SPEC_VEC3; else if (op->literal_size == 4) ti->spec.type = SLANG_SPEC_VEC4; else { _mesa_problem(NULL, "Unexpected float literal_size %d in _slang_typeof_operation()", op->literal_size); ti->spec.type = SLANG_SPEC_FLOAT; } break; case SLANG_OPER_IDENTIFIER: case SLANG_OPER_VARIABLE_DECL: { slang_variable *var; var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); if (!var) { slang_info_log_error(log, "undefined variable '%s'", (char *) op->a_id); return GL_FALSE; } if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) { slang_info_log_memory(log); 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, log)) { 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, log)) { 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: assert(op->num_children == 2); if (!typeof_math_call("+", op, space, &ti->spec, atoms, log)) return GL_FALSE; break; case SLANG_OPER_SUBTRACT: assert(op->num_children == 2); if (!typeof_math_call("-", op, space, &ti->spec, atoms, log)) return GL_FALSE; break; case SLANG_OPER_MULTIPLY: assert(op->num_children == 2); if (!typeof_math_call("*", op, space, &ti->spec, atoms, log)) return GL_FALSE; break; case SLANG_OPER_DIVIDE: assert(op->num_children == 2); if (!typeof_math_call("/", op, space, &ti->spec, atoms, log)) return GL_FALSE; break; /*case SLANG_OPER_MODULUS: */ case SLANG_OPER_PLUS: if (!_slang_typeof_operation_(op->children, space, ti, atoms, log)) return GL_FALSE; ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; case SLANG_OPER_MINUS: assert(op->num_children == 1); if (!typeof_math_call("-", op, space, &ti->spec, atoms, log)) return GL_FALSE; break; /*case SLANG_OPER_COMPLEMENT: */ case SLANG_OPER_SUBSCRIPT: { slang_typeinfo _ti; if (!slang_typeinfo_construct(&_ti)) return GL_FALSE; if (!_slang_typeof_operation_(op->children, space, &_ti, atoms, log)) { slang_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_typeinfo_destruct(&_ti); return GL_FALSE; } } else { if (!_slang_type_is_vector(_ti.spec.type) && !_slang_type_is_matrix(_ti.spec.type)) { slang_typeinfo_destruct(&_ti); slang_info_log_error(log, "cannot index a non-array type"); return GL_FALSE; } ti->spec.type = _slang_type_base(_ti.spec.type); } slang_typeinfo_destruct(&_ti); } break; case SLANG_OPER_CALL: if (op->fun) { /* we've resolved this call before */ slang_type_specifier_copy(&ti->spec, &op->fun->header.type.specifier); } else { slang_function *fun; if (!_slang_typeof_function(op->a_id, op->children, op->num_children, space, &ti->spec, &fun, atoms, log)) return GL_FALSE; if (fun) { /* save result for future use */ op->fun = fun; } else { slang_struct *s = slang_struct_scope_find(space->structs, op->a_id, GL_TRUE); if (s) { /* struct initializer */ ti->spec.type = SLANG_SPEC_STRUCT; ti->spec._struct = (slang_struct *) _slang_alloc(sizeof(slang_struct)); if (ti->spec._struct == NULL) return GL_FALSE; if (!slang_struct_construct(ti->spec._struct)) { _slang_free(ti->spec._struct); ti->spec._struct = NULL; return GL_FALSE; } if (!slang_struct_copy(ti->spec._struct, s)) return GL_FALSE; } else { /* float, int, vec4, mat3, etc. constructor? */ const char *name; slang_type_specifier_type type; name = slang_atom_pool_id(atoms, op->a_id); type = slang_type_specifier_type_from_string(name); if (type == SLANG_SPEC_VOID) { slang_info_log_error(log, "undefined function '%s'", name); return GL_FALSE; } ti->spec.type = type; } } } break; case SLANG_OPER_FIELD: { slang_typeinfo _ti; if (!slang_typeinfo_construct(&_ti)) return GL_FALSE; if (!_slang_typeof_operation_(op->children, space, &_ti, atoms, log)) { slang_typeinfo_destruct(&_ti); return GL_FALSE; } if (_ti.spec.type == SLANG_SPEC_STRUCT) { slang_variable *field; field = _slang_locate_variable(_ti.spec._struct->fields, op->a_id, GL_FALSE); if (field == NULL) { slang_typeinfo_destruct(&_ti); return GL_FALSE; } if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) { slang_typeinfo_destruct(&_ti); return GL_FALSE; } ti->can_be_referenced = _ti.can_be_referenced; } else { GLuint rows; const char *swizzle; slang_type_specifier_type base; /* determine the swizzle of the field expression */ if (!_slang_type_is_vector(_ti.spec.type)) { slang_typeinfo_destruct(&_ti); slang_info_log_error(log, "Can't swizzle scalar expression"); return GL_FALSE; } rows = _slang_type_dim(_ti.spec.type); swizzle = slang_atom_pool_id(atoms, op->a_id); if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) { slang_typeinfo_destruct(&_ti); slang_info_log_error(log, "bad swizzle '%s'", swizzle); return GL_FALSE; } ti->is_swizzled = GL_TRUE; ti->can_be_referenced = _ti.can_be_referenced && _slang_is_swizzle_mask(&ti->swz, rows); if (_ti.is_swizzled) { slang_swizzle swz; /* swizzle the swizzle */ _slang_multiply_swizzles(&swz, &_ti.swz, &ti->swz); ti->swz = swz; } base = _slang_type_base(_ti.spec.type); switch (ti->swz.num_components) { case 1: ti->spec.type = base; break; case 2: switch (base) { case SLANG_SPEC_FLOAT: ti->spec.type = SLANG_SPEC_VEC2; break; case SLANG_SPEC_INT: ti->spec.type = SLANG_SPEC_IVEC2; break; case SLANG_SPEC_BOOL: ti->spec.type = SLANG_SPEC_BVEC2; break; default: break; } break; case 3: switch (base) { case SLANG_SPEC_FLOAT: ti->spec.type = SLANG_SPEC_VEC3; break; case SLANG_SPEC_INT: ti->spec.type = SLANG_SPEC_IVEC3; break; case SLANG_SPEC_BOOL: ti->spec.type = SLANG_SPEC_BVEC3; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -