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

📄 slang_compile.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
#define PARAMETER_NONE 0#define PARAMETER_NEXT 1/* operator type */#define OPERATOR_ADDASSIGN 1#define OPERATOR_SUBASSIGN 2#define OPERATOR_MULASSIGN 3#define OPERATOR_DIVASSIGN 4/*#define OPERATOR_MODASSIGN 5*//*#define OPERATOR_LSHASSIGN 6*//*#define OPERATOR_RSHASSIGN 7*//*#define OPERATOR_ANDASSIGN 8*//*#define OPERATOR_XORASSIGN 9*//*#define OPERATOR_ORASSIGN 10*/#define OPERATOR_LOGICALXOR 11/*#define OPERATOR_BITOR 12*//*#define OPERATOR_BITXOR 13*//*#define OPERATOR_BITAND 14*/#define OPERATOR_LESS 15#define OPERATOR_GREATER 16#define OPERATOR_LESSEQUAL 17#define OPERATOR_GREATEREQUAL 18/*#define OPERATOR_LSHIFT 19*//*#define OPERATOR_RSHIFT 20*/#define OPERATOR_MULTIPLY 21#define OPERATOR_DIVIDE 22/*#define OPERATOR_MODULUS 23*/#define OPERATOR_INCREMENT 24#define OPERATOR_DECREMENT 25#define OPERATOR_PLUS 26#define OPERATOR_MINUS 27/*#define OPERATOR_COMPLEMENT 28*/#define OPERATOR_NOT 29static const struct{   unsigned int o_code;   const char *o_name;} operator_names[] = {   {OPERATOR_INCREMENT, "++"},   {OPERATOR_ADDASSIGN, "+="},   {OPERATOR_PLUS, "+"},   {OPERATOR_DECREMENT, "--"},   {OPERATOR_SUBASSIGN, "-="},   {OPERATOR_MINUS, "-"},   {OPERATOR_NOT, "!"},   {OPERATOR_MULASSIGN, "*="},   {OPERATOR_MULTIPLY, "*"},   {OPERATOR_DIVASSIGN, "/="},   {OPERATOR_DIVIDE, "/"},   {OPERATOR_LESSEQUAL, "<="},   /*{ OPERATOR_LSHASSIGN, "<<=" }, */   /*{ OPERATOR_LSHIFT, "<<" }, */   {OPERATOR_LESS, "<"},   {OPERATOR_GREATEREQUAL, ">="},   /*{ OPERATOR_RSHASSIGN, ">>=" }, */   /*{ OPERATOR_RSHIFT, ">>" }, */   {OPERATOR_GREATER, ">"},   /*{ OPERATOR_MODASSIGN, "%=" }, */   /*{ OPERATOR_MODULUS, "%" }, */   /*{ OPERATOR_ANDASSIGN, "&=" }, */   /*{ OPERATOR_BITAND, "&" }, */   /*{ OPERATOR_ORASSIGN, "|=" }, */   /*{ OPERATOR_BITOR, "|" }, */   /*{ OPERATOR_COMPLEMENT, "~" }, */   /*{ OPERATOR_XORASSIGN, "^=" }, */   {OPERATOR_LOGICALXOR, "^^"},   /*{ OPERATOR_BITXOR, "^" } */};static slang_atomparse_operator_name(slang_parse_ctx * C){   unsigned int i;   for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) {      if (operator_names[i].o_code == (unsigned int) (*C->I)) {         slang_atom atom =            slang_atom_pool_atom(C->atoms, operator_names[i].o_name);         if (atom == SLANG_ATOM_NULL) {            slang_info_log_memory(C->L);            return 0;         }         C->I++;         return atom;      }   }   return 0;}static intparse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,                         slang_function * func){   /* parse function type and name */   if (!parse_fully_specified_type(C, O, &func->header.type))      return 0;   switch (*C->I++) {   case FUNCTION_ORDINARY:      func->kind = SLANG_FUNC_ORDINARY;      func->header.a_name = parse_identifier(C);      if (func->header.a_name == SLANG_ATOM_NULL)         return 0;      break;   case FUNCTION_CONSTRUCTOR:      func->kind = SLANG_FUNC_CONSTRUCTOR;      if (func->header.type.specifier.type == SLANG_SPEC_STRUCT)         return 0;      func->header.a_name =         slang_atom_pool_atom(C->atoms,                              slang_type_specifier_type_to_string                              (func->header.type.specifier.type));      if (func->header.a_name == SLANG_ATOM_NULL) {         slang_info_log_memory(C->L);         return 0;      }      break;   case FUNCTION_OPERATOR:      func->kind = SLANG_FUNC_OPERATOR;      func->header.a_name = parse_operator_name(C);      if (func->header.a_name == SLANG_ATOM_NULL)         return 0;      break;   default:      return 0;   }   if (!legal_identifier(func->header.a_name)) {      slang_info_log_error(C->L, "illegal function name '%s'",                           (char *) func->header.a_name);      return 0;   }   /* parse function parameters */   while (*C->I++ == PARAMETER_NEXT) {      slang_variable *p = slang_variable_scope_grow(func->parameters);      if (!p) {         slang_info_log_memory(C->L);         return 0;      }      if (!parse_parameter_declaration(C, O, p))         return 0;   }   /* if the function returns a value, append a hidden __retVal 'out'    * parameter that corresponds to the return value.    */   if (_slang_function_has_return_value(func)) {      slang_variable *p = slang_variable_scope_grow(func->parameters);      slang_atom a_retVal = slang_atom_pool_atom(C->atoms, "__retVal");      assert(a_retVal);      p->a_name = a_retVal;      p->type = func->header.type;      p->type.qualifier = SLANG_QUAL_OUT;   }   /* function formal parameters and local variables share the same    * scope, so save the information about param count in a seperate    * place also link the scope to the global variable scope so when a    * given identifier is not found here, the search process continues    * in the global space    */   func->param_count = func->parameters->num_variables;   func->parameters->outer_scope = O->vars;   return 1;}static intparse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,                          slang_function * func){   slang_output_ctx o = *O;   if (!parse_function_prototype(C, O, func))      return 0;   /* create function's body operation */   func->body = (slang_operation *) _slang_alloc(sizeof(slang_operation));   if (func->body == NULL) {      slang_info_log_memory(C->L);      return 0;   }   if (!slang_operation_construct(func->body)) {      _slang_free(func->body);      func->body = NULL;      slang_info_log_memory(C->L);      return 0;   }   /* to parse the body the parse context is modified in order to    * capture parsed variables into function's local variable scope    */   C->global_scope = GL_FALSE;   o.vars = func->parameters;   if (!parse_statement(C, &o, func->body))      return 0;   C->global_scope = GL_TRUE;   return 1;}static GLbooleaninitialize_global(slang_assemble_ctx * A, slang_variable * var){   slang_operation op_id, op_assign;   GLboolean result;   /* construct the left side of assignment */   if (!slang_operation_construct(&op_id))      return GL_FALSE;   op_id.type = SLANG_OPER_IDENTIFIER;   op_id.a_id = var->a_name;   /* put the variable into operation's scope */   op_id.locals->variables =      (slang_variable **) _slang_alloc(sizeof(slang_variable *));   if (op_id.locals->variables == NULL) {      slang_operation_destruct(&op_id);      return GL_FALSE;   }   op_id.locals->num_variables = 1;   op_id.locals->variables[0] = var;   /* construct the assignment expression */   if (!slang_operation_construct(&op_assign)) {      op_id.locals->num_variables = 0;      slang_operation_destruct(&op_id);      return GL_FALSE;   }   op_assign.type = SLANG_OPER_ASSIGN;   op_assign.children =      (slang_operation *) _slang_alloc(2 * sizeof(slang_operation));   if (op_assign.children == NULL) {      slang_operation_destruct(&op_assign);      op_id.locals->num_variables = 0;      slang_operation_destruct(&op_id);      return GL_FALSE;   }   op_assign.num_children = 2;   op_assign.children[0] = op_id;   op_assign.children[1] = *var->initializer;   result = 1;   /* carefully destroy the operations */   op_assign.num_children = 0;   _slang_free(op_assign.children);   op_assign.children = NULL;   slang_operation_destruct(&op_assign);   op_id.locals->num_variables = 0;   slang_operation_destruct(&op_id);   if (!result)      return GL_FALSE;   return GL_TRUE;}/* init declarator list */#define DECLARATOR_NONE 0#define DECLARATOR_NEXT 1/* variable declaration */#define VARIABLE_NONE 0#define VARIABLE_IDENTIFIER 1#define VARIABLE_INITIALIZER 2#define VARIABLE_ARRAY_EXPLICIT 3#define VARIABLE_ARRAY_UNKNOWN 4/** * Parse the initializer for a variable declaration. */static intparse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,                      const slang_fully_specified_type * type){   slang_variable *var;   slang_atom a_name;   /* empty init declatator (without name, e.g. "float ;") */   if (*C->I++ == VARIABLE_NONE)      return 1;   a_name = parse_identifier(C);   /* check if name is already in this scope */   if (_slang_locate_variable(O->vars, a_name, GL_FALSE)) {      slang_info_log_error(C->L,                   "declaration of '%s' conflicts with previous declaration",                   (char *) a_name);      return 0;   }   /* make room for the new variable and initialize it */   var = slang_variable_scope_grow(O->vars);   if (!var) {      slang_info_log_memory(C->L);      return 0;   }   /* copy the declarator qualifier type, parse the identifier */   var->type.qualifier = type->qualifier;   var->a_name = a_name;   if (var->a_name == SLANG_ATOM_NULL)      return 0;   switch (*C->I++) {   case VARIABLE_NONE:      /* simple variable declarator - just copy the specifier */      if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))         return 0;      break;   case VARIABLE_INITIALIZER:      /* initialized variable - copy the specifier and parse the expression */      if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))         return 0;      var->initializer =         (slang_operation *) _slang_alloc(sizeof(slang_operation));      if (var->initializer == NULL) {         slang_info_log_memory(C->L);         return 0;      }      if (!slang_operation_construct(var->initializer)) {         _slang_free(var->initializer);         var->initializer = NULL;         slang_info_log_memory(C->L);         return 0;      }      if (!parse_expression(C, O, var->initializer))         return 0;      break;   case VARIABLE_ARRAY_UNKNOWN:      /* unsized array - mark it as array and copy the specifier to         the array element      */      if (!convert_to_array(C, var, &type->specifier))         return GL_FALSE;      break;   case VARIABLE_ARRAY_EXPLICIT:      if (!convert_to_array(C, var, &type->specifier))         return GL_FALSE;      if (!parse_array_len(C, O, &var->array_len))         return GL_FALSE;      break;   default:      return 0;   }   /* allocate global address space for a variable with a known size */   if (C->global_scope       && !(var->type.specifier.type == SLANG_SPEC_ARRAY            && var->array_len == 0)) {      if (!calculate_var_size(C, O, var))         return GL_FALSE;      var->address = slang_var_pool_alloc(O->global_pool, var->size);   }   /* emit code for global var decl */   if (C->global_scope) {      slang_assemble_ctx A;      A.atoms = C->atoms;      A.space.funcs = O->funs;      A.space.structs = O->structs;      A.space.vars = O->vars;      A.program = O->program;      A.vartable = O->vartable;      A.log = C->L;      A.curFuncEndLabel = NULL;      if (!_slang_codegen_global_variable(&A, var, C->type))         return 0;   }   /* initialize global variable */   if (C->global_scope) {      if (var->initializer != NULL) {         slang_assemble_ctx A;         A.atoms = C->atoms;         A.space.funcs = O->funs;         A.space.structs = O->structs;         A.space.vars = O->vars;         if (!initialize_global(&A, var))            return 0;      }   }   return 1;}/** * Parse a list of variable declarations.  Each variable may have an * initializer. */static intparse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O){   slang_fully_specified_type type;   /* parse the fully specified type, common to all declarators */   if (!slang_fully_specified_type_construct(&type))      return 0;   if (!parse_fully_specified_type(C, O, &type)) {      slang_fully_specified_type_destruct(&type);      return 0;   }   /* parse declarators, pass-in the parsed type */   do {      if (!parse_init_declarator(C, O, &type)) {         slang_fully_specified_type_destruct(&type);         return 0;      }   }   while (*C->I++ == DECLARATOR_NEXT);   slang_fully_specified_type_destruct(&type);   return 1;}/** * Parse a function definition or declaration. * \param C  parsing context * \param O  output context * \param definition if non-zero expect a definition, else a declaration * \param parsed_func_ret  returns the parsed function * \return GL_TRUE if success, GL_FALSE if failure */static GLbooleanparse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,               slang_function ** parsed_func_ret){   slang_function parsed_func, *found_func;   /* parse function definition/declaration */   if (!slang_function_construct(&parsed_func))      return GL_FALSE;   if (definition) {      if (!parse_function_definition(C, O, &parsed_func)) {         slang_function_destruct(&parsed_func);         return GL_FALSE;      }   }   else {      if (!parse_function_prototype(C, O, &parsed_func)) {         slang_function_destruct(&parsed_func);         return GL_FALSE;      }   }   /* find a function with a prototype matching the parsed one - only    * the current scope is being searched to allow built-in function    * overriding    */   found_func = slang_function_scope_find(O->funs, &parsed_func, 0);

⌨️ 快捷键说明

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