Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenslang_compile.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * 00004 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. 00005 * Copyright (C) 2008 VMware, Inc. All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00031 #include "main/imports.h" 00032 #include "main/context.h" 00033 #include "shader/program.h" 00034 #include "shader/programopt.h" 00035 #include "shader/prog_print.h" 00036 #include "shader/prog_parameter.h" 00037 #include "shader/grammar/grammar_mesa.h" 00038 #include "slang_codegen.h" 00039 #include "slang_compile.h" 00040 #include "slang_preprocess.h" 00041 #include "slang_storage.h" 00042 #include "slang_emit.h" 00043 #include "slang_log.h" 00044 #include "slang_mem.h" 00045 #include "slang_vartable.h" 00046 #include "slang_simplify.h" 00047 00048 #include "slang_print.h" 00049 00050 /* 00051 * This is a straightforward implementation of the slang front-end 00052 * compiler. Lots of error-checking functionality is missing but 00053 * every well-formed shader source should compile successfully and 00054 * execute as expected. However, some semantically ill-formed shaders 00055 * may be accepted resulting in undefined behaviour. 00056 */ 00057 00058 00060 #define TYPE_SPECIFIER_COUNT 32 00061 00062 00066 static GLboolean 00067 legal_identifier(slang_atom name) 00068 { 00069 /* "gl_" is a reserved prefix */ 00070 if (_mesa_strncmp((char *) name, "gl_", 3) == 0) { 00071 return GL_FALSE; 00072 } 00073 return GL_TRUE; 00074 } 00075 00076 00077 /* 00078 * slang_code_unit 00079 */ 00080 00081 GLvoid 00082 _slang_code_unit_ctr(slang_code_unit * self, 00083 struct slang_code_object_ * object) 00084 { 00085 _slang_variable_scope_ctr(&self->vars); 00086 _slang_function_scope_ctr(&self->funs); 00087 _slang_struct_scope_ctr(&self->structs); 00088 self->object = object; 00089 } 00090 00091 GLvoid 00092 _slang_code_unit_dtr(slang_code_unit * self) 00093 { 00094 slang_variable_scope_destruct(&self->vars); 00095 slang_function_scope_destruct(&self->funs); 00096 slang_struct_scope_destruct(&self->structs); 00097 } 00098 00099 /* 00100 * slang_code_object 00101 */ 00102 00103 GLvoid 00104 _slang_code_object_ctr(slang_code_object * self) 00105 { 00106 GLuint i; 00107 00108 for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) 00109 _slang_code_unit_ctr(&self->builtin[i], self); 00110 _slang_code_unit_ctr(&self->unit, self); 00111 slang_atom_pool_construct(&self->atompool); 00112 } 00113 00114 GLvoid 00115 _slang_code_object_dtr(slang_code_object * self) 00116 { 00117 GLuint i; 00118 00119 for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) 00120 _slang_code_unit_dtr(&self->builtin[i]); 00121 _slang_code_unit_dtr(&self->unit); 00122 slang_atom_pool_destruct(&self->atompool); 00123 } 00124 00125 00126 /* slang_parse_ctx */ 00127 00128 typedef struct slang_parse_ctx_ 00129 { 00130 const byte *I; 00131 slang_info_log *L; 00132 int parsing_builtin; 00133 GLboolean global_scope; 00134 slang_atom_pool *atoms; 00135 slang_unit_type type; 00136 GLuint version; 00137 } slang_parse_ctx; 00138 00139 /* slang_output_ctx */ 00140 00141 typedef struct slang_output_ctx_ 00142 { 00143 slang_variable_scope *vars; 00144 slang_function_scope *funs; 00145 slang_struct_scope *structs; 00146 struct gl_program *program; 00147 struct gl_sl_pragmas *pragmas; 00148 slang_var_table *vartable; 00149 GLuint default_precision[TYPE_SPECIFIER_COUNT]; 00150 GLboolean allow_precision; 00151 GLboolean allow_invariant; 00152 GLboolean allow_centroid; 00153 GLboolean allow_array_types; /* float[] syntax */ 00154 } slang_output_ctx; 00155 00156 /* _slang_compile() */ 00157 00158 00159 /* Debugging aid, print file/line where parsing error is detected */ 00160 #define RETURN0 \ 00161 do { \ 00162 if (0) \ 00163 printf("slang error at %s:%d\n", __FILE__, __LINE__); \ 00164 return 0; \ 00165 } while (0) 00166 00167 00168 static void 00169 parse_identifier_str(slang_parse_ctx * C, char **id) 00170 { 00171 *id = (char *) C->I; 00172 C->I += _mesa_strlen(*id) + 1; 00173 } 00174 00175 static slang_atom 00176 parse_identifier(slang_parse_ctx * C) 00177 { 00178 const char *id; 00179 00180 id = (const char *) C->I; 00181 C->I += _mesa_strlen(id) + 1; 00182 return slang_atom_pool_atom(C->atoms, id); 00183 } 00184 00185 static int 00186 parse_number(slang_parse_ctx * C, int *number) 00187 { 00188 const int radix = (int) (*C->I++); 00189 *number = 0; 00190 while (*C->I != '\0') { 00191 int digit; 00192 if (*C->I >= '0' && *C->I <= '9') 00193 digit = (int) (*C->I - '0'); 00194 else if (*C->I >= 'A' && *C->I <= 'Z') 00195 digit = (int) (*C->I - 'A') + 10; 00196 else 00197 digit = (int) (*C->I - 'a') + 10; 00198 *number = *number * radix + digit; 00199 C->I++; 00200 } 00201 C->I++; 00202 if (*number > 65535) 00203 slang_info_log_warning(C->L, "%d: literal integer overflow.", *number); 00204 return 1; 00205 } 00206 00207 static int 00208 parse_float(slang_parse_ctx * C, float *number) 00209 { 00210 char *integral = NULL; 00211 char *fractional = NULL; 00212 char *exponent = NULL; 00213 char *whole = NULL; 00214 00215 parse_identifier_str(C, &integral); 00216 parse_identifier_str(C, &fractional); 00217 parse_identifier_str(C, &exponent); 00218 00219 whole = (char *) _slang_alloc((_mesa_strlen(integral) + 00220 _mesa_strlen(fractional) + 00221 _mesa_strlen(exponent) + 3) * sizeof(char)); 00222 if (whole == NULL) { 00223 slang_info_log_memory(C->L); 00224 RETURN0; 00225 } 00226 00227 slang_string_copy(whole, integral); 00228 slang_string_concat(whole, "."); 00229 slang_string_concat(whole, fractional); 00230 slang_string_concat(whole, "E"); 00231 slang_string_concat(whole, exponent); 00232 00233 *number = (float) (_mesa_strtod(whole, (char **) NULL)); 00234 00235 _slang_free(whole); 00236 00237 return 1; 00238 } 00239 00240 /* revision number - increment after each change affecting emitted output */ 00241 #define REVISION 5 00242 00243 static int 00244 check_revision(slang_parse_ctx * C) 00245 { 00246 if (*C->I != REVISION) { 00247 slang_info_log_error(C->L, "Internal compiler error."); 00248 RETURN0; 00249 } 00250 C->I++; 00251 return 1; 00252 } 00253 00254 static int parse_statement(slang_parse_ctx *, slang_output_ctx *, 00255 slang_operation *); 00256 static int parse_expression(slang_parse_ctx *, slang_output_ctx *, 00257 slang_operation *); 00258 static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *, 00259 slang_type_specifier *); 00260 static int 00261 parse_type_array_size(slang_parse_ctx *C, 00262 slang_output_ctx *O, 00263 GLint *array_len); 00264 00265 static GLboolean 00266 parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len) 00267 { 00268 slang_operation array_size; 00269 slang_name_space space; 00270 GLboolean result; 00271 00272 if (!slang_operation_construct(&array_size)) 00273 return GL_FALSE; 00274 if (!parse_expression(C, O, &array_size)) { 00275 slang_operation_destruct(&array_size); 00276 return GL_FALSE; 00277 } 00278 00279 space.funcs = O->funs; 00280 space.structs = O->structs; 00281 space.vars = O->vars; 00282 00283 /* evaluate compile-time expression which is array size */ 00284 _slang_simplify(&array_size, &space, C->atoms); 00285 00286 if (array_size.type == SLANG_OPER_LITERAL_INT) { 00287 result = GL_TRUE; 00288 *len = (GLint) array_size.literal[0]; 00289 } else if (array_size.type == SLANG_OPER_IDENTIFIER) { 00290 slang_variable *var = _slang_variable_locate(array_size.locals, array_size.a_id, GL_TRUE); 00291 if (!var) { 00292 slang_info_log_error(C->L, "undefined variable '%s'", 00293 (char *) array_size.a_id); 00294 result = GL_FALSE; 00295 } else if (var->type.qualifier == SLANG_QUAL_CONST && 00296 var->type.specifier.type == SLANG_SPEC_INT) { 00297 if (var->initializer && 00298 var->initializer->type == SLANG_OPER_LITERAL_INT) { 00299 *len = (GLint) var->initializer->literal[0]; 00300 result = GL_TRUE; 00301 } else { 00302 slang_info_log_error(C->L, "unable to parse array size declaration"); 00303 result = GL_FALSE; 00304 } 00305 } else { 00306 slang_info_log_error(C->L, "unable to parse array size declaration"); 00307 result = GL_FALSE; 00308 } 00309 } else { 00310 result = GL_FALSE; 00311 } 00312 00313 slang_operation_destruct(&array_size); 00314 return result; 00315 } 00316 00317 static GLboolean 00318 calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O, 00319 slang_variable * var) 00320 { 00321 slang_storage_aggregate agg; 00322 00323 if (!slang_storage_aggregate_construct(&agg)) 00324 return GL_FALSE; 00325 if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len, 00326 O->funs, O->structs, O->vars, C->atoms)) { 00327 slang_storage_aggregate_destruct(&agg); 00328 return GL_FALSE; 00329 } 00330 var->size = _slang_sizeof_aggregate(&agg); 00331 slang_storage_aggregate_destruct(&agg); 00332 return GL_TRUE; 00333 } 00334 00335 static void 00336 promote_type_to_array(slang_parse_ctx *C, 00337 slang_fully_specified_type *type, 00338 GLint array_len) 00339 { 00340 slang_type_specifier *baseType = 00341 slang_type_specifier_new(type->specifier.type, NULL, NULL); 00342 00343 type->specifier.type = SLANG_SPEC_ARRAY; 00344 type->specifier._array = baseType; 00345 type->array_len = array_len; 00346 } 00347 00348 00349 static GLboolean 00350 convert_to_array(slang_parse_ctx * C, slang_variable * var, 00351 const slang_type_specifier * sp) 00352 { 00353 /* sized array - mark it as array, copy the specifier to the array element 00354 * and parse the expression */ 00355 var->type.specifier.type = SLANG_SPEC_ARRAY; 00356 var->type.specifier._array = (slang_type_specifier *) 00357 _slang_alloc(sizeof(slang_type_specifier)); 00358 if (var->type.specifier._array == NULL) { 00359 slang_info_log_memory(C->L); 00360 return GL_FALSE; 00361 } 00362 slang_type_specifier_ctr(var->type.specifier._array); 00363 return slang_type_specifier_copy(var->type.specifier._array, sp); 00364 } 00365 00366 /* structure field */ 00367 #define FIELD_NONE 0 00368 #define FIELD_NEXT 1 00369 #define FIELD_ARRAY 2 00370 00371 static GLboolean 00372 parse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O, 00373 slang_variable * var, slang_atom a_name, 00374 const slang_type_specifier * sp, 00375 GLuint array_len) 00376 { 00377 var->a_name = a_name; 00378 if (var->a_name == SLANG_ATOM_NULL) 00379 return GL_FALSE; 00380 00381 switch (*C->I++) { 00382 case FIELD_NONE: 00383 if (array_len != -1) { 00384 if (!convert_to_array(C, var, sp)) 00385 return GL_FALSE; 00386 var->array_len = array_len; 00387 } 00388 else { 00389 if (!slang_type_specifier_copy(&var->type.specifier, sp)) 00390 return GL_FALSE; 00391 } 00392 break; 00393 case FIELD_ARRAY: 00394 if (array_len != -1) 00395 return GL_FALSE; 00396 if (!convert_to_array(C, var, sp)) 00397 return GL_FALSE; 00398 if (!parse_array_len(C, O, &var->array_len)) 00399 return GL_FALSE; 00400 break; 00401 default: 00402 return GL_FALSE; 00403 } 00404 00405 return calculate_var_size(C, O, var); 00406 } 00407 00408 static int 00409 parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O, 00410 slang_struct * st, slang_type_specifier * sp) 00411 { 00412 slang_output_ctx o = *O; 00413 GLint array_len; 00414 00415 o.structs = st->structs; 00416 if (!parse_type_specifier(C, &o, sp)) 00417 RETURN0; 00418 if (!parse_type_array_size(C, &o, &array_len)) 00419 RETURN0; 00420 00421 do { 00422 slang_atom a_name; 00423 slang_variable *var = slang_variable_scope_grow(st->fields); 00424 if (!var) { 00425 slang_info_log_memory(C->L); 00426 RETURN0; 00427 } 00428 a_name = parse_identifier(C); 00429 if (_slang_variable_locate(st->fields, a_name, GL_FALSE)) { 00430 slang_info_log_error(C->L, "duplicate field '%s'", (char *) a_name); 00431 RETURN0; 00432 } 00433 00434 if (!parse_struct_field_var(C, &o, var, a_name, sp, array_len)) 00435 RETURN0; 00436 } 00437 while (*C->I++ != FIELD_NONE); 00438 00439 return 1; 00440 } 00441 00442 static int 00443 parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st) 00444 { 00445 slang_atom a_name; 00446 const char *name; 00447 00448 /* parse struct name (if any) and make sure it is unique in current scope */ 00449 a_name = parse_identifier(C); 00450 if (a_name == SLANG_ATOM_NULL) 00451 RETURN0; 00452 00453 name = slang_atom_pool_id(C->atoms, a_name); 00454 if (name[0] != '\0' 00455 && slang_struct_scope_find(O->structs, a_name, 0) != NULL) { 00456 slang_info_log_error(C->L, "%s: duplicate type name.", name); 00457 RETURN0; 00458 } 00459 00460 /* set-up a new struct */ 00461 *st = (slang_struct *) _slang_alloc(sizeof(slang_struct)); 00462 if (*st == NULL) { 00463 slang_info_log_memory(C->L); 00464 RETURN0; 00465 } 00466 if (!slang_struct_construct(*st)) { 00467 _slang_free(*st); 00468 *st = NULL; 00469 slang_info_log_memory(C->L); 00470 RETURN0; 00471 } 00472 (**st).a_name = a_name; 00473 (**st).structs->outer_scope = O->structs; 00474 00475 /* parse individual struct fields */ 00476 do { 00477 slang_type_specifier sp; 00478 00479 slang_type_specifier_ctr(&sp); 00480 if (!parse_struct_field(C, O, *st, &sp)) { 00481 slang_type_specifier_dtr(&sp); 00482 RETURN0; 00483 } 00484 slang_type_specifier_dtr(&sp); 00485 } 00486 while (*C->I++ != FIELD_NONE); 00487 00488 /* if named struct, copy it to current scope */ 00489 if (name[0] != '\0') { 00490 slang_struct *s; 00491 00492 O->structs->structs = 00493 (slang_struct *) _slang_realloc(O->structs->structs, 00494 O->structs->num_structs 00495 * sizeof(slang_struct), 00496 (O->structs->num_structs + 1) 00497 * sizeof(slang_struct)); 00498 if (O->structs->structs == NULL) { 00499 slang_info_log_memory(C->L); 00500 RETURN0; 00501 } 00502 s = &O->structs->structs[O->structs->num_structs]; 00503 if (!slang_struct_construct(s)) 00504 RETURN0; 00505 O->structs->num_structs++; 00506 if (!slang_struct_copy(s, *st)) 00507 RETURN0; 00508 } 00509 00510 return 1; 00511 } 00512 00513 00514 /* invariant qualifer */ 00515 #define TYPE_VARIANT 90 00516 #define TYPE_INVARIANT 91 00517 00518 static int 00519 parse_type_variant(slang_parse_ctx * C, slang_type_variant *variant) 00520 { 00521 GLuint invariant = *C->I++; 00522 switch (invariant) { 00523 case TYPE_VARIANT: 00524 *variant = SLANG_VARIANT; 00525 return 1; 00526 case TYPE_INVARIANT: 00527 *variant = SLANG_INVARIANT; 00528 return 1; 00529 default: 00530 RETURN0; 00531 } 00532 } 00533 00534 00535 /* centroid qualifer */ 00536 #define TYPE_CENTER 95 00537 #define TYPE_CENTROID 96 00538 00539 static int 00540 parse_type_centroid(slang_parse_ctx * C, slang_type_centroid *centroid) 00541 { 00542 GLuint c = *C->I++; 00543 switch (c) { 00544 case TYPE_CENTER: 00545 *centroid = SLANG_CENTER; 00546 return 1; 00547 case TYPE_CENTROID: 00548 *centroid = SLANG_CENTROID; 00549 return 1; 00550 default: 00551 RETURN0; 00552 } 00553 } 00554 00555 00556 /* type qualifier */ 00557 #define TYPE_QUALIFIER_NONE 0 00558 #define TYPE_QUALIFIER_CONST 1 00559 #define TYPE_QUALIFIER_ATTRIBUTE 2 00560 #define TYPE_QUALIFIER_VARYING 3 00561 #define TYPE_QUALIFIER_UNIFORM 4 00562 #define TYPE_QUALIFIER_FIXEDOUTPUT 5 00563 #define TYPE_QUALIFIER_FIXEDINPUT 6 00564 00565 static int 00566 parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual) 00567 { 00568 GLuint qualifier = *C->I++; 00569 switch (qualifier) { 00570 case TYPE_QUALIFIER_NONE: 00571 *qual = SLANG_QUAL_NONE; 00572 break; 00573 case TYPE_QUALIFIER_CONST: 00574 *qual = SLANG_QUAL_CONST; 00575 break; 00576 case TYPE_QUALIFIER_ATTRIBUTE: 00577 *qual = SLANG_QUAL_ATTRIBUTE; 00578 break; 00579 case TYPE_QUALIFIER_VARYING: 00580 *qual = SLANG_QUAL_VARYING; 00581 break; 00582 case TYPE_QUALIFIER_UNIFORM: 00583 *qual = SLANG_QUAL_UNIFORM; 00584 break; 00585 case TYPE_QUALIFIER_FIXEDOUTPUT: 00586 *qual = SLANG_QUAL_FIXEDOUTPUT; 00587 break; 00588 case TYPE_QUALIFIER_FIXEDINPUT: 00589 *qual = SLANG_QUAL_FIXEDINPUT; 00590 break; 00591 default: 00592 RETURN0; 00593 } 00594 return 1; 00595 } 00596 00597 /* type specifier */ 00598 #define TYPE_SPECIFIER_VOID 0 00599 #define TYPE_SPECIFIER_BOOL 1 00600 #define TYPE_SPECIFIER_BVEC2 2 00601 #define TYPE_SPECIFIER_BVEC3 3 00602 #define TYPE_SPECIFIER_BVEC4 4 00603 #define TYPE_SPECIFIER_INT 5 00604 #define TYPE_SPECIFIER_IVEC2 6 00605 #define TYPE_SPECIFIER_IVEC3 7 00606 #define TYPE_SPECIFIER_IVEC4 8 00607 #define TYPE_SPECIFIER_FLOAT 9 00608 #define TYPE_SPECIFIER_VEC2 10 00609 #define TYPE_SPECIFIER_VEC3 11 00610 #define TYPE_SPECIFIER_VEC4 12 00611 #define TYPE_SPECIFIER_MAT2 13 00612 #define TYPE_SPECIFIER_MAT3 14 00613 #define TYPE_SPECIFIER_MAT4 15 00614 #define TYPE_SPECIFIER_SAMPLER1D 16 00615 #define TYPE_SPECIFIER_SAMPLER2D 17 00616 #define TYPE_SPECIFIER_SAMPLER3D 18 00617 #define TYPE_SPECIFIER_SAMPLERCUBE 19 00618 #define TYPE_SPECIFIER_SAMPLER1DSHADOW 20 00619 #define TYPE_SPECIFIER_SAMPLER2DSHADOW 21 00620 #define TYPE_SPECIFIER_SAMPLER2DRECT 22 00621 #define TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23 00622 #define TYPE_SPECIFIER_STRUCT 24 00623 #define TYPE_SPECIFIER_TYPENAME 25 00624 #define TYPE_SPECIFIER_MAT23 26 00625 #define TYPE_SPECIFIER_MAT32 27 00626 #define TYPE_SPECIFIER_MAT24 28 00627 #define TYPE_SPECIFIER_MAT42 29 00628 #define TYPE_SPECIFIER_MAT34 30 00629 #define TYPE_SPECIFIER_MAT43 31 00630 #define TYPE_SPECIFIER_COUNT 32 00631 00632 static int 00633 parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O, 00634 slang_type_specifier * spec) 00635 { 00636 switch (*C->I++) { 00637 case TYPE_SPECIFIER_VOID: 00638 spec->type = SLANG_SPEC_VOID; 00639 break; 00640 case TYPE_SPECIFIER_BOOL: 00641 spec->type = SLANG_SPEC_BOOL; 00642 break; 00643 case TYPE_SPECIFIER_BVEC2: 00644 spec->type = SLANG_SPEC_BVEC2; 00645 break; 00646 case TYPE_SPECIFIER_BVEC3: 00647 spec->type = SLANG_SPEC_BVEC3; 00648 break; 00649 case TYPE_SPECIFIER_BVEC4: 00650 spec->type = SLANG_SPEC_BVEC4; 00651 break; 00652 case TYPE_SPECIFIER_INT: 00653 spec->type = SLANG_SPEC_INT; 00654 break; 00655 case TYPE_SPECIFIER_IVEC2: 00656 spec->type = SLANG_SPEC_IVEC2; 00657 break; 00658 case TYPE_SPECIFIER_IVEC3: 00659 spec->type = SLANG_SPEC_IVEC3; 00660 break; 00661 case TYPE_SPECIFIER_IVEC4: 00662 spec->type = SLANG_SPEC_IVEC4; 00663 break; 00664 case TYPE_SPECIFIER_FLOAT: 00665 spec->type = SLANG_SPEC_FLOAT; 00666 break; 00667 case TYPE_SPECIFIER_VEC2: 00668 spec->type = SLANG_SPEC_VEC2; 00669 break; 00670 case TYPE_SPECIFIER_VEC3: 00671 spec->type = SLANG_SPEC_VEC3; 00672 break; 00673 case TYPE_SPECIFIER_VEC4: 00674 spec->type = SLANG_SPEC_VEC4; 00675 break; 00676 case TYPE_SPECIFIER_MAT2: 00677 spec->type = SLANG_SPEC_MAT2; 00678 break; 00679 case TYPE_SPECIFIER_MAT3: 00680 spec->type = SLANG_SPEC_MAT3; 00681 break; 00682 case TYPE_SPECIFIER_MAT4: 00683 spec->type = SLANG_SPEC_MAT4; 00684 break; 00685 case TYPE_SPECIFIER_MAT23: 00686 spec->type = SLANG_SPEC_MAT23; 00687 break; 00688 case TYPE_SPECIFIER_MAT32: 00689 spec->type = SLANG_SPEC_MAT32; 00690 break; 00691 case TYPE_SPECIFIER_MAT24: 00692 spec->type = SLANG_SPEC_MAT24; 00693 break; 00694 case TYPE_SPECIFIER_MAT42: 00695 spec->type = SLANG_SPEC_MAT42; 00696 break; 00697 case TYPE_SPECIFIER_MAT34: 00698 spec->type = SLANG_SPEC_MAT34; 00699 break; 00700 case TYPE_SPECIFIER_MAT43: 00701 spec->type = SLANG_SPEC_MAT43; 00702 break; 00703 case TYPE_SPECIFIER_SAMPLER1D: 00704 spec->type = SLANG_SPEC_SAMPLER1D; 00705 break; 00706 case TYPE_SPECIFIER_SAMPLER2D: 00707 spec->type = SLANG_SPEC_SAMPLER2D; 00708 break; 00709 case TYPE_SPECIFIER_SAMPLER3D: 00710 spec->type = SLANG_SPEC_SAMPLER3D; 00711 break; 00712 case TYPE_SPECIFIER_SAMPLERCUBE: 00713 spec->type = SLANG_SPEC_SAMPLERCUBE; 00714 break; 00715 case TYPE_SPECIFIER_SAMPLER2DRECT: 00716 spec->type = SLANG_SPEC_SAMPLER2DRECT; 00717 break; 00718 case TYPE_SPECIFIER_SAMPLER1DSHADOW: 00719 spec->type = SLANG_SPEC_SAMPLER1DSHADOW; 00720 break; 00721 case TYPE_SPECIFIER_SAMPLER2DSHADOW: 00722 spec->type = SLANG_SPEC_SAMPLER2DSHADOW; 00723 break; 00724 case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW: 00725 spec->type = SLANG_SPEC_SAMPLER2DRECTSHADOW; 00726 break; 00727 case TYPE_SPECIFIER_STRUCT: 00728 spec->type = SLANG_SPEC_STRUCT; 00729 if (!parse_struct(C, O, &spec->_struct)) 00730 RETURN0; 00731 break; 00732 case TYPE_SPECIFIER_TYPENAME: 00733 spec->type = SLANG_SPEC_STRUCT; 00734 { 00735 slang_atom a_name; 00736 slang_struct *stru; 00737 00738 a_name = parse_identifier(C); 00739 if (a_name == NULL) 00740 RETURN0; 00741 00742 stru = slang_struct_scope_find(O->structs, a_name, 1); 00743 if (stru == NULL) { 00744 slang_info_log_error(C->L, "undeclared type name '%s'", 00745 slang_atom_pool_id(C->atoms, a_name)); 00746 RETURN0; 00747 } 00748 00749 spec->_struct = (slang_struct *) _slang_alloc(sizeof(slang_struct)); 00750 if (spec->_struct == NULL) { 00751 slang_info_log_memory(C->L); 00752 RETURN0; 00753 } 00754 if (!slang_struct_construct(spec->_struct)) { 00755 _slang_free(spec->_struct); 00756 spec->_struct = NULL; 00757 RETURN0; 00758 } 00759 if (!slang_struct_copy(spec->_struct, stru)) 00760 RETURN0; 00761 } 00762 break; 00763 default: 00764 RETURN0; 00765 } 00766 return 1; 00767 } 00768 00769 #define TYPE_SPECIFIER_NONARRAY 0 00770 #define TYPE_SPECIFIER_ARRAY 1 00771 00772 static int 00773 parse_type_array_size(slang_parse_ctx *C, 00774 slang_output_ctx *O, 00775 GLint *array_len) 00776 { 00777 GLuint size; 00778 00779 switch (*C->I++) { 00780 case TYPE_SPECIFIER_NONARRAY: 00781 *array_len = -1; /* -1 = not an array */ 00782 break; 00783 case TYPE_SPECIFIER_ARRAY: 00784 if (!parse_array_len(C, O, &size)) 00785 RETURN0; 00786 *array_len = (GLint) size; 00787 break; 00788 default: 00789 assert(0); 00790 RETURN0; 00791 } 00792 return 1; 00793 } 00794 00795 #define PRECISION_DEFAULT 0 00796 #define PRECISION_LOW 1 00797 #define PRECISION_MEDIUM 2 00798 #define PRECISION_HIGH 3 00799 00800 static int 00801 parse_type_precision(slang_parse_ctx *C, 00802 slang_type_precision *precision) 00803 { 00804 GLint prec = *C->I++; 00805 switch (prec) { 00806 case PRECISION_DEFAULT: 00807 *precision = SLANG_PREC_DEFAULT; 00808 return 1; 00809 case PRECISION_LOW: 00810 *precision = SLANG_PREC_LOW; 00811 return 1; 00812 case PRECISION_MEDIUM: 00813 *precision = SLANG_PREC_MEDIUM; 00814 return 1; 00815 case PRECISION_HIGH: 00816 *precision = SLANG_PREC_HIGH; 00817 return 1; 00818 default: 00819 RETURN0; 00820 } 00821 } 00822 00823 static int 00824 parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O, 00825 slang_fully_specified_type * type) 00826 { 00827 if (!parse_type_variant(C, &type->variant)) 00828 RETURN0; 00829 00830 if (!parse_type_centroid(C, &type->centroid)) 00831 RETURN0; 00832 00833 if (!parse_type_qualifier(C, &type->qualifier)) 00834 RETURN0; 00835 00836 if (!parse_type_precision(C, &type->precision)) 00837 RETURN0; 00838 00839 if (!parse_type_specifier(C, O, &type->specifier)) 00840 RETURN0; 00841 00842 if (!parse_type_array_size(C, O, &type->array_len)) 00843 RETURN0; 00844 00845 if (!O->allow_invariant && type->variant == SLANG_INVARIANT) { 00846 slang_info_log_error(C->L, 00847 "'invariant' keyword not allowed (perhaps set #version 120)"); 00848 RETURN0; 00849 } 00850 00851 if (!O->allow_centroid && type->centroid == SLANG_CENTROID) { 00852 slang_info_log_error(C->L, 00853 "'centroid' keyword not allowed (perhaps set #version 120)"); 00854 RETURN0; 00855 } 00856 else if (type->centroid == SLANG_CENTROID && 00857 type->qualifier != SLANG_QUAL_VARYING) { 00858 slang_info_log_error(C->L, 00859 "'centroid' keyword only allowed for varying vars"); 00860 RETURN0; 00861 } 00862 00863 00864 /* need this? 00865 if (type->qualifier != SLANG_QUAL_VARYING && 00866 type->variant == SLANG_INVARIANT) { 00867 slang_info_log_error(C->L, 00868 "invariant qualifer only allowed for varying vars"); 00869 RETURN0; 00870 } 00871 */ 00872 00873 if (O->allow_precision) { 00874 if (type->precision == SLANG_PREC_DEFAULT) { 00875 assert(type->specifier.type < TYPE_SPECIFIER_COUNT); 00876 /* use the default precision for this datatype */ 00877 type->precision = O->default_precision[type->specifier.type]; 00878 } 00879 } 00880 else { 00881 /* only default is allowed */ 00882 if (type->precision != SLANG_PREC_DEFAULT) { 00883 slang_info_log_error(C->L, "precision qualifiers not allowed"); 00884 RETURN0; 00885 } 00886 } 00887 00888 if (!O->allow_array_types && type->array_len >= 0) { 00889 slang_info_log_error(C->L, "first-class array types not allowed"); 00890 RETURN0; 00891 } 00892 00893 if (type->array_len >= 0) { 00894 /* convert type to array type (ex: convert "int" to "array of int" */ 00895 promote_type_to_array(C, type, type->array_len); 00896 } 00897 00898 return 1; 00899 } 00900 00901 /* operation */ 00902 #define OP_END 0 00903 #define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1 00904 #define OP_BLOCK_BEGIN_NEW_SCOPE 2 00905 #define OP_DECLARE 3 00906 #define OP_ASM 4 00907 #define OP_BREAK 5 00908 #define OP_CONTINUE 6 00909 #define OP_DISCARD 7 00910 #define OP_RETURN 8 00911 #define OP_EXPRESSION 9 00912 #define OP_IF 10 00913 #define OP_WHILE 11 00914 #define OP_DO 12 00915 #define OP_FOR 13 00916 #define OP_PUSH_VOID 14 00917 #define OP_PUSH_BOOL 15 00918 #define OP_PUSH_INT 16 00919 #define OP_PUSH_FLOAT 17 00920 #define OP_PUSH_IDENTIFIER 18 00921 #define OP_SEQUENCE 19 00922 #define OP_ASSIGN 20 00923 #define OP_ADDASSIGN 21 00924 #define OP_SUBASSIGN 22 00925 #define OP_MULASSIGN 23 00926 #define OP_DIVASSIGN 24 00927 /*#define OP_MODASSIGN 25*/ 00928 /*#define OP_LSHASSIGN 26*/ 00929 /*#define OP_RSHASSIGN 27*/ 00930 /*#define OP_ORASSIGN 28*/ 00931 /*#define OP_XORASSIGN 29*/ 00932 /*#define OP_ANDASSIGN 30*/ 00933 #define OP_SELECT 31 00934 #define OP_LOGICALOR 32 00935 #define OP_LOGICALXOR 33 00936 #define OP_LOGICALAND 34 00937 /*#define OP_BITOR 35*/ 00938 /*#define OP_BITXOR 36*/ 00939 /*#define OP_BITAND 37*/ 00940 #define OP_EQUAL 38 00941 #define OP_NOTEQUAL 39 00942 #define OP_LESS 40 00943 #define OP_GREATER 41 00944 #define OP_LESSEQUAL 42 00945 #define OP_GREATEREQUAL 43 00946 /*#define OP_LSHIFT 44*/ 00947 /*#define OP_RSHIFT 45*/ 00948 #define OP_ADD 46 00949 #define OP_SUBTRACT 47 00950 #define OP_MULTIPLY 48 00951 #define OP_DIVIDE 49 00952 /*#define OP_MODULUS 50*/ 00953 #define OP_PREINCREMENT 51 00954 #define OP_PREDECREMENT 52 00955 #define OP_PLUS 53 00956 #define OP_MINUS 54 00957 /*#define OP_COMPLEMENT 55*/ 00958 #define OP_NOT 56 00959 #define OP_SUBSCRIPT 57 00960 #define OP_CALL 58 00961 #define OP_FIELD 59 00962 #define OP_POSTINCREMENT 60 00963 #define OP_POSTDECREMENT 61 00964 #define OP_PRECISION 62 00965 #define OP_METHOD 63 00966 00967 00980 static int 00981 parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O, 00982 slang_operation * oper, GLboolean statement) 00983 { 00984 slang_operation *ch; 00985 00986 /* grow child array */ 00987 ch = slang_operation_grow(&oper->num_children, &oper->children); 00988 if (statement) 00989 return parse_statement(C, O, ch); 00990 return parse_expression(C, O, ch); 00991 } 00992 00993 static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O); 00994 00995 static int 00996 parse_statement(slang_parse_ctx * C, slang_output_ctx * O, 00997 slang_operation * oper) 00998 { 00999 int op; 01000 01001 oper->locals->outer_scope = O->vars; 01002 01003 op = *C->I++; 01004 switch (op) { 01005 case OP_BLOCK_BEGIN_NO_NEW_SCOPE: 01006 /* parse child statements, do not create new variable scope */ 01007 oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; 01008 while (*C->I != OP_END) 01009 if (!parse_child_operation(C, O, oper, GL_TRUE)) 01010 RETURN0; 01011 C->I++; 01012 break; 01013 case OP_BLOCK_BEGIN_NEW_SCOPE: 01014 /* parse child statements, create new variable scope */ 01015 { 01016 slang_output_ctx o = *O; 01017 01018 oper->type = SLANG_OPER_BLOCK_NEW_SCOPE; 01019 o.vars = oper->locals; 01020 while (*C->I != OP_END) 01021 if (!parse_child_operation(C, &o, oper, GL_TRUE)) 01022 RETURN0; 01023 C->I++; 01024 } 01025 break; 01026 case OP_DECLARE: 01027 /* local variable declaration, individual declarators are stored as 01028 * children identifiers 01029 */ 01030 oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; 01031 { 01032 const unsigned int first_var = O->vars->num_variables; 01033 01034 /* parse the declaration, note that there can be zero or more 01035 * than one declarators 01036 */ 01037 if (!parse_declaration(C, O)) 01038 RETURN0; 01039 if (first_var < O->vars->num_variables) { 01040 const unsigned int num_vars = O->vars->num_variables - first_var; 01041 unsigned int i; 01042 assert(oper->num_children == 0); 01043 oper->num_children = num_vars; 01044 oper->children = slang_operation_new(num_vars); 01045 if (oper->children == NULL) { 01046 slang_info_log_memory(C->L); 01047 RETURN0; 01048 } 01049 for (i = first_var; i < O->vars->num_variables; i++) { 01050 slang_operation *o = &oper->children[i - first_var]; 01051 slang_variable *var = O->vars->variables[i]; 01052 o->type = SLANG_OPER_VARIABLE_DECL; 01053 o->locals->outer_scope = O->vars; 01054 o->a_id = var->a_name; 01055 01056 /* new/someday... 01057 calculate_var_size(C, O, var); 01058 */ 01059 01060 if (!legal_identifier(o->a_id)) { 01061 slang_info_log_error(C->L, "illegal variable name '%s'", 01062 (char *) o->a_id); 01063 RETURN0; 01064 } 01065 } 01066 } 01067 } 01068 break; 01069 case OP_ASM: 01070 /* the __asm statement, parse the mnemonic and all its arguments 01071 * as expressions 01072 */ 01073 oper->type = SLANG_OPER_ASM; 01074 oper->a_id = parse_identifier(C); 01075 if (oper->a_id == SLANG_ATOM_NULL) 01076 RETURN0; 01077 while (*C->I != OP_END) { 01078 if (!parse_child_operation(C, O, oper, GL_FALSE)) 01079 RETURN0; 01080 } 01081 C->I++; 01082 break; 01083 case OP_BREAK: 01084 oper->type = SLANG_OPER_BREAK; 01085 break; 01086 case OP_CONTINUE: 01087 oper->type = SLANG_OPER_CONTINUE; 01088 break; 01089 case OP_DISCARD: 01090 oper->type = SLANG_OPER_DISCARD; 01091 break; 01092 case OP_RETURN: 01093 oper->type = SLANG_OPER_RETURN; 01094 if (!parse_child_operation(C, O, oper, GL_FALSE)) 01095 RETURN0; 01096 break; 01097 case OP_EXPRESSION: 01098 oper->type = SLANG_OPER_EXPRESSION; 01099 if (!parse_child_operation(C, O, oper, GL_FALSE)) 01100 RETURN0; 01101 break; 01102 case OP_IF: 01103 oper->type = SLANG_OPER_IF; 01104 if (!parse_child_operation(C, O, oper, GL_FALSE)) 01105 RETURN0; 01106 if (!parse_child_operation(C, O, oper, GL_TRUE)) 01107 RETURN0; 01108 if (!parse_child_operation(C, O, oper, GL_TRUE)) 01109 RETURN0; 01110 break; 01111 case OP_WHILE: 01112 { 01113 slang_output_ctx o = *O; 01114 01115 oper->type = SLANG_OPER_WHILE; 01116 o.vars = oper->locals; 01117 if (!parse_child_operation(C, &o, oper, GL_TRUE)) 01118 RETURN0; 01119 if (!parse_child_operation(C, &o, oper, GL_TRUE)) 01120 RETURN0; 01121 } 01122 break; 01123 case OP_DO: 01124 oper->type = SLANG_OPER_DO; 01125 if (!parse_child_operation(C, O, oper, GL_TRUE)) 01126 RETURN0; 01127 if (!parse_child_operation(C, O, oper, GL_FALSE)) 01128 RETURN0; 01129 break; 01130 case OP_FOR: 01131 { 01132 slang_output_ctx o = *O; 01133 01134 oper->type = SLANG_OPER_FOR; 01135 o.vars = oper->locals; 01136 if (!parse_child_operation(C, &o, oper, GL_TRUE)) 01137 RETURN0; 01138 if (!parse_child_operation(C, &o, oper, GL_TRUE)) 01139 RETURN0; 01140 if (!parse_child_operation(C, &o, oper, GL_FALSE)) 01141 RETURN0; 01142 if (!parse_child_operation(C, &o, oper, GL_TRUE)) 01143 RETURN0; 01144 } 01145 break; 01146 case OP_PRECISION: 01147 { 01148 /* set default precision for a type in this scope */ 01149 /* ignored at this time */ 01150 int prec_qual = *C->I++; 01151 int datatype = *C->I++; 01152 (void) prec_qual; 01153 (void) datatype; 01154 } 01155 break; 01156 default: 01157 /*printf("Unexpected operation %d\n", op);*/ 01158 RETURN0; 01159 } 01160 return 1; 01161 } 01162 01163 static int 01164 handle_nary_expression(slang_parse_ctx * C, slang_operation * op, 01165 slang_operation ** ops, unsigned int *total_ops, 01166 unsigned int n) 01167 { 01168 unsigned int i; 01169 01170 op->children = slang_operation_new(n); 01171 if (op->children == NULL) { 01172 slang_info_log_memory(C->L); 01173 RETURN0; 01174 } 01175 op->num_children = n; 01176 01177 for (i = 0; i < n; i++) { 01178 slang_operation_destruct(&op->children[i]); 01179 op->children[i] = (*ops)[*total_ops - (n + 1 - i)]; 01180 } 01181 01182 (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1]; 01183 *total_ops -= n; 01184 01185 *ops = (slang_operation *) 01186 _slang_realloc(*ops, 01187 (*total_ops + n) * sizeof(slang_operation), 01188 *total_ops * sizeof(slang_operation)); 01189 if (*ops == NULL) { 01190 slang_info_log_memory(C->L); 01191 RETURN0; 01192 } 01193 return 1; 01194 } 01195 01196 static int 01197 is_constructor_name(const char *name, slang_atom a_name, 01198 slang_struct_scope * structs) 01199 { 01200 if (slang_type_specifier_type_from_string(name) != SLANG_SPEC_VOID) 01201 return 1; 01202 return slang_struct_scope_find(structs, a_name, 1) != NULL; 01203 } 01204 01205 #define FUNCTION_CALL_NONARRAY 0 01206 #define FUNCTION_CALL_ARRAY 1 01207 01208 static int 01209 parse_expression(slang_parse_ctx * C, slang_output_ctx * O, 01210 slang_operation * oper) 01211 { 01212 slang_operation *ops = NULL; 01213 unsigned int num_ops = 0; 01214 int number; 01215 01216 while (*C->I != OP_END) { 01217 slang_operation *op; 01218 const unsigned int op_code = *C->I++; 01219 01220 /* allocate default operation, becomes a no-op if not used */ 01221 ops = (slang_operation *) 01222 _slang_realloc(ops, 01223 num_ops * sizeof(slang_operation), 01224 (num_ops + 1) * sizeof(slang_operation)); 01225 if (ops == NULL) { 01226 slang_info_log_memory(C->L); 01227 RETURN0; 01228 } 01229 op = &ops[num_ops]; 01230 if (!slang_operation_construct(op)) { 01231 slang_info_log_memory(C->L); 01232 RETURN0; 01233 } 01234 num_ops++; 01235 op->locals->outer_scope = O->vars; 01236 01237 switch (op_code) { 01238 case OP_PUSH_VOID: 01239 op->type = SLANG_OPER_VOID; 01240 break; 01241 case OP_PUSH_BOOL: 01242 op->type = SLANG_OPER_LITERAL_BOOL; 01243 if (!parse_number(C, &number)) 01244 RETURN0; 01245 op->literal[0] = 01246 op->literal[1] = 01247 op->literal[2] = 01248 op->literal[3] = (GLfloat) number; 01249 op->literal_size = 1; 01250 break; 01251 case OP_PUSH_INT: 01252 op->type = SLANG_OPER_LITERAL_INT; 01253 if (!parse_number(C, &number)) 01254 RETURN0; 01255 op->literal[0] = 01256 op->literal[1] = 01257 op->literal[2] = 01258 op->literal[3] = (GLfloat) number; 01259 op->literal_size = 1; 01260 break; 01261 case OP_PUSH_FLOAT: 01262 op->type = SLANG_OPER_LITERAL_FLOAT; 01263 if (!parse_float(C, &op->literal[0])) 01264 RETURN0; 01265 op->literal[1] = 01266 op->literal[2] = 01267 op->literal[3] = op->literal[0]; 01268 op->literal_size = 1; 01269 break; 01270 case OP_PUSH_IDENTIFIER: 01271 op->type = SLANG_OPER_IDENTIFIER; 01272 op->a_id = parse_identifier(C); 01273 if (op->a_id == SLANG_ATOM_NULL) 01274 RETURN0; 01275 break; 01276 case OP_SEQUENCE: 01277 op->type = SLANG_OPER_SEQUENCE; 01278 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01279 RETURN0; 01280 break; 01281 case OP_ASSIGN: 01282 op->type = SLANG_OPER_ASSIGN; 01283 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01284 RETURN0; 01285 break; 01286 case OP_ADDASSIGN: 01287 op->type = SLANG_OPER_ADDASSIGN; 01288 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01289 RETURN0; 01290 break; 01291 case OP_SUBASSIGN: 01292 op->type = SLANG_OPER_SUBASSIGN; 01293 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01294 RETURN0; 01295 break; 01296 case OP_MULASSIGN: 01297 op->type = SLANG_OPER_MULASSIGN; 01298 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01299 RETURN0; 01300 break; 01301 case OP_DIVASSIGN: 01302 op->type = SLANG_OPER_DIVASSIGN; 01303 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01304 RETURN0; 01305 break; 01306 /*case OP_MODASSIGN: */ 01307 /*case OP_LSHASSIGN: */ 01308 /*case OP_RSHASSIGN: */ 01309 /*case OP_ORASSIGN: */ 01310 /*case OP_XORASSIGN: */ 01311 /*case OP_ANDASSIGN: */ 01312 case OP_SELECT: 01313 op->type = SLANG_OPER_SELECT; 01314 if (!handle_nary_expression(C, op, &ops, &num_ops, 3)) 01315 RETURN0; 01316 break; 01317 case OP_LOGICALOR: 01318 op->type = SLANG_OPER_LOGICALOR; 01319 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01320 RETURN0; 01321 break; 01322 case OP_LOGICALXOR: 01323 op->type = SLANG_OPER_LOGICALXOR; 01324 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01325 RETURN0; 01326 break; 01327 case OP_LOGICALAND: 01328 op->type = SLANG_OPER_LOGICALAND; 01329 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01330 RETURN0; 01331 break; 01332 /*case OP_BITOR: */ 01333 /*case OP_BITXOR: */ 01334 /*case OP_BITAND: */ 01335 case OP_EQUAL: 01336 op->type = SLANG_OPER_EQUAL; 01337 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01338 RETURN0; 01339 break; 01340 case OP_NOTEQUAL: 01341 op->type = SLANG_OPER_NOTEQUAL; 01342 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01343 RETURN0; 01344 break; 01345 case OP_LESS: 01346 op->type = SLANG_OPER_LESS; 01347 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01348 RETURN0; 01349 break; 01350 case OP_GREATER: 01351 op->type = SLANG_OPER_GREATER; 01352 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01353 RETURN0; 01354 break; 01355 case OP_LESSEQUAL: 01356 op->type = SLANG_OPER_LESSEQUAL; 01357 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01358 RETURN0; 01359 break; 01360 case OP_GREATEREQUAL: 01361 op->type = SLANG_OPER_GREATEREQUAL; 01362 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01363 RETURN0; 01364 break; 01365 /*case OP_LSHIFT: */ 01366 /*case OP_RSHIFT: */ 01367 case OP_ADD: 01368 op->type = SLANG_OPER_ADD; 01369 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01370 RETURN0; 01371 break; 01372 case OP_SUBTRACT: 01373 op->type = SLANG_OPER_SUBTRACT; 01374 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01375 RETURN0; 01376 break; 01377 case OP_MULTIPLY: 01378 op->type = SLANG_OPER_MULTIPLY; 01379 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01380 RETURN0; 01381 break; 01382 case OP_DIVIDE: 01383 op->type = SLANG_OPER_DIVIDE; 01384 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01385 RETURN0; 01386 break; 01387 /*case OP_MODULUS: */ 01388 case OP_PREINCREMENT: 01389 op->type = SLANG_OPER_PREINCREMENT; 01390 if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) 01391 RETURN0; 01392 break; 01393 case OP_PREDECREMENT: 01394 op->type = SLANG_OPER_PREDECREMENT; 01395 if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) 01396 RETURN0; 01397 break; 01398 case OP_PLUS: 01399 op->type = SLANG_OPER_PLUS; 01400 if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) 01401 RETURN0; 01402 break; 01403 case OP_MINUS: 01404 op->type = SLANG_OPER_MINUS; 01405 if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) 01406 RETURN0; 01407 break; 01408 case OP_NOT: 01409 op->type = SLANG_OPER_NOT; 01410 if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) 01411 RETURN0; 01412 break; 01413 /*case OP_COMPLEMENT: */ 01414 case OP_SUBSCRIPT: 01415 op->type = SLANG_OPER_SUBSCRIPT; 01416 if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) 01417 RETURN0; 01418 break; 01419 case OP_METHOD: 01420 op->type = SLANG_OPER_METHOD; 01421 op->a_obj = parse_identifier(C); 01422 if (op->a_obj == SLANG_ATOM_NULL) 01423 RETURN0; 01424 01425 op->a_id = parse_identifier(C); 01426 if (op->a_id == SLANG_ATOM_NULL) 01427 RETURN0; 01428 01429 assert(*C->I == OP_END); 01430 C->I++; 01431 01432 while (*C->I != OP_END) 01433 if (!parse_child_operation(C, O, op, GL_FALSE)) 01434 RETURN0; 01435 C->I++; 01436 #if 0 01437 /* don't lookup the method (not yet anyway) */ 01438 if (!C->parsing_builtin 01439 && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) { 01440 const char *id; 01441 01442 id = slang_atom_pool_id(C->atoms, op->a_id); 01443 if (!is_constructor_name(id, op->a_id, O->structs)) { 01444 slang_info_log_error(C->L, "%s: undeclared function name.", id); 01445 RETURN0; 01446 } 01447 } 01448 #endif 01449 break; 01450 case OP_CALL: 01451 { 01452 GLboolean array_constructor = GL_FALSE; 01453 GLint array_constructor_size = 0; 01454 01455 op->type = SLANG_OPER_CALL; 01456 op->a_id = parse_identifier(C); 01457 if (op->a_id == SLANG_ATOM_NULL) 01458 RETURN0; 01459 switch (*C->I++) { 01460 case FUNCTION_CALL_NONARRAY: 01461 /* Nothing to do. */ 01462 break; 01463 case FUNCTION_CALL_ARRAY: 01464 /* Calling an array constructor. For example: 01465 * float[3](1.1, 2.2, 3.3); 01466 */ 01467 if (!O->allow_array_types) { 01468 slang_info_log_error(C->L, 01469 "array constructors not allowed " 01470 "in this GLSL version"); 01471 RETURN0; 01472 } 01473 else { 01474 /* parse the array constructor size */ 01475 slang_operation array_size; 01476 array_constructor = GL_TRUE; 01477 slang_operation_construct(&array_size); 01478 if (!parse_expression(C, O, &array_size)) { 01479 slang_operation_destruct(&array_size); 01480 return GL_FALSE; 01481 } 01482 if (array_size.type != SLANG_OPER_LITERAL_INT) { 01483 slang_info_log_error(C->L, 01484 "constructor array size is not an integer"); 01485 slang_operation_destruct(&array_size); 01486 RETURN0; 01487 } 01488 array_constructor_size = (int) array_size.literal[0]; 01489 op->array_constructor = GL_TRUE; 01490 slang_operation_destruct(&array_size); 01491 } 01492 break; 01493 default: 01494 assert(0); 01495 RETURN0; 01496 } 01497 while (*C->I != OP_END) 01498 if (!parse_child_operation(C, O, op, GL_FALSE)) 01499 RETURN0; 01500 C->I++; 01501 01502 if (array_constructor && 01503 array_constructor_size != op->num_children) { 01504 slang_info_log_error(C->L, "number of parameters to array" 01505 " constructor does not match array size"); 01506 RETURN0; 01507 } 01508 01509 if (!C->parsing_builtin 01510 && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) { 01511 const char *id; 01512 01513 id = slang_atom_pool_id(C->atoms, op->a_id); 01514 if (!is_constructor_name(id, op->a_id, O->structs)) { 01515 slang_info_log_error(C->L, "%s: undeclared function name.", id); 01516 RETURN0; 01517 } 01518 } 01519 } 01520 break; 01521 case OP_FIELD: 01522 op->type = SLANG_OPER_FIELD; 01523 op->a_id = parse_identifier(C); 01524 if (op->a_id == SLANG_ATOM_NULL) 01525 RETURN0; 01526 if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) 01527 RETURN0; 01528 break; 01529 case OP_POSTINCREMENT: 01530 op->type = SLANG_OPER_POSTINCREMENT; 01531 if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) 01532 RETURN0; 01533 break; 01534 case OP_POSTDECREMENT: 01535 op->type = SLANG_OPER_POSTDECREMENT; 01536 if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) 01537 RETURN0; 01538 break; 01539 default: 01540 RETURN0; 01541 } 01542 } 01543 C->I++; 01544 01545 slang_operation_destruct(oper); 01546 *oper = *ops; /* struct copy */ 01547 _slang_free(ops); 01548 01549 return 1; 01550 } 01551 01552 /* parameter qualifier */ 01553 #define PARAM_QUALIFIER_IN 0 01554 #define PARAM_QUALIFIER_OUT 1 01555 #define PARAM_QUALIFIER_INOUT 2 01556 01557 /* function parameter array presence */ 01558 #define PARAMETER_ARRAY_NOT_PRESENT 0 01559 #define PARAMETER_ARRAY_PRESENT 1 01560 01561 static int 01562 parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O, 01563 slang_variable * param) 01564 { 01565 int param_qual, precision_qual; 01566 01567 /* parse and validate the parameter's type qualifiers (there can be 01568 * two at most) because not all combinations are valid 01569 */ 01570 if (!parse_type_qualifier(C, ¶m->type.qualifier)) 01571 RETURN0; 01572 01573 param_qual = *C->I++; 01574 switch (param_qual) { 01575 case PARAM_QUALIFIER_IN: 01576 if (param->type.qualifier != SLANG_QUAL_CONST 01577 && param->type.qualifier != SLANG_QUAL_NONE) { 01578 slang_info_log_error(C->L, "Invalid type qualifier."); 01579 RETURN0; 01580 } 01581 break; 01582 case PARAM_QUALIFIER_OUT: 01583 if (param->type.qualifier == SLANG_QUAL_NONE) 01584 param->type.qualifier = SLANG_QUAL_OUT; 01585 else { 01586 slang_info_log_error(C->L, "Invalid type qualifier."); 01587 RETURN0; 01588 } 01589 break; 01590 case PARAM_QUALIFIER_INOUT: 01591 if (param->type.qualifier == SLANG_QUAL_NONE) 01592 param->type.qualifier = SLANG_QUAL_INOUT; 01593 else { 01594 slang_info_log_error(C->L, "Invalid type qualifier."); 01595 RETURN0; 01596 } 01597 break; 01598 default: 01599 RETURN0; 01600 } 01601 01602 /* parse precision qualifier (lowp, mediump, highp */ 01603 precision_qual = *C->I++; 01604 /* ignored at this time */ 01605 (void) precision_qual; 01606 01607 /* parse parameter's type specifier and name */ 01608 if (!parse_type_specifier(C, O, ¶m->type.specifier)) 01609 RETURN0; 01610 if (!parse_type_array_size(C, O, ¶m->type.array_len)) 01611 RETURN0; 01612 param->a_name = parse_identifier(C); 01613 if (param->a_name == SLANG_ATOM_NULL) 01614 RETURN0; 01615 01616 /* first-class array 01617 */ 01618 if (param->type.array_len >= 0) { 01619 slang_type_specifier p; 01620 01621 slang_type_specifier_ctr(&p); 01622 if (!slang_type_specifier_copy(&p, ¶m->type.specifier)) { 01623 slang_type_specifier_dtr(&p); 01624 RETURN0; 01625 } 01626 if (!convert_to_array(C, param, &p)) { 01627 slang_type_specifier_dtr(&p); 01628 RETURN0; 01629 } 01630 slang_type_specifier_dtr(&p); 01631 param->array_len = param->type.array_len; 01632 } 01633 01634 /* if the parameter is an array, parse its size (the size must be 01635 * explicitly defined 01636 */ 01637 if (*C->I++ == PARAMETER_ARRAY_PRESENT) { 01638 slang_type_specifier p; 01639 01640 if (param->type.array_len >= 0) { 01641 slang_info_log_error(C->L, "multi-dimensional arrays not allowed"); 01642 RETURN0; 01643 } 01644 slang_type_specifier_ctr(&p); 01645 if (!slang_type_specifier_copy(&p, ¶m->type.specifier)) { 01646 slang_type_specifier_dtr(&p); 01647 RETURN0; 01648 } 01649 if (!convert_to_array(C, param, &p)) { 01650 slang_type_specifier_dtr(&p); 01651 RETURN0; 01652 } 01653 slang_type_specifier_dtr(&p); 01654 if (!parse_array_len(C, O, ¶m->array_len)) 01655 RETURN0; 01656 } 01657 01658 #if 0 01659 /* calculate the parameter size */ 01660 if (!calculate_var_size(C, O, param)) 01661 RETURN0; 01662 #endif 01663 /* TODO: allocate the local address here? */ 01664 return 1; 01665 } 01666 01667 /* function type */ 01668 #define FUNCTION_ORDINARY 0 01669 #define FUNCTION_CONSTRUCTOR 1 01670 #define FUNCTION_OPERATOR 2 01671 01672 /* function parameter */ 01673 #define PARAMETER_NONE 0 01674 #define PARAMETER_NEXT 1 01675 01676 /* operator type */ 01677 #define OPERATOR_ADDASSIGN 1 01678 #define OPERATOR_SUBASSIGN 2 01679 #define OPERATOR_MULASSIGN 3 01680 #define OPERATOR_DIVASSIGN 4 01681 /*#define OPERATOR_MODASSIGN 5*/ 01682 /*#define OPERATOR_LSHASSIGN 6*/ 01683 /*#define OPERATOR_RSHASSIGN 7*/ 01684 /*#define OPERATOR_ANDASSIGN 8*/ 01685 /*#define OPERATOR_XORASSIGN 9*/ 01686 /*#define OPERATOR_ORASSIGN 10*/ 01687 #define OPERATOR_LOGICALXOR 11 01688 /*#define OPERATOR_BITOR 12*/ 01689 /*#define OPERATOR_BITXOR 13*/ 01690 /*#define OPERATOR_BITAND 14*/ 01691 #define OPERATOR_LESS 15 01692 #define OPERATOR_GREATER 16 01693 #define OPERATOR_LESSEQUAL 17 01694 #define OPERATOR_GREATEREQUAL 18 01695 /*#define OPERATOR_LSHIFT 19*/ 01696 /*#define OPERATOR_RSHIFT 20*/ 01697 #define OPERATOR_MULTIPLY 21 01698 #define OPERATOR_DIVIDE 22 01699 /*#define OPERATOR_MODULUS 23*/ 01700 #define OPERATOR_INCREMENT 24 01701 #define OPERATOR_DECREMENT 25 01702 #define OPERATOR_PLUS 26 01703 #define OPERATOR_MINUS 27 01704 /*#define OPERATOR_COMPLEMENT 28*/ 01705 #define OPERATOR_NOT 29 01706 01707 static const struct 01708 { 01709 unsigned int o_code; 01710 const char *o_name; 01711 } operator_names[] = { 01712 {OPERATOR_INCREMENT, "++"}, 01713 {OPERATOR_ADDASSIGN, "+="}, 01714 {OPERATOR_PLUS, "+"}, 01715 {OPERATOR_DECREMENT, "--"}, 01716 {OPERATOR_SUBASSIGN, "-="}, 01717 {OPERATOR_MINUS, "-"}, 01718 {OPERATOR_NOT, "!"}, 01719 {OPERATOR_MULASSIGN, "*="}, 01720 {OPERATOR_MULTIPLY, "*"}, 01721 {OPERATOR_DIVASSIGN, "/="}, 01722 {OPERATOR_DIVIDE, "/"}, 01723 {OPERATOR_LESSEQUAL, "<="}, 01724 /*{ OPERATOR_LSHASSIGN, "<<=" }, */ 01725 /*{ OPERATOR_LSHIFT, "<<" }, */ 01726 {OPERATOR_LESS, "<"}, 01727 {OPERATOR_GREATEREQUAL, ">="}, 01728 /*{ OPERATOR_RSHASSIGN, ">>=" }, */ 01729 /*{ OPERATOR_RSHIFT, ">>" }, */ 01730 {OPERATOR_GREATER, ">"}, 01731 /*{ OPERATOR_MODASSIGN, "%=" }, */ 01732 /*{ OPERATOR_MODULUS, "%" }, */ 01733 /*{ OPERATOR_ANDASSIGN, "&=" }, */ 01734 /*{ OPERATOR_BITAND, "&" }, */ 01735 /*{ OPERATOR_ORASSIGN, "|=" }, */ 01736 /*{ OPERATOR_BITOR, "|" }, */ 01737 /*{ OPERATOR_COMPLEMENT, "~" }, */ 01738 /*{ OPERATOR_XORASSIGN, "^=" }, */ 01739 {OPERATOR_LOGICALXOR, "^^"}, 01740 /*{ OPERATOR_BITXOR, "^" } */ 01741 }; 01742 01743 static slang_atom 01744 parse_operator_name(slang_parse_ctx * C) 01745 { 01746 unsigned int i; 01747 01748 for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) { 01749 if (operator_names[i].o_code == (unsigned int) (*C->I)) { 01750 slang_atom atom = 01751 slang_atom_pool_atom(C->atoms, operator_names[i].o_name); 01752 if (atom == SLANG_ATOM_NULL) { 01753 slang_info_log_memory(C->L); 01754 RETURN0; 01755 } 01756 C->I++; 01757 return atom; 01758 } 01759 } 01760 RETURN0; 01761 } 01762 01763 01764 static int 01765 parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O, 01766 slang_function * func) 01767 { 01768 GLuint functype; 01769 /* parse function type and name */ 01770 if (!parse_fully_specified_type(C, O, &func->header.type)) 01771 RETURN0; 01772 01773 functype = *C->I++; 01774 switch (functype) { 01775 case FUNCTION_ORDINARY: 01776 func->kind = SLANG_FUNC_ORDINARY; 01777 func->header.a_name = parse_identifier(C); 01778 if (func->header.a_name == SLANG_ATOM_NULL) 01779 RETURN0; 01780 break; 01781 case FUNCTION_CONSTRUCTOR: 01782 func->kind = SLANG_FUNC_CONSTRUCTOR; 01783 if (func->header.type.specifier.type == SLANG_SPEC_STRUCT) 01784 RETURN0; 01785 func->header.a_name = 01786 slang_atom_pool_atom(C->atoms, 01787 slang_type_specifier_type_to_string 01788 (func->header.type.specifier.type)); 01789 if (func->header.a_name == SLANG_ATOM_NULL) { 01790 slang_info_log_memory(C->L); 01791 RETURN0; 01792 } 01793 break; 01794 case FUNCTION_OPERATOR: 01795 func->kind = SLANG_FUNC_OPERATOR; 01796 func->header.a_name = parse_operator_name(C); 01797 if (func->header.a_name == SLANG_ATOM_NULL) 01798 RETURN0; 01799 break; 01800 default: 01801 RETURN0; 01802 } 01803 01804 if (!legal_identifier(func->header.a_name)) { 01805 slang_info_log_error(C->L, "illegal function name '%s'", 01806 (char *) func->header.a_name); 01807 RETURN0; 01808 } 01809 01810 /* parse function parameters */ 01811 while (*C->I++ == PARAMETER_NEXT) { 01812 slang_variable *p = slang_variable_scope_grow(func->parameters); 01813 if (!p) { 01814 slang_info_log_memory(C->L); 01815 RETURN0; 01816 } 01817 if (!parse_parameter_declaration(C, O, p)) 01818 RETURN0; 01819 } 01820 01821 /* if the function returns a value, append a hidden __retVal 'out' 01822 * parameter that corresponds to the return value. 01823 */ 01824 if (_slang_function_has_return_value(func)) { 01825 slang_variable *p = slang_variable_scope_grow(func->parameters); 01826 slang_atom a_retVal = slang_atom_pool_atom(C->atoms, "__retVal"); 01827 assert(a_retVal); 01828 p->a_name = a_retVal; 01829 p->type = func->header.type; 01830 p->type.qualifier = SLANG_QUAL_OUT; 01831 } 01832 01833 /* function formal parameters and local variables share the same 01834 * scope, so save the information about param count in a seperate 01835 * place also link the scope to the global variable scope so when a 01836 * given identifier is not found here, the search process continues 01837 * in the global space 01838 */ 01839 func->param_count = func->parameters->num_variables; 01840 func->parameters->outer_scope = O->vars; 01841 01842 return 1; 01843 } 01844 01845 static int 01846 parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O, 01847 slang_function * func) 01848 { 01849 slang_output_ctx o = *O; 01850 01851 if (!parse_function_prototype(C, O, func)) 01852 RETURN0; 01853 01854 /* create function's body operation */ 01855 func->body = (slang_operation *) _slang_alloc(sizeof(slang_operation)); 01856 if (func->body == NULL) { 01857 slang_info_log_memory(C->L); 01858 RETURN0; 01859 } 01860 if (!slang_operation_construct(func->body)) { 01861 _slang_free(func->body); 01862 func->body = NULL; 01863 slang_info_log_memory(C->L); 01864 RETURN0; 01865 } 01866 01867 /* to parse the body the parse context is modified in order to 01868 * capture parsed variables into function's local variable scope 01869 */ 01870 C->global_scope = GL_FALSE; 01871 o.vars = func->parameters; 01872 if (!parse_statement(C, &o, func->body)) 01873 RETURN0; 01874 01875 C->global_scope = GL_TRUE; 01876 return 1; 01877 } 01878 01879 static GLboolean 01880 initialize_global(slang_assemble_ctx * A, slang_variable * var) 01881 { 01882 slang_operation op_id, op_assign; 01883 GLboolean result; 01884 01885 /* construct the left side of assignment */ 01886 if (!slang_operation_construct(&op_id)) 01887 return GL_FALSE; 01888 op_id.type = SLANG_OPER_IDENTIFIER; 01889 op_id.a_id = var->a_name; 01890 01891 /* put the variable into operation's scope */ 01892 op_id.locals->variables = 01893 (slang_variable **) _slang_alloc(sizeof(slang_variable *)); 01894 if (op_id.locals->variables == NULL) { 01895 slang_operation_destruct(&op_id); 01896 return GL_FALSE; 01897 } 01898 op_id.locals->num_variables = 1; 01899 op_id.locals->variables[0] = var; 01900 01901 /* construct the assignment expression */ 01902 if (!slang_operation_construct(&op_assign)) { 01903 op_id.locals->num_variables = 0; 01904 slang_operation_destruct(&op_id); 01905 return GL_FALSE; 01906 } 01907 op_assign.type = SLANG_OPER_ASSIGN; 01908 op_assign.children = 01909 (slang_operation *) _slang_alloc(2 * sizeof(slang_operation)); 01910 if (op_assign.children == NULL) { 01911 slang_operation_destruct(&op_assign); 01912 op_id.locals->num_variables = 0; 01913 slang_operation_destruct(&op_id); 01914 return GL_FALSE; 01915 } 01916 op_assign.num_children = 2; 01917 op_assign.children[0] = op_id; 01918 op_assign.children[1] = *var->initializer; 01919 01920 result = 1; 01921 01922 /* carefully destroy the operations */ 01923 op_assign.num_children = 0; 01924 _slang_free(op_assign.children); 01925 op_assign.children = NULL; 01926 slang_operation_destruct(&op_assign); 01927 op_id.locals->num_variables = 0; 01928 slang_operation_destruct(&op_id); 01929 01930 if (!result) 01931 return GL_FALSE; 01932 01933 return GL_TRUE; 01934 } 01935 01936 /* init declarator list */ 01937 #define DECLARATOR_NONE 0 01938 #define DECLARATOR_NEXT 1 01939 01940 /* variable declaration */ 01941 #define VARIABLE_NONE 0 01942 #define VARIABLE_IDENTIFIER 1 01943 #define VARIABLE_INITIALIZER 2 01944 #define VARIABLE_ARRAY_EXPLICIT 3 01945 #define VARIABLE_ARRAY_UNKNOWN 4 01946 01947 01951 static int 01952 parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, 01953 const slang_fully_specified_type * type) 01954 { 01955 slang_variable *var; 01956 slang_atom a_name; 01957 01958 /* empty init declatator (without name, e.g. "float ;") */ 01959 if (*C->I++ == VARIABLE_NONE) 01960 return 1; 01961 01962 a_name = parse_identifier(C); 01963 01964 /* check if name is already in this scope */ 01965 if (_slang_variable_locate(O->vars, a_name, GL_FALSE)) { 01966 slang_info_log_error(C->L, 01967 "declaration of '%s' conflicts with previous declaration", 01968 (char *) a_name); 01969 RETURN0; 01970 } 01971 01972 /* make room for the new variable and initialize it */ 01973 var = slang_variable_scope_grow(O->vars); 01974 if (!var) { 01975 slang_info_log_memory(C->L); 01976 RETURN0; 01977 } 01978 01979 /* copy the declarator type qualifier/etc info, parse the identifier */ 01980 var->type.qualifier = type->qualifier; 01981 var->type.centroid = type->centroid; 01982 var->type.precision = type->precision; 01983 var->type.variant = type->variant; 01984 var->type.array_len = type->array_len; 01985 var->a_name = a_name; 01986 if (var->a_name == SLANG_ATOM_NULL) 01987 RETURN0; 01988 01989 switch (*C->I++) { 01990 case VARIABLE_NONE: 01991 /* simple variable declarator - just copy the specifier */ 01992 if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier)) 01993 RETURN0; 01994 break; 01995 case VARIABLE_INITIALIZER: 01996 /* initialized variable - copy the specifier and parse the expression */ 01997 if (0 && type->array_len >= 0) { 01998 /* The type was something like "float[4]" */ 01999 convert_to_array(C, var, &type->specifier); 02000 var->array_len = type->array_len; 02001 } 02002 else { 02003 if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier)) 02004 RETURN0; 02005 } 02006 var->initializer = 02007 (slang_operation *) _slang_alloc(sizeof(slang_operation)); 02008 if (var->initializer == NULL) { 02009 slang_info_log_memory(C->L); 02010 RETURN0; 02011 } 02012 if (!slang_operation_construct(var->initializer)) { 02013 _slang_free(var->initializer); 02014 var->initializer = NULL; 02015 slang_info_log_memory(C->L); 02016 RETURN0; 02017 } 02018 if (!parse_expression(C, O, var->initializer)) 02019 RETURN0; 02020 break; 02021 case VARIABLE_ARRAY_UNKNOWN: 02022 /* unsized array - mark it as array and copy the specifier to 02023 * the array element 02024 */ 02025 if (type->array_len >= 0) { 02026 slang_info_log_error(C->L, "multi-dimensional arrays not allowed"); 02027 RETURN0; 02028 } 02029 if (!convert_to_array(C, var, &type->specifier)) 02030 return GL_FALSE; 02031 break; 02032 case VARIABLE_ARRAY_EXPLICIT: 02033 if (type->array_len >= 0) { 02034 /* the user is trying to do something like: float[2] x[3]; */ 02035 slang_info_log_error(C->L, "multi-dimensional arrays not allowed"); 02036 RETURN0; 02037 } 02038 if (!convert_to_array(C, var, &type->specifier)) 02039 return GL_FALSE; 02040 if (!parse_array_len(C, O, &var->array_len)) 02041 return GL_FALSE; 02042 break; 02043 default: 02044 RETURN0; 02045 } 02046 02047 /* allocate global address space for a variable with a known size */ 02048 if (C->global_scope 02049 && !(var->type.specifier.type == SLANG_SPEC_ARRAY 02050 && var->array_len == 0)) { 02051 if (!calculate_var_size(C, O, var)) 02052 return GL_FALSE; 02053 } 02054 02055 /* emit code for global var decl */ 02056 if (C->global_scope) { 02057 slang_assemble_ctx A; 02058 A.atoms = C->atoms; 02059 A.space.funcs = O->funs; 02060 A.space.structs = O->structs; 02061 A.space.vars = O->vars; 02062 A.program = O->program; 02063 A.pragmas = O->pragmas; 02064 A.vartable = O->vartable; 02065 A.log = C->L; 02066 A.curFuncEndLabel = NULL; 02067 if (!_slang_codegen_global_variable(&A, var, C->type)) 02068 RETURN0; 02069 } 02070 02071 /* initialize global variable */ 02072 if (C->global_scope) { 02073 if (var->initializer != NULL) { 02074 slang_assemble_ctx A; 02075 02076 A.atoms = C->atoms; 02077 A.space.funcs = O->funs; 02078 A.space.structs = O->structs; 02079 A.space.vars = O->vars; 02080 if (!initialize_global(&A, var)) 02081 RETURN0; 02082 } 02083 } 02084 return 1; 02085 } 02086 02091 static int 02092 parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O) 02093 { 02094 slang_fully_specified_type type; 02095 02096 /* parse the fully specified type, common to all declarators */ 02097 if (!slang_fully_specified_type_construct(&type)) 02098 RETURN0; 02099 if (!parse_fully_specified_type(C, O, &type)) { 02100 slang_fully_specified_type_destruct(&type); 02101 RETURN0; 02102 } 02103 02104 /* parse declarators, pass-in the parsed type */ 02105 do { 02106 if (!parse_init_declarator(C, O, &type)) { 02107 slang_fully_specified_type_destruct(&type); 02108 RETURN0; 02109 } 02110 } 02111 while (*C->I++ == DECLARATOR_NEXT); 02112 02113 slang_fully_specified_type_destruct(&type); 02114 return 1; 02115 } 02116 02117 02126 static GLboolean 02127 parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, 02128 slang_function ** parsed_func_ret) 02129 { 02130 slang_function parsed_func, *found_func; 02131 02132 /* parse function definition/declaration */ 02133 if (!slang_function_construct(&parsed_func)) 02134 return GL_FALSE; 02135 if (definition) { 02136 if (!parse_function_definition(C, O, &parsed_func)) { 02137 slang_function_destruct(&parsed_func); 02138 return GL_FALSE; 02139 } 02140 } 02141 else { 02142 if (!parse_function_prototype(C, O, &parsed_func)) { 02143 slang_function_destruct(&parsed_func); 02144 return GL_FALSE; 02145 } 02146 } 02147 02148 /* find a function with a prototype matching the parsed one - only 02149 * the current scope is being searched to allow built-in function 02150 * overriding 02151 */ 02152 found_func = slang_function_scope_find(O->funs, &parsed_func, 0); 02153 if (found_func == NULL) { 02154 /* New function, add it to the function list */ 02155 O->funs->functions = 02156 (slang_function *) _slang_realloc(O->funs->functions, 02157 O->funs->num_functions 02158 * sizeof(slang_function), 02159 (O->funs->num_functions + 1) 02160 * sizeof(slang_function)); 02161 if (O->funs->functions == NULL) { 02162 slang_info_log_memory(C->L); 02163 slang_function_destruct(&parsed_func); 02164 return GL_FALSE; 02165 } 02166 O->funs->functions[O->funs->num_functions] = parsed_func; 02167 O->funs->num_functions++; 02168 02169 /* return the newly parsed function */ 02170 *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1]; 02171 } 02172 else { 02173 /* previously defined or declared */ 02174 /* TODO: check function return type qualifiers and specifiers */ 02175 if (definition) { 02176 if (found_func->body != NULL) { 02177 slang_info_log_error(C->L, "%s: function already has a body.", 02178 slang_atom_pool_id(C->atoms, 02179 parsed_func.header. 02180 a_name)); 02181 slang_function_destruct(&parsed_func); 02182 return GL_FALSE; 02183 } 02184 02185 /* destroy the existing function declaration and replace it 02186 * with the new one 02187 */ 02188 slang_function_destruct(found_func); 02189 *found_func = parsed_func; 02190 } 02191 else { 02192 /* another declaration of the same function prototype - ignore it */ 02193 slang_function_destruct(&parsed_func); 02194 } 02195 02196 /* return the found function */ 02197 *parsed_func_ret = found_func; 02198 } 02199 02200 return GL_TRUE; 02201 } 02202 02203 /* declaration */ 02204 #define DECLARATION_FUNCTION_PROTOTYPE 1 02205 #define DECLARATION_INIT_DECLARATOR_LIST 2 02206 02207 static int 02208 parse_declaration(slang_parse_ctx * C, slang_output_ctx * O) 02209 { 02210 switch (*C->I++) { 02211 case DECLARATION_INIT_DECLARATOR_LIST: 02212 if (!parse_init_declarator_list(C, O)) 02213 RETURN0; 02214 break; 02215 case DECLARATION_FUNCTION_PROTOTYPE: 02216 { 02217 slang_function *dummy_func; 02218 02219 if (!parse_function(C, O, 0, &dummy_func)) 02220 RETURN0; 02221 } 02222 break; 02223 default: 02224 RETURN0; 02225 } 02226 return 1; 02227 } 02228 02229 static int 02230 parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O) 02231 { 02232 int precision, type; 02233 02234 if (!O->allow_precision) { 02235 slang_info_log_error(C->L, "syntax error at \"precision\""); 02236 RETURN0; 02237 } 02238 02239 precision = *C->I++; 02240 switch (precision) { 02241 case PRECISION_LOW: 02242 case PRECISION_MEDIUM: 02243 case PRECISION_HIGH: 02244 /* OK */ 02245 break; 02246 default: 02247 _mesa_problem(NULL, "unexpected precision %d at %s:%d\n", 02248 precision, __FILE__, __LINE__); 02249 RETURN0; 02250 } 02251 02252 type = *C->I++; 02253 switch (type) { 02254 case TYPE_SPECIFIER_FLOAT: 02255 case TYPE_SPECIFIER_INT: 02256 case TYPE_SPECIFIER_SAMPLER1D: 02257 case TYPE_SPECIFIER_SAMPLER2D: 02258 case TYPE_SPECIFIER_SAMPLER3D: 02259 case TYPE_SPECIFIER_SAMPLERCUBE: 02260 case TYPE_SPECIFIER_SAMPLER1DSHADOW: 02261 case TYPE_SPECIFIER_SAMPLER2DSHADOW: 02262 case TYPE_SPECIFIER_SAMPLER2DRECT: 02263 case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW: 02264 /* OK */ 02265 break; 02266 default: 02267 _mesa_problem(NULL, "unexpected type %d at %s:%d\n", 02268 type, __FILE__, __LINE__); 02269 RETURN0; 02270 } 02271 02272 assert(type < TYPE_SPECIFIER_COUNT); 02273 O->default_precision[type] = precision; 02274 02275 return 1; 02276 } 02277 02278 02283 static void 02284 init_default_precision(slang_output_ctx *O, slang_unit_type type) 02285 { 02286 GLuint i; 02287 for (i = 0; i < TYPE_SPECIFIER_COUNT; i++) { 02288 #if FEATURE_es2_glsl 02289 O->default_precision[i] = PRECISION_LOW; 02290 #else 02291 O->default_precision[i] = PRECISION_HIGH; 02292 #endif 02293 } 02294 02295 if (type == SLANG_UNIT_VERTEX_SHADER) { 02296 O->default_precision[TYPE_SPECIFIER_FLOAT] = PRECISION_HIGH; 02297 O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_HIGH; 02298 } 02299 else { 02300 O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_MEDIUM; 02301 } 02302 } 02303 02304 02305 static int 02306 parse_invariant(slang_parse_ctx * C, slang_output_ctx * O) 02307 { 02308 if (O->allow_invariant) { 02309 slang_atom *a = parse_identifier(C); 02310 /* XXX not doing anything with this var yet */ 02311 /*printf("ID: %s\n", (char*) a);*/ 02312 return a ? 1 : 0; 02313 } 02314 else { 02315 slang_info_log_error(C->L, "syntax error at \"invariant\""); 02316 RETURN0; 02317 } 02318 } 02319 02320 02321 /* external declaration or default precision specifier */ 02322 #define EXTERNAL_NULL 0 02323 #define EXTERNAL_FUNCTION_DEFINITION 1 02324 #define EXTERNAL_DECLARATION 2 02325 #define DEFAULT_PRECISION 3 02326 #define INVARIANT_STMT 4 02327 02328 02329 static GLboolean 02330 parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, 02331 struct gl_shader *shader) 02332 { 02333 GET_CURRENT_CONTEXT(ctx); 02334 slang_output_ctx o; 02335 GLboolean success; 02336 GLuint maxRegs; 02337 slang_function *mainFunc = NULL; 02338 02339 if (unit->type == SLANG_UNIT_FRAGMENT_BUILTIN || 02340 unit->type == SLANG_UNIT_FRAGMENT_SHADER) { 02341 maxRegs = ctx->Const.FragmentProgram.MaxTemps; 02342 } 02343 else { 02344 assert(unit->type == SLANG_UNIT_VERTEX_BUILTIN || 02345 unit->type == SLANG_UNIT_VERTEX_SHADER); 02346 maxRegs = ctx->Const.VertexProgram.MaxTemps; 02347 } 02348 02349 /* setup output context */ 02350 o.funs = &unit->funs; 02351 o.structs = &unit->structs; 02352 o.vars = &unit->vars; 02353 o.program = shader ? shader->Program : NULL; 02354 o.pragmas = shader ? &shader->Pragmas : NULL; 02355 o.vartable = _slang_new_var_table(maxRegs); 02356 _slang_push_var_table(o.vartable); 02357 02358 /* allow 'invariant' keyword? */ 02359 #if FEATURE_es2_glsl 02360 o.allow_invariant = GL_TRUE; 02361 #else 02362 o.allow_invariant = (C->version >= 120) ? GL_TRUE : GL_FALSE; 02363 #endif 02364 02365 /* allow 'centroid' keyword? */ 02366 o.allow_centroid = (C->version >= 120) ? GL_TRUE : GL_FALSE; 02367 02368 /* allow 'lowp/mediump/highp' keywords? */ 02369 #if FEATURE_es2_glsl 02370 o.allow_precision = GL_TRUE; 02371 #else 02372 o.allow_precision = (C->version >= 120) ? GL_TRUE : GL_FALSE; 02373 #endif 02374 init_default_precision(&o, unit->type); 02375 02376 /* allow 'float[]' keyword? */ 02377 o.allow_array_types = (C->version >= 120) ? GL_TRUE : GL_FALSE; 02378 02379 /* parse individual functions and declarations */ 02380 while (*C->I != EXTERNAL_NULL) { 02381 switch (*C->I++) { 02382 case EXTERNAL_FUNCTION_DEFINITION: 02383 { 02384 slang_function *func; 02385 success = parse_function(C, &o, 1, &func); 02386 if (success && 02387 _mesa_strcmp((char *) func->header.a_name, "main") == 0) { 02388 /* found main() */ 02389 mainFunc = func; 02390 } 02391 } 02392 break; 02393 case EXTERNAL_DECLARATION: 02394 success = parse_declaration(C, &o); 02395 break; 02396 case DEFAULT_PRECISION: 02397 success = parse_default_precision(C, &o); 02398 break; 02399 case INVARIANT_STMT: 02400 success = parse_invariant(C, &o); 02401 break; 02402 default: 02403 success = GL_FALSE; 02404 } 02405 02406 if (!success) { 02407 /* xxx free codegen */ 02408 _slang_pop_var_table(o.vartable); 02409 return GL_FALSE; 02410 } 02411 } 02412 C->I++; 02413 02414 if (mainFunc) { 02415 /* assemble (generate code) for main() */ 02416 slang_assemble_ctx A; 02417 02418 A.atoms = C->atoms; 02419 A.space.funcs = o.funs; 02420 A.space.structs = o.structs; 02421 A.space.vars = o.vars; 02422 A.program = o.program; 02423 A.pragmas = &shader->Pragmas; 02424 A.vartable = o.vartable; 02425 A.log = C->L; 02426 02427 /* main() takes no parameters */ 02428 if (mainFunc->param_count > 0) { 02429 slang_info_log_error(A.log, "main() takes no arguments"); 02430 return GL_FALSE; 02431 } 02432 02433 _slang_codegen_function(&A, mainFunc); 02434 02435 shader->Main = GL_TRUE; /* this shader defines main() */ 02436 } 02437 02438 _slang_pop_var_table(o.vartable); 02439 _slang_delete_var_table(o.vartable); 02440 02441 return GL_TRUE; 02442 } 02443 02444 static GLboolean 02445 compile_binary(const byte * prod, slang_code_unit * unit, 02446 GLuint version, 02447 slang_unit_type type, slang_info_log * infolog, 02448 slang_code_unit * builtin, slang_code_unit * downlink, 02449 struct gl_shader *shader) 02450 { 02451 slang_parse_ctx C; 02452 02453 unit->type = type; 02454 02455 /* setup parse context */ 02456 C.I = prod; 02457 C.L = infolog; 02458 C.parsing_builtin = (builtin == NULL); 02459 C.global_scope = GL_TRUE; 02460 C.atoms = &unit->object->atompool; 02461 C.type = type; 02462 C.version = version; 02463 02464 if (!check_revision(&C)) 02465 return GL_FALSE; 02466 02467 if (downlink != NULL) { 02468 unit->vars.outer_scope = &downlink->vars; 02469 unit->funs.outer_scope = &downlink->funs; 02470 unit->structs.outer_scope = &downlink->structs; 02471 } 02472 02473 /* parse translation unit */ 02474 return parse_code_unit(&C, unit, shader); 02475 } 02476 02477 static GLboolean 02478 compile_with_grammar(grammar id, const char *source, slang_code_unit * unit, 02479 slang_unit_type type, slang_info_log * infolog, 02480 slang_code_unit * builtin, 02481 struct gl_shader *shader, 02482 const struct gl_extensions *extensions, 02483 struct gl_sl_pragmas *pragmas) 02484 { 02485 byte *prod; 02486 GLuint size, start, version; 02487 slang_string preprocessed; 02488 GLuint maxVersion; 02489 02490 #if FEATURE_ARB_shading_language_120 02491 maxVersion = 120; 02492 #elif FEATURE_es2_glsl 02493 maxVersion = 100; 02494 #else 02495 maxVersion = 110; 02496 #endif 02497 02498 /* First retrieve the version number. */ 02499 if (!_slang_preprocess_version(source, &version, &start, infolog)) 02500 return GL_FALSE; 02501 02502 if (version > maxVersion) { 02503 slang_info_log_error(infolog, 02504 "language version %.2f is not supported.", 02505 version * 0.01); 02506 return GL_FALSE; 02507 } 02508 02509 /* Now preprocess the source string. */ 02510 slang_string_init(&preprocessed); 02511 if (!_slang_preprocess_directives(&preprocessed, &source[start], 02512 infolog, extensions, pragmas)) { 02513 slang_string_free(&preprocessed); 02514 slang_info_log_error(infolog, "failed to preprocess the source."); 02515 return GL_FALSE; 02516 } 02517 02518 /* Finally check the syntax and generate its binary representation. */ 02519 if (!grammar_fast_check(id, 02520 (const byte *) (slang_string_cstr(&preprocessed)), 02521 &prod, &size, 65536)) { 02522 char buf[1024]; 02523 GLint pos; 02524 02525 slang_string_free(&preprocessed); 02526 grammar_get_last_error((byte *) (buf), sizeof(buf), &pos); 02527 slang_info_log_error(infolog, buf); 02528 /* syntax error (possibly in library code) */ 02529 #if 0 02530 { 02531 int line, col; 02532 char *s; 02533 s = (char *) _mesa_find_line_column((const GLubyte *) source, 02534 (const GLubyte *) source + pos, 02535 &line, &col); 02536 printf("Error on line %d, col %d: %s\n", line, col, s); 02537 } 02538 #endif 02539 return GL_FALSE; 02540 } 02541 slang_string_free(&preprocessed); 02542 02543 /* Syntax is okay - translate it to internal representation. */ 02544 if (!compile_binary(prod, unit, version, type, infolog, builtin, 02545 &builtin[SLANG_BUILTIN_TOTAL - 1], 02546 shader)) { 02547 grammar_alloc_free(prod); 02548 return GL_FALSE; 02549 } 02550 grammar_alloc_free(prod); 02551 return GL_TRUE; 02552 } 02553 02554 LONGSTRING static const char *slang_shader_syn = 02555 #include "library/slang_shader_syn.h" 02556 ; 02557 02558 static const byte slang_core_gc[] = { 02559 #include "library/slang_core_gc.h" 02560 }; 02561 02562 static const byte slang_120_core_gc[] = { 02563 #include "library/slang_120_core_gc.h" 02564 }; 02565 02566 static const byte slang_120_fragment_gc[] = { 02567 #include "library/slang_builtin_120_fragment_gc.h" 02568 }; 02569 02570 static const byte slang_common_builtin_gc[] = { 02571 #include "library/slang_common_builtin_gc.h" 02572 }; 02573 02574 static const byte slang_fragment_builtin_gc[] = { 02575 #include "library/slang_fragment_builtin_gc.h" 02576 }; 02577 02578 static const byte slang_vertex_builtin_gc[] = { 02579 #include "library/slang_vertex_builtin_gc.h" 02580 }; 02581 02582 static GLboolean 02583 compile_object(grammar * id, const char *source, slang_code_object * object, 02584 slang_unit_type type, slang_info_log * infolog, 02585 struct gl_shader *shader, 02586 const struct gl_extensions *extensions, 02587 struct gl_sl_pragmas *pragmas) 02588 { 02589 slang_code_unit *builtins = NULL; 02590 GLuint base_version = 110; 02591 02592 /* load GLSL grammar */ 02593 *id = grammar_load_from_text((const byte *) (slang_shader_syn)); 02594 if (*id == 0) { 02595 byte buf[1024]; 02596 int pos; 02597 02598 grammar_get_last_error(buf, 1024, &pos); 02599 slang_info_log_error(infolog, (const char *) (buf)); 02600 return GL_FALSE; 02601 } 02602 02603 /* set shader type - the syntax is slightly different for different shaders */ 02604 if (type == SLANG_UNIT_FRAGMENT_SHADER 02605 || type == SLANG_UNIT_FRAGMENT_BUILTIN) 02606 grammar_set_reg8(*id, (const byte *) "shader_type", 1); 02607 else 02608 grammar_set_reg8(*id, (const byte *) "shader_type", 2); 02609 02610 /* enable language extensions */ 02611 grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1); 02612 02613 /* if parsing user-specified shader, load built-in library */ 02614 if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_VERTEX_SHADER) { 02615 /* compile core functionality first */ 02616 if (!compile_binary(slang_core_gc, 02617 &object->builtin[SLANG_BUILTIN_CORE], 02618 base_version, 02619 SLANG_UNIT_FRAGMENT_BUILTIN, infolog, 02620 NULL, NULL, NULL)) 02621 return GL_FALSE; 02622 02623 #if FEATURE_ARB_shading_language_120 02624 if (!compile_binary(slang_120_core_gc, 02625 &object->builtin[SLANG_BUILTIN_120_CORE], 02626 120, 02627 SLANG_UNIT_FRAGMENT_BUILTIN, infolog, 02628 NULL, &object->builtin[SLANG_BUILTIN_CORE], NULL)) 02629 return GL_FALSE; 02630 #endif 02631 02632 /* compile common functions and variables, link to core */ 02633 if (!compile_binary(slang_common_builtin_gc, 02634 &object->builtin[SLANG_BUILTIN_COMMON], 02635 #if FEATURE_ARB_shading_language_120 02636 120, 02637 #else 02638 base_version, 02639 #endif 02640 SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, 02641 #if FEATURE_ARB_shading_language_120 02642 &object->builtin[SLANG_BUILTIN_120_CORE], 02643 #else 02644 &object->builtin[SLANG_BUILTIN_CORE], 02645 #endif 02646 NULL)) 02647 return GL_FALSE; 02648 02649 /* compile target-specific functions and variables, link to common */ 02650 if (type == SLANG_UNIT_FRAGMENT_SHADER) { 02651 if (!compile_binary(slang_fragment_builtin_gc, 02652 &object->builtin[SLANG_BUILTIN_TARGET], 02653 base_version, 02654 SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, 02655 &object->builtin[SLANG_BUILTIN_COMMON], NULL)) 02656 return GL_FALSE; 02657 #if FEATURE_ARB_shading_language_120 02658 if (!compile_binary(slang_120_fragment_gc, 02659 &object->builtin[SLANG_BUILTIN_TARGET], 02660 120, 02661 SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, 02662 &object->builtin[SLANG_BUILTIN_COMMON], NULL)) 02663 return GL_FALSE; 02664 #endif 02665 } 02666 else if (type == SLANG_UNIT_VERTEX_SHADER) { 02667 if (!compile_binary(slang_vertex_builtin_gc, 02668 &object->builtin[SLANG_BUILTIN_TARGET], 02669 base_version, 02670 SLANG_UNIT_VERTEX_BUILTIN, infolog, NULL, 02671 &object->builtin[SLANG_BUILTIN_COMMON], NULL)) 02672 return GL_FALSE; 02673 } 02674 02675 /* disable language extensions */ 02676 #if NEW_SLANG /* allow-built-ins */ 02677 grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1); 02678 #else 02679 grammar_set_reg8(*id, (const byte *) "parsing_builtin", 0); 02680 #endif 02681 builtins = object->builtin; 02682 } 02683 02684 /* compile the actual shader - pass-in built-in library for external shader */ 02685 return compile_with_grammar(*id, source, &object->unit, type, infolog, 02686 builtins, shader, extensions, pragmas); 02687 } 02688 02689 02690 static GLboolean 02691 compile_shader(GLcontext *ctx, slang_code_object * object, 02692 slang_unit_type type, slang_info_log * infolog, 02693 struct gl_shader *shader) 02694 { 02695 GLboolean success; 02696 grammar id = 0; 02697 02698 #if 0 /* for debug */ 02699 _mesa_printf("********* COMPILE SHADER ***********\n"); 02700 _mesa_printf("%s\n", shader->Source); 02701 _mesa_printf("************************************\n"); 02702 #endif 02703 02704 assert(shader->Program); 02705 02706 _slang_code_object_dtr(object); 02707 _slang_code_object_ctr(object); 02708 02709 success = compile_object(&id, shader->Source, object, type, infolog, shader, 02710 &ctx->Extensions, &shader->Pragmas); 02711 if (id != 0) 02712 grammar_destroy(id); 02713 if (!success) 02714 return GL_FALSE; 02715 02716 return GL_TRUE; 02717 } 02718 02719 02720 02721 GLboolean 02722 _slang_compile(GLcontext *ctx, struct gl_shader *shader) 02723 { 02724 GLboolean success; 02725 slang_info_log info_log; 02726 slang_code_object obj; 02727 slang_unit_type type; 02728 02729 if (shader->Type == GL_VERTEX_SHADER) { 02730 type = SLANG_UNIT_VERTEX_SHADER; 02731 } 02732 else { 02733 assert(shader->Type == GL_FRAGMENT_SHADER); 02734 type = SLANG_UNIT_FRAGMENT_SHADER; 02735 } 02736 02737 if (!shader->Source) 02738 return GL_FALSE; 02739 02740 ctx->Shader.MemPool = _slang_new_mempool(1024*1024); 02741 02742 shader->Main = GL_FALSE; 02743 02744 if (!shader->Program) { 02745 GLenum progTarget; 02746 if (shader->Type == GL_VERTEX_SHADER) 02747 progTarget = GL_VERTEX_PROGRAM_ARB; 02748 else 02749 progTarget = GL_FRAGMENT_PROGRAM_ARB; 02750 shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1); 02751 shader->Program->Parameters = _mesa_new_parameter_list(); 02752 shader->Program->Varying = _mesa_new_parameter_list(); 02753 shader->Program->Attributes = _mesa_new_parameter_list(); 02754 } 02755 02756 slang_info_log_construct(&info_log); 02757 _slang_code_object_ctr(&obj); 02758 02759 success = compile_shader(ctx, &obj, type, &info_log, shader); 02760 02761 /* free shader's prev info log */ 02762 if (shader->InfoLog) { 02763 _mesa_free(shader->InfoLog); 02764 shader->InfoLog = NULL; 02765 } 02766 02767 if (info_log.text) { 02768 /* copy info-log string to shader object */ 02769 shader->InfoLog = _mesa_strdup(info_log.text); 02770 } 02771 02772 if (info_log.error_flag) { 02773 success = GL_FALSE; 02774 } 02775 02776 slang_info_log_destruct(&info_log); 02777 _slang_code_object_dtr(&obj); 02778 02779 _slang_delete_mempool((slang_mempool *) ctx->Shader.MemPool); 02780 ctx->Shader.MemPool = NULL; 02781 02782 /* remove any reads of output registers */ 02783 #if 0 02784 printf("Pre-remove output reads:\n"); 02785 _mesa_print_program(shader->Program); 02786 #endif 02787 _mesa_remove_output_reads(shader->Program, PROGRAM_OUTPUT); 02788 if (shader->Type == GL_VERTEX_SHADER) { 02789 /* and remove writes to varying vars in vertex programs */ 02790 _mesa_remove_output_reads(shader->Program, PROGRAM_VARYING); 02791 } 02792 #if 0 02793 printf("Post-remove output reads:\n"); 02794 _mesa_print_program(shader->Program); 02795 #endif 02796 02797 return success; 02798 } 02799 Generated on Fri May 25 2012 04:18:48 for ReactOS by
1.7.6.1
|