⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slang_compile.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Mesa 3-D graphics library * Version:  6.5.2 * * 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_compile.c * slang front-end compiler * \author Michal Krol */#include "main/imports.h"#include "main/context.h"#include "shader/program.h"#include "shader/programopt.h"#include "shader/prog_print.h"#include "shader/prog_parameter.h"#include "shader/grammar/grammar_mesa.h"#include "slang_codegen.h"#include "slang_compile.h"#include "slang_preprocess.h"#include "slang_storage.h"#include "slang_emit.h"#include "slang_log.h"#include "slang_mem.h"#include "slang_vartable.h"#include "slang_simplify.h"#include "slang_print.h"/* * This is a straightforward implementation of the slang front-end * compiler.  Lots of error-checking functionality is missing but * every well-formed shader source should compile successfully and * execute as expected. However, some semantically ill-formed shaders * may be accepted resulting in undefined behaviour. *//** re-defined below, should be the same though */#define TYPE_SPECIFIER_COUNT 32/** * Check if the given identifier is legal. */static GLbooleanlegal_identifier(slang_atom name){   /* "gl_" is a reserved prefix */   if (_mesa_strncmp((char *) name, "gl_", 3) == 0) {      return GL_FALSE;   }   return GL_TRUE;}/** * Allocate storage for a variable of 'size' bytes from given pool. * Return the allocated address for the variable. */static GLuintslang_var_pool_alloc(slang_var_pool * pool, unsigned int size){   const GLuint addr = pool->next_addr;   pool->next_addr += size;   return addr;}/* * slang_code_unit */GLvoid_slang_code_unit_ctr(slang_code_unit * self,                     struct slang_code_object_ * object){   _slang_variable_scope_ctr(&self->vars);   _slang_function_scope_ctr(&self->funs);   _slang_struct_scope_ctr(&self->structs);   self->object = object;}GLvoid_slang_code_unit_dtr(slang_code_unit * self){   slang_variable_scope_destruct(&self->vars);   slang_function_scope_destruct(&self->funs);   slang_struct_scope_destruct(&self->structs);}/* * slang_code_object */GLvoid_slang_code_object_ctr(slang_code_object * self){   GLuint i;   for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)      _slang_code_unit_ctr(&self->builtin[i], self);   _slang_code_unit_ctr(&self->unit, self);   self->varpool.next_addr = 0;   slang_atom_pool_construct(&self->atompool);}GLvoid_slang_code_object_dtr(slang_code_object * self){   GLuint i;   for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)      _slang_code_unit_dtr(&self->builtin[i]);   _slang_code_unit_dtr(&self->unit);   slang_atom_pool_destruct(&self->atompool);}/* slang_parse_ctx */typedef struct slang_parse_ctx_{   const byte *I;   slang_info_log *L;   int parsing_builtin;   GLboolean global_scope;   /**< Is object being declared a global? */   slang_atom_pool *atoms;   slang_unit_type type;     /**< Vertex vs. Fragment */   GLuint version;           /**< user-specified (or default) #version */} slang_parse_ctx;/* slang_output_ctx */typedef struct slang_output_ctx_{   slang_variable_scope *vars;   slang_function_scope *funs;   slang_struct_scope *structs;   slang_var_pool *global_pool;   struct gl_program *program;   slang_var_table *vartable;   GLuint default_precision[TYPE_SPECIFIER_COUNT];} slang_output_ctx;/* _slang_compile() */static voidparse_identifier_str(slang_parse_ctx * C, char **id){   *id = (char *) C->I;   C->I += _mesa_strlen(*id) + 1;}static slang_atomparse_identifier(slang_parse_ctx * C){   const char *id;   id = (const char *) C->I;   C->I += _mesa_strlen(id) + 1;   return slang_atom_pool_atom(C->atoms, id);}static intparse_number(slang_parse_ctx * C, int *number){   const int radix = (int) (*C->I++);   *number = 0;   while (*C->I != '\0') {      int digit;      if (*C->I >= '0' && *C->I <= '9')         digit = (int) (*C->I - '0');      else if (*C->I >= 'A' && *C->I <= 'Z')         digit = (int) (*C->I - 'A') + 10;      else         digit = (int) (*C->I - 'a') + 10;      *number = *number * radix + digit;      C->I++;   }   C->I++;   if (*number > 65535)      slang_info_log_warning(C->L, "%d: literal integer overflow.", *number);   return 1;}static intparse_float(slang_parse_ctx * C, float *number){   char *integral = NULL;   char *fractional = NULL;   char *exponent = NULL;   char *whole = NULL;   parse_identifier_str(C, &integral);   parse_identifier_str(C, &fractional);   parse_identifier_str(C, &exponent);   whole = (char *) _slang_alloc((_mesa_strlen(integral) +                                  _mesa_strlen(fractional) +                                  _mesa_strlen(exponent) + 3) * sizeof(char));   if (whole == NULL) {      slang_info_log_memory(C->L);      return 0;   }   slang_string_copy(whole, integral);   slang_string_concat(whole, ".");   slang_string_concat(whole, fractional);   slang_string_concat(whole, "E");   slang_string_concat(whole, exponent);   *number = (float) (_mesa_strtod(whole, (char **) NULL));   _slang_free(whole);   return 1;}/* revision number - increment after each change affecting emitted output */#define REVISION 4static intcheck_revision(slang_parse_ctx * C){   if (*C->I != REVISION) {      slang_info_log_error(C->L, "Internal compiler error.");      return 0;   }   C->I++;   return 1;}static int parse_statement(slang_parse_ctx *, slang_output_ctx *,                           slang_operation *);static int parse_expression(slang_parse_ctx *, slang_output_ctx *,                            slang_operation *);static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *,                                slang_type_specifier *);static GLbooleanparse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len){   slang_operation array_size;   slang_name_space space;   GLboolean result;   if (!slang_operation_construct(&array_size))      return GL_FALSE;   if (!parse_expression(C, O, &array_size)) {      slang_operation_destruct(&array_size);      return GL_FALSE;   }   space.funcs = O->funs;   space.structs = O->structs;   space.vars = O->vars;   /* evaluate compile-time expression which is array size */   _slang_simplify(&array_size, &space, C->atoms);   if (array_size.type == SLANG_OPER_LITERAL_INT) {      result = GL_TRUE;      *len = (GLint) array_size.literal[0];   } else if (array_size.type == SLANG_OPER_IDENTIFIER) {      slang_variable *var = _slang_locate_variable(array_size.locals, array_size.a_id, GL_TRUE);      if (!var) {         slang_info_log_error(C->L, "undefined variable '%s'",                              (char *) array_size.a_id);         result = GL_FALSE;      } else if (var->type.qualifier == SLANG_QUAL_CONST &&                 var->type.specifier.type == SLANG_SPEC_INT) {         if (var->initializer &&             var->initializer->type == SLANG_OPER_LITERAL_INT) {            *len = (GLint) var->initializer->literal[0];            result = GL_TRUE;         } else {            slang_info_log_error(C->L, "unable to parse array size declaration");            result = GL_FALSE;         }      } else {         slang_info_log_error(C->L, "unable to parse array size declaration");         result = GL_FALSE;      }   } else {      result = GL_FALSE;   }   slang_operation_destruct(&array_size);   return result;}static GLbooleancalculate_var_size(slang_parse_ctx * C, slang_output_ctx * O,                   slang_variable * var){   slang_storage_aggregate agg;   if (!slang_storage_aggregate_construct(&agg))      return GL_FALSE;   if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len,                                  O->funs, O->structs, O->vars, C->atoms)) {      slang_storage_aggregate_destruct(&agg);      return GL_FALSE;   }   var->size = _slang_sizeof_aggregate(&agg);   slang_storage_aggregate_destruct(&agg);   return GL_TRUE;}static GLbooleanconvert_to_array(slang_parse_ctx * C, slang_variable * var,                 const slang_type_specifier * sp){   /* sized array - mark it as array, copy the specifier to the array element and    * parse the expression */   var->type.specifier.type = SLANG_SPEC_ARRAY;   var->type.specifier._array = (slang_type_specifier *)      _slang_alloc(sizeof(slang_type_specifier));   if (var->type.specifier._array == NULL) {      slang_info_log_memory(C->L);      return GL_FALSE;   }   slang_type_specifier_ctr(var->type.specifier._array);   return slang_type_specifier_copy(var->type.specifier._array, sp);}/* structure field */#define FIELD_NONE 0#define FIELD_NEXT 1#define FIELD_ARRAY 2static GLbooleanparse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O,                       slang_variable * var, slang_atom a_name,                       const slang_type_specifier * sp){   var->a_name = a_name;   if (var->a_name == SLANG_ATOM_NULL)      return GL_FALSE;   switch (*C->I++) {   case FIELD_NONE:      if (!slang_type_specifier_copy(&var->type.specifier, sp))         return GL_FALSE;      break;   case FIELD_ARRAY:      if (!convert_to_array(C, var, sp))         return GL_FALSE;      if (!parse_array_len(C, O, &var->array_len))         return GL_FALSE;      break;   default:      return GL_FALSE;   }   return calculate_var_size(C, O, var);}static intparse_struct_field(slang_parse_ctx * C, slang_output_ctx * O,                   slang_struct * st, slang_type_specifier * sp){   slang_output_ctx o = *O;   o.structs = st->structs;   if (!parse_type_specifier(C, &o, sp))      return 0;   do {      slang_atom a_name;      slang_variable *var = slang_variable_scope_grow(st->fields);      if (!var) {         slang_info_log_memory(C->L);         return 0;      }      a_name = parse_identifier(C);      if (_slang_locate_variable(st->fields, a_name, GL_FALSE)) {         slang_info_log_error(C->L, "duplicate field '%s'", (char *) a_name);         return 0;      }      if (!parse_struct_field_var(C, &o, var, a_name, sp))         return 0;   }   while (*C->I++ != FIELD_NONE);   return 1;}static intparse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st){   slang_atom a_name;   const char *name;   /* parse struct name (if any) and make sure it is unique in current scope */   a_name = parse_identifier(C);   if (a_name == SLANG_ATOM_NULL)      return 0;   name = slang_atom_pool_id(C->atoms, a_name);   if (name[0] != '\0'       && slang_struct_scope_find(O->structs, a_name, 0) != NULL) {      slang_info_log_error(C->L, "%s: duplicate type name.", name);      return 0;   }   /* set-up a new struct */   *st = (slang_struct *) _slang_alloc(sizeof(slang_struct));   if (*st == NULL) {      slang_info_log_memory(C->L);      return 0;   }   if (!slang_struct_construct(*st)) {      _slang_free(*st);      *st = NULL;      slang_info_log_memory(C->L);      return 0;   }   (**st).a_name = a_name;   (**st).structs->outer_scope = O->structs;   /* parse individual struct fields */   do {      slang_type_specifier sp;      slang_type_specifier_ctr(&sp);      if (!parse_struct_field(C, O, *st, &sp)) {         slang_type_specifier_dtr(&sp);         return 0;      }      slang_type_specifier_dtr(&sp);   }   while (*C->I++ != FIELD_NONE);   /* if named struct, copy it to current scope */   if (name[0] != '\0') {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -