~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/mesa/shader/slang/slang_compile.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Mesa 3-D graphics library
3
 
 *
4
 
 * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
5
 
 * Copyright (C) 2008 VMware, Inc.  All Rights Reserved.
6
 
 *
7
 
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 
 * copy of this software and associated documentation files (the "Software"),
9
 
 * to deal in the Software without restriction, including without limitation
10
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
 
 * and/or sell copies of the Software, and to permit persons to whom the
12
 
 * Software is furnished to do so, subject to the following conditions:
13
 
 *
14
 
 * The above copyright notice and this permission notice shall be included
15
 
 * in all copies or substantial portions of the Software.
16
 
 *
17
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21
 
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
 
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 
 */
24
 
 
25
 
/**
26
 
 * \file slang_compile.c
27
 
 * slang front-end compiler
28
 
 * \author Michal Krol
29
 
 */
30
 
 
31
 
#include "main/imports.h"
32
 
#include "main/context.h"
33
 
#include "shader/program.h"
34
 
#include "shader/programopt.h"
35
 
#include "shader/prog_optimize.h"
36
 
#include "shader/prog_print.h"
37
 
#include "shader/prog_parameter.h"
38
 
#include "../../glsl/pp/sl_pp_public.h"
39
 
#include "../../glsl/cl/sl_cl_parse.h"
40
 
#include "slang_codegen.h"
41
 
#include "slang_compile.h"
42
 
#include "slang_storage.h"
43
 
#include "slang_log.h"
44
 
#include "slang_mem.h"
45
 
#include "slang_vartable.h"
46
 
#include "slang_simplify.h"
47
 
 
48
 
/*
49
 
 * This is a straightforward implementation of the slang front-end
50
 
 * compiler.  Lots of error-checking functionality is missing but
51
 
 * every well-formed shader source should compile successfully and
52
 
 * execute as expected. However, some semantically ill-formed shaders
53
 
 * may be accepted resulting in undefined behaviour.
54
 
 */
55
 
 
56
 
 
57
 
/** re-defined below, should be the same though */
58
 
#define TYPE_SPECIFIER_COUNT 36
59
 
 
60
 
 
61
 
/**
62
 
 * Check if the given identifier is legal.
63
 
 */
64
 
static GLboolean
65
 
legal_identifier(slang_atom name)
66
 
{
67
 
   /* "gl_" is a reserved prefix */
68
 
   if (strncmp((char *) name, "gl_", 3) == 0) {
69
 
      return GL_FALSE;
70
 
   }
71
 
   return GL_TRUE;
72
 
}
73
 
 
74
 
 
75
 
/*
76
 
 * slang_code_unit
77
 
 */
78
 
 
79
 
GLvoid
80
 
_slang_code_unit_ctr(slang_code_unit * self,
81
 
                     struct slang_code_object_ * object)
82
 
{
83
 
   _slang_variable_scope_ctr(&self->vars);
84
 
   _slang_function_scope_ctr(&self->funs);
85
 
   _slang_struct_scope_ctr(&self->structs);
86
 
   self->object = object;
87
 
}
88
 
 
89
 
GLvoid
90
 
_slang_code_unit_dtr(slang_code_unit * self)
91
 
{
92
 
   slang_variable_scope_destruct(&self->vars);
93
 
   slang_function_scope_destruct(&self->funs);
94
 
   slang_struct_scope_destruct(&self->structs);
95
 
}
96
 
 
97
 
/*
98
 
 * slang_code_object
99
 
 */
100
 
 
101
 
GLvoid
102
 
_slang_code_object_ctr(slang_code_object * self)
103
 
{
104
 
   GLuint i;
105
 
 
106
 
   for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
107
 
      _slang_code_unit_ctr(&self->builtin[i], self);
108
 
   _slang_code_unit_ctr(&self->unit, self);
109
 
   slang_atom_pool_construct(&self->atompool);
110
 
}
111
 
 
112
 
GLvoid
113
 
_slang_code_object_dtr(slang_code_object * self)
114
 
{
115
 
   GLuint i;
116
 
 
117
 
   for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
118
 
      _slang_code_unit_dtr(&self->builtin[i]);
119
 
   _slang_code_unit_dtr(&self->unit);
120
 
   slang_atom_pool_destruct(&self->atompool);
121
 
}
122
 
 
123
 
 
124
 
/* slang_parse_ctx */
125
 
 
126
 
typedef struct slang_parse_ctx_
127
 
{
128
 
   const unsigned char *I;
129
 
   slang_info_log *L;
130
 
   int parsing_builtin;
131
 
   GLboolean global_scope;   /**< Is object being declared a global? */
132
 
   slang_atom_pool *atoms;
133
 
   slang_unit_type type;     /**< Vertex vs. Fragment */
134
 
   GLuint version;           /**< user-specified (or default) #version */
135
 
} slang_parse_ctx;
136
 
 
137
 
/* slang_output_ctx */
138
 
 
139
 
typedef struct slang_output_ctx_
140
 
{
141
 
   slang_variable_scope *vars;
142
 
   slang_function_scope *funs;
143
 
   slang_struct_scope *structs;
144
 
   struct gl_program *program;
145
 
   struct gl_sl_pragmas *pragmas;
146
 
   slang_var_table *vartable;
147
 
   GLuint default_precision[TYPE_SPECIFIER_COUNT];
148
 
   GLboolean allow_precision;
149
 
   GLboolean allow_invariant;
150
 
   GLboolean allow_centroid;
151
 
   GLboolean allow_array_types;  /* float[] syntax */
152
 
} slang_output_ctx;
153
 
 
154
 
/* _slang_compile() */
155
 
 
156
 
 
157
 
/* Debugging aid, print file/line where parsing error is detected */
158
 
#define RETURN0 \
159
 
   do { \
160
 
      if (0) \
161
 
         printf("slang error at %s:%d\n", __FILE__, __LINE__); \
162
 
      return 0; \
163
 
   } while (0)
164
 
 
165
 
 
166
 
static void
167
 
parse_identifier_str(slang_parse_ctx * C, char **id)
168
 
{
169
 
   *id = (char *) C->I;
170
 
   C->I += strlen(*id) + 1;
171
 
}
172
 
 
173
 
static slang_atom
174
 
parse_identifier(slang_parse_ctx * C)
175
 
{
176
 
   const char *id;
177
 
 
178
 
   id = (const char *) C->I;
179
 
   C->I += strlen(id) + 1;
180
 
   return slang_atom_pool_atom(C->atoms, id);
181
 
}
182
 
 
183
 
static int
184
 
is_hex_digit(char c)
185
 
{
186
 
   return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
187
 
}
188
 
 
189
 
static int
190
 
parse_general_number(slang_parse_ctx *ctx, float *number)
191
 
{
192
 
   char *flt = NULL;
193
 
 
194
 
   if (*ctx->I == '0') {
195
 
      int value = 0;
196
 
      const unsigned char *pi;
197
 
 
198
 
      if (ctx->I[1] == 'x' || ctx->I[1] == 'X') {
199
 
         ctx->I += 2;
200
 
         if (!is_hex_digit(*ctx->I)) {
201
 
            return 0;
202
 
         }
203
 
         do {
204
 
            int digit;
205
 
 
206
 
            if (*ctx->I >= '0' && *ctx->I <= '9') {
207
 
               digit = (int)(*ctx->I - '0');
208
 
            } else if (*ctx->I >= 'a' && *ctx->I <= 'f') {
209
 
               digit = (int)(*ctx->I - 'a') + 10;
210
 
            } else {
211
 
               digit = (int)(*ctx->I - 'A') + 10;
212
 
            }
213
 
            value = value * 0x10 + digit;
214
 
            ctx->I++;
215
 
         } while (is_hex_digit(*ctx->I));
216
 
         if (*ctx->I != '\0') {
217
 
            return 0;
218
 
         }
219
 
         ctx->I++;
220
 
         *number = (float)value;
221
 
         return 1;
222
 
      }
223
 
 
224
 
      pi = ctx->I;
225
 
      pi++;
226
 
      while (*pi >= '0' && *pi <= '7') {
227
 
         int digit;
228
 
 
229
 
         digit = (int)(*pi - '0');
230
 
         value = value * 010 + digit;
231
 
         pi++;
232
 
      }
233
 
      if (*pi == '\0') {
234
 
         pi++;
235
 
         ctx->I = pi;
236
 
         *number = (float)value;
237
 
         return 1;
238
 
      }
239
 
   }
240
 
 
241
 
   parse_identifier_str(ctx, &flt);
242
 
   flt = _mesa_strdup(flt);
243
 
   if (!flt) {
244
 
      return 0;
245
 
   }
246
 
   if (flt[strlen(flt) - 1] == 'f' || flt[strlen(flt) - 1] == 'F') {
247
 
      flt[strlen(flt) - 1] = '\0';
248
 
   }
249
 
   *number = _mesa_strtof(flt, (char **)NULL);
250
 
   free(flt);
251
 
 
252
 
   return 1;
253
 
}
254
 
 
255
 
static int
256
 
parse_number(slang_parse_ctx * C, int *number)
257
 
{
258
 
   const int radix = (int) (*C->I++);
259
 
 
260
 
   if (radix == 1) {
261
 
      float f = 0.0f;
262
 
 
263
 
      parse_general_number(C, &f);
264
 
      *number = (int)f;
265
 
   } else {
266
 
      *number = 0;
267
 
      while (*C->I != '\0') {
268
 
         int digit;
269
 
         if (*C->I >= '0' && *C->I <= '9')
270
 
            digit = (int) (*C->I - '0');
271
 
         else if (*C->I >= 'A' && *C->I <= 'Z')
272
 
            digit = (int) (*C->I - 'A') + 10;
273
 
         else
274
 
            digit = (int) (*C->I - 'a') + 10;
275
 
         *number = *number * radix + digit;
276
 
         C->I++;
277
 
      }
278
 
      C->I++;
279
 
   }
280
 
   if (*number > 65535)
281
 
      slang_info_log_warning(C->L, "%d: literal integer overflow.", *number);
282
 
   return 1;
283
 
}
284
 
 
285
 
static int
286
 
parse_float(slang_parse_ctx * C, float *number)
287
 
{
288
 
   if (*C->I == 1) {
289
 
      C->I++;
290
 
      parse_general_number(C, number);
291
 
   } else {
292
 
      char *integral = NULL;
293
 
      char *fractional = NULL;
294
 
      char *exponent = NULL;
295
 
      char *whole = NULL;
296
 
 
297
 
      parse_identifier_str(C, &integral);
298
 
      parse_identifier_str(C, &fractional);
299
 
      parse_identifier_str(C, &exponent);
300
 
 
301
 
      whole = (char *) _slang_alloc((strlen(integral) +
302
 
                                     strlen(fractional) +
303
 
                                     strlen(exponent) + 3) * sizeof(char));
304
 
      if (whole == NULL) {
305
 
         slang_info_log_memory(C->L);
306
 
         RETURN0;
307
 
      }
308
 
 
309
 
      slang_string_copy(whole, integral);
310
 
      slang_string_concat(whole, ".");
311
 
      slang_string_concat(whole, fractional);
312
 
      slang_string_concat(whole, "E");
313
 
      slang_string_concat(whole, exponent);
314
 
 
315
 
      *number = _mesa_strtof(whole, (char **) NULL);
316
 
 
317
 
      _slang_free(whole);
318
 
   }
319
 
 
320
 
   return 1;
321
 
}
322
 
 
323
 
/* revision number - increment after each change affecting emitted output */
324
 
#define REVISION 5
325
 
 
326
 
static int
327
 
check_revision(slang_parse_ctx * C)
328
 
{
329
 
   if (*C->I != REVISION) {
330
 
      slang_info_log_error(C->L, "Internal compiler error.");
331
 
      RETURN0;
332
 
   }
333
 
   C->I++;
334
 
   return 1;
335
 
}
336
 
 
337
 
static int parse_statement(slang_parse_ctx *, slang_output_ctx *,
338
 
                           slang_operation *);
339
 
static int parse_expression(slang_parse_ctx *, slang_output_ctx *,
340
 
                            slang_operation *);
341
 
static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *,
342
 
                                slang_type_specifier *);
343
 
static int
344
 
parse_type_array_size(slang_parse_ctx *C,
345
 
                      slang_output_ctx *O,
346
 
                      GLint *array_len);
347
 
 
348
 
static GLboolean
349
 
parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len)
350
 
{
351
 
   slang_operation array_size;
352
 
   slang_name_space space;
353
 
   GLboolean result;
354
 
 
355
 
   if (!slang_operation_construct(&array_size))
356
 
      return GL_FALSE;
357
 
   if (!parse_expression(C, O, &array_size)) {
358
 
      slang_operation_destruct(&array_size);
359
 
      return GL_FALSE;
360
 
   }
361
 
 
362
 
   space.funcs = O->funs;
363
 
   space.structs = O->structs;
364
 
   space.vars = O->vars;
365
 
 
366
 
   /* evaluate compile-time expression which is array size */
367
 
   _slang_simplify(&array_size, &space, C->atoms);
368
 
 
369
 
   if (array_size.type == SLANG_OPER_LITERAL_INT) {
370
 
      result = GL_TRUE;
371
 
      *len = (GLint) array_size.literal[0];
372
 
   } else if (array_size.type == SLANG_OPER_IDENTIFIER) {
373
 
      slang_variable *var = _slang_variable_locate(array_size.locals, array_size.a_id, GL_TRUE);
374
 
      if (!var) {
375
 
         slang_info_log_error(C->L, "undefined variable '%s'",
376
 
                              (char *) array_size.a_id);
377
 
         result = GL_FALSE;
378
 
      } else if (var->type.qualifier == SLANG_QUAL_CONST &&
379
 
                 var->type.specifier.type == SLANG_SPEC_INT) {
380
 
         if (var->initializer &&
381
 
             var->initializer->type == SLANG_OPER_LITERAL_INT) {
382
 
            *len = (GLint) var->initializer->literal[0];
383
 
            result = GL_TRUE;
384
 
         } else {
385
 
            slang_info_log_error(C->L, "unable to parse array size declaration");
386
 
            result = GL_FALSE;
387
 
         }
388
 
      } else {
389
 
         slang_info_log_error(C->L, "unable to parse array size declaration");
390
 
         result = GL_FALSE;
391
 
      }
392
 
   } else {
393
 
      result = GL_FALSE;
394
 
   }
395
 
 
396
 
   slang_operation_destruct(&array_size);
397
 
   return result;
398
 
}
399
 
 
400
 
static GLboolean
401
 
calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O,
402
 
                   slang_variable * var)
403
 
{
404
 
   slang_storage_aggregate agg;
405
 
 
406
 
   if (!slang_storage_aggregate_construct(&agg))
407
 
      return GL_FALSE;
408
 
   if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len,
409
 
                                  O->funs, O->structs, O->vars, C->atoms)) {
410
 
      slang_storage_aggregate_destruct(&agg);
411
 
      return GL_FALSE;
412
 
   }
413
 
   var->size = _slang_sizeof_aggregate(&agg);
414
 
   slang_storage_aggregate_destruct(&agg);
415
 
   return GL_TRUE;
416
 
}
417
 
 
418
 
static void
419
 
promote_type_to_array(slang_parse_ctx *C,
420
 
                      slang_fully_specified_type *type,
421
 
                      GLint array_len)
422
 
{
423
 
   slang_type_specifier *baseType =
424
 
      slang_type_specifier_new(type->specifier.type, NULL, NULL);
425
 
 
426
 
   type->specifier.type = SLANG_SPEC_ARRAY;
427
 
   type->specifier._array = baseType;
428
 
   type->array_len = array_len;
429
 
}
430
 
 
431
 
 
432
 
static GLboolean
433
 
convert_to_array(slang_parse_ctx * C, slang_variable * var,
434
 
                 const slang_type_specifier * sp)
435
 
{
436
 
   /* sized array - mark it as array, copy the specifier to the array element
437
 
    * and parse the expression */
438
 
   var->type.specifier.type = SLANG_SPEC_ARRAY;
439
 
   var->type.specifier._array = (slang_type_specifier *)
440
 
      _slang_alloc(sizeof(slang_type_specifier));
441
 
   if (var->type.specifier._array == NULL) {
442
 
      slang_info_log_memory(C->L);
443
 
      return GL_FALSE;
444
 
   }
445
 
   slang_type_specifier_ctr(var->type.specifier._array);
446
 
   return slang_type_specifier_copy(var->type.specifier._array, sp);
447
 
}
448
 
 
449
 
/* structure field */
450
 
#define FIELD_NONE 0
451
 
#define FIELD_NEXT 1
452
 
#define FIELD_ARRAY 2
453
 
 
454
 
static GLboolean
455
 
parse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O,
456
 
                       slang_variable * var, slang_atom a_name,
457
 
                       const slang_type_specifier * sp,
458
 
                       GLuint array_len)
459
 
{
460
 
   var->a_name = a_name;
461
 
   if (var->a_name == SLANG_ATOM_NULL)
462
 
      return GL_FALSE;
463
 
 
464
 
   switch (*C->I++) {
465
 
   case FIELD_NONE:
466
 
      if (array_len != -1) {
467
 
         if (!convert_to_array(C, var, sp))
468
 
            return GL_FALSE;
469
 
         var->array_len = array_len;
470
 
      }
471
 
      else {
472
 
         if (!slang_type_specifier_copy(&var->type.specifier, sp))
473
 
            return GL_FALSE;
474
 
      }
475
 
      break;
476
 
   case FIELD_ARRAY:
477
 
      if (array_len != -1)
478
 
         return GL_FALSE;
479
 
      if (!convert_to_array(C, var, sp))
480
 
         return GL_FALSE;
481
 
      if (!parse_array_len(C, O, &var->array_len))
482
 
         return GL_FALSE;
483
 
      break;
484
 
   default:
485
 
      return GL_FALSE;
486
 
   }
487
 
 
488
 
   return calculate_var_size(C, O, var);
489
 
}
490
 
 
491
 
static int
492
 
parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O,
493
 
                   slang_struct * st, slang_type_specifier * sp)
494
 
{
495
 
   slang_output_ctx o = *O;
496
 
   GLint array_len;
497
 
 
498
 
   o.structs = st->structs;
499
 
   if (!parse_type_specifier(C, &o, sp))
500
 
      RETURN0;
501
 
   if (!parse_type_array_size(C, &o, &array_len))
502
 
      RETURN0;
503
 
 
504
 
   do {
505
 
      slang_atom a_name;
506
 
      slang_variable *var = slang_variable_scope_grow(st->fields);
507
 
      if (!var) {
508
 
         slang_info_log_memory(C->L);
509
 
         RETURN0;
510
 
      }
511
 
      a_name = parse_identifier(C);
512
 
      if (_slang_variable_locate(st->fields, a_name, GL_FALSE)) {
513
 
         slang_info_log_error(C->L, "duplicate field '%s'", (char *) a_name);
514
 
         RETURN0;
515
 
      }
516
 
 
517
 
      if (!parse_struct_field_var(C, &o, var, a_name, sp, array_len))
518
 
         RETURN0;
519
 
   }
520
 
   while (*C->I++ != FIELD_NONE);
521
 
 
522
 
   return 1;
523
 
}
524
 
 
525
 
static int
526
 
parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st)
527
 
{
528
 
   slang_atom a_name;
529
 
   const char *name;
530
 
 
531
 
   /* parse struct name (if any) and make sure it is unique in current scope */
532
 
   a_name = parse_identifier(C);
533
 
   if (a_name == SLANG_ATOM_NULL)
534
 
      RETURN0;
535
 
 
536
 
   name = slang_atom_pool_id(C->atoms, a_name);
537
 
   if (name[0] != '\0'
538
 
       && slang_struct_scope_find(O->structs, a_name, 0) != NULL) {
539
 
      slang_info_log_error(C->L, "%s: duplicate type name.", name);
540
 
      RETURN0;
541
 
   }
542
 
 
543
 
   /* set-up a new struct */
544
 
   *st = (slang_struct *) _slang_alloc(sizeof(slang_struct));
545
 
   if (*st == NULL) {
546
 
      slang_info_log_memory(C->L);
547
 
      RETURN0;
548
 
   }
549
 
   if (!slang_struct_construct(*st)) {
550
 
      _slang_free(*st);
551
 
      *st = NULL;
552
 
      slang_info_log_memory(C->L);
553
 
      RETURN0;
554
 
   }
555
 
   (**st).a_name = a_name;
556
 
   (**st).structs->outer_scope = O->structs;
557
 
 
558
 
   /* parse individual struct fields */
559
 
   do {
560
 
      slang_type_specifier sp;
561
 
 
562
 
      slang_type_specifier_ctr(&sp);
563
 
      if (!parse_struct_field(C, O, *st, &sp)) {
564
 
         slang_type_specifier_dtr(&sp);
565
 
         RETURN0;
566
 
      }
567
 
      slang_type_specifier_dtr(&sp);
568
 
   }
569
 
   while (*C->I++ != FIELD_NONE);
570
 
 
571
 
   /* if named struct, copy it to current scope */
572
 
   if (name[0] != '\0') {
573
 
      slang_struct *s;
574
 
 
575
 
      O->structs->structs =
576
 
         (slang_struct *) _slang_realloc(O->structs->structs,
577
 
                                         O->structs->num_structs
578
 
                                         * sizeof(slang_struct),
579
 
                                         (O->structs->num_structs + 1)
580
 
                                         * sizeof(slang_struct));
581
 
      if (O->structs->structs == NULL) {
582
 
         slang_info_log_memory(C->L);
583
 
         RETURN0;
584
 
      }
585
 
      s = &O->structs->structs[O->structs->num_structs];
586
 
      if (!slang_struct_construct(s))
587
 
         RETURN0;
588
 
      O->structs->num_structs++;
589
 
      if (!slang_struct_copy(s, *st))
590
 
         RETURN0;
591
 
   }
592
 
 
593
 
   return 1;
594
 
}
595
 
 
596
 
 
597
 
/* invariant qualifer */
598
 
#define TYPE_VARIANT    90
599
 
#define TYPE_INVARIANT  91
600
 
 
601
 
static int
602
 
parse_type_variant(slang_parse_ctx * C, slang_type_variant *variant)
603
 
{
604
 
   GLuint invariant = *C->I++;
605
 
   switch (invariant) {
606
 
   case TYPE_VARIANT:
607
 
      *variant = SLANG_VARIANT;
608
 
      return 1;
609
 
   case TYPE_INVARIANT:
610
 
      *variant = SLANG_INVARIANT;
611
 
      return 1;
612
 
   default:
613
 
      RETURN0;
614
 
   }
615
 
}
616
 
 
617
 
 
618
 
/* centroid qualifer */
619
 
#define TYPE_CENTER    95
620
 
#define TYPE_CENTROID  96
621
 
 
622
 
static int
623
 
parse_type_centroid(slang_parse_ctx * C, slang_type_centroid *centroid)
624
 
{
625
 
   GLuint c = *C->I++;
626
 
   switch (c) {
627
 
   case TYPE_CENTER:
628
 
      *centroid = SLANG_CENTER;
629
 
      return 1;
630
 
   case TYPE_CENTROID:
631
 
      *centroid = SLANG_CENTROID;
632
 
      return 1;
633
 
   default:
634
 
      RETURN0;
635
 
   }
636
 
}
637
 
 
638
 
 
639
 
/* Layout qualifiers */
640
 
#define LAYOUT_QUALIFIER_NONE                      0
641
 
#define LAYOUT_QUALIFIER_UPPER_LEFT                1
642
 
#define LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER      2
643
 
 
644
 
static int
645
 
parse_layout_qualifiers(slang_parse_ctx * C, slang_layout_qualifier *layout)
646
 
{
647
 
   *layout = 0x0;
648
 
 
649
 
   /* the layout qualifiers come as a list of LAYOUT_QUALIFER_x tokens,
650
 
    * terminated by LAYOUT_QUALIFIER_NONE.
651
 
    */
652
 
   while (1) {
653
 
      GLuint c = *C->I++;
654
 
      switch (c) {
655
 
      case LAYOUT_QUALIFIER_NONE:
656
 
         /* end of list of qualifiers */
657
 
         return 1;
658
 
      case LAYOUT_QUALIFIER_UPPER_LEFT:
659
 
         *layout |= SLANG_LAYOUT_UPPER_LEFT_BIT;
660
 
         break;
661
 
      case LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER:
662
 
         *layout |= SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT;
663
 
         break;
664
 
      default:
665
 
         assert(0 && "Bad layout qualifier");
666
 
      }
667
 
   }
668
 
}
669
 
 
670
 
 
671
 
/* type qualifier */
672
 
#define TYPE_QUALIFIER_NONE 0
673
 
#define TYPE_QUALIFIER_CONST 1
674
 
#define TYPE_QUALIFIER_ATTRIBUTE 2
675
 
#define TYPE_QUALIFIER_VARYING 3
676
 
#define TYPE_QUALIFIER_UNIFORM 4
677
 
#define TYPE_QUALIFIER_FIXEDOUTPUT 5
678
 
#define TYPE_QUALIFIER_FIXEDINPUT 6
679
 
 
680
 
static int
681
 
parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual)
682
 
{
683
 
   GLuint qualifier = *C->I++;
684
 
   switch (qualifier) {
685
 
   case TYPE_QUALIFIER_NONE:
686
 
      *qual = SLANG_QUAL_NONE;
687
 
      break;
688
 
   case TYPE_QUALIFIER_CONST:
689
 
      *qual = SLANG_QUAL_CONST;
690
 
      break;
691
 
   case TYPE_QUALIFIER_ATTRIBUTE:
692
 
      *qual = SLANG_QUAL_ATTRIBUTE;
693
 
      break;
694
 
   case TYPE_QUALIFIER_VARYING:
695
 
      *qual = SLANG_QUAL_VARYING;
696
 
      break;
697
 
   case TYPE_QUALIFIER_UNIFORM:
698
 
      *qual = SLANG_QUAL_UNIFORM;
699
 
      break;
700
 
   case TYPE_QUALIFIER_FIXEDOUTPUT:
701
 
      *qual = SLANG_QUAL_FIXEDOUTPUT;
702
 
      break;
703
 
   case TYPE_QUALIFIER_FIXEDINPUT:
704
 
      *qual = SLANG_QUAL_FIXEDINPUT;
705
 
      break;
706
 
   default:
707
 
      RETURN0;
708
 
   }
709
 
   return 1;
710
 
}
711
 
 
712
 
/* type specifier */
713
 
#define TYPE_SPECIFIER_VOID 0
714
 
#define TYPE_SPECIFIER_BOOL 1
715
 
#define TYPE_SPECIFIER_BVEC2 2
716
 
#define TYPE_SPECIFIER_BVEC3 3
717
 
#define TYPE_SPECIFIER_BVEC4 4
718
 
#define TYPE_SPECIFIER_INT 5
719
 
#define TYPE_SPECIFIER_IVEC2 6
720
 
#define TYPE_SPECIFIER_IVEC3 7
721
 
#define TYPE_SPECIFIER_IVEC4 8
722
 
#define TYPE_SPECIFIER_FLOAT 9
723
 
#define TYPE_SPECIFIER_VEC2 10
724
 
#define TYPE_SPECIFIER_VEC3 11
725
 
#define TYPE_SPECIFIER_VEC4 12
726
 
#define TYPE_SPECIFIER_MAT2 13
727
 
#define TYPE_SPECIFIER_MAT3 14
728
 
#define TYPE_SPECIFIER_MAT4 15
729
 
#define TYPE_SPECIFIER_SAMPLER1D 16
730
 
#define TYPE_SPECIFIER_SAMPLER2D 17
731
 
#define TYPE_SPECIFIER_SAMPLER3D 18
732
 
#define TYPE_SPECIFIER_SAMPLERCUBE 19
733
 
#define TYPE_SPECIFIER_SAMPLER1DSHADOW 20
734
 
#define TYPE_SPECIFIER_SAMPLER2DSHADOW 21
735
 
#define TYPE_SPECIFIER_SAMPLER2DRECT 22
736
 
#define TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23
737
 
#define TYPE_SPECIFIER_STRUCT 24
738
 
#define TYPE_SPECIFIER_TYPENAME 25
739
 
#define TYPE_SPECIFIER_MAT23 26
740
 
#define TYPE_SPECIFIER_MAT32 27
741
 
#define TYPE_SPECIFIER_MAT24 28
742
 
#define TYPE_SPECIFIER_MAT42 29
743
 
#define TYPE_SPECIFIER_MAT34 30
744
 
#define TYPE_SPECIFIER_MAT43 31
745
 
#define TYPE_SPECIFIER_SAMPLER_1D_ARRAY 32
746
 
#define TYPE_SPECIFIER_SAMPLER_2D_ARRAY 33
747
 
#define TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW 34
748
 
#define TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW 35
749
 
#define TYPE_SPECIFIER_COUNT 36
750
 
 
751
 
static int
752
 
parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O,
753
 
                     slang_type_specifier * spec)
754
 
{
755
 
   int type = *C->I++;
756
 
   switch (type) {
757
 
   case TYPE_SPECIFIER_VOID:
758
 
      spec->type = SLANG_SPEC_VOID;
759
 
      break;
760
 
   case TYPE_SPECIFIER_BOOL:
761
 
      spec->type = SLANG_SPEC_BOOL;
762
 
      break;
763
 
   case TYPE_SPECIFIER_BVEC2:
764
 
      spec->type = SLANG_SPEC_BVEC2;
765
 
      break;
766
 
   case TYPE_SPECIFIER_BVEC3:
767
 
      spec->type = SLANG_SPEC_BVEC3;
768
 
      break;
769
 
   case TYPE_SPECIFIER_BVEC4:
770
 
      spec->type = SLANG_SPEC_BVEC4;
771
 
      break;
772
 
   case TYPE_SPECIFIER_INT:
773
 
      spec->type = SLANG_SPEC_INT;
774
 
      break;
775
 
   case TYPE_SPECIFIER_IVEC2:
776
 
      spec->type = SLANG_SPEC_IVEC2;
777
 
      break;
778
 
   case TYPE_SPECIFIER_IVEC3:
779
 
      spec->type = SLANG_SPEC_IVEC3;
780
 
      break;
781
 
   case TYPE_SPECIFIER_IVEC4:
782
 
      spec->type = SLANG_SPEC_IVEC4;
783
 
      break;
784
 
   case TYPE_SPECIFIER_FLOAT:
785
 
      spec->type = SLANG_SPEC_FLOAT;
786
 
      break;
787
 
   case TYPE_SPECIFIER_VEC2:
788
 
      spec->type = SLANG_SPEC_VEC2;
789
 
      break;
790
 
   case TYPE_SPECIFIER_VEC3:
791
 
      spec->type = SLANG_SPEC_VEC3;
792
 
      break;
793
 
   case TYPE_SPECIFIER_VEC4:
794
 
      spec->type = SLANG_SPEC_VEC4;
795
 
      break;
796
 
   case TYPE_SPECIFIER_MAT2:
797
 
      spec->type = SLANG_SPEC_MAT2;
798
 
      break;
799
 
   case TYPE_SPECIFIER_MAT3:
800
 
      spec->type = SLANG_SPEC_MAT3;
801
 
      break;
802
 
   case TYPE_SPECIFIER_MAT4:
803
 
      spec->type = SLANG_SPEC_MAT4;
804
 
      break;
805
 
   case TYPE_SPECIFIER_MAT23:
806
 
      spec->type = SLANG_SPEC_MAT23;
807
 
      break;
808
 
   case TYPE_SPECIFIER_MAT32:
809
 
      spec->type = SLANG_SPEC_MAT32;
810
 
      break;
811
 
   case TYPE_SPECIFIER_MAT24:
812
 
      spec->type = SLANG_SPEC_MAT24;
813
 
      break;
814
 
   case TYPE_SPECIFIER_MAT42:
815
 
      spec->type = SLANG_SPEC_MAT42;
816
 
      break;
817
 
   case TYPE_SPECIFIER_MAT34:
818
 
      spec->type = SLANG_SPEC_MAT34;
819
 
      break;
820
 
   case TYPE_SPECIFIER_MAT43:
821
 
      spec->type = SLANG_SPEC_MAT43;
822
 
      break;
823
 
   case TYPE_SPECIFIER_SAMPLER1D:
824
 
      spec->type = SLANG_SPEC_SAMPLER_1D;
825
 
      break;
826
 
   case TYPE_SPECIFIER_SAMPLER2D:
827
 
      spec->type = SLANG_SPEC_SAMPLER_2D;
828
 
      break;
829
 
   case TYPE_SPECIFIER_SAMPLER3D:
830
 
      spec->type = SLANG_SPEC_SAMPLER_3D;
831
 
      break;
832
 
   case TYPE_SPECIFIER_SAMPLERCUBE:
833
 
      spec->type = SLANG_SPEC_SAMPLER_CUBE;
834
 
      break;
835
 
   case TYPE_SPECIFIER_SAMPLER2DRECT:
836
 
      spec->type = SLANG_SPEC_SAMPLER_RECT;
837
 
      break;
838
 
   case TYPE_SPECIFIER_SAMPLER1DSHADOW:
839
 
      spec->type = SLANG_SPEC_SAMPLER_1D_SHADOW;
840
 
      break;
841
 
   case TYPE_SPECIFIER_SAMPLER2DSHADOW:
842
 
      spec->type = SLANG_SPEC_SAMPLER_2D_SHADOW;
843
 
      break;
844
 
   case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW:
845
 
      spec->type = SLANG_SPEC_SAMPLER_RECT_SHADOW;
846
 
      break;
847
 
   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY:
848
 
      spec->type = SLANG_SPEC_SAMPLER_1D_ARRAY;
849
 
      break;
850
 
   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY:
851
 
      spec->type = SLANG_SPEC_SAMPLER_2D_ARRAY;
852
 
      break;
853
 
   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW:
854
 
      spec->type = SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW;
855
 
      break;
856
 
   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW:
857
 
      spec->type = SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW;
858
 
      break;
859
 
   case TYPE_SPECIFIER_STRUCT:
860
 
      spec->type = SLANG_SPEC_STRUCT;
861
 
      if (!parse_struct(C, O, &spec->_struct))
862
 
         RETURN0;
863
 
      break;
864
 
   case TYPE_SPECIFIER_TYPENAME:
865
 
      spec->type = SLANG_SPEC_STRUCT;
866
 
      {
867
 
         slang_atom a_name;
868
 
         slang_struct *stru;
869
 
 
870
 
         a_name = parse_identifier(C);
871
 
         if (a_name == NULL)
872
 
            RETURN0;
873
 
 
874
 
         stru = slang_struct_scope_find(O->structs, a_name, 1);
875
 
         if (stru == NULL) {
876
 
            slang_info_log_error(C->L, "undeclared type name '%s'",
877
 
                                 slang_atom_pool_id(C->atoms, a_name));
878
 
            RETURN0;
879
 
         }
880
 
 
881
 
         spec->_struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
882
 
         if (spec->_struct == NULL) {
883
 
            slang_info_log_memory(C->L);
884
 
            RETURN0;
885
 
         }
886
 
         if (!slang_struct_construct(spec->_struct)) {
887
 
            _slang_free(spec->_struct);
888
 
            spec->_struct = NULL;
889
 
            RETURN0;
890
 
         }
891
 
         if (!slang_struct_copy(spec->_struct, stru))
892
 
            RETURN0;
893
 
      }
894
 
      break;
895
 
   default:
896
 
      RETURN0;
897
 
   }
898
 
   return 1;
899
 
}
900
 
 
901
 
#define TYPE_SPECIFIER_NONARRAY 0
902
 
#define TYPE_SPECIFIER_ARRAY    1
903
 
 
904
 
static int
905
 
parse_type_array_size(slang_parse_ctx *C,
906
 
                      slang_output_ctx *O,
907
 
                      GLint *array_len)
908
 
{
909
 
   GLuint size;
910
 
 
911
 
   switch (*C->I++) {
912
 
   case TYPE_SPECIFIER_NONARRAY:
913
 
      *array_len = -1; /* -1 = not an array */
914
 
      break;
915
 
   case TYPE_SPECIFIER_ARRAY:
916
 
      if (!parse_array_len(C, O, &size))
917
 
         RETURN0;
918
 
      *array_len = (GLint) size;
919
 
      break;
920
 
   default:
921
 
      assert(0);
922
 
      RETURN0;
923
 
   }
924
 
   return 1;
925
 
}
926
 
 
927
 
#define PRECISION_DEFAULT 0
928
 
#define PRECISION_LOW     1
929
 
#define PRECISION_MEDIUM  2
930
 
#define PRECISION_HIGH    3
931
 
 
932
 
static int
933
 
parse_type_precision(slang_parse_ctx *C,
934
 
                     slang_type_precision *precision)
935
 
{
936
 
   GLint prec = *C->I++;
937
 
   switch (prec) {
938
 
   case PRECISION_DEFAULT:
939
 
      *precision = SLANG_PREC_DEFAULT;
940
 
      return 1;
941
 
   case PRECISION_LOW:
942
 
      *precision = SLANG_PREC_LOW;
943
 
      return 1;
944
 
   case PRECISION_MEDIUM:
945
 
      *precision = SLANG_PREC_MEDIUM;
946
 
      return 1;
947
 
   case PRECISION_HIGH:
948
 
      *precision = SLANG_PREC_HIGH;
949
 
      return 1;
950
 
   default:
951
 
      RETURN0;
952
 
   }
953
 
}
954
 
 
955
 
static int
956
 
parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
957
 
                           slang_fully_specified_type * type)
958
 
{
959
 
   if (!parse_layout_qualifiers(C, &type->layout))
960
 
      RETURN0;
961
 
 
962
 
   if (!parse_type_variant(C, &type->variant))
963
 
      RETURN0;
964
 
 
965
 
   if (!parse_type_centroid(C, &type->centroid))
966
 
      RETURN0;
967
 
 
968
 
   if (!parse_type_qualifier(C, &type->qualifier))
969
 
      RETURN0;
970
 
 
971
 
   if (!parse_type_precision(C, &type->precision))
972
 
      RETURN0;
973
 
 
974
 
   if (!parse_type_specifier(C, O, &type->specifier))
975
 
      RETURN0;
976
 
 
977
 
   if (!parse_type_array_size(C, O, &type->array_len))
978
 
      RETURN0;
979
 
 
980
 
   if (!O->allow_invariant && type->variant == SLANG_INVARIANT) {
981
 
      slang_info_log_error(C->L,
982
 
         "'invariant' keyword not allowed (perhaps set #version 120)");
983
 
      RETURN0;
984
 
   }
985
 
 
986
 
   if (!O->allow_centroid && type->centroid == SLANG_CENTROID) {
987
 
      slang_info_log_error(C->L,
988
 
         "'centroid' keyword not allowed (perhaps set #version 120)");
989
 
      RETURN0;
990
 
   }
991
 
   else if (type->centroid == SLANG_CENTROID &&
992
 
            type->qualifier != SLANG_QUAL_VARYING) {
993
 
      slang_info_log_error(C->L,
994
 
         "'centroid' keyword only allowed for varying vars");
995
 
      RETURN0;
996
 
   }
997
 
 
998
 
 
999
 
   /* need this?
1000
 
   if (type->qualifier != SLANG_QUAL_VARYING &&
1001
 
       type->variant == SLANG_INVARIANT) {
1002
 
      slang_info_log_error(C->L,
1003
 
                           "invariant qualifer only allowed for varying vars");
1004
 
      RETURN0;
1005
 
   }
1006
 
   */
1007
 
 
1008
 
   if (O->allow_precision) {
1009
 
      if (type->precision == SLANG_PREC_DEFAULT) {
1010
 
         assert(type->specifier.type < TYPE_SPECIFIER_COUNT);
1011
 
         /* use the default precision for this datatype */
1012
 
         type->precision = O->default_precision[type->specifier.type];
1013
 
      }
1014
 
   }
1015
 
   else {
1016
 
      /* only default is allowed */
1017
 
      if (type->precision != SLANG_PREC_DEFAULT) {
1018
 
         slang_info_log_error(C->L, "precision qualifiers not allowed");
1019
 
         RETURN0;
1020
 
      }
1021
 
   }
1022
 
 
1023
 
   if (!O->allow_array_types && type->array_len >= 0) {
1024
 
      slang_info_log_error(C->L, "first-class array types not allowed");
1025
 
      RETURN0;
1026
 
   }
1027
 
 
1028
 
   if (type->array_len >= 0) {
1029
 
      /* convert type to array type (ex: convert "int" to "array of int" */
1030
 
      promote_type_to_array(C, type, type->array_len);
1031
 
   }
1032
 
 
1033
 
   return 1;
1034
 
}
1035
 
 
1036
 
/* operation */
1037
 
#define OP_END 0
1038
 
#define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1
1039
 
#define OP_BLOCK_BEGIN_NEW_SCOPE 2
1040
 
#define OP_DECLARE 3
1041
 
#define OP_ASM 4
1042
 
#define OP_BREAK 5
1043
 
#define OP_CONTINUE 6
1044
 
#define OP_DISCARD 7
1045
 
#define OP_RETURN 8
1046
 
#define OP_EXPRESSION 9
1047
 
#define OP_IF 10
1048
 
#define OP_WHILE 11
1049
 
#define OP_DO 12
1050
 
#define OP_FOR 13
1051
 
#define OP_PUSH_VOID 14
1052
 
#define OP_PUSH_BOOL 15
1053
 
#define OP_PUSH_INT 16
1054
 
#define OP_PUSH_FLOAT 17
1055
 
#define OP_PUSH_IDENTIFIER 18
1056
 
#define OP_SEQUENCE 19
1057
 
#define OP_ASSIGN 20
1058
 
#define OP_ADDASSIGN 21
1059
 
#define OP_SUBASSIGN 22
1060
 
#define OP_MULASSIGN 23
1061
 
#define OP_DIVASSIGN 24
1062
 
/*#define OP_MODASSIGN 25*/
1063
 
/*#define OP_LSHASSIGN 26*/
1064
 
/*#define OP_RSHASSIGN 27*/
1065
 
/*#define OP_ORASSIGN 28*/
1066
 
/*#define OP_XORASSIGN 29*/
1067
 
/*#define OP_ANDASSIGN 30*/
1068
 
#define OP_SELECT 31
1069
 
#define OP_LOGICALOR 32
1070
 
#define OP_LOGICALXOR 33
1071
 
#define OP_LOGICALAND 34
1072
 
/*#define OP_BITOR 35*/
1073
 
/*#define OP_BITXOR 36*/
1074
 
/*#define OP_BITAND 37*/
1075
 
#define OP_EQUAL 38
1076
 
#define OP_NOTEQUAL 39
1077
 
#define OP_LESS 40
1078
 
#define OP_GREATER 41
1079
 
#define OP_LESSEQUAL 42
1080
 
#define OP_GREATEREQUAL 43
1081
 
/*#define OP_LSHIFT 44*/
1082
 
/*#define OP_RSHIFT 45*/
1083
 
#define OP_ADD 46
1084
 
#define OP_SUBTRACT 47
1085
 
#define OP_MULTIPLY 48
1086
 
#define OP_DIVIDE 49
1087
 
/*#define OP_MODULUS 50*/
1088
 
#define OP_PREINCREMENT 51
1089
 
#define OP_PREDECREMENT 52
1090
 
#define OP_PLUS 53
1091
 
#define OP_MINUS 54
1092
 
/*#define OP_COMPLEMENT 55*/
1093
 
#define OP_NOT 56
1094
 
#define OP_SUBSCRIPT 57
1095
 
#define OP_CALL 58
1096
 
#define OP_FIELD 59
1097
 
#define OP_POSTINCREMENT 60
1098
 
#define OP_POSTDECREMENT 61
1099
 
#define OP_PRECISION 62
1100
 
#define OP_METHOD 63
1101
 
 
1102
 
 
1103
 
/**
1104
 
 * When parsing a compound production, this function is used to parse the
1105
 
 * children.
1106
 
 * For example, a while-loop compound will have two children, the
1107
 
 * while condition expression and the loop body.  So, this function will
1108
 
 * be called twice to parse those two sub-expressions.
1109
 
 * \param C  the parsing context
1110
 
 * \param O  the output context
1111
 
 * \param oper  the operation we're parsing
1112
 
 * \param statement  indicates whether parsing a statement, or expression
1113
 
 * \return 1 if success, 0 if error
1114
 
 */
1115
 
static int
1116
 
parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O,
1117
 
                      slang_operation * oper, GLboolean statement)
1118
 
{
1119
 
   slang_operation *ch;
1120
 
 
1121
 
   /* grow child array */
1122
 
   ch = slang_operation_grow(&oper->num_children, &oper->children);
1123
 
   if (statement)
1124
 
      return parse_statement(C, O, ch);
1125
 
   return parse_expression(C, O, ch);
1126
 
}
1127
 
 
1128
 
static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O);
1129
 
 
1130
 
static int
1131
 
parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
1132
 
                slang_operation * oper)
1133
 
{
1134
 
   int op;
1135
 
 
1136
 
   oper->locals->outer_scope = O->vars;
1137
 
 
1138
 
   op = *C->I++;
1139
 
   switch (op) {
1140
 
   case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
1141
 
      /* parse child statements, do not create new variable scope */
1142
 
      oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
1143
 
      while (*C->I != OP_END)
1144
 
         if (!parse_child_operation(C, O, oper, GL_TRUE))
1145
 
            RETURN0;
1146
 
      C->I++;
1147
 
      break;
1148
 
   case OP_BLOCK_BEGIN_NEW_SCOPE:
1149
 
      /* parse child statements, create new variable scope */
1150
 
      {
1151
 
         slang_output_ctx o = *O;
1152
 
 
1153
 
         oper->type = SLANG_OPER_BLOCK_NEW_SCOPE;
1154
 
         o.vars = oper->locals;
1155
 
         while (*C->I != OP_END)
1156
 
            if (!parse_child_operation(C, &o, oper, GL_TRUE))
1157
 
               RETURN0;
1158
 
         C->I++;
1159
 
      }
1160
 
      break;
1161
 
   case OP_DECLARE:
1162
 
      /* local variable declaration, individual declarators are stored as
1163
 
       * children identifiers
1164
 
       */
1165
 
      oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
1166
 
      {
1167
 
         const unsigned int first_var = O->vars->num_variables;
1168
 
 
1169
 
         /* parse the declaration, note that there can be zero or more
1170
 
          * than one declarators
1171
 
          */
1172
 
         if (!parse_declaration(C, O))
1173
 
            RETURN0;
1174
 
         if (first_var < O->vars->num_variables) {
1175
 
            const unsigned int num_vars = O->vars->num_variables - first_var;
1176
 
            unsigned int i;
1177
 
            assert(oper->num_children == 0);
1178
 
            oper->num_children = num_vars;
1179
 
            oper->children = slang_operation_new(num_vars);
1180
 
            if (oper->children == NULL) {
1181
 
               slang_info_log_memory(C->L);
1182
 
               RETURN0;
1183
 
            }
1184
 
            for (i = first_var; i < O->vars->num_variables; i++) {
1185
 
               slang_operation *o = &oper->children[i - first_var];
1186
 
               slang_variable *var = O->vars->variables[i];
1187
 
               o->type = SLANG_OPER_VARIABLE_DECL;
1188
 
               o->locals->outer_scope = O->vars;
1189
 
               o->a_id = var->a_name;
1190
 
 
1191
 
               /* new/someday...
1192
 
               calculate_var_size(C, O, var);
1193
 
               */
1194
 
 
1195
 
               if (!legal_identifier(o->a_id)) {
1196
 
                  slang_info_log_error(C->L, "illegal variable name '%s'",
1197
 
                                       (char *) o->a_id);
1198
 
                  RETURN0;
1199
 
               }
1200
 
            }
1201
 
         }
1202
 
      }
1203
 
      break;
1204
 
   case OP_ASM:
1205
 
      /* the __asm statement, parse the mnemonic and all its arguments
1206
 
       * as expressions
1207
 
       */
1208
 
      oper->type = SLANG_OPER_ASM;
1209
 
      oper->a_id = parse_identifier(C);
1210
 
      if (oper->a_id == SLANG_ATOM_NULL)
1211
 
         RETURN0;
1212
 
      while (*C->I != OP_END) {
1213
 
         if (!parse_child_operation(C, O, oper, GL_FALSE))
1214
 
            RETURN0;
1215
 
      }
1216
 
      C->I++;
1217
 
      break;
1218
 
   case OP_BREAK:
1219
 
      oper->type = SLANG_OPER_BREAK;
1220
 
      break;
1221
 
   case OP_CONTINUE:
1222
 
      oper->type = SLANG_OPER_CONTINUE;
1223
 
      break;
1224
 
   case OP_DISCARD:
1225
 
      oper->type = SLANG_OPER_DISCARD;
1226
 
      break;
1227
 
   case OP_RETURN:
1228
 
      oper->type = SLANG_OPER_RETURN;
1229
 
      if (!parse_child_operation(C, O, oper, GL_FALSE))
1230
 
         RETURN0;
1231
 
      break;
1232
 
   case OP_EXPRESSION:
1233
 
      oper->type = SLANG_OPER_EXPRESSION;
1234
 
      if (!parse_child_operation(C, O, oper, GL_FALSE))
1235
 
         RETURN0;
1236
 
      break;
1237
 
   case OP_IF:
1238
 
      oper->type = SLANG_OPER_IF;
1239
 
      if (!parse_child_operation(C, O, oper, GL_FALSE))
1240
 
         RETURN0;
1241
 
      if (!parse_child_operation(C, O, oper, GL_TRUE))
1242
 
         RETURN0;
1243
 
      if (!parse_child_operation(C, O, oper, GL_TRUE))
1244
 
         RETURN0;
1245
 
      break;
1246
 
   case OP_WHILE:
1247
 
      {
1248
 
         slang_output_ctx o = *O;
1249
 
 
1250
 
         oper->type = SLANG_OPER_WHILE;
1251
 
         o.vars = oper->locals;
1252
 
         if (!parse_child_operation(C, &o, oper, GL_TRUE))
1253
 
            RETURN0;
1254
 
         if (!parse_child_operation(C, &o, oper, GL_TRUE))
1255
 
            RETURN0;
1256
 
      }
1257
 
      break;
1258
 
   case OP_DO:
1259
 
      oper->type = SLANG_OPER_DO;
1260
 
      if (!parse_child_operation(C, O, oper, GL_TRUE))
1261
 
         RETURN0;
1262
 
      if (!parse_child_operation(C, O, oper, GL_FALSE))
1263
 
         RETURN0;
1264
 
      break;
1265
 
   case OP_FOR:
1266
 
      {
1267
 
         slang_output_ctx o = *O;
1268
 
 
1269
 
         oper->type = SLANG_OPER_FOR;
1270
 
         o.vars = oper->locals;
1271
 
         if (!parse_child_operation(C, &o, oper, GL_TRUE))
1272
 
            RETURN0;
1273
 
         if (!parse_child_operation(C, &o, oper, GL_TRUE))
1274
 
            RETURN0;
1275
 
         if (!parse_child_operation(C, &o, oper, GL_FALSE))
1276
 
            RETURN0;
1277
 
         if (!parse_child_operation(C, &o, oper, GL_TRUE))
1278
 
            RETURN0;
1279
 
      }
1280
 
      break;
1281
 
   case OP_PRECISION:
1282
 
      {
1283
 
         /* set default precision for a type in this scope */
1284
 
         /* ignored at this time */
1285
 
         int prec_qual = *C->I++;
1286
 
         int datatype = *C->I++;
1287
 
         (void) prec_qual;
1288
 
         (void) datatype;
1289
 
      }
1290
 
      break;
1291
 
   default:
1292
 
      /*printf("Unexpected operation %d\n", op);*/
1293
 
      RETURN0;
1294
 
   }
1295
 
   return 1;
1296
 
}
1297
 
 
1298
 
static int
1299
 
handle_nary_expression(slang_parse_ctx * C, slang_operation * op,
1300
 
                       slang_operation ** ops, unsigned int *total_ops,
1301
 
                       unsigned int n)
1302
 
{
1303
 
   unsigned int i;
1304
 
 
1305
 
   op->children = slang_operation_new(n);
1306
 
   if (op->children == NULL) {
1307
 
      slang_info_log_memory(C->L);
1308
 
      RETURN0;
1309
 
   }
1310
 
   op->num_children = n;
1311
 
 
1312
 
   for (i = 0; i < n; i++) {
1313
 
      slang_operation_destruct(&op->children[i]);
1314
 
      op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
1315
 
   }
1316
 
 
1317
 
   (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
1318
 
   *total_ops -= n;
1319
 
 
1320
 
   *ops = (slang_operation *)
1321
 
      _slang_realloc(*ops,
1322
 
                     (*total_ops + n) * sizeof(slang_operation),
1323
 
                     *total_ops * sizeof(slang_operation));
1324
 
   if (*ops == NULL) {
1325
 
      slang_info_log_memory(C->L);
1326
 
      RETURN0;
1327
 
   }
1328
 
   return 1;
1329
 
}
1330
 
 
1331
 
static int
1332
 
is_constructor_name(const char *name, slang_atom a_name,
1333
 
                    slang_struct_scope * structs)
1334
 
{
1335
 
   if (slang_type_specifier_type_from_string(name) != SLANG_SPEC_VOID)
1336
 
      return 1;
1337
 
   return slang_struct_scope_find(structs, a_name, 1) != NULL;
1338
 
}
1339
 
 
1340
 
#define FUNCTION_CALL_NONARRAY 0
1341
 
#define FUNCTION_CALL_ARRAY    1
1342
 
 
1343
 
static int
1344
 
parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
1345
 
                 slang_operation * oper)
1346
 
{
1347
 
   slang_operation *ops = NULL;
1348
 
   unsigned int num_ops = 0;
1349
 
   int number;
1350
 
 
1351
 
   while (*C->I != OP_END) {
1352
 
      slang_operation *op;
1353
 
      const unsigned int op_code = *C->I++;
1354
 
 
1355
 
      /* allocate default operation, becomes a no-op if not used  */
1356
 
      ops = (slang_operation *)
1357
 
         _slang_realloc(ops,
1358
 
                        num_ops * sizeof(slang_operation),
1359
 
                        (num_ops + 1) * sizeof(slang_operation));
1360
 
      if (ops == NULL) {
1361
 
         slang_info_log_memory(C->L);
1362
 
         RETURN0;
1363
 
      }
1364
 
      op = &ops[num_ops];
1365
 
      if (!slang_operation_construct(op)) {
1366
 
         slang_info_log_memory(C->L);
1367
 
         RETURN0;
1368
 
      }
1369
 
      num_ops++;
1370
 
      op->locals->outer_scope = O->vars;
1371
 
 
1372
 
      switch (op_code) {
1373
 
      case OP_PUSH_VOID:
1374
 
         op->type = SLANG_OPER_VOID;
1375
 
         break;
1376
 
      case OP_PUSH_BOOL:
1377
 
         op->type = SLANG_OPER_LITERAL_BOOL;
1378
 
         if (!parse_number(C, &number))
1379
 
            RETURN0;
1380
 
         op->literal[0] =
1381
 
         op->literal[1] =
1382
 
         op->literal[2] =
1383
 
         op->literal[3] = (GLfloat) number;
1384
 
         op->literal_size = 1;
1385
 
         break;
1386
 
      case OP_PUSH_INT:
1387
 
         op->type = SLANG_OPER_LITERAL_INT;
1388
 
         if (!parse_number(C, &number))
1389
 
            RETURN0;
1390
 
         op->literal[0] =
1391
 
         op->literal[1] =
1392
 
         op->literal[2] =
1393
 
         op->literal[3] = (GLfloat) number;
1394
 
         op->literal_size = 1;
1395
 
         break;
1396
 
      case OP_PUSH_FLOAT:
1397
 
         op->type = SLANG_OPER_LITERAL_FLOAT;
1398
 
         if (!parse_float(C, &op->literal[0]))
1399
 
            RETURN0;
1400
 
         op->literal[1] =
1401
 
         op->literal[2] =
1402
 
         op->literal[3] = op->literal[0];
1403
 
         op->literal_size = 1;
1404
 
         break;
1405
 
      case OP_PUSH_IDENTIFIER:
1406
 
         op->type = SLANG_OPER_IDENTIFIER;
1407
 
         op->a_id = parse_identifier(C);
1408
 
         if (op->a_id == SLANG_ATOM_NULL)
1409
 
            RETURN0;
1410
 
         break;
1411
 
      case OP_SEQUENCE:
1412
 
         op->type = SLANG_OPER_SEQUENCE;
1413
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1414
 
            RETURN0;
1415
 
         break;
1416
 
      case OP_ASSIGN:
1417
 
         op->type = SLANG_OPER_ASSIGN;
1418
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1419
 
            RETURN0;
1420
 
         break;
1421
 
      case OP_ADDASSIGN:
1422
 
         op->type = SLANG_OPER_ADDASSIGN;
1423
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1424
 
            RETURN0;
1425
 
         break;
1426
 
      case OP_SUBASSIGN:
1427
 
         op->type = SLANG_OPER_SUBASSIGN;
1428
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1429
 
            RETURN0;
1430
 
         break;
1431
 
      case OP_MULASSIGN:
1432
 
         op->type = SLANG_OPER_MULASSIGN;
1433
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1434
 
            RETURN0;
1435
 
         break;
1436
 
      case OP_DIVASSIGN:
1437
 
         op->type = SLANG_OPER_DIVASSIGN;
1438
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1439
 
            RETURN0;
1440
 
         break;
1441
 
         /*case OP_MODASSIGN: */
1442
 
         /*case OP_LSHASSIGN: */
1443
 
         /*case OP_RSHASSIGN: */
1444
 
         /*case OP_ORASSIGN: */
1445
 
         /*case OP_XORASSIGN: */
1446
 
         /*case OP_ANDASSIGN: */
1447
 
      case OP_SELECT:
1448
 
         op->type = SLANG_OPER_SELECT;
1449
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 3))
1450
 
            RETURN0;
1451
 
         break;
1452
 
      case OP_LOGICALOR:
1453
 
         op->type = SLANG_OPER_LOGICALOR;
1454
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1455
 
            RETURN0;
1456
 
         break;
1457
 
      case OP_LOGICALXOR:
1458
 
         op->type = SLANG_OPER_LOGICALXOR;
1459
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1460
 
            RETURN0;
1461
 
         break;
1462
 
      case OP_LOGICALAND:
1463
 
         op->type = SLANG_OPER_LOGICALAND;
1464
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1465
 
            RETURN0;
1466
 
         break;
1467
 
         /*case OP_BITOR: */
1468
 
         /*case OP_BITXOR: */
1469
 
         /*case OP_BITAND: */
1470
 
      case OP_EQUAL:
1471
 
         op->type = SLANG_OPER_EQUAL;
1472
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1473
 
            RETURN0;
1474
 
         break;
1475
 
      case OP_NOTEQUAL:
1476
 
         op->type = SLANG_OPER_NOTEQUAL;
1477
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1478
 
            RETURN0;
1479
 
         break;
1480
 
      case OP_LESS:
1481
 
         op->type = SLANG_OPER_LESS;
1482
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1483
 
            RETURN0;
1484
 
         break;
1485
 
      case OP_GREATER:
1486
 
         op->type = SLANG_OPER_GREATER;
1487
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1488
 
            RETURN0;
1489
 
         break;
1490
 
      case OP_LESSEQUAL:
1491
 
         op->type = SLANG_OPER_LESSEQUAL;
1492
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1493
 
            RETURN0;
1494
 
         break;
1495
 
      case OP_GREATEREQUAL:
1496
 
         op->type = SLANG_OPER_GREATEREQUAL;
1497
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1498
 
            RETURN0;
1499
 
         break;
1500
 
         /*case OP_LSHIFT: */
1501
 
         /*case OP_RSHIFT: */
1502
 
      case OP_ADD:
1503
 
         op->type = SLANG_OPER_ADD;
1504
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1505
 
            RETURN0;
1506
 
         break;
1507
 
      case OP_SUBTRACT:
1508
 
         op->type = SLANG_OPER_SUBTRACT;
1509
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1510
 
            RETURN0;
1511
 
         break;
1512
 
      case OP_MULTIPLY:
1513
 
         op->type = SLANG_OPER_MULTIPLY;
1514
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1515
 
            RETURN0;
1516
 
         break;
1517
 
      case OP_DIVIDE:
1518
 
         op->type = SLANG_OPER_DIVIDE;
1519
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1520
 
            RETURN0;
1521
 
         break;
1522
 
         /*case OP_MODULUS: */
1523
 
      case OP_PREINCREMENT:
1524
 
         op->type = SLANG_OPER_PREINCREMENT;
1525
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1526
 
            RETURN0;
1527
 
         break;
1528
 
      case OP_PREDECREMENT:
1529
 
         op->type = SLANG_OPER_PREDECREMENT;
1530
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1531
 
            RETURN0;
1532
 
         break;
1533
 
      case OP_PLUS:
1534
 
         op->type = SLANG_OPER_PLUS;
1535
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1536
 
            RETURN0;
1537
 
         break;
1538
 
      case OP_MINUS:
1539
 
         op->type = SLANG_OPER_MINUS;
1540
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1541
 
            RETURN0;
1542
 
         break;
1543
 
      case OP_NOT:
1544
 
         op->type = SLANG_OPER_NOT;
1545
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1546
 
            RETURN0;
1547
 
         break;
1548
 
         /*case OP_COMPLEMENT: */
1549
 
      case OP_SUBSCRIPT:
1550
 
         op->type = SLANG_OPER_SUBSCRIPT;
1551
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
1552
 
            RETURN0;
1553
 
         break;
1554
 
      case OP_METHOD:
1555
 
         op->type = SLANG_OPER_METHOD;
1556
 
         op->a_obj = parse_identifier(C);
1557
 
         if (op->a_obj == SLANG_ATOM_NULL)
1558
 
            RETURN0;
1559
 
 
1560
 
         op->a_id = parse_identifier(C);
1561
 
         if (op->a_id == SLANG_ATOM_NULL)
1562
 
            RETURN0;
1563
 
 
1564
 
         assert(*C->I == OP_END);
1565
 
         C->I++;
1566
 
 
1567
 
         while (*C->I != OP_END)
1568
 
            if (!parse_child_operation(C, O, op, GL_FALSE))
1569
 
               RETURN0;
1570
 
         C->I++;
1571
 
#if 0
1572
 
         /* don't lookup the method (not yet anyway) */
1573
 
         if (!C->parsing_builtin
1574
 
             && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
1575
 
            const char *id;
1576
 
 
1577
 
            id = slang_atom_pool_id(C->atoms, op->a_id);
1578
 
            if (!is_constructor_name(id, op->a_id, O->structs)) {
1579
 
               slang_info_log_error(C->L, "%s: undeclared function name.", id);
1580
 
               RETURN0;
1581
 
            }
1582
 
         }
1583
 
#endif
1584
 
         break;
1585
 
      case OP_CALL:
1586
 
         {
1587
 
            GLboolean array_constructor = GL_FALSE;
1588
 
            GLint array_constructor_size = 0;
1589
 
 
1590
 
            op->type = SLANG_OPER_CALL;
1591
 
            op->a_id = parse_identifier(C);
1592
 
            if (op->a_id == SLANG_ATOM_NULL)
1593
 
               RETURN0;
1594
 
            switch (*C->I++) {
1595
 
            case FUNCTION_CALL_NONARRAY:
1596
 
               /* Nothing to do. */
1597
 
               break;
1598
 
            case FUNCTION_CALL_ARRAY:
1599
 
               /* Calling an array constructor. For example:
1600
 
                *   float[3](1.1, 2.2, 3.3);
1601
 
                */
1602
 
               if (!O->allow_array_types) {
1603
 
                  slang_info_log_error(C->L,
1604
 
                                       "array constructors not allowed "
1605
 
                                       "in this GLSL version");
1606
 
                  RETURN0;
1607
 
               }
1608
 
               else {
1609
 
                  /* parse the array constructor size */
1610
 
                  slang_operation array_size;
1611
 
                  array_constructor = GL_TRUE;
1612
 
                  slang_operation_construct(&array_size);
1613
 
                  if (!parse_expression(C, O, &array_size)) {
1614
 
                     slang_operation_destruct(&array_size);
1615
 
                     return GL_FALSE;
1616
 
                  }
1617
 
                  if (array_size.type != SLANG_OPER_LITERAL_INT) {
1618
 
                     slang_info_log_error(C->L,
1619
 
                        "constructor array size is not an integer");
1620
 
                     slang_operation_destruct(&array_size);
1621
 
                     RETURN0;
1622
 
                  }
1623
 
                  array_constructor_size = (int) array_size.literal[0];
1624
 
                  op->array_constructor = GL_TRUE;
1625
 
                  slang_operation_destruct(&array_size);
1626
 
               }
1627
 
               break;
1628
 
            default:
1629
 
               assert(0);
1630
 
               RETURN0;
1631
 
            }
1632
 
            while (*C->I != OP_END)
1633
 
               if (!parse_child_operation(C, O, op, GL_FALSE))
1634
 
                  RETURN0;
1635
 
            C->I++;
1636
 
 
1637
 
            if (array_constructor &&
1638
 
                array_constructor_size != op->num_children) {
1639
 
               slang_info_log_error(C->L, "number of parameters to array"
1640
 
                                    " constructor does not match array size");
1641
 
               RETURN0;
1642
 
            }
1643
 
 
1644
 
            if (!C->parsing_builtin
1645
 
                && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
1646
 
               const char *id;
1647
 
 
1648
 
               id = slang_atom_pool_id(C->atoms, op->a_id);
1649
 
               if (!is_constructor_name(id, op->a_id, O->structs)) {
1650
 
                  slang_info_log_error(C->L, "%s: undeclared function name.", id);
1651
 
                  RETURN0;
1652
 
               }
1653
 
            }
1654
 
         }
1655
 
         break;
1656
 
      case OP_FIELD:
1657
 
         op->type = SLANG_OPER_FIELD;
1658
 
         op->a_id = parse_identifier(C);
1659
 
         if (op->a_id == SLANG_ATOM_NULL)
1660
 
            RETURN0;
1661
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1662
 
            RETURN0;
1663
 
         break;
1664
 
      case OP_POSTINCREMENT:
1665
 
         op->type = SLANG_OPER_POSTINCREMENT;
1666
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1667
 
            RETURN0;
1668
 
         break;
1669
 
      case OP_POSTDECREMENT:
1670
 
         op->type = SLANG_OPER_POSTDECREMENT;
1671
 
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
1672
 
            RETURN0;
1673
 
         break;
1674
 
      default:
1675
 
         RETURN0;
1676
 
      }
1677
 
   }
1678
 
   C->I++;
1679
 
 
1680
 
   slang_operation_destruct(oper);
1681
 
   *oper = *ops; /* struct copy */
1682
 
   _slang_free(ops);
1683
 
 
1684
 
   return 1;
1685
 
}
1686
 
 
1687
 
/* parameter qualifier */
1688
 
#define PARAM_QUALIFIER_IN 0
1689
 
#define PARAM_QUALIFIER_OUT 1
1690
 
#define PARAM_QUALIFIER_INOUT 2
1691
 
 
1692
 
/* function parameter array presence */
1693
 
#define PARAMETER_ARRAY_NOT_PRESENT 0
1694
 
#define PARAMETER_ARRAY_PRESENT 1
1695
 
 
1696
 
static int
1697
 
parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
1698
 
                            slang_variable * param)
1699
 
{
1700
 
   int param_qual, precision_qual;
1701
 
 
1702
 
   /* parse and validate the parameter's type qualifiers (there can be
1703
 
    * two at most) because not all combinations are valid
1704
 
    */
1705
 
   if (!parse_type_qualifier(C, &param->type.qualifier))
1706
 
      RETURN0;
1707
 
 
1708
 
   param_qual = *C->I++;
1709
 
   switch (param_qual) {
1710
 
   case PARAM_QUALIFIER_IN:
1711
 
      if (param->type.qualifier != SLANG_QUAL_CONST
1712
 
          && param->type.qualifier != SLANG_QUAL_NONE) {
1713
 
         slang_info_log_error(C->L, "Invalid type qualifier.");
1714
 
         RETURN0;
1715
 
      }
1716
 
      break;
1717
 
   case PARAM_QUALIFIER_OUT:
1718
 
      if (param->type.qualifier == SLANG_QUAL_NONE)
1719
 
         param->type.qualifier = SLANG_QUAL_OUT;
1720
 
      else {
1721
 
         slang_info_log_error(C->L, "Invalid type qualifier.");
1722
 
         RETURN0;
1723
 
      }
1724
 
      break;
1725
 
   case PARAM_QUALIFIER_INOUT:
1726
 
      if (param->type.qualifier == SLANG_QUAL_NONE)
1727
 
         param->type.qualifier = SLANG_QUAL_INOUT;
1728
 
      else {
1729
 
         slang_info_log_error(C->L, "Invalid type qualifier.");
1730
 
         RETURN0;
1731
 
      }
1732
 
      break;
1733
 
   default:
1734
 
      RETURN0;
1735
 
   }
1736
 
 
1737
 
   /* parse precision qualifier (lowp, mediump, highp */
1738
 
   precision_qual = *C->I++;
1739
 
   /* ignored at this time */
1740
 
   (void) precision_qual;
1741
 
 
1742
 
   /* parse parameter's type specifier and name */
1743
 
   if (!parse_type_specifier(C, O, &param->type.specifier))
1744
 
      RETURN0;
1745
 
   if (!parse_type_array_size(C, O, &param->type.array_len))
1746
 
      RETURN0;
1747
 
   param->a_name = parse_identifier(C);
1748
 
   if (param->a_name == SLANG_ATOM_NULL)
1749
 
      RETURN0;
1750
 
 
1751
 
   /* first-class array
1752
 
    */
1753
 
   if (param->type.array_len >= 0) {
1754
 
      slang_type_specifier p;
1755
 
 
1756
 
      slang_type_specifier_ctr(&p);
1757
 
      if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
1758
 
         slang_type_specifier_dtr(&p);
1759
 
         RETURN0;
1760
 
      }
1761
 
      if (!convert_to_array(C, param, &p)) {
1762
 
         slang_type_specifier_dtr(&p);
1763
 
         RETURN0;
1764
 
      }
1765
 
      slang_type_specifier_dtr(&p);
1766
 
      param->array_len = param->type.array_len;
1767
 
   }
1768
 
 
1769
 
   /* if the parameter is an array, parse its size (the size must be
1770
 
    * explicitly defined
1771
 
    */
1772
 
   if (*C->I++ == PARAMETER_ARRAY_PRESENT) {
1773
 
      slang_type_specifier p;
1774
 
 
1775
 
      if (param->type.array_len >= 0) {
1776
 
         slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
1777
 
         RETURN0;
1778
 
      }
1779
 
      slang_type_specifier_ctr(&p);
1780
 
      if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
1781
 
         slang_type_specifier_dtr(&p);
1782
 
         RETURN0;
1783
 
      }
1784
 
      if (!convert_to_array(C, param, &p)) {
1785
 
         slang_type_specifier_dtr(&p);
1786
 
         RETURN0;
1787
 
      }
1788
 
      slang_type_specifier_dtr(&p);
1789
 
      if (!parse_array_len(C, O, &param->array_len))
1790
 
         RETURN0;
1791
 
   }
1792
 
 
1793
 
#if 0
1794
 
   /* calculate the parameter size */
1795
 
   if (!calculate_var_size(C, O, param))
1796
 
      RETURN0;
1797
 
#endif
1798
 
   /* TODO: allocate the local address here? */
1799
 
   return 1;
1800
 
}
1801
 
 
1802
 
/* function type */
1803
 
#define FUNCTION_ORDINARY 0
1804
 
#define FUNCTION_CONSTRUCTOR 1
1805
 
#define FUNCTION_OPERATOR 2
1806
 
 
1807
 
/* function parameter */
1808
 
#define PARAMETER_NONE 0
1809
 
#define PARAMETER_NEXT 1
1810
 
 
1811
 
/* operator type */
1812
 
#define OPERATOR_ADDASSIGN 1
1813
 
#define OPERATOR_SUBASSIGN 2
1814
 
#define OPERATOR_MULASSIGN 3
1815
 
#define OPERATOR_DIVASSIGN 4
1816
 
/*#define OPERATOR_MODASSIGN 5*/
1817
 
/*#define OPERATOR_LSHASSIGN 6*/
1818
 
/*#define OPERATOR_RSHASSIGN 7*/
1819
 
/*#define OPERATOR_ANDASSIGN 8*/
1820
 
/*#define OPERATOR_XORASSIGN 9*/
1821
 
/*#define OPERATOR_ORASSIGN 10*/
1822
 
#define OPERATOR_LOGICALXOR 11
1823
 
/*#define OPERATOR_BITOR 12*/
1824
 
/*#define OPERATOR_BITXOR 13*/
1825
 
/*#define OPERATOR_BITAND 14*/
1826
 
#define OPERATOR_LESS 15
1827
 
#define OPERATOR_GREATER 16
1828
 
#define OPERATOR_LESSEQUAL 17
1829
 
#define OPERATOR_GREATEREQUAL 18
1830
 
/*#define OPERATOR_LSHIFT 19*/
1831
 
/*#define OPERATOR_RSHIFT 20*/
1832
 
#define OPERATOR_MULTIPLY 21
1833
 
#define OPERATOR_DIVIDE 22
1834
 
/*#define OPERATOR_MODULUS 23*/
1835
 
#define OPERATOR_INCREMENT 24
1836
 
#define OPERATOR_DECREMENT 25
1837
 
#define OPERATOR_PLUS 26
1838
 
#define OPERATOR_MINUS 27
1839
 
/*#define OPERATOR_COMPLEMENT 28*/
1840
 
#define OPERATOR_NOT 29
1841
 
 
1842
 
static const struct
1843
 
{
1844
 
   unsigned int o_code;
1845
 
   const char *o_name;
1846
 
} operator_names[] = {
1847
 
   {OPERATOR_INCREMENT, "++"},
1848
 
   {OPERATOR_ADDASSIGN, "+="},
1849
 
   {OPERATOR_PLUS, "+"},
1850
 
   {OPERATOR_DECREMENT, "--"},
1851
 
   {OPERATOR_SUBASSIGN, "-="},
1852
 
   {OPERATOR_MINUS, "-"},
1853
 
   {OPERATOR_NOT, "!"},
1854
 
   {OPERATOR_MULASSIGN, "*="},
1855
 
   {OPERATOR_MULTIPLY, "*"},
1856
 
   {OPERATOR_DIVASSIGN, "/="},
1857
 
   {OPERATOR_DIVIDE, "/"},
1858
 
   {OPERATOR_LESSEQUAL, "<="},
1859
 
   /*{ OPERATOR_LSHASSIGN, "<<=" }, */
1860
 
   /*{ OPERATOR_LSHIFT, "<<" }, */
1861
 
   {OPERATOR_LESS, "<"},
1862
 
   {OPERATOR_GREATEREQUAL, ">="},
1863
 
   /*{ OPERATOR_RSHASSIGN, ">>=" }, */
1864
 
   /*{ OPERATOR_RSHIFT, ">>" }, */
1865
 
   {OPERATOR_GREATER, ">"},
1866
 
   /*{ OPERATOR_MODASSIGN, "%=" }, */
1867
 
   /*{ OPERATOR_MODULUS, "%" }, */
1868
 
   /*{ OPERATOR_ANDASSIGN, "&=" }, */
1869
 
   /*{ OPERATOR_BITAND, "&" }, */
1870
 
   /*{ OPERATOR_ORASSIGN, "|=" }, */
1871
 
   /*{ OPERATOR_BITOR, "|" }, */
1872
 
   /*{ OPERATOR_COMPLEMENT, "~" }, */
1873
 
   /*{ OPERATOR_XORASSIGN, "^=" }, */
1874
 
   {OPERATOR_LOGICALXOR, "^^"},
1875
 
   /*{ OPERATOR_BITXOR, "^" } */
1876
 
};
1877
 
 
1878
 
static slang_atom
1879
 
parse_operator_name(slang_parse_ctx * C)
1880
 
{
1881
 
   unsigned int i;
1882
 
 
1883
 
   for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) {
1884
 
      if (operator_names[i].o_code == (unsigned int) (*C->I)) {
1885
 
         slang_atom atom =
1886
 
            slang_atom_pool_atom(C->atoms, operator_names[i].o_name);
1887
 
         if (atom == SLANG_ATOM_NULL) {
1888
 
            slang_info_log_memory(C->L);
1889
 
            RETURN0;
1890
 
         }
1891
 
         C->I++;
1892
 
         return atom;
1893
 
      }
1894
 
   }
1895
 
   RETURN0;
1896
 
}
1897
 
 
1898
 
 
1899
 
static int
1900
 
parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
1901
 
                         slang_function * func)
1902
 
{
1903
 
   GLuint functype;
1904
 
   /* parse function type and name */
1905
 
   if (!parse_fully_specified_type(C, O, &func->header.type))
1906
 
      RETURN0;
1907
 
 
1908
 
   functype = *C->I++;
1909
 
   switch (functype) {
1910
 
   case FUNCTION_ORDINARY:
1911
 
      func->kind = SLANG_FUNC_ORDINARY;
1912
 
      func->header.a_name = parse_identifier(C);
1913
 
      if (func->header.a_name == SLANG_ATOM_NULL)
1914
 
         RETURN0;
1915
 
      break;
1916
 
   case FUNCTION_CONSTRUCTOR:
1917
 
      func->kind = SLANG_FUNC_CONSTRUCTOR;
1918
 
      if (func->header.type.specifier.type == SLANG_SPEC_STRUCT)
1919
 
         RETURN0;
1920
 
      func->header.a_name =
1921
 
         slang_atom_pool_atom(C->atoms,
1922
 
                              slang_type_specifier_type_to_string
1923
 
                              (func->header.type.specifier.type));
1924
 
      if (func->header.a_name == SLANG_ATOM_NULL) {
1925
 
         slang_info_log_memory(C->L);
1926
 
         RETURN0;
1927
 
      }
1928
 
      break;
1929
 
   case FUNCTION_OPERATOR:
1930
 
      func->kind = SLANG_FUNC_OPERATOR;
1931
 
      func->header.a_name = parse_operator_name(C);
1932
 
      if (func->header.a_name == SLANG_ATOM_NULL)
1933
 
         RETURN0;
1934
 
      break;
1935
 
   default:
1936
 
      RETURN0;
1937
 
   }
1938
 
 
1939
 
   if (!legal_identifier(func->header.a_name)) {
1940
 
      slang_info_log_error(C->L, "illegal function name '%s'",
1941
 
                           (char *) func->header.a_name);
1942
 
      RETURN0;
1943
 
   }
1944
 
 
1945
 
   /* parse function parameters */
1946
 
   while (*C->I++ == PARAMETER_NEXT) {
1947
 
      slang_variable *p = slang_variable_scope_grow(func->parameters);
1948
 
      if (!p) {
1949
 
         slang_info_log_memory(C->L);
1950
 
         RETURN0;
1951
 
      }
1952
 
      if (!parse_parameter_declaration(C, O, p))
1953
 
         RETURN0;
1954
 
   }
1955
 
 
1956
 
   /* if the function returns a value, append a hidden __retVal 'out'
1957
 
    * parameter that corresponds to the return value.
1958
 
    */
1959
 
   if (_slang_function_has_return_value(func)) {
1960
 
      slang_variable *p = slang_variable_scope_grow(func->parameters);
1961
 
      slang_atom a_retVal = slang_atom_pool_atom(C->atoms, "__retVal");
1962
 
      assert(a_retVal);
1963
 
      p->a_name = a_retVal;
1964
 
      p->type = func->header.type;
1965
 
      p->type.qualifier = SLANG_QUAL_OUT;
1966
 
   }
1967
 
 
1968
 
   /* function formal parameters and local variables share the same
1969
 
    * scope, so save the information about param count in a seperate
1970
 
    * place also link the scope to the global variable scope so when a
1971
 
    * given identifier is not found here, the search process continues
1972
 
    * in the global space
1973
 
    */
1974
 
   func->param_count = func->parameters->num_variables;
1975
 
   func->parameters->outer_scope = O->vars;
1976
 
 
1977
 
   return 1;
1978
 
}
1979
 
 
1980
 
static int
1981
 
parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
1982
 
                          slang_function * func)
1983
 
{
1984
 
   slang_output_ctx o = *O;
1985
 
 
1986
 
   if (!parse_function_prototype(C, O, func))
1987
 
      RETURN0;
1988
 
 
1989
 
   /* create function's body operation */
1990
 
   func->body = (slang_operation *) _slang_alloc(sizeof(slang_operation));
1991
 
   if (func->body == NULL) {
1992
 
      slang_info_log_memory(C->L);
1993
 
      RETURN0;
1994
 
   }
1995
 
   if (!slang_operation_construct(func->body)) {
1996
 
      _slang_free(func->body);
1997
 
      func->body = NULL;
1998
 
      slang_info_log_memory(C->L);
1999
 
      RETURN0;
2000
 
   }
2001
 
 
2002
 
   /* to parse the body the parse context is modified in order to
2003
 
    * capture parsed variables into function's local variable scope
2004
 
    */
2005
 
   C->global_scope = GL_FALSE;
2006
 
   o.vars = func->parameters;
2007
 
   if (!parse_statement(C, &o, func->body))
2008
 
      RETURN0;
2009
 
 
2010
 
   C->global_scope = GL_TRUE;
2011
 
   return 1;
2012
 
}
2013
 
 
2014
 
static GLboolean
2015
 
initialize_global(slang_assemble_ctx * A, slang_variable * var)
2016
 
{
2017
 
   slang_operation op_id, op_assign;
2018
 
   GLboolean result;
2019
 
 
2020
 
   /* construct the left side of assignment */
2021
 
   if (!slang_operation_construct(&op_id))
2022
 
      return GL_FALSE;
2023
 
   op_id.type = SLANG_OPER_IDENTIFIER;
2024
 
   op_id.a_id = var->a_name;
2025
 
 
2026
 
   /* put the variable into operation's scope */
2027
 
   op_id.locals->variables =
2028
 
      (slang_variable **) _slang_alloc(sizeof(slang_variable *));
2029
 
   if (op_id.locals->variables == NULL) {
2030
 
      slang_operation_destruct(&op_id);
2031
 
      return GL_FALSE;
2032
 
   }
2033
 
   op_id.locals->num_variables = 1;
2034
 
   op_id.locals->variables[0] = var;
2035
 
 
2036
 
   /* construct the assignment expression */
2037
 
   if (!slang_operation_construct(&op_assign)) {
2038
 
      op_id.locals->num_variables = 0;
2039
 
      slang_operation_destruct(&op_id);
2040
 
      return GL_FALSE;
2041
 
   }
2042
 
   op_assign.type = SLANG_OPER_ASSIGN;
2043
 
   op_assign.children =
2044
 
      (slang_operation *) _slang_alloc(2 * sizeof(slang_operation));
2045
 
   if (op_assign.children == NULL) {
2046
 
      slang_operation_destruct(&op_assign);
2047
 
      op_id.locals->num_variables = 0;
2048
 
      slang_operation_destruct(&op_id);
2049
 
      return GL_FALSE;
2050
 
   }
2051
 
   op_assign.num_children = 2;
2052
 
   op_assign.children[0] = op_id;
2053
 
   op_assign.children[1] = *var->initializer;
2054
 
 
2055
 
   result = 1;
2056
 
 
2057
 
   /* carefully destroy the operations */
2058
 
   op_assign.num_children = 0;
2059
 
   _slang_free(op_assign.children);
2060
 
   op_assign.children = NULL;
2061
 
   slang_operation_destruct(&op_assign);
2062
 
   op_id.locals->num_variables = 0;
2063
 
   slang_operation_destruct(&op_id);
2064
 
 
2065
 
   if (!result)
2066
 
      return GL_FALSE;
2067
 
 
2068
 
   return GL_TRUE;
2069
 
}
2070
 
 
2071
 
/* init declarator list */
2072
 
#define DECLARATOR_NONE 0
2073
 
#define DECLARATOR_NEXT 1
2074
 
 
2075
 
/* variable declaration */
2076
 
#define VARIABLE_NONE 0
2077
 
#define VARIABLE_IDENTIFIER 1
2078
 
#define VARIABLE_INITIALIZER 2
2079
 
#define VARIABLE_ARRAY_EXPLICIT 3
2080
 
#define VARIABLE_ARRAY_UNKNOWN 4
2081
 
 
2082
 
 
2083
 
/**
2084
 
 * Check if it's OK to re-declare a variable with the given new type.
2085
 
 * This happens when applying layout qualifiers to gl_FragCoord or
2086
 
 * (re)setting an array size.
2087
 
 * If redeclaration is OK, return a pointer to the incoming variable
2088
 
 * updated with new type info.  Else return NULL;
2089
 
 */
2090
 
static slang_variable *
2091
 
redeclare_variable(slang_variable *var, 
2092
 
                   const slang_fully_specified_type *type)
2093
 
{
2094
 
   if (slang_fully_specified_types_compatible(&var->type, type)) {
2095
 
      /* replace orig var layout with new layout */
2096
 
      var->type.layout = type->layout;
2097
 
 
2098
 
      /* XXX there may be other type updates in the future here */
2099
 
 
2100
 
      return var;
2101
 
   }
2102
 
   else
2103
 
      return NULL;
2104
 
}
2105
 
 
2106
 
 
2107
 
/**
2108
 
 * Parse the initializer for a variable declaration.
2109
 
 */
2110
 
static int
2111
 
parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
2112
 
                      const slang_fully_specified_type * type)
2113
 
{
2114
 
   GET_CURRENT_CONTEXT(ctx); /* a hack */
2115
 
   slang_variable *var = NULL, *prevDecl;
2116
 
   slang_atom a_name;
2117
 
 
2118
 
   /* empty init declatator (without name, e.g. "float ;") */
2119
 
   if (*C->I++ == VARIABLE_NONE)
2120
 
      return 1;
2121
 
 
2122
 
   a_name = parse_identifier(C);
2123
 
 
2124
 
   /* check if name is already in this scope */
2125
 
   prevDecl = _slang_variable_locate(O->vars, a_name, C->global_scope);
2126
 
   if (prevDecl) {
2127
 
      /* A var with this name has already been declared.
2128
 
       * Check if redeclaring the var with a different type/layout is legal.
2129
 
       */
2130
 
      if (C->global_scope) {
2131
 
         var = redeclare_variable(prevDecl, type);
2132
 
      }
2133
 
      if (!var) {
2134
 
         slang_info_log_error(C->L,
2135
 
                   "declaration of '%s' conflicts with previous declaration",
2136
 
                   (char *) a_name);
2137
 
         RETURN0;
2138
 
      }
2139
 
   }
2140
 
 
2141
 
   if (!var) {
2142
 
      /* make room for a new variable and initialize it */
2143
 
      var = slang_variable_scope_grow(O->vars);
2144
 
      if (!var) {
2145
 
         slang_info_log_memory(C->L);
2146
 
         RETURN0;
2147
 
      }
2148
 
 
2149
 
      /* copy the declarator type qualifier/etc info, parse the identifier */
2150
 
      var->type.qualifier = type->qualifier;
2151
 
      var->type.centroid = type->centroid;
2152
 
      var->type.precision = type->precision;
2153
 
      var->type.specifier = type->specifier;/*new*/
2154
 
      var->type.variant = type->variant;
2155
 
      var->type.layout = type->layout;
2156
 
      var->type.array_len = type->array_len;
2157
 
      var->a_name = a_name;
2158
 
      if (var->a_name == SLANG_ATOM_NULL)
2159
 
         RETURN0;
2160
 
   }
2161
 
 
2162
 
   switch (*C->I++) {
2163
 
   case VARIABLE_NONE:
2164
 
      /* simple variable declarator - just copy the specifier */
2165
 
      if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
2166
 
         RETURN0;
2167
 
      break;
2168
 
   case VARIABLE_INITIALIZER:
2169
 
      /* initialized variable - copy the specifier and parse the expression */
2170
 
      if (0 && type->array_len >= 0) {
2171
 
         /* The type was something like "float[4]" */
2172
 
         convert_to_array(C, var, &type->specifier);
2173
 
         var->array_len = type->array_len;
2174
 
      }
2175
 
      else {
2176
 
         if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
2177
 
            RETURN0;
2178
 
      }
2179
 
      var->initializer =
2180
 
         (slang_operation *) _slang_alloc(sizeof(slang_operation));
2181
 
      if (var->initializer == NULL) {
2182
 
         slang_info_log_memory(C->L);
2183
 
         RETURN0;
2184
 
      }
2185
 
      if (!slang_operation_construct(var->initializer)) {
2186
 
         _slang_free(var->initializer);
2187
 
         var->initializer = NULL;
2188
 
         slang_info_log_memory(C->L);
2189
 
         RETURN0;
2190
 
      }
2191
 
      if (!parse_expression(C, O, var->initializer))
2192
 
         RETURN0;
2193
 
      break;
2194
 
   case VARIABLE_ARRAY_UNKNOWN:
2195
 
      /* unsized array - mark it as array and copy the specifier to
2196
 
       * the array element
2197
 
       */
2198
 
      if (type->array_len >= 0) {
2199
 
         slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
2200
 
         RETURN0;
2201
 
      }
2202
 
      if (!convert_to_array(C, var, &type->specifier))
2203
 
         return GL_FALSE;
2204
 
      break;
2205
 
   case VARIABLE_ARRAY_EXPLICIT:
2206
 
      if (type->array_len >= 0) {
2207
 
         /* the user is trying to do something like: float[2] x[3]; */
2208
 
         slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
2209
 
         RETURN0;
2210
 
      }
2211
 
      if (!convert_to_array(C, var, &type->specifier))
2212
 
         return GL_FALSE;
2213
 
      if (!parse_array_len(C, O, &var->array_len))
2214
 
         return GL_FALSE;
2215
 
      break;
2216
 
   default:
2217
 
      RETURN0;
2218
 
   }
2219
 
 
2220
 
   /* allocate global address space for a variable with a known size */
2221
 
   if (C->global_scope
2222
 
       && !(var->type.specifier.type == SLANG_SPEC_ARRAY
2223
 
            && var->array_len == 0)) {
2224
 
      if (!calculate_var_size(C, O, var))
2225
 
         return GL_FALSE;
2226
 
   }
2227
 
 
2228
 
   /* emit code for global var decl */
2229
 
   if (C->global_scope) {
2230
 
      slang_assemble_ctx A;
2231
 
      memset(&A, 0, sizeof(slang_assemble_ctx));
2232
 
      A.allow_uniform_initializers = C->version > 110;
2233
 
      A.atoms = C->atoms;
2234
 
      A.space.funcs = O->funs;
2235
 
      A.space.structs = O->structs;
2236
 
      A.space.vars = O->vars;
2237
 
      A.program = O->program;
2238
 
      A.pragmas = O->pragmas;
2239
 
      A.vartable = O->vartable;
2240
 
      A.log = C->L;
2241
 
      A.curFuncEndLabel = NULL;
2242
 
      A.EmitContReturn = ctx->Shader.EmitContReturn;
2243
 
      if (!_slang_codegen_global_variable(&A, var, C->type))
2244
 
         RETURN0;
2245
 
   }
2246
 
 
2247
 
   /* initialize global variable */
2248
 
   if (C->global_scope) {
2249
 
      if (var->initializer != NULL) {
2250
 
         slang_assemble_ctx A;
2251
 
         memset(&A, 0, sizeof(slang_assemble_ctx));
2252
 
         A.allow_uniform_initializers = C->version > 110;
2253
 
         A.atoms = C->atoms;
2254
 
         A.space.funcs = O->funs;
2255
 
         A.space.structs = O->structs;
2256
 
         A.space.vars = O->vars;
2257
 
         if (!initialize_global(&A, var))
2258
 
            RETURN0;
2259
 
      }
2260
 
   }
2261
 
 
2262
 
   if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT &&
2263
 
       var->a_name == slang_atom_pool_atom(C->atoms, "gl_FragCoord")) {
2264
 
      /* set the program's PixelCenterInteger, OriginUpperLeft fields */
2265
 
      struct gl_fragment_program *fragProg =
2266
 
         (struct gl_fragment_program *) O->program;
2267
 
 
2268
 
      if (var->type.layout & SLANG_LAYOUT_UPPER_LEFT_BIT) {
2269
 
         fragProg->OriginUpperLeft = GL_TRUE;
2270
 
      }
2271
 
      if (var->type.layout & SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT) {
2272
 
         fragProg->PixelCenterInteger = GL_TRUE;
2273
 
      }
2274
 
   }
2275
 
 
2276
 
   return 1;
2277
 
}
2278
 
 
2279
 
/**
2280
 
 * Parse a list of variable declarations.  Each variable may have an
2281
 
 * initializer.
2282
 
 */
2283
 
static int
2284
 
parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O)
2285
 
{
2286
 
   slang_fully_specified_type type;
2287
 
 
2288
 
   /* parse the fully specified type, common to all declarators */
2289
 
   if (!slang_fully_specified_type_construct(&type))
2290
 
      RETURN0;
2291
 
   if (!parse_fully_specified_type(C, O, &type)) {
2292
 
      slang_fully_specified_type_destruct(&type);
2293
 
      RETURN0;
2294
 
   }
2295
 
 
2296
 
   /* parse declarators, pass-in the parsed type */
2297
 
   do {
2298
 
      if (!parse_init_declarator(C, O, &type)) {
2299
 
         slang_fully_specified_type_destruct(&type);
2300
 
         RETURN0;
2301
 
      }
2302
 
   }
2303
 
   while (*C->I++ == DECLARATOR_NEXT);
2304
 
 
2305
 
   slang_fully_specified_type_destruct(&type);
2306
 
   return 1;
2307
 
}
2308
 
 
2309
 
 
2310
 
/**
2311
 
 * Parse a function definition or declaration.
2312
 
 * \param C  parsing context
2313
 
 * \param O  output context
2314
 
 * \param definition if non-zero expect a definition, else a declaration
2315
 
 * \param parsed_func_ret  returns the parsed function
2316
 
 * \return GL_TRUE if success, GL_FALSE if failure
2317
 
 */
2318
 
static GLboolean
2319
 
parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
2320
 
               slang_function ** parsed_func_ret)
2321
 
{
2322
 
   slang_function parsed_func, *found_func;
2323
 
 
2324
 
   /* parse function definition/declaration */
2325
 
   if (!slang_function_construct(&parsed_func))
2326
 
      return GL_FALSE;
2327
 
   if (definition) {
2328
 
      if (!parse_function_definition(C, O, &parsed_func)) {
2329
 
         slang_function_destruct(&parsed_func);
2330
 
         return GL_FALSE;
2331
 
      }
2332
 
   }
2333
 
   else {
2334
 
      if (!parse_function_prototype(C, O, &parsed_func)) {
2335
 
         slang_function_destruct(&parsed_func);
2336
 
         return GL_FALSE;
2337
 
      }
2338
 
   }
2339
 
 
2340
 
   /* find a function with a prototype matching the parsed one - only
2341
 
    * the current scope is being searched to allow built-in function
2342
 
    * overriding
2343
 
    */
2344
 
   found_func = slang_function_scope_find(O->funs, &parsed_func, 0);
2345
 
   if (found_func == NULL) {
2346
 
      /* New function, add it to the function list */
2347
 
      O->funs->functions =
2348
 
         (slang_function *) _slang_realloc(O->funs->functions,
2349
 
                                           O->funs->num_functions
2350
 
                                           * sizeof(slang_function),
2351
 
                                           (O->funs->num_functions + 1)
2352
 
                                           * sizeof(slang_function));
2353
 
      if (O->funs->functions == NULL) {
2354
 
         /* Make sure that there are no functions marked, as the
2355
 
          * allocation is currently NULL, in order to avoid
2356
 
          * a potental segfault as we clean up later.
2357
 
          */
2358
 
         O->funs->num_functions = 0;
2359
 
 
2360
 
         slang_info_log_memory(C->L);
2361
 
         slang_function_destruct(&parsed_func);
2362
 
         return GL_FALSE;
2363
 
      }
2364
 
      O->funs->functions[O->funs->num_functions] = parsed_func;
2365
 
      O->funs->num_functions++;
2366
 
 
2367
 
      /* return the newly parsed function */
2368
 
      *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
2369
 
   }
2370
 
   else {
2371
 
      /* previously defined or declared */
2372
 
      /* TODO: check function return type qualifiers and specifiers */
2373
 
      if (definition) {
2374
 
         if (found_func->body != NULL) {
2375
 
            slang_info_log_error(C->L, "%s: function already has a body.",
2376
 
                                 slang_atom_pool_id(C->atoms,
2377
 
                                                    parsed_func.header.
2378
 
                                                    a_name));
2379
 
            slang_function_destruct(&parsed_func);
2380
 
            return GL_FALSE;
2381
 
         }
2382
 
 
2383
 
         /* destroy the existing function declaration and replace it
2384
 
          * with the new one
2385
 
          */
2386
 
         slang_function_destruct(found_func);
2387
 
         *found_func = parsed_func;
2388
 
      }
2389
 
      else {
2390
 
         /* another declaration of the same function prototype - ignore it */
2391
 
         slang_function_destruct(&parsed_func);
2392
 
      }
2393
 
 
2394
 
      /* return the found function */
2395
 
      *parsed_func_ret = found_func;
2396
 
   }
2397
 
 
2398
 
   return GL_TRUE;
2399
 
}
2400
 
 
2401
 
/* declaration */
2402
 
#define DECLARATION_FUNCTION_PROTOTYPE 1
2403
 
#define DECLARATION_INIT_DECLARATOR_LIST 2
2404
 
 
2405
 
static int
2406
 
parse_declaration(slang_parse_ctx * C, slang_output_ctx * O)
2407
 
{
2408
 
   switch (*C->I++) {
2409
 
   case DECLARATION_INIT_DECLARATOR_LIST:
2410
 
      if (!parse_init_declarator_list(C, O))
2411
 
         RETURN0;
2412
 
      break;
2413
 
   case DECLARATION_FUNCTION_PROTOTYPE:
2414
 
      {
2415
 
         slang_function *dummy_func;
2416
 
 
2417
 
         if (!parse_function(C, O, 0, &dummy_func))
2418
 
            RETURN0;
2419
 
      }
2420
 
      break;
2421
 
   default:
2422
 
      RETURN0;
2423
 
   }
2424
 
   return 1;
2425
 
}
2426
 
 
2427
 
static int
2428
 
parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O)
2429
 
{
2430
 
   int precision, type;
2431
 
 
2432
 
   if (!O->allow_precision) {
2433
 
      slang_info_log_error(C->L, "syntax error at \"precision\"");
2434
 
      RETURN0;
2435
 
   }
2436
 
 
2437
 
   precision = *C->I++;
2438
 
   switch (precision) {
2439
 
   case PRECISION_LOW:
2440
 
   case PRECISION_MEDIUM:
2441
 
   case PRECISION_HIGH:
2442
 
      /* OK */
2443
 
      break;
2444
 
   default:
2445
 
      _mesa_problem(NULL, "unexpected precision %d at %s:%d\n",
2446
 
                    precision, __FILE__, __LINE__);
2447
 
      RETURN0;
2448
 
   }
2449
 
 
2450
 
   type = *C->I++;
2451
 
   switch (type) {
2452
 
   case TYPE_SPECIFIER_FLOAT:
2453
 
   case TYPE_SPECIFIER_INT:
2454
 
   case TYPE_SPECIFIER_SAMPLER1D:
2455
 
   case TYPE_SPECIFIER_SAMPLER2D:
2456
 
   case TYPE_SPECIFIER_SAMPLER3D:
2457
 
   case TYPE_SPECIFIER_SAMPLERCUBE:
2458
 
   case TYPE_SPECIFIER_SAMPLER1DSHADOW:
2459
 
   case TYPE_SPECIFIER_SAMPLER2DSHADOW:
2460
 
   case TYPE_SPECIFIER_SAMPLER2DRECT:
2461
 
   case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW:
2462
 
   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY:
2463
 
   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY:
2464
 
   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW:
2465
 
   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW:
2466
 
      /* OK */
2467
 
      break;
2468
 
   default:
2469
 
      _mesa_problem(NULL, "unexpected type %d at %s:%d\n",
2470
 
                    type, __FILE__, __LINE__);
2471
 
      RETURN0;
2472
 
   }
2473
 
 
2474
 
   assert(type < TYPE_SPECIFIER_COUNT);
2475
 
   O->default_precision[type] = precision;
2476
 
 
2477
 
   return 1;
2478
 
}
2479
 
 
2480
 
 
2481
 
/**
2482
 
 * Initialize the default precision for all types.
2483
 
 * XXX this info isn't used yet.
2484
 
 */
2485
 
static void
2486
 
init_default_precision(slang_output_ctx *O, slang_unit_type type)
2487
 
{
2488
 
   GLuint i;
2489
 
   for (i = 0; i < TYPE_SPECIFIER_COUNT; i++) {
2490
 
#if FEATURE_es2_glsl
2491
 
      O->default_precision[i] = PRECISION_LOW;
2492
 
#else
2493
 
      O->default_precision[i] = PRECISION_HIGH;
2494
 
#endif
2495
 
   }
2496
 
 
2497
 
   if (type == SLANG_UNIT_VERTEX_SHADER) {
2498
 
      O->default_precision[TYPE_SPECIFIER_FLOAT] = PRECISION_HIGH;
2499
 
      O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_HIGH;
2500
 
   }
2501
 
   else {
2502
 
      O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_MEDIUM;
2503
 
   }
2504
 
}
2505
 
 
2506
 
 
2507
 
static int
2508
 
parse_invariant(slang_parse_ctx * C, slang_output_ctx * O)
2509
 
{
2510
 
   if (O->allow_invariant) {
2511
 
      slang_atom *a = parse_identifier(C);
2512
 
      /* XXX not doing anything with this var yet */
2513
 
      /*printf("ID: %s\n", (char*) a);*/
2514
 
      return a ? 1 : 0;
2515
 
   }
2516
 
   else {
2517
 
      slang_info_log_error(C->L, "syntax error at \"invariant\"");
2518
 
      RETURN0;
2519
 
   }
2520
 
}
2521
 
      
2522
 
 
2523
 
/* external declaration or default precision specifier */
2524
 
#define EXTERNAL_NULL 0
2525
 
#define EXTERNAL_FUNCTION_DEFINITION 1
2526
 
#define EXTERNAL_DECLARATION 2
2527
 
#define DEFAULT_PRECISION 3
2528
 
#define INVARIANT_STMT 4
2529
 
 
2530
 
 
2531
 
static GLboolean
2532
 
parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
2533
 
                struct gl_shader *shader)
2534
 
{
2535
 
   GET_CURRENT_CONTEXT(ctx);
2536
 
   slang_output_ctx o;
2537
 
   GLboolean success;
2538
 
   GLuint maxRegs;
2539
 
   slang_function *mainFunc = NULL;
2540
 
 
2541
 
   if (unit->type == SLANG_UNIT_FRAGMENT_BUILTIN ||
2542
 
       unit->type == SLANG_UNIT_FRAGMENT_SHADER) {
2543
 
      maxRegs = ctx->Const.FragmentProgram.MaxTemps;
2544
 
   }
2545
 
   else {
2546
 
      assert(unit->type == SLANG_UNIT_VERTEX_BUILTIN ||
2547
 
             unit->type == SLANG_UNIT_VERTEX_SHADER);
2548
 
      maxRegs = ctx->Const.VertexProgram.MaxTemps;
2549
 
   }
2550
 
 
2551
 
   /* setup output context */
2552
 
   o.funs = &unit->funs;
2553
 
   o.structs = &unit->structs;
2554
 
   o.vars = &unit->vars;
2555
 
   o.program = shader ? shader->Program : NULL;
2556
 
   o.pragmas = shader ? &shader->Pragmas : NULL;
2557
 
   o.vartable = _slang_new_var_table(maxRegs);
2558
 
   _slang_push_var_table(o.vartable);
2559
 
 
2560
 
   /* allow 'invariant' keyword? */
2561
 
#if FEATURE_es2_glsl
2562
 
   o.allow_invariant = GL_TRUE;
2563
 
#else
2564
 
   o.allow_invariant = (C->version >= 120) ? GL_TRUE : GL_FALSE;
2565
 
#endif
2566
 
 
2567
 
   /* allow 'centroid' keyword? */
2568
 
   o.allow_centroid = (C->version >= 120) ? GL_TRUE : GL_FALSE;
2569
 
 
2570
 
   /* allow 'lowp/mediump/highp' keywords? */
2571
 
#if FEATURE_es2_glsl
2572
 
   o.allow_precision = GL_TRUE;
2573
 
#else
2574
 
   o.allow_precision = (C->version >= 120) ? GL_TRUE : GL_FALSE;
2575
 
#endif
2576
 
   init_default_precision(&o, unit->type);
2577
 
 
2578
 
   /* allow 'float[]' keyword? */
2579
 
   o.allow_array_types = (C->version >= 120) ? GL_TRUE : GL_FALSE;
2580
 
 
2581
 
   /* parse individual functions and declarations */
2582
 
   while (*C->I != EXTERNAL_NULL) {
2583
 
      switch (*C->I++) {
2584
 
      case EXTERNAL_FUNCTION_DEFINITION:
2585
 
         {
2586
 
            slang_function *func;
2587
 
            success = parse_function(C, &o, 1, &func);
2588
 
            if (success && strcmp((char *) func->header.a_name, "main") == 0) {
2589
 
               /* found main() */
2590
 
               mainFunc = func;
2591
 
            }
2592
 
         }
2593
 
         break;
2594
 
      case EXTERNAL_DECLARATION:
2595
 
         success = parse_declaration(C, &o);
2596
 
         break;
2597
 
      case DEFAULT_PRECISION:
2598
 
         success = parse_default_precision(C, &o);
2599
 
         break;
2600
 
      case INVARIANT_STMT:
2601
 
         success = parse_invariant(C, &o);
2602
 
         break;
2603
 
      default:
2604
 
         success = GL_FALSE;
2605
 
      }
2606
 
 
2607
 
      if (!success) {
2608
 
         /* xxx free codegen */
2609
 
         _slang_pop_var_table(o.vartable);
2610
 
         return GL_FALSE;
2611
 
      }
2612
 
   }
2613
 
   C->I++;
2614
 
 
2615
 
   if (mainFunc) {
2616
 
      /* assemble (generate code) for main() */
2617
 
      slang_assemble_ctx A;
2618
 
      memset(&A, 0, sizeof(slang_assemble_ctx));
2619
 
      A.atoms = C->atoms;
2620
 
      A.space.funcs = o.funs;
2621
 
      A.space.structs = o.structs;
2622
 
      A.space.vars = o.vars;
2623
 
      A.program = o.program;
2624
 
      A.pragmas = &shader->Pragmas;
2625
 
      A.vartable = o.vartable;
2626
 
      A.EmitContReturn = ctx->Shader.EmitContReturn;
2627
 
      A.log = C->L;
2628
 
      A.allow_uniform_initializers = C->version > 110;
2629
 
 
2630
 
      /* main() takes no parameters */
2631
 
      if (mainFunc->param_count > 0) {
2632
 
         slang_info_log_error(A.log, "main() takes no arguments");
2633
 
         return GL_FALSE;
2634
 
      }
2635
 
 
2636
 
      _slang_codegen_function(&A, mainFunc);
2637
 
 
2638
 
      shader->Main = GL_TRUE; /* this shader defines main() */
2639
 
 
2640
 
      shader->UnresolvedRefs = A.UnresolvedRefs;
2641
 
   }
2642
 
 
2643
 
   _slang_pop_var_table(o.vartable);
2644
 
   _slang_delete_var_table(o.vartable);
2645
 
 
2646
 
   return GL_TRUE;
2647
 
}
2648
 
 
2649
 
static GLboolean
2650
 
compile_binary(const unsigned char * prod, slang_code_unit * unit,
2651
 
               GLuint version,
2652
 
               slang_unit_type type, slang_info_log * infolog,
2653
 
               slang_code_unit * builtin, slang_code_unit * downlink,
2654
 
               struct gl_shader *shader)
2655
 
{
2656
 
   slang_parse_ctx C;
2657
 
 
2658
 
   unit->type = type;
2659
 
 
2660
 
   /* setup parse context */
2661
 
   C.I = prod;
2662
 
   C.L = infolog;
2663
 
   C.parsing_builtin = (builtin == NULL);
2664
 
   C.global_scope = GL_TRUE;
2665
 
   C.atoms = &unit->object->atompool;
2666
 
   C.type = type;
2667
 
   C.version = version;
2668
 
 
2669
 
   if (!check_revision(&C))
2670
 
      return GL_FALSE;
2671
 
 
2672
 
   if (downlink != NULL) {
2673
 
      unit->vars.outer_scope = &downlink->vars;
2674
 
      unit->funs.outer_scope = &downlink->funs;
2675
 
      unit->structs.outer_scope = &downlink->structs;
2676
 
   }
2677
 
 
2678
 
   /* parse translation unit */
2679
 
   return parse_code_unit(&C, unit, shader);
2680
 
}
2681
 
 
2682
 
static GLboolean
2683
 
compile_with_grammar(const char *source,
2684
 
                     slang_code_unit *unit,
2685
 
                     slang_unit_type type,
2686
 
                     slang_info_log *infolog,
2687
 
                     slang_code_unit *builtin,
2688
 
                     struct gl_shader *shader,
2689
 
                     struct gl_sl_pragmas *pragmas,
2690
 
                     unsigned int shader_type,
2691
 
                     unsigned int parsing_builtin)
2692
 
{
2693
 
   struct sl_pp_purify_options options;
2694
 
   struct sl_pp_context *context;
2695
 
   unsigned char *prod;
2696
 
   GLuint size;
2697
 
   unsigned int version;
2698
 
   unsigned int maxVersion;
2699
 
   int result;
2700
 
   char errmsg[200] = "";
2701
 
 
2702
 
   assert(shader_type == 1 || shader_type == 2);
2703
 
 
2704
 
   memset(&options, 0, sizeof(options));
2705
 
 
2706
 
   context = sl_pp_context_create(source, &options);
2707
 
   if (!context) {
2708
 
      slang_info_log_error(infolog, "out of memory");
2709
 
      return GL_FALSE;
2710
 
   }
2711
 
 
2712
 
   if (sl_pp_version(context, &version)) {
2713
 
      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
2714
 
      sl_pp_context_destroy(context);
2715
 
      return GL_FALSE;
2716
 
   }
2717
 
 
2718
 
   if (sl_pp_context_add_extension(context, "GL_ARB_draw_buffers") ||
2719
 
       sl_pp_context_add_extension(context, "GL_ARB_texture_rectangle")) {
2720
 
      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
2721
 
      sl_pp_context_destroy(context);
2722
 
      return GL_FALSE;
2723
 
   }
2724
 
 
2725
 
   if (type == SLANG_UNIT_FRAGMENT_SHADER) {
2726
 
      sl_pp_context_add_extension(context, "GL_ARB_fragment_coord_conventions");
2727
 
   }
2728
 
 
2729
 
 
2730
 
#if FEATURE_es2_glsl
2731
 
   if (sl_pp_context_add_predefined(context, "GL_ES", "1") ||
2732
 
       sl_pp_context_add_predefined(context, "GL_FRAGMENT_PRECISION_HIGH", "1")) {
2733
 
      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
2734
 
      sl_pp_context_destroy(context);
2735
 
      return GL_FALSE;
2736
 
   }
2737
 
#endif
2738
 
 
2739
 
#if FEATURE_ARB_shading_language_120
2740
 
   maxVersion = 120;
2741
 
#elif FEATURE_es2_glsl
2742
 
   maxVersion = 100;
2743
 
#else
2744
 
   maxVersion = 110;
2745
 
#endif
2746
 
 
2747
 
   if (version > maxVersion ||
2748
 
       (version != 100 && version != 110 && version != 120)) {
2749
 
      slang_info_log_error(infolog,
2750
 
                           "language version %.2f is not supported.",
2751
 
                           version * 0.01);
2752
 
      sl_pp_context_destroy(context);
2753
 
      return GL_FALSE;
2754
 
   }
2755
 
 
2756
 
   /* Finally check the syntax and generate its binary representation. */
2757
 
   result = sl_cl_compile(context,
2758
 
                          shader_type,
2759
 
                          parsing_builtin,
2760
 
                          &prod,
2761
 
                          &size,
2762
 
                          errmsg,
2763
 
                          sizeof(errmsg));
2764
 
 
2765
 
   sl_pp_context_destroy(context);
2766
 
 
2767
 
   if (result) {
2768
 
      /*GLint pos;*/
2769
 
 
2770
 
      slang_info_log_error(infolog, errmsg);
2771
 
      /* syntax error (possibly in library code) */
2772
 
#if 0
2773
 
      {
2774
 
         int line, col;
2775
 
         char *s;
2776
 
         s = (char *) _mesa_find_line_column((const GLubyte *) source,
2777
 
                                             (const GLubyte *) source + pos,
2778
 
                                             &line, &col);
2779
 
         printf("Error on line %d, col %d: %s\n", line, col, s);
2780
 
      }
2781
 
#endif
2782
 
      return GL_FALSE;
2783
 
   }
2784
 
 
2785
 
   /* Syntax is okay - translate it to internal representation. */
2786
 
   if (!compile_binary(prod, unit, version, type, infolog, builtin,
2787
 
                       &builtin[SLANG_BUILTIN_TOTAL - 1],
2788
 
                       shader)) {
2789
 
      free(prod);
2790
 
      return GL_FALSE;
2791
 
   }
2792
 
   free(prod);
2793
 
   return GL_TRUE;
2794
 
}
2795
 
 
2796
 
static const unsigned char slang_core_gc[] = {
2797
 
#include "library/slang_core_gc.h"
2798
 
};
2799
 
 
2800
 
static const unsigned char slang_120_core_gc[] = {
2801
 
#include "library/slang_120_core_gc.h"
2802
 
};
2803
 
 
2804
 
static const unsigned char slang_120_fragment_gc[] = {
2805
 
#include "library/slang_builtin_120_fragment_gc.h"
2806
 
};
2807
 
 
2808
 
static const unsigned char slang_common_builtin_gc[] = {
2809
 
#include "library/slang_common_builtin_gc.h"
2810
 
};
2811
 
 
2812
 
static const unsigned char slang_fragment_builtin_gc[] = {
2813
 
#include "library/slang_fragment_builtin_gc.h"
2814
 
};
2815
 
 
2816
 
static const unsigned char slang_vertex_builtin_gc[] = {
2817
 
#include "library/slang_vertex_builtin_gc.h"
2818
 
};
2819
 
 
2820
 
static GLboolean
2821
 
compile_object(const char *source,
2822
 
               slang_code_object *object,
2823
 
               slang_unit_type type,
2824
 
               slang_info_log *infolog,
2825
 
               struct gl_shader *shader,
2826
 
               struct gl_sl_pragmas *pragmas)
2827
 
{
2828
 
   slang_code_unit *builtins = NULL;
2829
 
   GLuint base_version = 110;
2830
 
   unsigned int shader_type;
2831
 
   unsigned int parsing_builtin;
2832
 
 
2833
 
   /* set shader type - the syntax is slightly different for different shaders */
2834
 
   if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_FRAGMENT_BUILTIN) {
2835
 
      shader_type = 1;
2836
 
   } else {
2837
 
      shader_type = 2;
2838
 
   }
2839
 
 
2840
 
   /* enable language extensions */
2841
 
   parsing_builtin = 1;
2842
 
 
2843
 
   /* if parsing user-specified shader, load built-in library */
2844
 
   if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_VERTEX_SHADER) {
2845
 
      /* compile core functionality first */
2846
 
      if (!compile_binary(slang_core_gc,
2847
 
                          &object->builtin[SLANG_BUILTIN_CORE],
2848
 
                          base_version,
2849
 
                          SLANG_UNIT_FRAGMENT_BUILTIN, infolog,
2850
 
                          NULL, NULL, NULL))
2851
 
         return GL_FALSE;
2852
 
 
2853
 
#if FEATURE_ARB_shading_language_120
2854
 
      if (!compile_binary(slang_120_core_gc,
2855
 
                          &object->builtin[SLANG_BUILTIN_120_CORE],
2856
 
                          120,
2857
 
                          SLANG_UNIT_FRAGMENT_BUILTIN, infolog,
2858
 
                          NULL, &object->builtin[SLANG_BUILTIN_CORE], NULL))
2859
 
         return GL_FALSE;
2860
 
#endif
2861
 
 
2862
 
      /* compile common functions and variables, link to core */
2863
 
      if (!compile_binary(slang_common_builtin_gc,
2864
 
                          &object->builtin[SLANG_BUILTIN_COMMON],
2865
 
#if FEATURE_ARB_shading_language_120
2866
 
                          120,
2867
 
#else
2868
 
                          base_version,
2869
 
#endif
2870
 
                          SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
2871
 
#if FEATURE_ARB_shading_language_120
2872
 
                          &object->builtin[SLANG_BUILTIN_120_CORE],
2873
 
#else
2874
 
                          &object->builtin[SLANG_BUILTIN_CORE],
2875
 
#endif
2876
 
                          NULL))
2877
 
         return GL_FALSE;
2878
 
 
2879
 
      /* compile target-specific functions and variables, link to common */
2880
 
      if (type == SLANG_UNIT_FRAGMENT_SHADER) {
2881
 
         if (!compile_binary(slang_fragment_builtin_gc,
2882
 
                             &object->builtin[SLANG_BUILTIN_TARGET],
2883
 
                             base_version,
2884
 
                             SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
2885
 
                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
2886
 
            return GL_FALSE;
2887
 
#if FEATURE_ARB_shading_language_120
2888
 
         if (!compile_binary(slang_120_fragment_gc,
2889
 
                             &object->builtin[SLANG_BUILTIN_TARGET],
2890
 
                             120,
2891
 
                             SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
2892
 
                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
2893
 
            return GL_FALSE;
2894
 
#endif
2895
 
      }
2896
 
      else if (type == SLANG_UNIT_VERTEX_SHADER) {
2897
 
         if (!compile_binary(slang_vertex_builtin_gc,
2898
 
                             &object->builtin[SLANG_BUILTIN_TARGET],
2899
 
                             base_version,
2900
 
                             SLANG_UNIT_VERTEX_BUILTIN, infolog, NULL,
2901
 
                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
2902
 
            return GL_FALSE;
2903
 
      }
2904
 
 
2905
 
      /* disable language extensions */
2906
 
      parsing_builtin = 0;
2907
 
 
2908
 
      builtins = object->builtin;
2909
 
   }
2910
 
 
2911
 
   /* compile the actual shader - pass-in built-in library for external shader */
2912
 
   return compile_with_grammar(source,
2913
 
                               &object->unit,
2914
 
                               type,
2915
 
                               infolog,
2916
 
                               builtins,
2917
 
                               shader,
2918
 
                               pragmas,
2919
 
                               shader_type,
2920
 
                               parsing_builtin);
2921
 
}
2922
 
 
2923
 
 
2924
 
GLboolean
2925
 
_slang_compile(GLcontext *ctx, struct gl_shader *shader)
2926
 
{
2927
 
   GLboolean success;
2928
 
   slang_info_log info_log;
2929
 
   slang_code_object obj;
2930
 
   slang_unit_type type;
2931
 
   GLenum progTarget;
2932
 
 
2933
 
   if (shader->Type == GL_VERTEX_SHADER) {
2934
 
      type = SLANG_UNIT_VERTEX_SHADER;
2935
 
   }
2936
 
   else {
2937
 
      assert(shader->Type == GL_FRAGMENT_SHADER);
2938
 
      type = SLANG_UNIT_FRAGMENT_SHADER;
2939
 
   }
2940
 
 
2941
 
   if (!shader->Source)
2942
 
      return GL_FALSE;
2943
 
 
2944
 
   ctx->Shader.MemPool = _slang_new_mempool(1024*1024);
2945
 
 
2946
 
   shader->Main = GL_FALSE;
2947
 
 
2948
 
   /* free the shader's old instructions, etc */
2949
 
   _mesa_reference_program(ctx, &shader->Program, NULL);
2950
 
 
2951
 
   /* allocate new GPU program, parameter lists, etc. */
2952
 
   if (shader->Type == GL_VERTEX_SHADER)
2953
 
      progTarget = GL_VERTEX_PROGRAM_ARB;
2954
 
   else
2955
 
      progTarget = GL_FRAGMENT_PROGRAM_ARB;
2956
 
   shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
2957
 
   shader->Program->Parameters = _mesa_new_parameter_list();
2958
 
   shader->Program->Varying = _mesa_new_parameter_list();
2959
 
   shader->Program->Attributes = _mesa_new_parameter_list();
2960
 
 
2961
 
   slang_info_log_construct(&info_log);
2962
 
   _slang_code_object_ctr(&obj);
2963
 
 
2964
 
   success = compile_object(shader->Source,
2965
 
                            &obj,
2966
 
                            type,
2967
 
                            &info_log,
2968
 
                            shader,
2969
 
                            &shader->Pragmas);
2970
 
 
2971
 
   /* free shader's prev info log */
2972
 
   if (shader->InfoLog) {
2973
 
      free(shader->InfoLog);
2974
 
      shader->InfoLog = NULL;
2975
 
   }
2976
 
 
2977
 
   if (info_log.text) {
2978
 
      /* copy info-log string to shader object */
2979
 
      shader->InfoLog = _mesa_strdup(info_log.text);
2980
 
   }
2981
 
 
2982
 
   if (info_log.error_flag) {
2983
 
      success = GL_FALSE;
2984
 
   }
2985
 
 
2986
 
   slang_info_log_destruct(&info_log);
2987
 
   _slang_code_object_dtr(&obj);
2988
 
 
2989
 
   _slang_delete_mempool((slang_mempool *) ctx->Shader.MemPool);
2990
 
   ctx->Shader.MemPool = NULL;
2991
 
 
2992
 
   /* remove any reads of output registers */
2993
 
#if 0
2994
 
   printf("Pre-remove output reads:\n");
2995
 
   _mesa_print_program(shader->Program);
2996
 
#endif
2997
 
   _mesa_remove_output_reads(shader->Program, PROGRAM_OUTPUT);
2998
 
   if (shader->Type == GL_VERTEX_SHADER) {
2999
 
      /* and remove writes to varying vars in vertex programs */
3000
 
      _mesa_remove_output_reads(shader->Program, PROGRAM_VARYING);
3001
 
   }
3002
 
#if 0
3003
 
   printf("Post-remove output reads:\n");
3004
 
   _mesa_print_program(shader->Program);
3005
 
#endif
3006
 
 
3007
 
   shader->CompileStatus = success;
3008
 
 
3009
 
   if (success) {
3010
 
      if (shader->Pragmas.Optimize &&
3011
 
          (ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
3012
 
         _mesa_optimize_program(ctx, shader->Program);
3013
 
      }
3014
 
      if ((ctx->Shader.Flags & GLSL_NOP_VERT) &&
3015
 
          shader->Program->Target == GL_VERTEX_PROGRAM_ARB) {
3016
 
         _mesa_nop_vertex_program(ctx,
3017
 
                                  (struct gl_vertex_program *) shader->Program);
3018
 
      }
3019
 
      if ((ctx->Shader.Flags & GLSL_NOP_FRAG) &&
3020
 
          shader->Program->Target == GL_FRAGMENT_PROGRAM_ARB) {
3021
 
         _mesa_nop_fragment_program(ctx,
3022
 
                                (struct gl_fragment_program *) shader->Program);
3023
 
      }
3024
 
   }
3025
 
 
3026
 
   if (ctx->Shader.Flags & GLSL_LOG) {
3027
 
      _mesa_write_shader_to_file(shader);
3028
 
   }
3029
 
 
3030
 
   return success;
3031
 
}
3032