~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Mesa 3-D graphics library
3
 
 * Version:  6.5
 
3
 * Version:  6.5.2
4
4
 *
5
5
 * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
6
6
 *
35
35
#include "slang_storage.h"
36
36
 
37
37
/*
38
 
 * This is a straightforward implementation of the slang front-end compiler.
39
 
 * Lots of error-checking functionality is missing but every well-formed shader source should
40
 
 * compile successfully and execute as expected. However, some semantically ill-formed shaders
 
38
 * This is a straightforward implementation of the slang front-end
 
39
 * compiler.  Lots of error-checking functionality is missing but
 
40
 * every well-formed shader source should compile successfully and
 
41
 * execute as expected. However, some semantically ill-formed shaders
41
42
 * may be accepted resulting in undefined behaviour.
42
43
 */
43
44
 
44
 
/* slang_var_pool */
45
 
 
46
 
static GLuint slang_var_pool_alloc (slang_var_pool *pool, unsigned int size)
 
45
 
 
46
 
 
47
/**
 
48
 * Allocate storage for a variable of 'size' bytes from given pool.
 
49
 * Return the allocated address for the variable.
 
50
 */
 
51
static GLuint
 
52
slang_var_pool_alloc(slang_var_pool * pool, unsigned int size)
47
53
{
48
 
        GLuint addr;
49
 
 
50
 
        addr = pool->next_addr;
51
 
        pool->next_addr += size;
52
 
        return addr;
 
54
   const GLuint addr = pool->next_addr;
 
55
   pool->next_addr += size;
 
56
   return addr;
53
57
}
54
58
 
55
59
/*
57
61
 */
58
62
 
59
63
GLvoid
60
 
_slang_code_unit_ctr (slang_code_unit *self, struct slang_code_object_ *object)
 
64
_slang_code_unit_ctr(slang_code_unit * self,
 
65
                     struct slang_code_object_ * object)
61
66
{
62
 
   _slang_variable_scope_ctr (&self->vars);
63
 
   _slang_function_scope_ctr (&self->funs);
64
 
   _slang_struct_scope_ctr (&self->structs);
 
67
   _slang_variable_scope_ctr(&self->vars);
 
68
   _slang_function_scope_ctr(&self->funs);
 
69
   _slang_struct_scope_ctr(&self->structs);
65
70
   self->object = object;
66
71
}
67
72
 
68
73
GLvoid
69
 
_slang_code_unit_dtr (slang_code_unit *self)
 
74
_slang_code_unit_dtr(slang_code_unit * self)
70
75
{
71
 
   slang_variable_scope_destruct (&self->vars);
72
 
   slang_function_scope_destruct (&self->funs);
73
 
   slang_struct_scope_destruct (&self->structs);
 
76
   slang_variable_scope_destruct(&self->vars);
 
77
   slang_function_scope_destruct(&self->funs);
 
78
   slang_struct_scope_destruct(&self->structs);
74
79
}
75
80
 
76
81
/*
78
83
 */
79
84
 
80
85
GLvoid
81
 
_slang_code_object_ctr (slang_code_object *self)
 
86
_slang_code_object_ctr(slang_code_object * self)
82
87
{
83
88
   GLuint i;
84
89
 
85
90
   for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
86
 
      _slang_code_unit_ctr (&self->builtin[i], self);
87
 
   _slang_code_unit_ctr (&self->unit, self);
88
 
   _slang_assembly_file_ctr (&self->assembly);
89
 
   slang_machine_ctr (&self->machine);
 
91
      _slang_code_unit_ctr(&self->builtin[i], self);
 
92
   _slang_code_unit_ctr(&self->unit, self);
 
93
   _slang_assembly_file_ctr(&self->assembly);
 
94
   slang_machine_ctr(&self->machine);
90
95
   self->varpool.next_addr = 0;
91
 
   slang_atom_pool_construct (&self->atompool);
92
 
   slang_export_data_table_ctr (&self->expdata);
 
96
   slang_atom_pool_construct(&self->atompool);
 
97
   slang_export_data_table_ctr(&self->expdata);
93
98
   self->expdata.atoms = &self->atompool;
94
 
   slang_export_code_table_ctr (&self->expcode);
 
99
   slang_export_code_table_ctr(&self->expcode);
95
100
   self->expcode.atoms = &self->atompool;
96
101
}
97
102
 
98
103
GLvoid
99
 
_slang_code_object_dtr (slang_code_object *self)
 
104
_slang_code_object_dtr(slang_code_object * self)
100
105
{
101
106
   GLuint i;
102
107
 
103
108
   for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
104
 
      _slang_code_unit_dtr (&self->builtin[i]);
105
 
   _slang_code_unit_dtr (&self->unit);
106
 
   slang_assembly_file_destruct (&self->assembly);
107
 
   slang_machine_dtr (&self->machine);
108
 
   slang_atom_pool_destruct (&self->atompool);
109
 
   slang_export_data_table_dtr (&self->expdata);
110
 
   slang_export_code_table_ctr (&self->expcode);
 
109
      _slang_code_unit_dtr(&self->builtin[i]);
 
110
   _slang_code_unit_dtr(&self->unit);
 
111
   slang_assembly_file_destruct(&self->assembly);
 
112
   slang_machine_dtr(&self->machine);
 
113
   slang_atom_pool_destruct(&self->atompool);
 
114
   slang_export_data_table_dtr(&self->expdata);
 
115
   slang_export_code_table_ctr(&self->expcode);
111
116
}
112
117
 
113
118
/* slang_info_log */
114
119
 
115
120
static char *out_of_memory = "Error: Out of memory.\n";
116
121
 
117
 
void slang_info_log_construct (slang_info_log *log)
118
 
{
119
 
        log->text = NULL;
120
 
        log->dont_free_text = 0;
121
 
}
122
 
 
123
 
void slang_info_log_destruct (slang_info_log *log)
124
 
{
125
 
        if (!log->dont_free_text)
126
 
                slang_alloc_free (log->text);
127
 
}
128
 
 
129
 
static int slang_info_log_message (slang_info_log *log, const char *prefix, const char *msg)
 
122
void
 
123
slang_info_log_construct(slang_info_log * log)
 
124
{
 
125
   log->text = NULL;
 
126
   log->dont_free_text = 0;
 
127
}
 
128
 
 
129
void
 
130
slang_info_log_destruct(slang_info_log * log)
 
131
{
 
132
   if (!log->dont_free_text)
 
133
      slang_alloc_free(log->text);
 
134
}
 
135
 
 
136
static int
 
137
slang_info_log_message(slang_info_log * log, const char *prefix,
 
138
                       const char *msg)
130
139
{
131
140
   GLuint size;
132
141
 
133
 
        if (log->dont_free_text)
134
 
                return 0;
135
 
   size = slang_string_length (msg) + 2;
 
142
   if (log->dont_free_text)
 
143
      return 0;
 
144
   size = slang_string_length(msg) + 2;
136
145
   if (prefix != NULL)
137
 
      size += slang_string_length (prefix) + 2;
 
146
      size += slang_string_length(prefix) + 2;
138
147
   if (log->text != NULL) {
139
 
      GLuint old_len = slang_string_length (log->text);
140
 
      log->text = (char *) (slang_alloc_realloc (log->text, old_len + 1, old_len + size));
 
148
      GLuint old_len = slang_string_length(log->text);
 
149
      log->text = (char *)
 
150
         slang_alloc_realloc(log->text, old_len + 1, old_len + size);
141
151
   }
142
152
   else {
143
 
      log->text = (char *) (slang_alloc_malloc (size));
 
153
      log->text = (char *) (slang_alloc_malloc(size));
144
154
      if (log->text != NULL)
145
155
         log->text[0] = '\0';
146
156
   }
147
 
        if (log->text == NULL)
148
 
                return 0;
 
157
   if (log->text == NULL)
 
158
      return 0;
149
159
   if (prefix != NULL) {
150
 
      slang_string_concat (log->text, prefix);
151
 
      slang_string_concat (log->text, ": ");
152
 
   }
153
 
        slang_string_concat (log->text, msg);
154
 
        slang_string_concat (log->text, "\n");
155
 
        return 1;
156
 
}
157
 
 
158
 
int slang_info_log_print (slang_info_log *log, const char *msg, ...)
159
 
{
160
 
   va_list va;
161
 
   char buf[1024];
162
 
 
163
 
   va_start (va, msg);
164
 
   _mesa_vsprintf (buf, msg, va);
165
 
   va_end (va);
166
 
   return slang_info_log_message (log, NULL, buf);
167
 
}
168
 
 
169
 
int slang_info_log_error (slang_info_log *log, const char *msg, ...)
170
 
{
171
 
        va_list va;
172
 
        char buf[1024];
173
 
 
174
 
        va_start (va, msg);
175
 
        _mesa_vsprintf (buf, msg, va);
176
 
   va_end (va);
177
 
        if (slang_info_log_message (log, "Error", buf))
178
 
                return 1;
179
 
        slang_info_log_memory (log);
180
 
        return 0;
181
 
}
182
 
 
183
 
int slang_info_log_warning (slang_info_log *log, const char *msg, ...)
184
 
{
185
 
        va_list va;
186
 
        char buf[1024];
187
 
 
188
 
        va_start (va, msg);
189
 
        _mesa_vsprintf (buf, msg, va);
190
 
   va_end (va);
191
 
        if (slang_info_log_message (log, "Warning", buf))
192
 
                return 1;
193
 
        slang_info_log_memory (log);
194
 
        return 0;
195
 
}
196
 
 
197
 
void slang_info_log_memory (slang_info_log *log)
198
 
{
199
 
        if (!slang_info_log_message (log, "Error", "Out of memory."))
200
 
        {
201
 
                log->dont_free_text = 1;
202
 
                log->text = out_of_memory;
203
 
        }
 
160
      slang_string_concat(log->text, prefix);
 
161
      slang_string_concat(log->text, ": ");
 
162
   }
 
163
   slang_string_concat(log->text, msg);
 
164
   slang_string_concat(log->text, "\n");
 
165
   return 1;
 
166
}
 
167
 
 
168
int
 
169
slang_info_log_print(slang_info_log * log, const char *msg, ...)
 
170
{
 
171
   va_list va;
 
172
   char buf[1024];
 
173
 
 
174
   va_start(va, msg);
 
175
   _mesa_vsprintf(buf, msg, va);
 
176
   va_end(va);
 
177
   return slang_info_log_message(log, NULL, buf);
 
178
}
 
179
 
 
180
int
 
181
slang_info_log_error(slang_info_log * log, const char *msg, ...)
 
182
{
 
183
   va_list va;
 
184
   char buf[1024];
 
185
 
 
186
   va_start(va, msg);
 
187
   _mesa_vsprintf(buf, msg, va);
 
188
   va_end(va);
 
189
   if (slang_info_log_message(log, "Error", buf))
 
190
      return 1;
 
191
   slang_info_log_memory(log);
 
192
   return 0;
 
193
}
 
194
 
 
195
int
 
196
slang_info_log_warning(slang_info_log * log, const char *msg, ...)
 
197
{
 
198
   va_list va;
 
199
   char buf[1024];
 
200
 
 
201
   va_start(va, msg);
 
202
   _mesa_vsprintf(buf, msg, va);
 
203
   va_end(va);
 
204
   if (slang_info_log_message(log, "Warning", buf))
 
205
      return 1;
 
206
   slang_info_log_memory(log);
 
207
   return 0;
 
208
}
 
209
 
 
210
void
 
211
slang_info_log_memory(slang_info_log * log)
 
212
{
 
213
   if (!slang_info_log_message(log, "Error", "Out of memory.")) {
 
214
      log->dont_free_text = 1;
 
215
      log->text = out_of_memory;
 
216
   }
204
217
}
205
218
 
206
219
/* slang_parse_ctx */
207
220
 
208
221
typedef struct slang_parse_ctx_
209
222
{
210
 
        const byte *I;
211
 
        slang_info_log *L;
212
 
        int parsing_builtin;
213
 
        int global_scope;
214
 
        slang_atom_pool *atoms;
 
223
   const byte *I;
 
224
   slang_info_log *L;
 
225
   int parsing_builtin;
 
226
   GLboolean global_scope;   /**< Is object being declared a global? */
 
227
   slang_atom_pool *atoms;
215
228
} slang_parse_ctx;
216
229
 
217
230
/* slang_output_ctx */
218
231
 
219
232
typedef struct slang_output_ctx_
220
233
{
221
 
        slang_variable_scope *vars;
222
 
        slang_function_scope *funs;
223
 
        slang_struct_scope *structs;
224
 
        slang_assembly_file *assembly;
225
 
        slang_var_pool *global_pool;
226
 
        slang_machine *machine;
 
234
   slang_variable_scope *vars;
 
235
   slang_function_scope *funs;
 
236
   slang_struct_scope *structs;
 
237
   slang_assembly_file *assembly;
 
238
   slang_var_pool *global_pool;
 
239
   slang_machine *machine;
227
240
} slang_output_ctx;
228
241
 
229
242
/* _slang_compile() */
230
243
 
231
 
static void parse_identifier_str (slang_parse_ctx *C, char **id)
232
 
{
233
 
        *id = (char *) C->I;
234
 
        C->I += _mesa_strlen (*id) + 1;
235
 
}
236
 
 
237
 
static slang_atom parse_identifier (slang_parse_ctx *C)
238
 
{
239
 
        const char *id;
240
 
        
241
 
        id = (const char *) C->I;
242
 
        C->I += _mesa_strlen (id) + 1;
243
 
        return slang_atom_pool_atom (C->atoms, id);
244
 
}
245
 
 
246
 
static int parse_number (slang_parse_ctx *C, int *number)
247
 
{
248
 
        const int radix = (int) (*C->I++);
249
 
        *number = 0;
250
 
        while (*C->I != '\0')
251
 
        {
252
 
                int digit;
253
 
                if (*C->I >= '0' && *C->I <= '9')
254
 
                        digit = (int) (*C->I - '0');
255
 
                else if (*C->I >= 'A' && *C->I <= 'Z')
256
 
                        digit = (int) (*C->I - 'A') + 10;
257
 
                else
258
 
                        digit = (int) (*C->I - 'a') + 10;
259
 
                *number = *number * radix + digit;
260
 
                C->I++;
261
 
        }
262
 
        C->I++;
263
 
        if (*number > 65535)
264
 
      slang_info_log_warning (C->L, "%d: literal integer overflow.", *number);
265
 
        return 1;
266
 
}
267
 
 
268
 
static int parse_float (slang_parse_ctx *C, float *number)
269
 
{
270
 
        char *integral = NULL;
271
 
        char *fractional = NULL;
272
 
        char *exponent = NULL;
273
 
        char *whole = NULL;
274
 
 
275
 
        parse_identifier_str (C, &integral);
276
 
        parse_identifier_str (C, &fractional);
277
 
        parse_identifier_str (C, &exponent);
278
 
 
279
 
        whole = (char *) (slang_alloc_malloc ((_mesa_strlen (integral) + _mesa_strlen (fractional) +
280
 
                _mesa_strlen (exponent) + 3) * sizeof (char)));
281
 
        if (whole == NULL)
282
 
        {
283
 
                slang_info_log_memory (C->L);
284
 
                return 0;
285
 
        }
286
 
 
287
 
        slang_string_copy (whole, integral);
288
 
        slang_string_concat (whole, ".");
289
 
        slang_string_concat (whole, fractional);
290
 
        slang_string_concat (whole, "E");
291
 
        slang_string_concat (whole, exponent);
292
 
 
293
 
        *number = (float) (_mesa_strtod(whole, (char **)NULL));
294
 
 
295
 
        slang_alloc_free (whole);
296
 
        return 1;
 
244
static void
 
245
parse_identifier_str(slang_parse_ctx * C, char **id)
 
246
{
 
247
   *id = (char *) C->I;
 
248
   C->I += _mesa_strlen(*id) + 1;
 
249
}
 
250
 
 
251
static slang_atom
 
252
parse_identifier(slang_parse_ctx * C)
 
253
{
 
254
   const char *id;
 
255
 
 
256
   id = (const char *) C->I;
 
257
   C->I += _mesa_strlen(id) + 1;
 
258
   return slang_atom_pool_atom(C->atoms, id);
 
259
}
 
260
 
 
261
static int
 
262
parse_number(slang_parse_ctx * C, int *number)
 
263
{
 
264
   const int radix = (int) (*C->I++);
 
265
   *number = 0;
 
266
   while (*C->I != '\0') {
 
267
      int digit;
 
268
      if (*C->I >= '0' && *C->I <= '9')
 
269
         digit = (int) (*C->I - '0');
 
270
      else if (*C->I >= 'A' && *C->I <= 'Z')
 
271
         digit = (int) (*C->I - 'A') + 10;
 
272
      else
 
273
         digit = (int) (*C->I - 'a') + 10;
 
274
      *number = *number * radix + digit;
 
275
      C->I++;
 
276
   }
 
277
   C->I++;
 
278
   if (*number > 65535)
 
279
      slang_info_log_warning(C->L, "%d: literal integer overflow.", *number);
 
280
   return 1;
 
281
}
 
282
 
 
283
static int
 
284
parse_float(slang_parse_ctx * C, float *number)
 
285
{
 
286
   char *integral = NULL;
 
287
   char *fractional = NULL;
 
288
   char *exponent = NULL;
 
289
   char *whole = NULL;
 
290
 
 
291
   parse_identifier_str(C, &integral);
 
292
   parse_identifier_str(C, &fractional);
 
293
   parse_identifier_str(C, &exponent);
 
294
 
 
295
   whole = (char *) (slang_alloc_malloc((_mesa_strlen(integral) +
 
296
                                         _mesa_strlen(fractional) +
 
297
                                         _mesa_strlen(exponent) + 3) * sizeof(char)));
 
298
   if (whole == NULL) {
 
299
      slang_info_log_memory(C->L);
 
300
      return 0;
 
301
   }
 
302
 
 
303
   slang_string_copy(whole, integral);
 
304
   slang_string_concat(whole, ".");
 
305
   slang_string_concat(whole, fractional);
 
306
   slang_string_concat(whole, "E");
 
307
   slang_string_concat(whole, exponent);
 
308
 
 
309
   *number = (float) (_mesa_strtod(whole, (char **) NULL));
 
310
 
 
311
   slang_alloc_free(whole);
 
312
   return 1;
297
313
}
298
314
 
299
315
/* revision number - increment after each change affecting emitted output */
300
316
#define REVISION 3
301
317
 
302
 
static int check_revision (slang_parse_ctx *C)
303
 
{
304
 
        if (*C->I != REVISION)
305
 
        {
306
 
      slang_info_log_error (C->L, "Internal compiler error.");
307
 
                return 0;
308
 
        }
309
 
        C->I++;
310
 
        return 1;
311
 
}
312
 
 
313
 
static int parse_statement (slang_parse_ctx *, slang_output_ctx *, slang_operation *);
314
 
static int parse_expression (slang_parse_ctx *, slang_output_ctx *, slang_operation *);
315
 
static int parse_type_specifier (slang_parse_ctx *, slang_output_ctx *, slang_type_specifier *);
316
 
 
317
 
static GLboolean parse_array_len (slang_parse_ctx *C, slang_output_ctx *O, GLuint *len)
318
 
{
319
 
        slang_operation array_size;
320
 
        slang_assembly_name_space space;
321
 
        GLboolean result;
322
 
 
323
 
        if (!slang_operation_construct (&array_size))
324
 
                return GL_FALSE;
325
 
        if (!parse_expression (C, O, &array_size))
326
 
        {
327
 
                slang_operation_destruct (&array_size);
328
 
                return GL_FALSE;
329
 
        }
330
 
 
331
 
        space.funcs = O->funs;
332
 
        space.structs = O->structs;
333
 
        space.vars = O->vars;
334
 
        result = _slang_evaluate_int (O->assembly, O->machine, &space, &array_size, len, C->atoms);
335
 
        slang_operation_destruct (&array_size);
336
 
        return result;
337
 
}
338
 
 
339
 
static GLboolean calculate_var_size (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var)
340
 
{
341
 
        slang_storage_aggregate agg;
342
 
 
343
 
        if (!slang_storage_aggregate_construct (&agg))
344
 
                return GL_FALSE;
345
 
        if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_len, O->funs, O->structs,
346
 
                        O->vars, O->machine, O->assembly, C->atoms))
347
 
        {
348
 
                slang_storage_aggregate_destruct (&agg);
349
 
                return GL_FALSE;
350
 
        }
351
 
        var->size = _slang_sizeof_aggregate (&agg);
352
 
        slang_storage_aggregate_destruct (&agg);
353
 
        return GL_TRUE;
354
 
}
355
 
 
356
 
static GLboolean convert_to_array (slang_parse_ctx *C, slang_variable *var,
357
 
        const slang_type_specifier *sp)
358
 
{
359
 
        /* sized array - mark it as array, copy the specifier to the array element and
360
 
         * parse the expression */
361
 
        var->type.specifier.type = slang_spec_array;
362
 
        var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc (sizeof (
363
 
                slang_type_specifier));
364
 
        if (var->type.specifier._array == NULL)
365
 
        {
366
 
                slang_info_log_memory (C->L);
367
 
                return GL_FALSE;
368
 
        }
369
 
        slang_type_specifier_ctr (var->type.specifier._array);
370
 
        return slang_type_specifier_copy (var->type.specifier._array, sp);
 
318
static int
 
319
check_revision(slang_parse_ctx * C)
 
320
{
 
321
   if (*C->I != REVISION) {
 
322
      slang_info_log_error(C->L, "Internal compiler error.");
 
323
      return 0;
 
324
   }
 
325
   C->I++;
 
326
   return 1;
 
327
}
 
328
 
 
329
static int parse_statement(slang_parse_ctx *, slang_output_ctx *,
 
330
                           slang_operation *);
 
331
static int parse_expression(slang_parse_ctx *, slang_output_ctx *,
 
332
                            slang_operation *);
 
333
static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *,
 
334
                                slang_type_specifier *);
 
335
 
 
336
static GLboolean
 
337
parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len)
 
338
{
 
339
   slang_operation array_size;
 
340
   slang_assembly_name_space space;
 
341
   GLboolean result;
 
342
 
 
343
   if (!slang_operation_construct(&array_size))
 
344
      return GL_FALSE;
 
345
   if (!parse_expression(C, O, &array_size)) {
 
346
      slang_operation_destruct(&array_size);
 
347
      return GL_FALSE;
 
348
   }
 
349
 
 
350
   space.funcs = O->funs;
 
351
   space.structs = O->structs;
 
352
   space.vars = O->vars;
 
353
   result = _slang_evaluate_int(O->assembly, O->machine, &space,
 
354
                                &array_size, len, C->atoms);
 
355
   slang_operation_destruct(&array_size);
 
356
   return result;
 
357
}
 
358
 
 
359
static GLboolean
 
360
calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O,
 
361
                   slang_variable * var)
 
362
{
 
363
   slang_storage_aggregate agg;
 
364
 
 
365
   if (!slang_storage_aggregate_construct(&agg))
 
366
      return GL_FALSE;
 
367
   if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len,
 
368
                                  O->funs, O->structs, O->vars, O->machine,
 
369
                                  O->assembly, C->atoms)) {
 
370
      slang_storage_aggregate_destruct(&agg);
 
371
      return GL_FALSE;
 
372
   }
 
373
   var->size = _slang_sizeof_aggregate(&agg);
 
374
   slang_storage_aggregate_destruct(&agg);
 
375
   return GL_TRUE;
 
376
}
 
377
 
 
378
static GLboolean
 
379
convert_to_array(slang_parse_ctx * C, slang_variable * var,
 
380
                 const slang_type_specifier * sp)
 
381
{
 
382
   /* sized array - mark it as array, copy the specifier to the array element and
 
383
    * parse the expression */
 
384
   var->type.specifier.type = slang_spec_array;
 
385
   var->type.specifier._array = (slang_type_specifier *)
 
386
      slang_alloc_malloc(sizeof(slang_type_specifier));
 
387
   if (var->type.specifier._array == NULL) {
 
388
      slang_info_log_memory(C->L);
 
389
      return GL_FALSE;
 
390
   }
 
391
   slang_type_specifier_ctr(var->type.specifier._array);
 
392
   return slang_type_specifier_copy(var->type.specifier._array, sp);
371
393
}
372
394
 
373
395
/* structure field */
375
397
#define FIELD_NEXT 1
376
398
#define FIELD_ARRAY 2
377
399
 
378
 
static GLboolean parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var,
379
 
        const slang_type_specifier *sp)
380
 
{
381
 
        var->a_name = parse_identifier (C);
382
 
        if (var->a_name == SLANG_ATOM_NULL)
383
 
                return GL_FALSE;
384
 
 
385
 
        switch (*C->I++)
386
 
        {
387
 
        case FIELD_NONE:
388
 
                if (!slang_type_specifier_copy (&var->type.specifier, sp))
389
 
                        return GL_FALSE;
390
 
                break;
391
 
        case FIELD_ARRAY:
392
 
                if (!convert_to_array (C, var, sp))
393
 
                        return GL_FALSE;
394
 
                if (!parse_array_len (C, O, &var->array_len))
395
 
                        return GL_FALSE;
396
 
                break;
397
 
        default:
398
 
                return GL_FALSE;
399
 
        }
400
 
 
401
 
        return calculate_var_size (C, O, var);
402
 
}
403
 
 
404
 
static int parse_struct_field (slang_parse_ctx *C, slang_output_ctx *O, slang_struct *st,
405
 
        slang_type_specifier *sp)
406
 
{
407
 
        slang_output_ctx o = *O;
408
 
 
409
 
        o.structs = st->structs;
410
 
        if (!parse_type_specifier (C, &o, sp))
411
 
                return 0;
412
 
        do
413
 
        {
414
 
                slang_variable *var;
415
 
 
416
 
                st->fields->variables = (slang_variable *) slang_alloc_realloc (st->fields->variables,
417
 
                        st->fields->num_variables * sizeof (slang_variable),
418
 
                        (st->fields->num_variables + 1) * sizeof (slang_variable));
419
 
                if (st->fields->variables == NULL)
420
 
                {
421
 
                        slang_info_log_memory (C->L);
422
 
                        return 0;
423
 
                }
424
 
                var = &st->fields->variables[st->fields->num_variables];
425
 
                if (!slang_variable_construct (var))
426
 
                        return 0;
427
 
                st->fields->num_variables++;
428
 
                if (!parse_struct_field_var (C, &o, var, sp))
429
 
                        return 0;
430
 
        }
431
 
        while (*C->I++ != FIELD_NONE);
432
 
 
433
 
        return 1;
434
 
}
435
 
 
436
 
static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct **st)
437
 
{
438
 
        slang_atom a_name;
439
 
        const char *name;
440
 
 
441
 
        /* parse struct name (if any) and make sure it is unique in current scope */
442
 
        a_name = parse_identifier (C);
443
 
        if (a_name == SLANG_ATOM_NULL)
444
 
                return 0;
445
 
        name = slang_atom_pool_id (C->atoms, a_name);
446
 
        if (name[0] != '\0' && slang_struct_scope_find (O->structs, a_name, 0) != NULL)
447
 
        {
448
 
      slang_info_log_error (C->L, "%s: duplicate type name.", name);
449
 
                return 0;
450
 
        }
451
 
 
452
 
        /* set-up a new struct */
453
 
        *st = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
454
 
        if (*st == NULL)
455
 
        {
456
 
                slang_info_log_memory (C->L);
457
 
                return 0;
458
 
        }
459
 
        if (!slang_struct_construct (*st))
460
 
        {
461
 
                slang_alloc_free (*st);
462
 
                *st = NULL;
463
 
                slang_info_log_memory (C->L);
464
 
                return 0;
465
 
        }
466
 
        (**st).a_name = a_name;
467
 
        (**st).structs->outer_scope = O->structs;
468
 
 
469
 
        /* parse individual struct fields */
470
 
        do
471
 
        {
472
 
                slang_type_specifier sp;
473
 
 
474
 
                slang_type_specifier_ctr (&sp);
475
 
                if (!parse_struct_field (C, O, *st, &sp))
476
 
                {
477
 
                        slang_type_specifier_dtr (&sp);
478
 
                        return 0;
479
 
                }
480
 
                slang_type_specifier_dtr (&sp);
481
 
        }
482
 
        while (*C->I++ != FIELD_NONE);
483
 
 
484
 
        /* if named struct, copy it to current scope */
485
 
        if (name[0] != '\0')
486
 
        {
487
 
                slang_struct *s;
488
 
 
489
 
                O->structs->structs = (slang_struct *) slang_alloc_realloc (O->structs->structs,
490
 
                        O->structs->num_structs * sizeof (slang_struct),
491
 
                        (O->structs->num_structs + 1) * sizeof (slang_struct));
492
 
                if (O->structs->structs == NULL)
493
 
                {
494
 
                        slang_info_log_memory (C->L);
495
 
                        return 0;
496
 
                }
497
 
                s = &O->structs->structs[O->structs->num_structs];
498
 
                if (!slang_struct_construct (s))
499
 
                        return 0;
500
 
                O->structs->num_structs++;
501
 
                if (!slang_struct_copy (s, *st))
502
 
                        return 0;
503
 
        }
504
 
 
505
 
        return 1;
506
 
}
 
400
static GLboolean
 
401
parse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O,
 
402
                       slang_variable * var, const slang_type_specifier * sp)
 
403
{
 
404
   var->a_name = parse_identifier(C);
 
405
   if (var->a_name == SLANG_ATOM_NULL)
 
406
      return GL_FALSE;
 
407
 
 
408
   switch (*C->I++) {
 
409
   case FIELD_NONE:
 
410
      if (!slang_type_specifier_copy(&var->type.specifier, sp))
 
411
         return GL_FALSE;
 
412
      break;
 
413
   case FIELD_ARRAY:
 
414
      if (!convert_to_array(C, var, sp))
 
415
         return GL_FALSE;
 
416
      if (!parse_array_len(C, O, &var->array_len))
 
417
         return GL_FALSE;
 
418
      break;
 
419
   default:
 
420
      return GL_FALSE;
 
421
   }
 
422
 
 
423
   return calculate_var_size(C, O, var);
 
424
}
 
425
 
 
426
static int
 
427
parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O,
 
428
                   slang_struct * st, slang_type_specifier * sp)
 
429
{
 
430
   slang_output_ctx o = *O;
 
431
 
 
432
   o.structs = st->structs;
 
433
   if (!parse_type_specifier(C, &o, sp))
 
434
      return 0;
 
435
 
 
436
   do {
 
437
      slang_variable *var = slang_variable_scope_grow(st->fields);
 
438
      if (!var) {
 
439
         slang_info_log_memory(C->L);
 
440
         return 0;
 
441
      }
 
442
      if (!parse_struct_field_var(C, &o, var, sp))
 
443
         return 0;
 
444
   }
 
445
   while (*C->I++ != FIELD_NONE);
 
446
 
 
447
   return 1;
 
448
}
 
449
 
 
450
static int
 
451
parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st)
 
452
{
 
453
   slang_atom a_name;
 
454
   const char *name;
 
455
 
 
456
   /* parse struct name (if any) and make sure it is unique in current scope */
 
457
   a_name = parse_identifier(C);
 
458
   if (a_name == SLANG_ATOM_NULL)
 
459
      return 0;
 
460
 
 
461
   name = slang_atom_pool_id(C->atoms, a_name);
 
462
   if (name[0] != '\0'
 
463
       && slang_struct_scope_find(O->structs, a_name, 0) != NULL) {
 
464
      slang_info_log_error(C->L, "%s: duplicate type name.", name);
 
465
      return 0;
 
466
   }
 
467
 
 
468
   /* set-up a new struct */
 
469
   *st = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
 
470
   if (*st == NULL) {
 
471
      slang_info_log_memory(C->L);
 
472
      return 0;
 
473
   }
 
474
   if (!slang_struct_construct(*st)) {
 
475
      slang_alloc_free(*st);
 
476
      *st = NULL;
 
477
      slang_info_log_memory(C->L);
 
478
      return 0;
 
479
   }
 
480
   (**st).a_name = a_name;
 
481
   (**st).structs->outer_scope = O->structs;
 
482
 
 
483
   /* parse individual struct fields */
 
484
   do {
 
485
      slang_type_specifier sp;
 
486
 
 
487
      slang_type_specifier_ctr(&sp);
 
488
      if (!parse_struct_field(C, O, *st, &sp)) {
 
489
         slang_type_specifier_dtr(&sp);
 
490
         return 0;
 
491
      }
 
492
      slang_type_specifier_dtr(&sp);
 
493
   }
 
494
   while (*C->I++ != FIELD_NONE);
 
495
 
 
496
   /* if named struct, copy it to current scope */
 
497
   if (name[0] != '\0') {
 
498
      slang_struct *s;
 
499
 
 
500
      O->structs->structs =
 
501
         (slang_struct *) slang_alloc_realloc(O->structs->structs,
 
502
                                              O->structs->num_structs *
 
503
                                              sizeof(slang_struct),
 
504
                                              (O->structs->num_structs +
 
505
                                               1) * sizeof(slang_struct));
 
506
      if (O->structs->structs == NULL) {
 
507
         slang_info_log_memory(C->L);
 
508
         return 0;
 
509
      }
 
510
      s = &O->structs->structs[O->structs->num_structs];
 
511
      if (!slang_struct_construct(s))
 
512
         return 0;
 
513
      O->structs->num_structs++;
 
514
      if (!slang_struct_copy(s, *st))
 
515
         return 0;
 
516
   }
 
517
 
 
518
   return 1;
 
519
}
 
520
 
507
521
 
508
522
/* type qualifier */
509
523
#define TYPE_QUALIFIER_NONE 0
514
528
#define TYPE_QUALIFIER_FIXEDOUTPUT 5
515
529
#define TYPE_QUALIFIER_FIXEDINPUT 6
516
530
 
517
 
static int parse_type_qualifier (slang_parse_ctx *C, slang_type_qualifier *qual)
 
531
static int
 
532
parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual)
518
533
{
519
 
        switch (*C->I++)
520
 
        {
521
 
        case TYPE_QUALIFIER_NONE:
522
 
                *qual = slang_qual_none;
523
 
                break;
524
 
        case TYPE_QUALIFIER_CONST:
525
 
                *qual = slang_qual_const;
526
 
                break;
527
 
        case TYPE_QUALIFIER_ATTRIBUTE:
528
 
                *qual = slang_qual_attribute;
529
 
                break;
530
 
        case TYPE_QUALIFIER_VARYING:
531
 
                *qual = slang_qual_varying;
532
 
                break;
533
 
        case TYPE_QUALIFIER_UNIFORM:
534
 
                *qual = slang_qual_uniform;
535
 
                break;
536
 
        case TYPE_QUALIFIER_FIXEDOUTPUT:
537
 
                *qual = slang_qual_fixedoutput;
538
 
                break;
539
 
        case TYPE_QUALIFIER_FIXEDINPUT:
540
 
                *qual = slang_qual_fixedinput;
541
 
                break;
542
 
        default:
543
 
                return 0;
544
 
        }
545
 
        return 1;
 
534
   switch (*C->I++) {
 
535
   case TYPE_QUALIFIER_NONE:
 
536
      *qual = slang_qual_none;
 
537
      break;
 
538
   case TYPE_QUALIFIER_CONST:
 
539
      *qual = slang_qual_const;
 
540
      break;
 
541
   case TYPE_QUALIFIER_ATTRIBUTE:
 
542
      *qual = slang_qual_attribute;
 
543
      break;
 
544
   case TYPE_QUALIFIER_VARYING:
 
545
      *qual = slang_qual_varying;
 
546
      break;
 
547
   case TYPE_QUALIFIER_UNIFORM:
 
548
      *qual = slang_qual_uniform;
 
549
      break;
 
550
   case TYPE_QUALIFIER_FIXEDOUTPUT:
 
551
      *qual = slang_qual_fixedoutput;
 
552
      break;
 
553
   case TYPE_QUALIFIER_FIXEDINPUT:
 
554
      *qual = slang_qual_fixedinput;
 
555
      break;
 
556
   default:
 
557
      return 0;
 
558
   }
 
559
   return 1;
546
560
}
547
561
 
548
562
/* type specifier */
571
585
#define TYPE_SPECIFIER_STRUCT 22
572
586
#define TYPE_SPECIFIER_TYPENAME 23
573
587
 
574
 
static int parse_type_specifier (slang_parse_ctx *C, slang_output_ctx *O, slang_type_specifier *spec)
 
588
static int
 
589
parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O,
 
590
                     slang_type_specifier * spec)
575
591
{
576
 
        switch (*C->I++)
577
 
        {
578
 
        case TYPE_SPECIFIER_VOID:
579
 
                spec->type = slang_spec_void;
580
 
                break;
581
 
        case TYPE_SPECIFIER_BOOL:
582
 
                spec->type = slang_spec_bool;
583
 
                break;
584
 
        case TYPE_SPECIFIER_BVEC2:
585
 
                spec->type = slang_spec_bvec2;
586
 
                break;
587
 
        case TYPE_SPECIFIER_BVEC3:
588
 
                spec->type = slang_spec_bvec3;
589
 
                break;
590
 
        case TYPE_SPECIFIER_BVEC4:
591
 
                spec->type = slang_spec_bvec4;
592
 
                break;
593
 
        case TYPE_SPECIFIER_INT:
594
 
                spec->type = slang_spec_int;
595
 
                break;
596
 
        case TYPE_SPECIFIER_IVEC2:
597
 
                spec->type = slang_spec_ivec2;
598
 
                break;
599
 
        case TYPE_SPECIFIER_IVEC3:
600
 
                spec->type = slang_spec_ivec3;
601
 
                break;
602
 
        case TYPE_SPECIFIER_IVEC4:
603
 
                spec->type = slang_spec_ivec4;
604
 
                break;
605
 
        case TYPE_SPECIFIER_FLOAT:
606
 
                spec->type = slang_spec_float;
607
 
                break;
608
 
        case TYPE_SPECIFIER_VEC2:
609
 
                spec->type = slang_spec_vec2;
610
 
                break;
611
 
        case TYPE_SPECIFIER_VEC3:
612
 
                spec->type = slang_spec_vec3;
613
 
                break;
614
 
        case TYPE_SPECIFIER_VEC4:
615
 
                spec->type = slang_spec_vec4;
616
 
                break;
617
 
        case TYPE_SPECIFIER_MAT2:
618
 
                spec->type = slang_spec_mat2;
619
 
                break;
620
 
        case TYPE_SPECIFIER_MAT3:
621
 
                spec->type = slang_spec_mat3;
622
 
                break;
623
 
        case TYPE_SPECIFIER_MAT4:
624
 
                spec->type = slang_spec_mat4;
625
 
                break;
626
 
        case TYPE_SPECIFIER_SAMPLER1D:
627
 
                spec->type = slang_spec_sampler1D;
628
 
                break;
629
 
        case TYPE_SPECIFIER_SAMPLER2D:
630
 
                spec->type = slang_spec_sampler2D;
631
 
                break;
632
 
        case TYPE_SPECIFIER_SAMPLER3D:
633
 
                spec->type = slang_spec_sampler3D;
634
 
                break;
635
 
        case TYPE_SPECIFIER_SAMPLERCUBE:
636
 
                spec->type = slang_spec_samplerCube;
637
 
                break;
638
 
        case TYPE_SPECIFIER_SAMPLER1DSHADOW:
639
 
                spec->type = slang_spec_sampler1DShadow;
640
 
                break;
641
 
        case TYPE_SPECIFIER_SAMPLER2DSHADOW:
642
 
                spec->type = slang_spec_sampler2DShadow;
643
 
                break;
644
 
        case TYPE_SPECIFIER_STRUCT:
645
 
                spec->type = slang_spec_struct;
646
 
                if (!parse_struct (C, O, &spec->_struct))
647
 
                        return 0;
648
 
                break;
649
 
        case TYPE_SPECIFIER_TYPENAME:
650
 
                spec->type = slang_spec_struct;
651
 
                {
652
 
                        slang_atom a_name;
653
 
                        slang_struct *stru;
654
 
 
655
 
                        a_name = parse_identifier (C);
656
 
                        if (a_name == NULL)
657
 
                                return 0;
658
 
 
659
 
                        stru = slang_struct_scope_find (O->structs, a_name, 1);
660
 
                        if (stru == NULL)
661
 
                        {
662
 
            slang_info_log_error (C->L, "%s: undeclared type name.",
663
 
                                        slang_atom_pool_id (C->atoms, a_name));
664
 
                                return 0;
665
 
                        }
666
 
 
667
 
                        spec->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
668
 
                        if (spec->_struct == NULL)
669
 
                        {
670
 
                                slang_info_log_memory (C->L);
671
 
                                return 0;
672
 
                        }
673
 
                        if (!slang_struct_construct (spec->_struct))
674
 
                        {
675
 
                                slang_alloc_free (spec->_struct);
676
 
                                spec->_struct = NULL;
677
 
                                return 0;
678
 
                        }
679
 
                        if (!slang_struct_copy (spec->_struct, stru))
680
 
                                return 0;
681
 
                }
682
 
                break;
683
 
        default:
684
 
                return 0;
685
 
        }
686
 
        return 1;
 
592
   switch (*C->I++) {
 
593
   case TYPE_SPECIFIER_VOID:
 
594
      spec->type = slang_spec_void;
 
595
      break;
 
596
   case TYPE_SPECIFIER_BOOL:
 
597
      spec->type = slang_spec_bool;
 
598
      break;
 
599
   case TYPE_SPECIFIER_BVEC2:
 
600
      spec->type = slang_spec_bvec2;
 
601
      break;
 
602
   case TYPE_SPECIFIER_BVEC3:
 
603
      spec->type = slang_spec_bvec3;
 
604
      break;
 
605
   case TYPE_SPECIFIER_BVEC4:
 
606
      spec->type = slang_spec_bvec4;
 
607
      break;
 
608
   case TYPE_SPECIFIER_INT:
 
609
      spec->type = slang_spec_int;
 
610
      break;
 
611
   case TYPE_SPECIFIER_IVEC2:
 
612
      spec->type = slang_spec_ivec2;
 
613
      break;
 
614
   case TYPE_SPECIFIER_IVEC3:
 
615
      spec->type = slang_spec_ivec3;
 
616
      break;
 
617
   case TYPE_SPECIFIER_IVEC4:
 
618
      spec->type = slang_spec_ivec4;
 
619
      break;
 
620
   case TYPE_SPECIFIER_FLOAT:
 
621
      spec->type = slang_spec_float;
 
622
      break;
 
623
   case TYPE_SPECIFIER_VEC2:
 
624
      spec->type = slang_spec_vec2;
 
625
      break;
 
626
   case TYPE_SPECIFIER_VEC3:
 
627
      spec->type = slang_spec_vec3;
 
628
      break;
 
629
   case TYPE_SPECIFIER_VEC4:
 
630
      spec->type = slang_spec_vec4;
 
631
      break;
 
632
   case TYPE_SPECIFIER_MAT2:
 
633
      spec->type = slang_spec_mat2;
 
634
      break;
 
635
   case TYPE_SPECIFIER_MAT3:
 
636
      spec->type = slang_spec_mat3;
 
637
      break;
 
638
   case TYPE_SPECIFIER_MAT4:
 
639
      spec->type = slang_spec_mat4;
 
640
      break;
 
641
   case TYPE_SPECIFIER_SAMPLER1D:
 
642
      spec->type = slang_spec_sampler1D;
 
643
      break;
 
644
   case TYPE_SPECIFIER_SAMPLER2D:
 
645
      spec->type = slang_spec_sampler2D;
 
646
      break;
 
647
   case TYPE_SPECIFIER_SAMPLER3D:
 
648
      spec->type = slang_spec_sampler3D;
 
649
      break;
 
650
   case TYPE_SPECIFIER_SAMPLERCUBE:
 
651
      spec->type = slang_spec_samplerCube;
 
652
      break;
 
653
   case TYPE_SPECIFIER_SAMPLER1DSHADOW:
 
654
      spec->type = slang_spec_sampler1DShadow;
 
655
      break;
 
656
   case TYPE_SPECIFIER_SAMPLER2DSHADOW:
 
657
      spec->type = slang_spec_sampler2DShadow;
 
658
      break;
 
659
   case TYPE_SPECIFIER_STRUCT:
 
660
      spec->type = slang_spec_struct;
 
661
      if (!parse_struct(C, O, &spec->_struct))
 
662
         return 0;
 
663
      break;
 
664
   case TYPE_SPECIFIER_TYPENAME:
 
665
      spec->type = slang_spec_struct;
 
666
      {
 
667
         slang_atom a_name;
 
668
         slang_struct *stru;
 
669
 
 
670
         a_name = parse_identifier(C);
 
671
         if (a_name == NULL)
 
672
            return 0;
 
673
 
 
674
         stru = slang_struct_scope_find(O->structs, a_name, 1);
 
675
         if (stru == NULL) {
 
676
            slang_info_log_error(C->L, "%s: undeclared type name.",
 
677
                                 slang_atom_pool_id(C->atoms, a_name));
 
678
            return 0;
 
679
         }
 
680
 
 
681
         spec->_struct =
 
682
            (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
 
683
         if (spec->_struct == NULL) {
 
684
            slang_info_log_memory(C->L);
 
685
            return 0;
 
686
         }
 
687
         if (!slang_struct_construct(spec->_struct)) {
 
688
            slang_alloc_free(spec->_struct);
 
689
            spec->_struct = NULL;
 
690
            return 0;
 
691
         }
 
692
         if (!slang_struct_copy(spec->_struct, stru))
 
693
            return 0;
 
694
      }
 
695
      break;
 
696
   default:
 
697
      return 0;
 
698
   }
 
699
   return 1;
687
700
}
688
701
 
689
 
static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O,
690
 
        slang_fully_specified_type *type)
 
702
static int
 
703
parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
 
704
                           slang_fully_specified_type * type)
691
705
{
692
 
        if (!parse_type_qualifier (C, &type->qualifier))
693
 
                return 0;
694
 
        return parse_type_specifier (C, O, &type->specifier);
 
706
   if (!parse_type_qualifier(C, &type->qualifier))
 
707
      return 0;
 
708
   return parse_type_specifier(C, O, &type->specifier);
695
709
}
696
710
 
697
711
/* operation */
758
772
#define OP_POSTINCREMENT 60
759
773
#define OP_POSTDECREMENT 61
760
774
 
761
 
static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper,
762
 
        int statement)
763
 
{
764
 
        slang_operation *ch;
765
 
 
766
 
        oper->children = (slang_operation *) slang_alloc_realloc (oper->children,
767
 
                oper->num_children * sizeof (slang_operation),
768
 
                (oper->num_children + 1) * sizeof (slang_operation));
769
 
        if (oper->children == NULL)
770
 
        {
771
 
                slang_info_log_memory (C->L);
772
 
                return 0;
773
 
        }
774
 
        ch = &oper->children[oper->num_children];
775
 
        if (!slang_operation_construct (ch))
776
 
        {
777
 
                slang_info_log_memory (C->L);
778
 
                return 0;
779
 
        }
780
 
        oper->num_children++;
781
 
        if (statement)
782
 
                return parse_statement (C, O, ch);
783
 
        return parse_expression (C, O, ch);
784
 
}
785
 
 
786
 
static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O);
787
 
 
788
 
static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper)
789
 
{
790
 
        oper->locals->outer_scope = O->vars;
791
 
        switch (*C->I++)
792
 
        {
793
 
        case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
794
 
                /* parse child statements, do not create new variable scope */
795
 
                oper->type = slang_oper_block_no_new_scope;
796
 
                while (*C->I != OP_END)
797
 
                        if (!parse_child_operation (C, O, oper, 1))
798
 
                                return 0;
799
 
                C->I++;
800
 
                break;
801
 
        case OP_BLOCK_BEGIN_NEW_SCOPE:
802
 
                /* parse child statements, create new variable scope */
803
 
                {
804
 
                        slang_output_ctx o = *O;
805
 
 
806
 
                        oper->type = slang_oper_block_new_scope;
807
 
                        o.vars = oper->locals;
808
 
                        while (*C->I != OP_END)
809
 
                                if (!parse_child_operation (C, &o, oper, 1))
810
 
                                        return 0;
811
 
                        C->I++;
812
 
                }
813
 
                break;
814
 
        case OP_DECLARE:
815
 
                /* local variable declaration, individual declarators are stored as children identifiers */
816
 
                oper->type = slang_oper_variable_decl;
817
 
                {
818
 
                        const unsigned int first_var = O->vars->num_variables;
819
 
 
820
 
                        /* parse the declaration, note that there can be zero or more than one declarators */
821
 
                        if (!parse_declaration (C, O))
822
 
                                return 0;
823
 
                        if (first_var < O->vars->num_variables)
824
 
                        {
825
 
                                const unsigned int num_vars = O->vars->num_variables - first_var;
826
 
                                unsigned int i;
827
 
 
828
 
                                oper->children = (slang_operation *) slang_alloc_malloc (num_vars * sizeof (
829
 
                                        slang_operation));
830
 
                                if (oper->children == NULL)
831
 
                                {
832
 
                                        slang_info_log_memory (C->L);
833
 
                                        return 0;
834
 
                                }
835
 
                                for (oper->num_children = 0; oper->num_children < num_vars; oper->num_children++)
836
 
                                        if (!slang_operation_construct (&oper->children[oper->num_children]))
837
 
                                        {
838
 
                                                slang_info_log_memory (C->L);
839
 
                                                return 0;
840
 
                                        }
841
 
                                for (i = first_var; i < O->vars->num_variables; i++)
842
 
                                {
843
 
                                        slang_operation *o = &oper->children[i - first_var];
844
 
 
845
 
                                        o->type = slang_oper_identifier;
846
 
                                        o->locals->outer_scope = O->vars;
847
 
                                        o->a_id = O->vars->variables[i].a_name;
848
 
                                }
849
 
                        }
850
 
                }
851
 
                break;
852
 
        case OP_ASM:
853
 
                /* the __asm statement, parse the mnemonic and all its arguments as expressions */
854
 
                oper->type = slang_oper_asm;
855
 
                oper->a_id = parse_identifier (C);
856
 
                if (oper->a_id == SLANG_ATOM_NULL)
857
 
                        return 0;
858
 
                while (*C->I != OP_END)
859
 
                        if (!parse_child_operation (C, O, oper, 0))
860
 
                                return 0;
861
 
                C->I++;
862
 
                break;
863
 
        case OP_BREAK:
864
 
                oper->type = slang_oper_break;
865
 
                break;
866
 
        case OP_CONTINUE:
867
 
                oper->type = slang_oper_continue;
868
 
                break;
869
 
        case OP_DISCARD:
870
 
                oper->type = slang_oper_discard;
871
 
                break;
872
 
        case OP_RETURN:
873
 
                oper->type = slang_oper_return;
874
 
                if (!parse_child_operation (C, O, oper, 0))
875
 
                        return 0;
876
 
                break;
877
 
        case OP_EXPRESSION:
878
 
                oper->type = slang_oper_expression;
879
 
                if (!parse_child_operation (C, O, oper, 0))
880
 
                        return 0;
881
 
                break;
882
 
        case OP_IF:
883
 
                oper->type = slang_oper_if;
884
 
                if (!parse_child_operation (C, O, oper, 0))
885
 
                        return 0;
886
 
                if (!parse_child_operation (C, O, oper, 1))
887
 
                        return 0;
888
 
                if (!parse_child_operation (C, O, oper, 1))
889
 
                        return 0;
890
 
                break;
891
 
        case OP_WHILE:
892
 
                {
893
 
                        slang_output_ctx o = *O;
894
 
 
895
 
                        oper->type = slang_oper_while;
896
 
                        o.vars = oper->locals;
897
 
                        if (!parse_child_operation (C, &o, oper, 1))
898
 
                                return 0;
899
 
                        if (!parse_child_operation (C, &o, oper, 1))
900
 
                                return 0;
901
 
                }
902
 
                break;
903
 
        case OP_DO:
904
 
                oper->type = slang_oper_do;
905
 
                if (!parse_child_operation (C, O, oper, 1))
906
 
                        return 0;
907
 
                if (!parse_child_operation (C, O, oper, 0))
908
 
                        return 0;
909
 
                break;
910
 
        case OP_FOR:
911
 
                {
912
 
                        slang_output_ctx o = *O;
913
 
 
914
 
                        oper->type = slang_oper_for;
915
 
                        o.vars = oper->locals;
916
 
                        if (!parse_child_operation (C, &o, oper, 1))
917
 
                                return 0;
918
 
                        if (!parse_child_operation (C, &o, oper, 1))
919
 
                                return 0;
920
 
                        if (!parse_child_operation (C, &o, oper, 0))
921
 
                                return 0;
922
 
                        if (!parse_child_operation (C, &o, oper, 1))
923
 
                                return 0;
924
 
                }
925
 
                break;
926
 
        default:
927
 
                return 0;
928
 
        }
929
 
        return 1;
930
 
}
931
 
 
932
 
static int handle_nary_expression (slang_parse_ctx *C, slang_operation *op, slang_operation **ops,
933
 
        unsigned int *total_ops, unsigned int n)
934
 
{
935
 
        unsigned int i;
936
 
 
937
 
        op->children = (slang_operation *) slang_alloc_malloc (n * sizeof (slang_operation));
938
 
        if (op->children == NULL)
939
 
        {
940
 
                slang_info_log_memory (C->L);
941
 
                return 0;
942
 
        }
943
 
        op->num_children = n;
944
 
 
945
 
        for (i = 0; i < n; i++)
946
 
                op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
947
 
        (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
948
 
        *total_ops -= n;
949
 
 
950
 
        *ops = (slang_operation *) slang_alloc_realloc (*ops, (*total_ops + n) * sizeof (slang_operation),
951
 
                *total_ops * sizeof (slang_operation));
952
 
        if (*ops == NULL)
953
 
        {
954
 
                slang_info_log_memory (C->L);
955
 
                return 0;
956
 
        }
957
 
        return 1;
958
 
}
959
 
 
960
 
static int is_constructor_name (const char *name, slang_atom a_name, slang_struct_scope *structs)
961
 
{
962
 
        if (slang_type_specifier_type_from_string (name) != slang_spec_void)
963
 
                return 1;
964
 
        return slang_struct_scope_find (structs, a_name, 1) != NULL;
965
 
}
966
 
 
967
 
static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper)
968
 
{
969
 
        slang_operation *ops = NULL;
970
 
        unsigned int num_ops = 0;
971
 
        int number;
972
 
 
973
 
        while (*C->I != OP_END)
974
 
        {
975
 
                slang_operation *op;
976
 
                const unsigned int op_code = *C->I++;
977
 
 
978
 
                /* allocate default operation, becomes a no-op if not used  */
979
 
                ops = (slang_operation *) slang_alloc_realloc (ops,
980
 
                        num_ops * sizeof (slang_operation), (num_ops + 1) * sizeof (slang_operation));
981
 
                if (ops == NULL)
982
 
                {
983
 
                        slang_info_log_memory (C->L);
984
 
                        return 0;
985
 
                }
986
 
                op = &ops[num_ops];
987
 
                if (!slang_operation_construct (op))
988
 
                {
989
 
                        slang_info_log_memory (C->L);
990
 
                        return 0;
991
 
                }
992
 
                num_ops++;
993
 
                op->locals->outer_scope = O->vars;
994
 
 
995
 
                switch (op_code)
996
 
                {
997
 
                case OP_PUSH_VOID:
998
 
                        op->type = slang_oper_void;
999
 
                        break;
1000
 
                case OP_PUSH_BOOL:
1001
 
                        op->type = slang_oper_literal_bool;
1002
 
                        if (!parse_number (C, &number))
1003
 
                                return 0;
1004
 
                        op->literal = (GLfloat) number;
1005
 
                        break;
1006
 
                case OP_PUSH_INT:
1007
 
                        op->type = slang_oper_literal_int;
1008
 
                        if (!parse_number (C, &number))
1009
 
                                return 0;
1010
 
                        op->literal = (GLfloat) number;
1011
 
                        break;
1012
 
                case OP_PUSH_FLOAT:
1013
 
                        op->type = slang_oper_literal_float;
1014
 
                        if (!parse_float (C, &op->literal))
1015
 
                                return 0;
1016
 
                        break;
1017
 
                case OP_PUSH_IDENTIFIER:
1018
 
                        op->type = slang_oper_identifier;
1019
 
                        op->a_id = parse_identifier (C);
1020
 
                        if (op->a_id == SLANG_ATOM_NULL)
1021
 
                                return 0;
1022
 
                        break;
1023
 
                case OP_SEQUENCE:
1024
 
                        op->type = slang_oper_sequence;
1025
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1026
 
                                return 0;
1027
 
                        break;
1028
 
                case OP_ASSIGN:
1029
 
                        op->type = slang_oper_assign;
1030
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1031
 
                                return 0;
1032
 
                        break;
1033
 
                case OP_ADDASSIGN:
1034
 
                        op->type = slang_oper_addassign;
1035
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1036
 
                                return 0;
1037
 
                        break;
1038
 
                case OP_SUBASSIGN:
1039
 
                        op->type = slang_oper_subassign;
1040
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1041
 
                                return 0;
1042
 
                        break;
1043
 
                case OP_MULASSIGN:
1044
 
                        op->type = slang_oper_mulassign;
1045
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1046
 
                                return 0;
1047
 
                        break;
1048
 
                case OP_DIVASSIGN:
1049
 
                        op->type = slang_oper_divassign;
1050
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1051
 
                                return 0;
1052
 
                        break;
1053
 
                /*case OP_MODASSIGN:*/
1054
 
                /*case OP_LSHASSIGN:*/
1055
 
                /*case OP_RSHASSIGN:*/
1056
 
                /*case OP_ORASSIGN:*/
1057
 
                /*case OP_XORASSIGN:*/
1058
 
                /*case OP_ANDASSIGN:*/
1059
 
                case OP_SELECT:
1060
 
                        op->type = slang_oper_select;
1061
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 3))
1062
 
                                return 0;
1063
 
                        break;
1064
 
                case OP_LOGICALOR:
1065
 
                        op->type = slang_oper_logicalor;
1066
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1067
 
                                return 0;
1068
 
                        break;
1069
 
                case OP_LOGICALXOR:
1070
 
                        op->type = slang_oper_logicalxor;
1071
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1072
 
                                return 0;
1073
 
                        break;
1074
 
                case OP_LOGICALAND:
1075
 
                        op->type = slang_oper_logicaland;
1076
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1077
 
                                return 0;
1078
 
                        break;
1079
 
                /*case OP_BITOR:*/
1080
 
                /*case OP_BITXOR:*/
1081
 
                /*case OP_BITAND:*/
1082
 
                case OP_EQUAL:
1083
 
                        op->type = slang_oper_equal;
1084
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1085
 
                                return 0;
1086
 
                        break;
1087
 
                case OP_NOTEQUAL:
1088
 
                        op->type = slang_oper_notequal;
1089
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1090
 
                                return 0;
1091
 
                        break;
1092
 
                case OP_LESS:
1093
 
                        op->type = slang_oper_less;
1094
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1095
 
                                return 0;
1096
 
                        break;
1097
 
                case OP_GREATER:
1098
 
                        op->type = slang_oper_greater;
1099
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1100
 
                                return 0;
1101
 
                        break;
1102
 
                case OP_LESSEQUAL:
1103
 
                        op->type = slang_oper_lessequal;
1104
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1105
 
                                return 0;
1106
 
                        break;
1107
 
                case OP_GREATEREQUAL:
1108
 
                        op->type = slang_oper_greaterequal;
1109
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1110
 
                                return 0;
1111
 
                        break;
1112
 
                /*case OP_LSHIFT:*/
1113
 
                /*case OP_RSHIFT:*/
1114
 
                case OP_ADD:
1115
 
                        op->type = slang_oper_add;
1116
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1117
 
                                return 0;
1118
 
                        break;
1119
 
                case OP_SUBTRACT:
1120
 
                        op->type = slang_oper_subtract;
1121
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1122
 
                                return 0;
1123
 
                        break;
1124
 
                case OP_MULTIPLY:
1125
 
                        op->type = slang_oper_multiply;
1126
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1127
 
                                return 0;
1128
 
                        break;
1129
 
                case OP_DIVIDE:
1130
 
                        op->type = slang_oper_divide;
1131
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1132
 
                                return 0;
1133
 
                        break;
1134
 
                /*case OP_MODULUS:*/
1135
 
                case OP_PREINCREMENT:
1136
 
                        op->type = slang_oper_preincrement;
1137
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
1138
 
                                return 0;
1139
 
                        break;
1140
 
                case OP_PREDECREMENT:
1141
 
                        op->type = slang_oper_predecrement;
1142
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
1143
 
                                return 0;
1144
 
                        break;
1145
 
                case OP_PLUS:
1146
 
                        op->type = slang_oper_plus;
1147
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
1148
 
                                return 0;
1149
 
                        break;
1150
 
                case OP_MINUS:
1151
 
                        op->type = slang_oper_minus;
1152
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
1153
 
                                return 0;
1154
 
                        break;
1155
 
                case OP_NOT:
1156
 
                        op->type = slang_oper_not;
1157
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
1158
 
                                return 0;
1159
 
                        break;
1160
 
                /*case OP_COMPLEMENT:*/
1161
 
                case OP_SUBSCRIPT:
1162
 
                        op->type = slang_oper_subscript;
1163
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 2))
1164
 
                                return 0;
1165
 
                        break;
1166
 
                case OP_CALL:
1167
 
                        op->type = slang_oper_call;
1168
 
                        op->a_id = parse_identifier (C);
1169
 
                        if (op->a_id == SLANG_ATOM_NULL)
1170
 
                                return 0;
1171
 
                        while (*C->I != OP_END)
1172
 
                                if (!parse_child_operation (C, O, op, 0))
1173
 
                                        return 0;
1174
 
                        C->I++;
1175
 
                        if (!C->parsing_builtin && !slang_function_scope_find_by_name (O->funs, op->a_id, 1))
1176
 
                        {
1177
 
                                const char *id;
1178
 
 
1179
 
                                id = slang_atom_pool_id (C->atoms, op->a_id);
1180
 
                                if (!is_constructor_name (id, op->a_id, O->structs))
1181
 
                                {
1182
 
               slang_info_log_error (C->L, "%s: undeclared function name.", id);
1183
 
                                        return 0;
1184
 
                                }
1185
 
                        }
1186
 
                        break;
1187
 
                case OP_FIELD:
1188
 
                        op->type = slang_oper_field;
1189
 
                        op->a_id = parse_identifier (C);
1190
 
                        if (op->a_id == SLANG_ATOM_NULL)
1191
 
                                return 0;
1192
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
1193
 
                                return 0;
1194
 
                        break;
1195
 
                case OP_POSTINCREMENT:
1196
 
                        op->type = slang_oper_postincrement;
1197
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
1198
 
                                return 0;
1199
 
                        break;
1200
 
                case OP_POSTDECREMENT:
1201
 
                        op->type = slang_oper_postdecrement;
1202
 
                        if (!handle_nary_expression (C, op, &ops, &num_ops, 1))
1203
 
                                return 0;
1204
 
                        break;
1205
 
                default:
1206
 
                        return 0;
1207
 
                }
1208
 
        }
1209
 
        C->I++;
1210
 
 
1211
 
        *oper = *ops;
1212
 
        slang_alloc_free (ops);
1213
 
        return 1;
 
775
 
 
776
/**
 
777
 * When parsing a compound production, this function is used to parse the
 
778
 * children.
 
779
 * For example, a a while-loop compound will have two children, the
 
780
 * while condition expression and the loop body.  So, this function will
 
781
 * be called twice to parse those two sub-expressions.
 
782
 * \param C  the parsing context
 
783
 * \param O  the output context
 
784
 * \param oper  the operation we're parsing
 
785
 * \param statment  which child of the operation is being parsed
 
786
 * \return 1 if success, 0 if error
 
787
 */
 
788
static int
 
789
parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O,
 
790
                      slang_operation * oper, unsigned int statement)
 
791
{
 
792
   slang_operation *ch;
 
793
 
 
794
   /* grow child array */
 
795
   oper->children = (slang_operation *)
 
796
      slang_alloc_realloc(oper->children,
 
797
                          oper->num_children * sizeof(slang_operation),
 
798
                          (oper->num_children + 1) * sizeof(slang_operation));
 
799
   if (oper->children == NULL) {
 
800
      slang_info_log_memory(C->L);
 
801
      return 0;
 
802
   }
 
803
 
 
804
   ch = &oper->children[oper->num_children];
 
805
   if (!slang_operation_construct(ch)) {
 
806
      slang_info_log_memory(C->L);
 
807
      return 0;
 
808
   }
 
809
   oper->num_children++;
 
810
   /* XXX I guess the 0th "statement" is not really a statement? */
 
811
   if (statement)
 
812
      return parse_statement(C, O, ch);
 
813
   return parse_expression(C, O, ch);
 
814
}
 
815
 
 
816
static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O);
 
817
 
 
818
static int
 
819
parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
 
820
                slang_operation * oper)
 
821
{
 
822
   oper->locals->outer_scope = O->vars;
 
823
   switch (*C->I++) {
 
824
   case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
 
825
      /* parse child statements, do not create new variable scope */
 
826
      oper->type = slang_oper_block_no_new_scope;
 
827
      while (*C->I != OP_END)
 
828
         if (!parse_child_operation(C, O, oper, 1))
 
829
            return 0;
 
830
      C->I++;
 
831
      break;
 
832
   case OP_BLOCK_BEGIN_NEW_SCOPE:
 
833
      /* parse child statements, create new variable scope */
 
834
      {
 
835
         slang_output_ctx o = *O;
 
836
 
 
837
         oper->type = slang_oper_block_new_scope;
 
838
         o.vars = oper->locals;
 
839
         while (*C->I != OP_END)
 
840
            if (!parse_child_operation(C, &o, oper, 1))
 
841
               return 0;
 
842
         C->I++;
 
843
      }
 
844
      break;
 
845
   case OP_DECLARE:
 
846
      /* local variable declaration, individual declarators are stored as
 
847
       * children identifiers
 
848
       */
 
849
      oper->type = slang_oper_variable_decl;
 
850
      {
 
851
         const unsigned int first_var = O->vars->num_variables;
 
852
 
 
853
         /* parse the declaration, note that there can be zero or more
 
854
          * than one declarators
 
855
          */
 
856
         if (!parse_declaration(C, O))
 
857
            return 0;
 
858
         if (first_var < O->vars->num_variables) {
 
859
            const unsigned int num_vars = O->vars->num_variables - first_var;
 
860
            unsigned int i;
 
861
 
 
862
            oper->children = (slang_operation *)
 
863
               slang_alloc_malloc(num_vars * sizeof(slang_operation));
 
864
            if (oper->children == NULL) {
 
865
               slang_info_log_memory(C->L);
 
866
               return 0;
 
867
            }
 
868
            for (oper->num_children = 0; oper->num_children < num_vars;
 
869
                 oper->num_children++) {
 
870
               if (!slang_operation_construct
 
871
                   (&oper->children[oper->num_children])) {
 
872
                  slang_info_log_memory(C->L);
 
873
                  return 0;
 
874
               }
 
875
            }
 
876
            for (i = first_var; i < O->vars->num_variables; i++) {
 
877
               slang_operation *o = &oper->children[i - first_var];
 
878
               o->type = slang_oper_identifier;
 
879
               o->locals->outer_scope = O->vars;
 
880
               o->a_id = O->vars->variables[i].a_name;
 
881
            }
 
882
         }
 
883
      }
 
884
      break;
 
885
   case OP_ASM:
 
886
      /* the __asm statement, parse the mnemonic and all its arguments
 
887
       * as expressions
 
888
       */
 
889
      oper->type = slang_oper_asm;
 
890
      oper->a_id = parse_identifier(C);
 
891
      if (oper->a_id == SLANG_ATOM_NULL)
 
892
         return 0;
 
893
      while (*C->I != OP_END) {
 
894
         if (!parse_child_operation(C, O, oper, 0))
 
895
            return 0;
 
896
      }
 
897
      C->I++;
 
898
      break;
 
899
   case OP_BREAK:
 
900
      oper->type = slang_oper_break;
 
901
      break;
 
902
   case OP_CONTINUE:
 
903
      oper->type = slang_oper_continue;
 
904
      break;
 
905
   case OP_DISCARD:
 
906
      oper->type = slang_oper_discard;
 
907
      break;
 
908
   case OP_RETURN:
 
909
      oper->type = slang_oper_return;
 
910
      if (!parse_child_operation(C, O, oper, 0))
 
911
         return 0;
 
912
      break;
 
913
   case OP_EXPRESSION:
 
914
      oper->type = slang_oper_expression;
 
915
      if (!parse_child_operation(C, O, oper, 0))
 
916
         return 0;
 
917
      break;
 
918
   case OP_IF:
 
919
      oper->type = slang_oper_if;
 
920
      if (!parse_child_operation(C, O, oper, 0))
 
921
         return 0;
 
922
      if (!parse_child_operation(C, O, oper, 1))
 
923
         return 0;
 
924
      if (!parse_child_operation(C, O, oper, 1))
 
925
         return 0;
 
926
      break;
 
927
   case OP_WHILE:
 
928
      {
 
929
         slang_output_ctx o = *O;
 
930
 
 
931
         oper->type = slang_oper_while;
 
932
         o.vars = oper->locals;
 
933
         if (!parse_child_operation(C, &o, oper, 1))
 
934
            return 0;
 
935
         if (!parse_child_operation(C, &o, oper, 1))
 
936
            return 0;
 
937
      }
 
938
      break;
 
939
   case OP_DO:
 
940
      oper->type = slang_oper_do;
 
941
      if (!parse_child_operation(C, O, oper, 1))
 
942
         return 0;
 
943
      if (!parse_child_operation(C, O, oper, 0))
 
944
         return 0;
 
945
      break;
 
946
   case OP_FOR:
 
947
      {
 
948
         slang_output_ctx o = *O;
 
949
 
 
950
         oper->type = slang_oper_for;
 
951
         o.vars = oper->locals;
 
952
         if (!parse_child_operation(C, &o, oper, 1))
 
953
            return 0;
 
954
         if (!parse_child_operation(C, &o, oper, 1))
 
955
            return 0;
 
956
         if (!parse_child_operation(C, &o, oper, 0))
 
957
            return 0;
 
958
         if (!parse_child_operation(C, &o, oper, 1))
 
959
            return 0;
 
960
      }
 
961
      break;
 
962
   default:
 
963
      return 0;
 
964
   }
 
965
   return 1;
 
966
}
 
967
 
 
968
static int
 
969
handle_nary_expression(slang_parse_ctx * C, slang_operation * op,
 
970
                       slang_operation ** ops, unsigned int *total_ops,
 
971
                       unsigned int n)
 
972
{
 
973
   unsigned int i;
 
974
 
 
975
   op->children =
 
976
      (slang_operation *) slang_alloc_malloc(n * sizeof(slang_operation));
 
977
   if (op->children == NULL) {
 
978
      slang_info_log_memory(C->L);
 
979
      return 0;
 
980
   }
 
981
   op->num_children = n;
 
982
 
 
983
   for (i = 0; i < n; i++)
 
984
      op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
 
985
   (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
 
986
   *total_ops -= n;
 
987
 
 
988
   *ops = (slang_operation *)
 
989
      slang_alloc_realloc(*ops,
 
990
                          (*total_ops + n) * sizeof(slang_operation),
 
991
                          *total_ops * sizeof(slang_operation));
 
992
   if (*ops == NULL) {
 
993
      slang_info_log_memory(C->L);
 
994
      return 0;
 
995
   }
 
996
   return 1;
 
997
}
 
998
 
 
999
static int
 
1000
is_constructor_name(const char *name, slang_atom a_name,
 
1001
                    slang_struct_scope * structs)
 
1002
{
 
1003
   if (slang_type_specifier_type_from_string(name) != slang_spec_void)
 
1004
      return 1;
 
1005
   return slang_struct_scope_find(structs, a_name, 1) != NULL;
 
1006
}
 
1007
 
 
1008
static int
 
1009
parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
 
1010
                 slang_operation * oper)
 
1011
{
 
1012
   slang_operation *ops = NULL;
 
1013
   unsigned int num_ops = 0;
 
1014
   int number;
 
1015
 
 
1016
   while (*C->I != OP_END) {
 
1017
      slang_operation *op;
 
1018
      const unsigned int op_code = *C->I++;
 
1019
 
 
1020
      /* allocate default operation, becomes a no-op if not used  */
 
1021
      ops = (slang_operation *)
 
1022
         slang_alloc_realloc(ops,
 
1023
                             num_ops * sizeof(slang_operation),
 
1024
                             (num_ops + 1) * sizeof(slang_operation));
 
1025
      if (ops == NULL) {
 
1026
         slang_info_log_memory(C->L);
 
1027
         return 0;
 
1028
      }
 
1029
      op = &ops[num_ops];
 
1030
      if (!slang_operation_construct(op)) {
 
1031
         slang_info_log_memory(C->L);
 
1032
         return 0;
 
1033
      }
 
1034
      num_ops++;
 
1035
      op->locals->outer_scope = O->vars;
 
1036
 
 
1037
      switch (op_code) {
 
1038
      case OP_PUSH_VOID:
 
1039
         op->type = slang_oper_void;
 
1040
         break;
 
1041
      case OP_PUSH_BOOL:
 
1042
         op->type = slang_oper_literal_bool;
 
1043
         if (!parse_number(C, &number))
 
1044
            return 0;
 
1045
         op->literal = (GLfloat) number;
 
1046
         break;
 
1047
      case OP_PUSH_INT:
 
1048
         op->type = slang_oper_literal_int;
 
1049
         if (!parse_number(C, &number))
 
1050
            return 0;
 
1051
         op->literal = (GLfloat) number;
 
1052
         break;
 
1053
      case OP_PUSH_FLOAT:
 
1054
         op->type = slang_oper_literal_float;
 
1055
         if (!parse_float(C, &op->literal))
 
1056
            return 0;
 
1057
         break;
 
1058
      case OP_PUSH_IDENTIFIER:
 
1059
         op->type = slang_oper_identifier;
 
1060
         op->a_id = parse_identifier(C);
 
1061
         if (op->a_id == SLANG_ATOM_NULL)
 
1062
            return 0;
 
1063
         break;
 
1064
      case OP_SEQUENCE:
 
1065
         op->type = slang_oper_sequence;
 
1066
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1067
            return 0;
 
1068
         break;
 
1069
      case OP_ASSIGN:
 
1070
         op->type = slang_oper_assign;
 
1071
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1072
            return 0;
 
1073
         break;
 
1074
      case OP_ADDASSIGN:
 
1075
         op->type = slang_oper_addassign;
 
1076
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1077
            return 0;
 
1078
         break;
 
1079
      case OP_SUBASSIGN:
 
1080
         op->type = slang_oper_subassign;
 
1081
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1082
            return 0;
 
1083
         break;
 
1084
      case OP_MULASSIGN:
 
1085
         op->type = slang_oper_mulassign;
 
1086
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1087
            return 0;
 
1088
         break;
 
1089
      case OP_DIVASSIGN:
 
1090
         op->type = slang_oper_divassign;
 
1091
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1092
            return 0;
 
1093
         break;
 
1094
         /*case OP_MODASSIGN: */
 
1095
         /*case OP_LSHASSIGN: */
 
1096
         /*case OP_RSHASSIGN: */
 
1097
         /*case OP_ORASSIGN: */
 
1098
         /*case OP_XORASSIGN: */
 
1099
         /*case OP_ANDASSIGN: */
 
1100
      case OP_SELECT:
 
1101
         op->type = slang_oper_select;
 
1102
         if (!handle_nary_expression(C, op, &ops, &num_ops, 3))
 
1103
            return 0;
 
1104
         break;
 
1105
      case OP_LOGICALOR:
 
1106
         op->type = slang_oper_logicalor;
 
1107
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1108
            return 0;
 
1109
         break;
 
1110
      case OP_LOGICALXOR:
 
1111
         op->type = slang_oper_logicalxor;
 
1112
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1113
            return 0;
 
1114
         break;
 
1115
      case OP_LOGICALAND:
 
1116
         op->type = slang_oper_logicaland;
 
1117
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1118
            return 0;
 
1119
         break;
 
1120
         /*case OP_BITOR: */
 
1121
         /*case OP_BITXOR: */
 
1122
         /*case OP_BITAND: */
 
1123
      case OP_EQUAL:
 
1124
         op->type = slang_oper_equal;
 
1125
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1126
            return 0;
 
1127
         break;
 
1128
      case OP_NOTEQUAL:
 
1129
         op->type = slang_oper_notequal;
 
1130
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1131
            return 0;
 
1132
         break;
 
1133
      case OP_LESS:
 
1134
         op->type = slang_oper_less;
 
1135
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1136
            return 0;
 
1137
         break;
 
1138
      case OP_GREATER:
 
1139
         op->type = slang_oper_greater;
 
1140
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1141
            return 0;
 
1142
         break;
 
1143
      case OP_LESSEQUAL:
 
1144
         op->type = slang_oper_lessequal;
 
1145
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1146
            return 0;
 
1147
         break;
 
1148
      case OP_GREATEREQUAL:
 
1149
         op->type = slang_oper_greaterequal;
 
1150
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1151
            return 0;
 
1152
         break;
 
1153
         /*case OP_LSHIFT: */
 
1154
         /*case OP_RSHIFT: */
 
1155
      case OP_ADD:
 
1156
         op->type = slang_oper_add;
 
1157
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1158
            return 0;
 
1159
         break;
 
1160
      case OP_SUBTRACT:
 
1161
         op->type = slang_oper_subtract;
 
1162
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1163
            return 0;
 
1164
         break;
 
1165
      case OP_MULTIPLY:
 
1166
         op->type = slang_oper_multiply;
 
1167
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1168
            return 0;
 
1169
         break;
 
1170
      case OP_DIVIDE:
 
1171
         op->type = slang_oper_divide;
 
1172
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1173
            return 0;
 
1174
         break;
 
1175
         /*case OP_MODULUS: */
 
1176
      case OP_PREINCREMENT:
 
1177
         op->type = slang_oper_preincrement;
 
1178
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
 
1179
            return 0;
 
1180
         break;
 
1181
      case OP_PREDECREMENT:
 
1182
         op->type = slang_oper_predecrement;
 
1183
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
 
1184
            return 0;
 
1185
         break;
 
1186
      case OP_PLUS:
 
1187
         op->type = slang_oper_plus;
 
1188
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
 
1189
            return 0;
 
1190
         break;
 
1191
      case OP_MINUS:
 
1192
         op->type = slang_oper_minus;
 
1193
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
 
1194
            return 0;
 
1195
         break;
 
1196
      case OP_NOT:
 
1197
         op->type = slang_oper_not;
 
1198
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
 
1199
            return 0;
 
1200
         break;
 
1201
         /*case OP_COMPLEMENT: */
 
1202
      case OP_SUBSCRIPT:
 
1203
         op->type = slang_oper_subscript;
 
1204
         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
 
1205
            return 0;
 
1206
         break;
 
1207
      case OP_CALL:
 
1208
         op->type = slang_oper_call;
 
1209
         op->a_id = parse_identifier(C);
 
1210
         if (op->a_id == SLANG_ATOM_NULL)
 
1211
            return 0;
 
1212
         while (*C->I != OP_END)
 
1213
            if (!parse_child_operation(C, O, op, 0))
 
1214
               return 0;
 
1215
         C->I++;
 
1216
 
 
1217
         if (!C->parsing_builtin
 
1218
             && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
 
1219
            const char *id;
 
1220
 
 
1221
            id = slang_atom_pool_id(C->atoms, op->a_id);
 
1222
            if (!is_constructor_name(id, op->a_id, O->structs)) {
 
1223
               slang_info_log_error(C->L, "%s: undeclared function name.", id);
 
1224
               return 0;
 
1225
            }
 
1226
         }
 
1227
         break;
 
1228
      case OP_FIELD:
 
1229
         op->type = slang_oper_field;
 
1230
         op->a_id = parse_identifier(C);
 
1231
         if (op->a_id == SLANG_ATOM_NULL)
 
1232
            return 0;
 
1233
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
 
1234
            return 0;
 
1235
         break;
 
1236
      case OP_POSTINCREMENT:
 
1237
         op->type = slang_oper_postincrement;
 
1238
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
 
1239
            return 0;
 
1240
         break;
 
1241
      case OP_POSTDECREMENT:
 
1242
         op->type = slang_oper_postdecrement;
 
1243
         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
 
1244
            return 0;
 
1245
         break;
 
1246
      default:
 
1247
         return 0;
 
1248
      }
 
1249
   }
 
1250
   C->I++;
 
1251
 
 
1252
   *oper = *ops;
 
1253
   slang_alloc_free(ops);
 
1254
 
 
1255
   return 1;
1214
1256
}
1215
1257
 
1216
1258
/* parameter qualifier */
1222
1264
#define PARAMETER_ARRAY_NOT_PRESENT 0
1223
1265
#define PARAMETER_ARRAY_PRESENT 1
1224
1266
 
1225
 
static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O,
1226
 
        slang_variable *param)
 
1267
static int
 
1268
parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
 
1269
                            slang_variable * param)
1227
1270
{
1228
 
        /* parse and validate the parameter's type qualifiers (there can be two at most) because
1229
 
         * not all combinations are valid */
1230
 
        if (!parse_type_qualifier (C, &param->type.qualifier))
1231
 
                return 0;
1232
 
        switch (*C->I++)
1233
 
        {
1234
 
        case PARAM_QUALIFIER_IN:
1235
 
                if (param->type.qualifier != slang_qual_const && param->type.qualifier != slang_qual_none)
1236
 
                {
1237
 
         slang_info_log_error (C->L, "Invalid type qualifier.");
1238
 
                        return 0;
1239
 
                }
1240
 
                break;
1241
 
        case PARAM_QUALIFIER_OUT:
1242
 
                if (param->type.qualifier == slang_qual_none)
1243
 
                        param->type.qualifier = slang_qual_out;
1244
 
                else
1245
 
                {
1246
 
         slang_info_log_error (C->L, "Invalid type qualifier.");
1247
 
                        return 0;
1248
 
                }
1249
 
                break;
1250
 
        case PARAM_QUALIFIER_INOUT:
1251
 
                if (param->type.qualifier == slang_qual_none)
1252
 
                        param->type.qualifier = slang_qual_inout;
1253
 
                else
1254
 
                {
1255
 
         slang_info_log_error (C->L, "Invalid type qualifier.");
1256
 
                        return 0;
1257
 
                }
1258
 
                break;
1259
 
        default:
1260
 
                return 0;
1261
 
        }
1262
 
 
1263
 
        /* parse parameter's type specifier and name */
1264
 
        if (!parse_type_specifier (C, O, &param->type.specifier))
1265
 
                return 0;
1266
 
        param->a_name = parse_identifier (C);
1267
 
        if (param->a_name == SLANG_ATOM_NULL)
1268
 
                return 0;
1269
 
 
1270
 
        /* if the parameter is an array, parse its size (the size must be explicitly defined */
1271
 
        if (*C->I++ == PARAMETER_ARRAY_PRESENT)
1272
 
        {
1273
 
                slang_type_specifier p;
1274
 
 
1275
 
                slang_type_specifier_ctr (&p);
1276
 
                if (!slang_type_specifier_copy (&p, &param->type.specifier))
1277
 
                {
1278
 
                        slang_type_specifier_dtr (&p);
1279
 
                        return GL_FALSE;
1280
 
                }
1281
 
                if (!convert_to_array (C, param, &p))
1282
 
                {
1283
 
                        slang_type_specifier_dtr (&p);
1284
 
                        return GL_FALSE;
1285
 
                }
1286
 
                slang_type_specifier_dtr (&p);
1287
 
                if (!parse_array_len (C, O, &param->array_len))
1288
 
                        return GL_FALSE;
1289
 
        }
1290
 
 
1291
 
        /* calculate the parameter size */
1292
 
        if (!calculate_var_size (C, O, param))
1293
 
                return GL_FALSE;
1294
 
 
1295
 
        /* TODO: allocate the local address here? */
1296
 
        return 1;
 
1271
   /* parse and validate the parameter's type qualifiers (there can be
 
1272
    * two at most) because not all combinations are valid
 
1273
    */
 
1274
   if (!parse_type_qualifier(C, &param->type.qualifier))
 
1275
      return 0;
 
1276
   switch (*C->I++) {
 
1277
   case PARAM_QUALIFIER_IN:
 
1278
      if (param->type.qualifier != slang_qual_const
 
1279
          && param->type.qualifier != slang_qual_none) {
 
1280
         slang_info_log_error(C->L, "Invalid type qualifier.");
 
1281
         return 0;
 
1282
      }
 
1283
      break;
 
1284
   case PARAM_QUALIFIER_OUT:
 
1285
      if (param->type.qualifier == slang_qual_none)
 
1286
         param->type.qualifier = slang_qual_out;
 
1287
      else {
 
1288
         slang_info_log_error(C->L, "Invalid type qualifier.");
 
1289
         return 0;
 
1290
      }
 
1291
      break;
 
1292
   case PARAM_QUALIFIER_INOUT:
 
1293
      if (param->type.qualifier == slang_qual_none)
 
1294
         param->type.qualifier = slang_qual_inout;
 
1295
      else {
 
1296
         slang_info_log_error(C->L, "Invalid type qualifier.");
 
1297
         return 0;
 
1298
      }
 
1299
      break;
 
1300
   default:
 
1301
      return 0;
 
1302
   }
 
1303
 
 
1304
   /* parse parameter's type specifier and name */
 
1305
   if (!parse_type_specifier(C, O, &param->type.specifier))
 
1306
      return 0;
 
1307
   param->a_name = parse_identifier(C);
 
1308
   if (param->a_name == SLANG_ATOM_NULL)
 
1309
      return 0;
 
1310
 
 
1311
   /* if the parameter is an array, parse its size (the size must be
 
1312
    * explicitly defined
 
1313
    */
 
1314
   if (*C->I++ == PARAMETER_ARRAY_PRESENT) {
 
1315
      slang_type_specifier p;
 
1316
 
 
1317
      slang_type_specifier_ctr(&p);
 
1318
      if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
 
1319
         slang_type_specifier_dtr(&p);
 
1320
         return GL_FALSE;
 
1321
      }
 
1322
      if (!convert_to_array(C, param, &p)) {
 
1323
         slang_type_specifier_dtr(&p);
 
1324
         return GL_FALSE;
 
1325
      }
 
1326
      slang_type_specifier_dtr(&p);
 
1327
      if (!parse_array_len(C, O, &param->array_len))
 
1328
         return GL_FALSE;
 
1329
   }
 
1330
 
 
1331
   /* calculate the parameter size */
 
1332
   if (!calculate_var_size(C, O, param))
 
1333
      return GL_FALSE;
 
1334
 
 
1335
   /* TODO: allocate the local address here? */
 
1336
   return 1;
1297
1337
}
1298
1338
 
1299
1339
/* function type */
1336
1376
/*#define OPERATOR_COMPLEMENT 28*/
1337
1377
#define OPERATOR_NOT 29
1338
1378
 
1339
 
static const struct {
1340
 
        unsigned int o_code;
1341
 
        const char *o_name;
 
1379
static const struct
 
1380
{
 
1381
   unsigned int o_code;
 
1382
   const char *o_name;
1342
1383
} operator_names[] = {
1343
 
        { OPERATOR_INCREMENT, "++" },
1344
 
        { OPERATOR_ADDASSIGN, "+=" },
1345
 
        { OPERATOR_PLUS, "+" },
1346
 
        { OPERATOR_DECREMENT, "--" },
1347
 
        { OPERATOR_SUBASSIGN, "-=" },
1348
 
        { OPERATOR_MINUS, "-" },
1349
 
        { OPERATOR_NOT, "!" },
1350
 
        { OPERATOR_MULASSIGN, "*=" },
1351
 
        { OPERATOR_MULTIPLY, "*" },
1352
 
        { OPERATOR_DIVASSIGN, "/=" },
1353
 
        { OPERATOR_DIVIDE, "/" },
1354
 
        { OPERATOR_LESSEQUAL, "<=" },
1355
 
        /*{ OPERATOR_LSHASSIGN, "<<=" },*/
1356
 
        /*{ OPERATOR_LSHIFT, "<<" },*/
1357
 
        { OPERATOR_LESS, "<" },
1358
 
        { OPERATOR_GREATEREQUAL, ">=" },
1359
 
        /*{ OPERATOR_RSHASSIGN, ">>=" },*/
1360
 
        /*{ OPERATOR_RSHIFT, ">>" },*/
1361
 
        { OPERATOR_GREATER, ">" },
1362
 
        /*{ OPERATOR_MODASSIGN, "%=" },*/
1363
 
        /*{ OPERATOR_MODULUS, "%" },*/
1364
 
        /*{ OPERATOR_ANDASSIGN, "&=" },*/
1365
 
        /*{ OPERATOR_BITAND, "&" },*/
1366
 
        /*{ OPERATOR_ORASSIGN, "|=" },*/
1367
 
        /*{ OPERATOR_BITOR, "|" },*/
1368
 
        /*{ OPERATOR_COMPLEMENT, "~" },*/
1369
 
        /*{ OPERATOR_XORASSIGN, "^=" },*/
1370
 
        { OPERATOR_LOGICALXOR, "^^" },
1371
 
        /*{ OPERATOR_BITXOR, "^" }*/
 
1384
   {OPERATOR_INCREMENT, "++"},
 
1385
   {OPERATOR_ADDASSIGN, "+="},
 
1386
   {OPERATOR_PLUS, "+"},
 
1387
   {OPERATOR_DECREMENT, "--"},
 
1388
   {OPERATOR_SUBASSIGN, "-="},
 
1389
   {OPERATOR_MINUS, "-"},
 
1390
   {OPERATOR_NOT, "!"},
 
1391
   {OPERATOR_MULASSIGN, "*="},
 
1392
   {OPERATOR_MULTIPLY, "*"},
 
1393
   {OPERATOR_DIVASSIGN, "/="},
 
1394
   {OPERATOR_DIVIDE, "/"},
 
1395
   {OPERATOR_LESSEQUAL, "<="},
 
1396
   /*{ OPERATOR_LSHASSIGN, "<<=" }, */
 
1397
   /*{ OPERATOR_LSHIFT, "<<" }, */
 
1398
   {OPERATOR_LESS, "<"},
 
1399
   {OPERATOR_GREATEREQUAL, ">="},
 
1400
   /*{ OPERATOR_RSHASSIGN, ">>=" }, */
 
1401
   /*{ OPERATOR_RSHIFT, ">>" }, */
 
1402
   {OPERATOR_GREATER, ">"},
 
1403
   /*{ OPERATOR_MODASSIGN, "%=" }, */
 
1404
   /*{ OPERATOR_MODULUS, "%" }, */
 
1405
   /*{ OPERATOR_ANDASSIGN, "&=" }, */
 
1406
   /*{ OPERATOR_BITAND, "&" }, */
 
1407
   /*{ OPERATOR_ORASSIGN, "|=" }, */
 
1408
   /*{ OPERATOR_BITOR, "|" }, */
 
1409
   /*{ OPERATOR_COMPLEMENT, "~" }, */
 
1410
   /*{ OPERATOR_XORASSIGN, "^=" }, */
 
1411
   {OPERATOR_LOGICALXOR, "^^"},
 
1412
   /*{ OPERATOR_BITXOR, "^" } */
1372
1413
};
1373
1414
 
1374
 
static slang_atom parse_operator_name (slang_parse_ctx *C)
1375
 
{
1376
 
        unsigned int i;
1377
 
 
1378
 
        for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++)
1379
 
        {
1380
 
                if (operator_names[i].o_code == (unsigned int) (*C->I))
1381
 
                {
1382
 
                        slang_atom atom = slang_atom_pool_atom (C->atoms, operator_names[i].o_name);
1383
 
                        if (atom == SLANG_ATOM_NULL)
1384
 
                        {
1385
 
                                slang_info_log_memory (C->L);
1386
 
                                return 0;
1387
 
                        }
1388
 
                        C->I++;
1389
 
                        return atom;
1390
 
                }
1391
 
        }
1392
 
        return 0;
1393
 
}
1394
 
 
1395
 
static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func)
1396
 
{
1397
 
        /* parse function type and name */
1398
 
        if (!parse_fully_specified_type (C, O, &func->header.type))
1399
 
                return 0;
1400
 
        switch (*C->I++)
1401
 
        {
1402
 
        case FUNCTION_ORDINARY:
1403
 
                func->kind = slang_func_ordinary;
1404
 
                func->header.a_name = parse_identifier (C);
1405
 
                if (func->header.a_name == SLANG_ATOM_NULL)
1406
 
                        return 0;
1407
 
                break;
1408
 
        case FUNCTION_CONSTRUCTOR:
1409
 
                func->kind = slang_func_constructor;
1410
 
                if (func->header.type.specifier.type == slang_spec_struct)
1411
 
                        return 0;
1412
 
                func->header.a_name = slang_atom_pool_atom (C->atoms,
1413
 
                        slang_type_specifier_type_to_string (func->header.type.specifier.type));
1414
 
                if (func->header.a_name == SLANG_ATOM_NULL)
1415
 
                {
1416
 
                        slang_info_log_memory (C->L);
1417
 
                        return 0;
1418
 
                }
1419
 
                break;
1420
 
        case FUNCTION_OPERATOR:
1421
 
                func->kind = slang_func_operator;
1422
 
                func->header.a_name = parse_operator_name (C);
1423
 
                if (func->header.a_name == SLANG_ATOM_NULL)
1424
 
                        return 0;
1425
 
                break;
1426
 
        default:
1427
 
                return 0;
1428
 
        }
1429
 
 
1430
 
        /* parse function parameters */
1431
 
        while (*C->I++ == PARAMETER_NEXT)
1432
 
        {
1433
 
                slang_variable *p;
1434
 
 
1435
 
                func->parameters->variables = (slang_variable *) slang_alloc_realloc (
1436
 
                        func->parameters->variables,
1437
 
                        func->parameters->num_variables * sizeof (slang_variable),
1438
 
                        (func->parameters->num_variables + 1) * sizeof (slang_variable));
1439
 
                if (func->parameters->variables == NULL)
1440
 
                {
1441
 
                        slang_info_log_memory (C->L);
1442
 
                        return 0;
1443
 
                }
1444
 
                p = &func->parameters->variables[func->parameters->num_variables];
1445
 
                if (!slang_variable_construct (p))
1446
 
                        return 0;
1447
 
                func->parameters->num_variables++;
1448
 
                if (!parse_parameter_declaration (C, O, p))
1449
 
                        return 0;
1450
 
        }
1451
 
 
1452
 
        /* function formal parameters and local variables share the same scope, so save
1453
 
         * the information about param count in a seperate place
1454
 
         * also link the scope to the global variable scope so when a given identifier is not
1455
 
         * found here, the search process continues in the global space */
1456
 
        func->param_count = func->parameters->num_variables;
1457
 
        func->parameters->outer_scope = O->vars;
1458
 
        return 1;
1459
 
}
1460
 
 
1461
 
static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func)
1462
 
{
1463
 
        slang_output_ctx o = *O;
1464
 
 
1465
 
        if (!parse_function_prototype (C, O, func))
1466
 
                return 0;
1467
 
 
1468
 
        /* create function's body operation */
1469
 
        func->body = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
1470
 
        if (func->body == NULL)
1471
 
        {
1472
 
                slang_info_log_memory (C->L);
1473
 
                return 0;
1474
 
        }
1475
 
        if (!slang_operation_construct (func->body))
1476
 
        {
1477
 
                slang_alloc_free (func->body);
1478
 
                func->body = NULL;
1479
 
                slang_info_log_memory (C->L);
1480
 
                return 0;
1481
 
        }
1482
 
 
1483
 
        /* to parse the body the parse context is modified in order to capture parsed variables
1484
 
         * into function's local variable scope */
1485
 
        C->global_scope = 0;
1486
 
        o.vars = func->parameters;
1487
 
        if (!parse_statement (C, &o, func->body))
1488
 
                return 0;
1489
 
        C->global_scope = 1;
1490
 
        return 1;
1491
 
}
1492
 
 
1493
 
static GLboolean initialize_global (slang_assemble_ctx *A, slang_variable *var)
1494
 
{
1495
 
        slang_assembly_file_restore_point point;
1496
 
        slang_machine mach;
1497
 
        slang_assembly_local_info save_local = A->local;
1498
 
        slang_operation op_id, op_assign;
1499
 
        GLboolean result;
1500
 
 
1501
 
        /* save the current assembly */
1502
 
        if (!slang_assembly_file_restore_point_save (A->file, &point))
1503
 
                return GL_FALSE;
1504
 
 
1505
 
        /* setup the machine */
1506
 
        mach = *A->mach;
1507
 
        mach.ip = A->file->count;
1508
 
 
1509
 
        /* allocate local storage for expression */
1510
 
        A->local.ret_size = 0;
1511
 
        A->local.addr_tmp = 0;
1512
 
        A->local.swizzle_tmp = 4;
1513
 
        if (!slang_assembly_file_push_label (A->file, slang_asm_local_alloc, 20))
1514
 
                return GL_FALSE;
1515
 
        if (!slang_assembly_file_push_label (A->file, slang_asm_enter, 20))
1516
 
                return GL_FALSE;
1517
 
 
1518
 
        /* construct the left side of assignment */
1519
 
        if (!slang_operation_construct (&op_id))
1520
 
                return GL_FALSE;
1521
 
        op_id.type = slang_oper_identifier;
1522
 
        op_id.a_id = var->a_name;
1523
 
 
1524
 
        /* put the variable into operation's scope */
1525
 
        op_id.locals->variables = (slang_variable *) slang_alloc_malloc (sizeof (slang_variable));
1526
 
        if (op_id.locals->variables == NULL)
1527
 
        {
1528
 
                slang_operation_destruct (&op_id);
1529
 
                return GL_FALSE;
1530
 
        }
1531
 
        op_id.locals->num_variables = 1;
1532
 
        op_id.locals->variables[0] = *var;
1533
 
 
1534
 
        /* construct the assignment expression */
1535
 
        if (!slang_operation_construct (&op_assign))
1536
 
        {
1537
 
                op_id.locals->num_variables = 0;
1538
 
                slang_operation_destruct (&op_id);
1539
 
                return GL_FALSE;
1540
 
        }
1541
 
        op_assign.type = slang_oper_assign;
1542
 
        op_assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation));
1543
 
        if (op_assign.children == NULL)
1544
 
        {
1545
 
                slang_operation_destruct (&op_assign);
1546
 
                op_id.locals->num_variables = 0;
1547
 
                slang_operation_destruct (&op_id);
1548
 
                return GL_FALSE;
1549
 
        }
1550
 
        op_assign.num_children = 2;
1551
 
        op_assign.children[0] = op_id;
1552
 
        op_assign.children[1] = *var->initializer;
1553
 
 
1554
 
        /* insert the actual expression */
1555
 
        result = _slang_assemble_operation (A, &op_assign, slang_ref_forbid);
1556
 
 
1557
 
        /* carefully destroy the operations */
1558
 
        op_assign.num_children = 0;
1559
 
        slang_alloc_free (op_assign.children);
1560
 
        op_assign.children = NULL;
1561
 
        slang_operation_destruct (&op_assign);
1562
 
        op_id.locals->num_variables = 0;
1563
 
        slang_operation_destruct (&op_id);
1564
 
 
1565
 
        if (!result)
1566
 
                return GL_FALSE;
1567
 
        if (!slang_assembly_file_push (A->file, slang_asm_exit))
1568
 
                return GL_FALSE;
1569
 
 
1570
 
        /* execute the expression */
1571
 
        if (!_slang_execute2 (A->file, &mach))
1572
 
                return GL_FALSE;
1573
 
 
1574
 
        /* restore the old assembly */
1575
 
        if (!slang_assembly_file_restore_point_load (A->file, &point))
1576
 
                return GL_FALSE;
1577
 
        A->local = save_local;
1578
 
 
1579
 
        /* now we copy the contents of the initialized variable back to the original machine */
1580
 
        _mesa_memcpy ((GLubyte *) A->mach->mem + var->address, (GLubyte *) mach.mem + var->address,
1581
 
                var->size);
1582
 
 
1583
 
        return GL_TRUE;
 
1415
static slang_atom
 
1416
parse_operator_name(slang_parse_ctx * C)
 
1417
{
 
1418
   unsigned int i;
 
1419
 
 
1420
   for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) {
 
1421
      if (operator_names[i].o_code == (unsigned int) (*C->I)) {
 
1422
         slang_atom atom =
 
1423
            slang_atom_pool_atom(C->atoms, operator_names[i].o_name);
 
1424
         if (atom == SLANG_ATOM_NULL) {
 
1425
            slang_info_log_memory(C->L);
 
1426
            return 0;
 
1427
         }
 
1428
         C->I++;
 
1429
         return atom;
 
1430
      }
 
1431
   }
 
1432
   return 0;
 
1433
}
 
1434
 
 
1435
static int
 
1436
parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
 
1437
                         slang_function * func)
 
1438
{
 
1439
   /* parse function type and name */
 
1440
   if (!parse_fully_specified_type(C, O, &func->header.type))
 
1441
      return 0;
 
1442
   switch (*C->I++) {
 
1443
   case FUNCTION_ORDINARY:
 
1444
      func->kind = slang_func_ordinary;
 
1445
      func->header.a_name = parse_identifier(C);
 
1446
      if (func->header.a_name == SLANG_ATOM_NULL)
 
1447
         return 0;
 
1448
      break;
 
1449
   case FUNCTION_CONSTRUCTOR:
 
1450
      func->kind = slang_func_constructor;
 
1451
      if (func->header.type.specifier.type == slang_spec_struct)
 
1452
         return 0;
 
1453
      func->header.a_name =
 
1454
         slang_atom_pool_atom(C->atoms,
 
1455
                              slang_type_specifier_type_to_string
 
1456
                              (func->header.type.specifier.type));
 
1457
      if (func->header.a_name == SLANG_ATOM_NULL) {
 
1458
         slang_info_log_memory(C->L);
 
1459
         return 0;
 
1460
      }
 
1461
      break;
 
1462
   case FUNCTION_OPERATOR:
 
1463
      func->kind = slang_func_operator;
 
1464
      func->header.a_name = parse_operator_name(C);
 
1465
      if (func->header.a_name == SLANG_ATOM_NULL)
 
1466
         return 0;
 
1467
      break;
 
1468
   default:
 
1469
      return 0;
 
1470
   }
 
1471
 
 
1472
   /* parse function parameters */
 
1473
   while (*C->I++ == PARAMETER_NEXT) {
 
1474
      slang_variable *p = slang_variable_scope_grow(func->parameters);
 
1475
      if (!p) {
 
1476
         slang_info_log_memory(C->L);
 
1477
         return 0;
 
1478
      }
 
1479
      if (!parse_parameter_declaration(C, O, p))
 
1480
         return 0;
 
1481
   }
 
1482
 
 
1483
   /* function formal parameters and local variables share the same
 
1484
    * scope, so save the information about param count in a seperate
 
1485
    * place also link the scope to the global variable scope so when a
 
1486
    * given identifier is not found here, the search process continues
 
1487
    * in the global space
 
1488
    */
 
1489
   func->param_count = func->parameters->num_variables;
 
1490
   func->parameters->outer_scope = O->vars;
 
1491
   return 1;
 
1492
}
 
1493
 
 
1494
static int
 
1495
parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
 
1496
                          slang_function * func)
 
1497
{
 
1498
   slang_output_ctx o = *O;
 
1499
 
 
1500
   if (!parse_function_prototype(C, O, func))
 
1501
      return 0;
 
1502
 
 
1503
   /* create function's body operation */
 
1504
   func->body =
 
1505
      (slang_operation *) slang_alloc_malloc(sizeof(slang_operation));
 
1506
   if (func->body == NULL) {
 
1507
      slang_info_log_memory(C->L);
 
1508
      return 0;
 
1509
   }
 
1510
   if (!slang_operation_construct(func->body)) {
 
1511
      slang_alloc_free(func->body);
 
1512
      func->body = NULL;
 
1513
      slang_info_log_memory(C->L);
 
1514
      return 0;
 
1515
   }
 
1516
 
 
1517
   /* to parse the body the parse context is modified in order to
 
1518
    * capture parsed variables into function's local variable scope
 
1519
    */
 
1520
   C->global_scope = GL_FALSE;
 
1521
   o.vars = func->parameters;
 
1522
   if (!parse_statement(C, &o, func->body))
 
1523
      return 0;
 
1524
 
 
1525
   C->global_scope = GL_TRUE;
 
1526
   return 1;
 
1527
}
 
1528
 
 
1529
static GLboolean
 
1530
initialize_global(slang_assemble_ctx * A, slang_variable * var)
 
1531
{
 
1532
   slang_assembly_file_restore_point point;
 
1533
   slang_machine mach;
 
1534
   slang_assembly_local_info save_local = A->local;
 
1535
   slang_operation op_id, op_assign;
 
1536
   GLboolean result;
 
1537
 
 
1538
   /* save the current assembly */
 
1539
   if (!slang_assembly_file_restore_point_save(A->file, &point))
 
1540
      return GL_FALSE;
 
1541
 
 
1542
   /* setup the machine */
 
1543
   mach = *A->mach;
 
1544
   mach.ip = A->file->count;
 
1545
 
 
1546
   /* allocate local storage for expression */
 
1547
   A->local.ret_size = 0;
 
1548
   A->local.addr_tmp = 0;
 
1549
   A->local.swizzle_tmp = 4;
 
1550
   if (!slang_assembly_file_push_label(A->file, slang_asm_local_alloc, 20))
 
1551
      return GL_FALSE;
 
1552
   if (!slang_assembly_file_push_label(A->file, slang_asm_enter, 20))
 
1553
      return GL_FALSE;
 
1554
 
 
1555
   /* construct the left side of assignment */
 
1556
   if (!slang_operation_construct(&op_id))
 
1557
      return GL_FALSE;
 
1558
   op_id.type = slang_oper_identifier;
 
1559
   op_id.a_id = var->a_name;
 
1560
 
 
1561
   /* put the variable into operation's scope */
 
1562
   op_id.locals->variables =
 
1563
      (slang_variable *) slang_alloc_malloc(sizeof(slang_variable));
 
1564
   if (op_id.locals->variables == NULL) {
 
1565
      slang_operation_destruct(&op_id);
 
1566
      return GL_FALSE;
 
1567
   }
 
1568
   op_id.locals->num_variables = 1;
 
1569
   op_id.locals->variables[0] = *var;
 
1570
 
 
1571
   /* construct the assignment expression */
 
1572
   if (!slang_operation_construct(&op_assign)) {
 
1573
      op_id.locals->num_variables = 0;
 
1574
      slang_operation_destruct(&op_id);
 
1575
      return GL_FALSE;
 
1576
   }
 
1577
   op_assign.type = slang_oper_assign;
 
1578
   op_assign.children =
 
1579
      (slang_operation *) slang_alloc_malloc(2 * sizeof(slang_operation));
 
1580
   if (op_assign.children == NULL) {
 
1581
      slang_operation_destruct(&op_assign);
 
1582
      op_id.locals->num_variables = 0;
 
1583
      slang_operation_destruct(&op_id);
 
1584
      return GL_FALSE;
 
1585
   }
 
1586
   op_assign.num_children = 2;
 
1587
   op_assign.children[0] = op_id;
 
1588
   op_assign.children[1] = *var->initializer;
 
1589
 
 
1590
   /* insert the actual expression */
 
1591
   result = _slang_assemble_operation(A, &op_assign, slang_ref_forbid);
 
1592
 
 
1593
   /* carefully destroy the operations */
 
1594
   op_assign.num_children = 0;
 
1595
   slang_alloc_free(op_assign.children);
 
1596
   op_assign.children = NULL;
 
1597
   slang_operation_destruct(&op_assign);
 
1598
   op_id.locals->num_variables = 0;
 
1599
   slang_operation_destruct(&op_id);
 
1600
 
 
1601
   if (!result)
 
1602
      return GL_FALSE;
 
1603
   if (!slang_assembly_file_push(A->file, slang_asm_exit))
 
1604
      return GL_FALSE;
 
1605
 
 
1606
   /* execute the expression */
 
1607
   if (!_slang_execute2(A->file, &mach))
 
1608
      return GL_FALSE;
 
1609
 
 
1610
   /* restore the old assembly */
 
1611
   if (!slang_assembly_file_restore_point_load(A->file, &point))
 
1612
      return GL_FALSE;
 
1613
   A->local = save_local;
 
1614
 
 
1615
   /* now we copy the contents of the initialized variable back to the original machine */
 
1616
   _mesa_memcpy((GLubyte *) A->mach->mem + var->address,
 
1617
                (GLubyte *) mach.mem + var->address, var->size);
 
1618
 
 
1619
   return GL_TRUE;
1584
1620
}
1585
1621
 
1586
1622
/* init declarator list */
1594
1630
#define VARIABLE_ARRAY_EXPLICIT 3
1595
1631
#define VARIABLE_ARRAY_UNKNOWN 4
1596
1632
 
1597
 
static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
1598
 
        const slang_fully_specified_type *type)
 
1633
 
 
1634
/**
 
1635
 * Parse the initializer for a variable declaration.
 
1636
 */
 
1637
static int
 
1638
parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
 
1639
                      const slang_fully_specified_type * type)
1599
1640
{
1600
 
        slang_variable *var;
1601
 
 
1602
 
        /* empty init declatator (without name, e.g. "float ;") */
1603
 
        if (*C->I++ == VARIABLE_NONE)
1604
 
                return 1;
1605
 
 
1606
 
        /* make room for the new variable and initialize it */
1607
 
        O->vars->variables = (slang_variable *) slang_alloc_realloc (O->vars->variables,
1608
 
                O->vars->num_variables * sizeof (slang_variable),
1609
 
                (O->vars->num_variables + 1) * sizeof (slang_variable));
1610
 
        if (O->vars->variables == NULL)
1611
 
        {
1612
 
                slang_info_log_memory (C->L);
1613
 
                return 0;
1614
 
        }
1615
 
        var = &O->vars->variables[O->vars->num_variables];
1616
 
        if (!slang_variable_construct (var))
1617
 
                return 0;
1618
 
        O->vars->num_variables++;
1619
 
 
1620
 
        /* copy the declarator qualifier type, parse the identifier */
1621
 
        var->global = C->global_scope;
1622
 
        var->type.qualifier = type->qualifier;
1623
 
        var->a_name = parse_identifier (C);
1624
 
        if (var->a_name == SLANG_ATOM_NULL)
1625
 
                return 0;
1626
 
 
1627
 
        switch (*C->I++)
1628
 
        {
1629
 
        case VARIABLE_NONE:
1630
 
                /* simple variable declarator - just copy the specifier */
1631
 
                if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier))
1632
 
                        return 0;
1633
 
                break;
1634
 
        case VARIABLE_INITIALIZER:
1635
 
                /* initialized variable - copy the specifier and parse the expression */
1636
 
                if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier))
1637
 
                        return 0;
1638
 
                var->initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));
1639
 
                if (var->initializer == NULL)
1640
 
                {
1641
 
                        slang_info_log_memory (C->L);
1642
 
                        return 0;
1643
 
                }
1644
 
                if (!slang_operation_construct (var->initializer))
1645
 
                {
1646
 
                        slang_alloc_free (var->initializer);
1647
 
                        var->initializer = NULL;
1648
 
                        slang_info_log_memory (C->L);
1649
 
                        return 0;
1650
 
                }
1651
 
                if (!parse_expression (C, O, var->initializer))
1652
 
                        return 0;
1653
 
                break;
 
1641
   slang_variable *var;
 
1642
 
 
1643
   /* empty init declatator (without name, e.g. "float ;") */
 
1644
   if (*C->I++ == VARIABLE_NONE)
 
1645
      return 1;
 
1646
 
 
1647
   /* make room for the new variable and initialize it */
 
1648
   var = slang_variable_scope_grow(O->vars);
 
1649
   if (!var) {
 
1650
      slang_info_log_memory(C->L);
 
1651
      return 0;
 
1652
   }
 
1653
 
 
1654
   /* copy the declarator qualifier type, parse the identifier */
 
1655
   var->global = C->global_scope;
 
1656
   var->type.qualifier = type->qualifier;
 
1657
   var->a_name = parse_identifier(C);
 
1658
   if (var->a_name == SLANG_ATOM_NULL)
 
1659
      return 0;
 
1660
 
 
1661
   switch (*C->I++) {
 
1662
   case VARIABLE_NONE:
 
1663
      /* simple variable declarator - just copy the specifier */
 
1664
      if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
 
1665
         return 0;
 
1666
      break;
 
1667
   case VARIABLE_INITIALIZER:
 
1668
      /* initialized variable - copy the specifier and parse the expression */
 
1669
      if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
 
1670
         return 0;
 
1671
      var->initializer =
 
1672
         (slang_operation *) slang_alloc_malloc(sizeof(slang_operation));
 
1673
      if (var->initializer == NULL) {
 
1674
         slang_info_log_memory(C->L);
 
1675
         return 0;
 
1676
      }
 
1677
      if (!slang_operation_construct(var->initializer)) {
 
1678
         slang_alloc_free(var->initializer);
 
1679
         var->initializer = NULL;
 
1680
         slang_info_log_memory(C->L);
 
1681
         return 0;
 
1682
      }
 
1683
      if (!parse_expression(C, O, var->initializer))
 
1684
         return 0;
 
1685
      break;
1654
1686
#if 0
1655
 
        case VARIABLE_ARRAY_UNKNOWN:
1656
 
                /* unsized array - mark it as array and copy the specifier to the array element */
1657
 
                if (!convert_to_array (C, var, &type->specifier))
1658
 
                        return GL_FALSE;
1659
 
                break;
 
1687
   case VARIABLE_ARRAY_UNKNOWN:
 
1688
      /* unsized array - mark it as array and copy the specifier to
 
1689
         the array element
 
1690
      */
 
1691
      if (!convert_to_array(C, var, &type->specifier))
 
1692
         return GL_FALSE;
 
1693
      break;
1660
1694
#endif
1661
 
        case VARIABLE_ARRAY_EXPLICIT:
1662
 
                if (!convert_to_array (C, var, &type->specifier))
1663
 
                        return GL_FALSE;
1664
 
                if (!parse_array_len (C, O, &var->array_len))
1665
 
                        return GL_FALSE;
1666
 
                break;
1667
 
        default:
1668
 
                return 0;
1669
 
        }
1670
 
 
1671
 
        /* allocate global address space for a variable with a known size */
1672
 
        if (C->global_scope && !(var->type.specifier.type == slang_spec_array && var->array_len == 0))
1673
 
        {
1674
 
                if (!calculate_var_size (C, O, var))
1675
 
                        return GL_FALSE;
1676
 
                var->address = slang_var_pool_alloc (O->global_pool, var->size);
1677
 
        }
1678
 
 
1679
 
        /* initialize global variable */
 
1695
   case VARIABLE_ARRAY_EXPLICIT:
 
1696
      if (!convert_to_array(C, var, &type->specifier))
 
1697
         return GL_FALSE;
 
1698
      if (!parse_array_len(C, O, &var->array_len))
 
1699
         return GL_FALSE;
 
1700
      break;
 
1701
   default:
 
1702
      return 0;
 
1703
   }
 
1704
 
 
1705
   /* allocate global address space for a variable with a known size */
 
1706
   if (C->global_scope
 
1707
       && !(var->type.specifier.type == slang_spec_array
 
1708
            && var->array_len == 0)) {
 
1709
      if (!calculate_var_size(C, O, var))
 
1710
         return GL_FALSE;
 
1711
      var->address = slang_var_pool_alloc(O->global_pool, var->size);
 
1712
   }
 
1713
 
 
1714
   /* initialize global variable */
1680
1715
   if (C->global_scope) {
1681
1716
      if (var->initializer != NULL) {
1682
1717
         slang_assemble_ctx A;
1687
1722
         A.space.funcs = O->funs;
1688
1723
         A.space.structs = O->structs;
1689
1724
         A.space.vars = O->vars;
1690
 
         if (!initialize_global (&A, var))
1691
 
            return 0;
1692
 
      }
1693
 
      else {
1694
 
         _mesa_memset ((GLubyte *) (O->machine->mem) + var->address, 0, var->size);
1695
 
      }
1696
 
        }
1697
 
        return 1;
1698
 
}
1699
 
 
1700
 
static int parse_init_declarator_list (slang_parse_ctx *C, slang_output_ctx *O)
1701
 
{
1702
 
        slang_fully_specified_type type;
1703
 
 
1704
 
        /* parse the fully specified type, common to all declarators */
1705
 
        if (!slang_fully_specified_type_construct (&type))
1706
 
                return 0;
1707
 
        if (!parse_fully_specified_type (C, O, &type))
1708
 
        {
1709
 
                slang_fully_specified_type_destruct (&type);
1710
 
                return 0;
1711
 
        }
1712
 
 
1713
 
        /* parse declarators, pass-in the parsed type */
1714
 
        do
1715
 
        {
1716
 
                if (!parse_init_declarator (C, O, &type))
1717
 
                {
1718
 
                        slang_fully_specified_type_destruct (&type);
1719
 
                        return 0;
1720
 
                }
1721
 
        }
1722
 
        while (*C->I++ == DECLARATOR_NEXT);
1723
 
 
1724
 
        slang_fully_specified_type_destruct (&type);
1725
 
        return 1;
1726
 
}
1727
 
 
1728
 
static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definition,
1729
 
        slang_function **parsed_func_ret)
1730
 
{
1731
 
        slang_function parsed_func, *found_func;
1732
 
 
1733
 
        /* parse function definition/declaration */
1734
 
        if (!slang_function_construct (&parsed_func))
1735
 
                return 0;
1736
 
        if (definition)
1737
 
        {
1738
 
                if (!parse_function_definition (C, O, &parsed_func))
1739
 
                {
1740
 
                        slang_function_destruct (&parsed_func);
1741
 
                        return 0;
1742
 
                }
1743
 
        }
1744
 
        else
1745
 
        {
1746
 
                if (!parse_function_prototype (C, O, &parsed_func))
1747
 
                {
1748
 
                        slang_function_destruct (&parsed_func);
1749
 
                        return 0;
1750
 
                }
1751
 
        }
1752
 
 
1753
 
        /* find a function with a prototype matching the parsed one - only the current scope
1754
 
         * is being searched to allow built-in function overriding */
1755
 
        found_func = slang_function_scope_find (O->funs, &parsed_func, 0);
1756
 
        if (found_func == NULL)
1757
 
        {
1758
 
                /* add the parsed function to the function list */
1759
 
                O->funs->functions = (slang_function *) slang_alloc_realloc (O->funs->functions,
1760
 
                        O->funs->num_functions * sizeof (slang_function),
1761
 
                        (O->funs->num_functions + 1) * sizeof (slang_function));
1762
 
                if (O->funs->functions == NULL)
1763
 
                {
1764
 
                        slang_info_log_memory (C->L);
1765
 
                        slang_function_destruct (&parsed_func);
1766
 
                        return 0;
1767
 
                }
1768
 
                O->funs->functions[O->funs->num_functions] = parsed_func;
1769
 
                O->funs->num_functions++;
1770
 
 
1771
 
                /* return the newly parsed function */
1772
 
                *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
1773
 
        }
1774
 
        else
1775
 
        {
1776
 
                /* TODO: check function return type qualifiers and specifiers */
1777
 
                if (definition)
1778
 
                {
1779
 
                        if (found_func->body != NULL)
1780
 
                        {
1781
 
            slang_info_log_error (C->L, "%s: function already has a body.",
1782
 
                                        slang_atom_pool_id (C->atoms, parsed_func.header.a_name));
1783
 
                                slang_function_destruct (&parsed_func);
1784
 
                                return 0;
1785
 
                        }
1786
 
 
1787
 
                        /* destroy the existing function declaration and replace it with the new one,
1788
 
                         * remember to save the fixup table */
1789
 
                        parsed_func.fixups = found_func->fixups;
1790
 
                        slang_fixup_table_init (&found_func->fixups);
1791
 
                        slang_function_destruct (found_func);
1792
 
                        *found_func = parsed_func;
1793
 
                }
1794
 
                else
1795
 
                {
1796
 
                        /* another declaration of the same function prototype - ignore it */
1797
 
                        slang_function_destruct (&parsed_func);
1798
 
                }
1799
 
 
1800
 
                /* return the found function */
1801
 
                *parsed_func_ret = found_func;
1802
 
        }
1803
 
 
1804
 
        /* assemble the parsed function */
1805
 
        {
1806
 
                slang_assemble_ctx A;
1807
 
 
1808
 
                A.file = O->assembly;
1809
 
                A.mach = O->machine;
1810
 
                A.atoms = C->atoms;
1811
 
                A.space.funcs = O->funs;
1812
 
                A.space.structs = O->structs;
1813
 
                A.space.vars = O->vars;
1814
 
                if (!_slang_assemble_function (&A, *parsed_func_ret))
1815
 
                        return 0;
1816
 
        }
1817
 
        return 1;
 
1725
         if (!initialize_global(&A, var))
 
1726
            return 0;
 
1727
      }
 
1728
      else {
 
1729
         _mesa_memset((GLubyte *) (O->machine->mem) + var->address, 0,
 
1730
                      var->size);
 
1731
      }
 
1732
   }
 
1733
   return 1;
 
1734
}
 
1735
 
 
1736
/**
 
1737
 * Parse a list of variable declarations.  Each variable may have an
 
1738
 * initializer.
 
1739
 */
 
1740
static int
 
1741
parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O)
 
1742
{
 
1743
   slang_fully_specified_type type;
 
1744
 
 
1745
   /* parse the fully specified type, common to all declarators */
 
1746
   if (!slang_fully_specified_type_construct(&type))
 
1747
      return 0;
 
1748
   if (!parse_fully_specified_type(C, O, &type)) {
 
1749
      slang_fully_specified_type_destruct(&type);
 
1750
      return 0;
 
1751
   }
 
1752
 
 
1753
   /* parse declarators, pass-in the parsed type */
 
1754
   do {
 
1755
      if (!parse_init_declarator(C, O, &type)) {
 
1756
         slang_fully_specified_type_destruct(&type);
 
1757
         return 0;
 
1758
      }
 
1759
   }
 
1760
   while (*C->I++ == DECLARATOR_NEXT);
 
1761
 
 
1762
   slang_fully_specified_type_destruct(&type);
 
1763
   return 1;
 
1764
}
 
1765
 
 
1766
 
 
1767
/**
 
1768
 * Parse a function definition or declaration.
 
1769
 * \param C  parsing context
 
1770
 * \param O  output context
 
1771
 * \param definition if non-zero expect a definition, else a declaration
 
1772
 * \param parsed_func_ret  returns the parsed function
 
1773
 * \return 1 if success, 0 if failure
 
1774
 */
 
1775
static int
 
1776
parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
 
1777
               slang_function ** parsed_func_ret)
 
1778
{
 
1779
   slang_function parsed_func, *found_func;
 
1780
 
 
1781
   /* parse function definition/declaration */
 
1782
   if (!slang_function_construct(&parsed_func))
 
1783
      return 0;
 
1784
   if (definition) {
 
1785
      if (!parse_function_definition(C, O, &parsed_func)) {
 
1786
         slang_function_destruct(&parsed_func);
 
1787
         return 0;
 
1788
      }
 
1789
   }
 
1790
   else {
 
1791
      if (!parse_function_prototype(C, O, &parsed_func)) {
 
1792
         slang_function_destruct(&parsed_func);
 
1793
         return 0;
 
1794
      }
 
1795
   }
 
1796
 
 
1797
   /* find a function with a prototype matching the parsed one - only
 
1798
    * the current scope is being searched to allow built-in function
 
1799
    * overriding
 
1800
    */
 
1801
   found_func = slang_function_scope_find(O->funs, &parsed_func, 0);
 
1802
   if (found_func == NULL) {
 
1803
      /* add the parsed function to the function list */
 
1804
      O->funs->functions =
 
1805
         (slang_function *) slang_alloc_realloc(O->funs->functions,
 
1806
                                                O->funs->num_functions *
 
1807
                                                sizeof(slang_function),
 
1808
                                                (O->funs->num_functions +
 
1809
                                                 1) * sizeof(slang_function));
 
1810
      if (O->funs->functions == NULL) {
 
1811
         slang_info_log_memory(C->L);
 
1812
         slang_function_destruct(&parsed_func);
 
1813
         return 0;
 
1814
      }
 
1815
      O->funs->functions[O->funs->num_functions] = parsed_func;
 
1816
      O->funs->num_functions++;
 
1817
 
 
1818
      /* return the newly parsed function */
 
1819
      *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
 
1820
   }
 
1821
   else {
 
1822
      /* TODO: check function return type qualifiers and specifiers */
 
1823
      if (definition) {
 
1824
         if (found_func->body != NULL) {
 
1825
            slang_info_log_error(C->L, "%s: function already has a body.",
 
1826
                                 slang_atom_pool_id(C->atoms,
 
1827
                                                    parsed_func.header.
 
1828
                                                    a_name));
 
1829
            slang_function_destruct(&parsed_func);
 
1830
            return 0;
 
1831
         }
 
1832
 
 
1833
         /* destroy the existing function declaration and replace it
 
1834
          * with the new one, remember to save the fixup table
 
1835
          */
 
1836
         parsed_func.fixups = found_func->fixups;
 
1837
         slang_fixup_table_init(&found_func->fixups);
 
1838
         slang_function_destruct(found_func);
 
1839
         *found_func = parsed_func;
 
1840
      }
 
1841
      else {
 
1842
         /* another declaration of the same function prototype - ignore it */
 
1843
         slang_function_destruct(&parsed_func);
 
1844
      }
 
1845
 
 
1846
      /* return the found function */
 
1847
      *parsed_func_ret = found_func;
 
1848
   }
 
1849
 
 
1850
   /* assemble the parsed function */
 
1851
   {
 
1852
      slang_assemble_ctx A;
 
1853
 
 
1854
      A.file = O->assembly;
 
1855
      A.mach = O->machine;
 
1856
      A.atoms = C->atoms;
 
1857
      A.space.funcs = O->funs;
 
1858
      A.space.structs = O->structs;
 
1859
      A.space.vars = O->vars;
 
1860
      if (!_slang_assemble_function(&A, *parsed_func_ret))
 
1861
         return 0;
 
1862
   }
 
1863
   return 1;
1818
1864
}
1819
1865
 
1820
1866
/* declaration */
1821
1867
#define DECLARATION_FUNCTION_PROTOTYPE 1
1822
1868
#define DECLARATION_INIT_DECLARATOR_LIST 2
1823
1869
 
1824
 
static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O)
 
1870
static int
 
1871
parse_declaration(slang_parse_ctx * C, slang_output_ctx * O)
1825
1872
{
1826
 
        switch (*C->I++)
1827
 
        {
1828
 
        case DECLARATION_INIT_DECLARATOR_LIST:
1829
 
                if (!parse_init_declarator_list (C, O))
1830
 
                        return 0;
1831
 
                break;
1832
 
        case DECLARATION_FUNCTION_PROTOTYPE:
1833
 
                {
1834
 
                        slang_function *dummy_func;
 
1873
   switch (*C->I++) {
 
1874
   case DECLARATION_INIT_DECLARATOR_LIST:
 
1875
      if (!parse_init_declarator_list(C, O))
 
1876
         return 0;
 
1877
      break;
 
1878
   case DECLARATION_FUNCTION_PROTOTYPE:
 
1879
      {
 
1880
         slang_function *dummy_func;
1835
1881
 
1836
 
                        if (!parse_function (C, O, 0, &dummy_func))
1837
 
                                return 0;
1838
 
                }
1839
 
                break;
1840
 
        default:
1841
 
                return 0;
1842
 
        }
1843
 
        return 1;
 
1882
         if (!parse_function(C, O, 0, &dummy_func))
 
1883
            return 0;
 
1884
      }
 
1885
      break;
 
1886
   default:
 
1887
      return 0;
 
1888
   }
 
1889
   return 1;
1844
1890
}
1845
1891
 
1846
1892
/* external declaration */
1849
1895
#define EXTERNAL_DECLARATION 2
1850
1896
 
1851
1897
static GLboolean
1852
 
parse_code_unit (slang_parse_ctx *C, slang_code_unit *unit)
 
1898
parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit)
1853
1899
{
1854
 
        slang_output_ctx o;
 
1900
   slang_output_ctx o;
1855
1901
 
1856
1902
   /* setup output context */
1857
1903
   o.funs = &unit->funs;
1861
1907
   o.global_pool = &unit->object->varpool;
1862
1908
   o.machine = &unit->object->machine;
1863
1909
 
1864
 
        /* parse individual functions and declarations */
1865
 
        while (*C->I != EXTERNAL_NULL)
1866
 
        {
1867
 
                switch (*C->I++)
1868
 
                {
1869
 
                case EXTERNAL_FUNCTION_DEFINITION:
1870
 
                        {
1871
 
                                slang_function *func;
 
1910
   /* parse individual functions and declarations */
 
1911
   while (*C->I != EXTERNAL_NULL) {
 
1912
      switch (*C->I++) {
 
1913
      case EXTERNAL_FUNCTION_DEFINITION:
 
1914
         {
 
1915
            slang_function *func;
1872
1916
 
1873
 
                                if (!parse_function (C, &o, 1, &func))
1874
 
                                        return 0;
1875
 
                        }
1876
 
                        break;
1877
 
                case EXTERNAL_DECLARATION:
1878
 
                        if (!parse_declaration (C, &o))
1879
 
                                return 0;
1880
 
                        break;
1881
 
                default:
1882
 
                        return 0;
1883
 
                }
1884
 
        }
1885
 
        C->I++;
1886
 
        return 1;
 
1917
            if (!parse_function(C, &o, 1, &func))
 
1918
               return 0;
 
1919
         }
 
1920
         break;
 
1921
      case EXTERNAL_DECLARATION:
 
1922
         if (!parse_declaration(C, &o))
 
1923
            return 0;
 
1924
         break;
 
1925
      default:
 
1926
         return 0;
 
1927
      }
 
1928
   }
 
1929
   C->I++;
 
1930
   return 1;
1887
1931
}
1888
1932
 
1889
1933
static GLboolean
1890
 
compile_binary (const byte *prod, slang_code_unit *unit, slang_unit_type type,
1891
 
                slang_info_log *infolog, slang_code_unit *builtin, slang_code_unit *downlink)
 
1934
compile_binary(const byte * prod, slang_code_unit * unit,
 
1935
               slang_unit_type type, slang_info_log * infolog,
 
1936
               slang_code_unit * builtin, slang_code_unit * downlink)
1892
1937
{
1893
1938
   slang_parse_ctx C;
1894
1939
 
1901
1946
   C.global_scope = GL_TRUE;
1902
1947
   C.atoms = &unit->object->atompool;
1903
1948
 
1904
 
   if (!check_revision (&C))
 
1949
   if (!check_revision(&C))
1905
1950
      return GL_FALSE;
1906
1951
 
1907
1952
   if (downlink != NULL) {
1911
1956
   }
1912
1957
 
1913
1958
   /* parse translation unit */
1914
 
   return parse_code_unit (&C, unit);
 
1959
   return parse_code_unit(&C, unit);
1915
1960
}
1916
1961
 
1917
1962
static GLboolean
1918
 
compile_with_grammar (grammar id, const char *source, slang_code_unit *unit, slang_unit_type type,
1919
 
                      slang_info_log *infolog, slang_code_unit *builtin)
 
1963
compile_with_grammar(grammar id, const char *source, slang_code_unit * unit,
 
1964
                     slang_unit_type type, slang_info_log * infolog,
 
1965
                     slang_code_unit * builtin)
1920
1966
{
1921
 
        byte *prod;
 
1967
   byte *prod;
1922
1968
   GLuint size, start, version;
1923
 
 
1924
 
        /* retrieve version */
1925
 
   if (!_slang_preprocess_version (source, &version, &start, infolog))
1926
 
      return GL_FALSE;
1927
 
 
1928
 
        /* check the syntax and generate its binary representation */
1929
 
        if (!grammar_fast_check (id, (const byte *) source + start, &prod, &size, 65536))
1930
 
        {
1931
 
                char buf[1024];
1932
 
                unsigned int pos;
1933
 
                grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos);
1934
 
      slang_info_log_error (infolog, buf);
1935
 
      return GL_FALSE;
1936
 
        }
1937
 
 
1938
 
        /* syntax is okay - translate it to internal representation */
1939
 
   if (!compile_binary (prod, unit, type, infolog, builtin, &builtin[SLANG_BUILTIN_TOTAL - 1])) {
1940
 
      grammar_alloc_free (prod);
1941
 
      return GL_FALSE;
1942
 
   }
1943
 
 
1944
 
   grammar_alloc_free (prod);
 
1969
   slang_string preprocessed;
 
1970
 
 
1971
   /* First retrieve the version number. */
 
1972
   if (!_slang_preprocess_version(source, &version, &start, infolog))
 
1973
      return GL_FALSE;
 
1974
 
 
1975
   if (version > 110) {
 
1976
      slang_info_log_error(infolog,
 
1977
                           "language version specified is not supported.");
 
1978
      return GL_FALSE;
 
1979
   }
 
1980
 
 
1981
   /* Now preprocess the source string. */
 
1982
   slang_string_init(&preprocessed);
 
1983
   if (!_slang_preprocess_directives(&preprocessed, &source[start], infolog)) {
 
1984
      slang_string_free(&preprocessed);
 
1985
      slang_info_log_error(infolog, "failed to preprocess the source.");
 
1986
      return GL_FALSE;
 
1987
   }
 
1988
 
 
1989
   /* Finally check the syntax and generate its binary representation. */
 
1990
   if (!grammar_fast_check
 
1991
       (id, (const byte *) (slang_string_cstr(&preprocessed)), &prod, &size,
 
1992
        65536)) {
 
1993
      char buf[1024];
 
1994
      GLint pos;
 
1995
 
 
1996
      slang_string_free(&preprocessed);
 
1997
      grammar_get_last_error((byte *) (buf), sizeof(buf), &pos);
 
1998
      slang_info_log_error(infolog, buf);
 
1999
      return GL_FALSE;
 
2000
   }
 
2001
   slang_string_free(&preprocessed);
 
2002
 
 
2003
   /* Syntax is okay - translate it to internal representation. */
 
2004
   if (!compile_binary
 
2005
       (prod, unit, type, infolog, builtin,
 
2006
        &builtin[SLANG_BUILTIN_TOTAL - 1])) {
 
2007
      grammar_alloc_free(prod);
 
2008
      return GL_FALSE;
 
2009
   }
 
2010
   grammar_alloc_free(prod);
1945
2011
   return GL_TRUE;
1946
2012
}
1947
2013
 
1948
 
static const char *slang_shader_syn =
 
2014
LONGSTRING static const char *slang_shader_syn =
1949
2015
#include "library/slang_shader_syn.h"
1950
 
;
 
2016
   ;
1951
2017
 
1952
2018
static const byte slang_core_gc[] = {
1953
2019
#include "library/slang_core_gc.h"
1972
2038
#endif
1973
2039
 
1974
2040
static GLboolean
1975
 
compile_object (grammar *id, const char *source, slang_code_object *object, slang_unit_type type,
1976
 
                slang_info_log *infolog)
 
2041
compile_object(grammar * id, const char *source, slang_code_object * object,
 
2042
               slang_unit_type type, slang_info_log * infolog)
1977
2043
{
1978
2044
   slang_code_unit *builtins = NULL;
1979
2045
 
1980
2046
   /* load GLSL grammar */
1981
 
        *id = grammar_load_from_text ((const byte *) (slang_shader_syn));
1982
 
        if (*id == 0)
1983
 
        {
1984
 
                byte buf[1024];
1985
 
                int pos;
 
2047
   *id = grammar_load_from_text((const byte *) (slang_shader_syn));
 
2048
   if (*id == 0) {
 
2049
      byte buf[1024];
 
2050
      int pos;
1986
2051
 
1987
 
                grammar_get_last_error (buf, 1024, &pos);
1988
 
      slang_info_log_error (infolog, (const char *) (buf));
 
2052
      grammar_get_last_error(buf, 1024, &pos);
 
2053
      slang_info_log_error(infolog, (const char *) (buf));
1989
2054
      return GL_FALSE;
1990
 
        }
1991
 
 
1992
 
        /* set shader type - the syntax is slightly different for different shaders */
1993
 
        if (type == slang_unit_fragment_shader || type == slang_unit_fragment_builtin)
1994
 
                grammar_set_reg8 (*id, (const byte *) "shader_type", 1);
1995
 
        else
1996
 
                grammar_set_reg8 (*id, (const byte *) "shader_type", 2);
1997
 
 
1998
 
        /* enable language extensions */
1999
 
        grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 1);
2000
 
 
2001
 
        /* if parsing user-specified shader, load built-in library */
2002
 
        if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)
2003
 
        {
2004
 
                /* compile core functionality first */
2005
 
      if (!compile_binary (slang_core_gc, &object->builtin[SLANG_BUILTIN_CORE],
2006
 
                           slang_unit_fragment_builtin, infolog, NULL, NULL))
2007
 
         return GL_FALSE;
2008
 
 
2009
 
                /* compile common functions and variables, link to core */
2010
 
      if (!compile_binary (slang_common_builtin_gc, &object->builtin[SLANG_BUILTIN_COMMON],
2011
 
                           slang_unit_fragment_builtin, infolog, NULL,
2012
 
                           &object->builtin[SLANG_BUILTIN_CORE]))
2013
 
         return GL_FALSE;
2014
 
 
2015
 
                /* compile target-specific functions and variables, link to common */
2016
 
                if (type == slang_unit_fragment_shader)
2017
 
                {
2018
 
         if (!compile_binary (slang_fragment_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET],
2019
 
                              slang_unit_fragment_builtin, infolog, NULL,
2020
 
                              &object->builtin[SLANG_BUILTIN_COMMON]))
2021
 
            return GL_FALSE;
2022
 
                }
2023
 
                else if (type == slang_unit_vertex_shader)
2024
 
                {
2025
 
         if (!compile_binary (slang_vertex_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET],
2026
 
                              slang_unit_vertex_builtin, infolog, NULL,
2027
 
                              &object->builtin[SLANG_BUILTIN_COMMON]))
2028
 
            return GL_FALSE;
2029
 
                }
 
2055
   }
 
2056
 
 
2057
   /* set shader type - the syntax is slightly different for different shaders */
 
2058
   if (type == slang_unit_fragment_shader
 
2059
       || type == slang_unit_fragment_builtin)
 
2060
      grammar_set_reg8(*id, (const byte *) "shader_type", 1);
 
2061
   else
 
2062
      grammar_set_reg8(*id, (const byte *) "shader_type", 2);
 
2063
 
 
2064
   /* enable language extensions */
 
2065
   grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1);
 
2066
 
 
2067
   /* if parsing user-specified shader, load built-in library */
 
2068
   if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) {
 
2069
      /* compile core functionality first */
 
2070
      if (!compile_binary(slang_core_gc, &object->builtin[SLANG_BUILTIN_CORE],
 
2071
                          slang_unit_fragment_builtin, infolog, NULL, NULL))
 
2072
         return GL_FALSE;
 
2073
 
 
2074
      /* compile common functions and variables, link to core */
 
2075
      if (!compile_binary
 
2076
          (slang_common_builtin_gc, &object->builtin[SLANG_BUILTIN_COMMON],
 
2077
           slang_unit_fragment_builtin, infolog, NULL,
 
2078
           &object->builtin[SLANG_BUILTIN_CORE]))
 
2079
         return GL_FALSE;
 
2080
 
 
2081
      /* compile target-specific functions and variables, link to common */
 
2082
      if (type == slang_unit_fragment_shader) {
 
2083
         if (!compile_binary
 
2084
             (slang_fragment_builtin_gc,
 
2085
              &object->builtin[SLANG_BUILTIN_TARGET],
 
2086
              slang_unit_fragment_builtin, infolog, NULL,
 
2087
              &object->builtin[SLANG_BUILTIN_COMMON]))
 
2088
            return GL_FALSE;
 
2089
      }
 
2090
      else if (type == slang_unit_vertex_shader) {
 
2091
         if (!compile_binary
 
2092
             (slang_vertex_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET],
 
2093
              slang_unit_vertex_builtin, infolog, NULL,
 
2094
              &object->builtin[SLANG_BUILTIN_COMMON]))
 
2095
            return GL_FALSE;
 
2096
      }
2030
2097
 
2031
2098
#if defined(USE_X86_ASM) || defined(SLANG_X86)
2032
2099
      /* compile x86 4-component vector overrides, link to target */
2033
 
      if (!compile_binary (slang_builtin_vec4_gc, &object->builtin[SLANG_BUILTIN_VEC4],
2034
 
                           slang_unit_fragment_builtin, infolog, NULL,
2035
 
                           &object->builtin[SLANG_BUILTIN_TARGET]))
 
2100
      if (!compile_binary
 
2101
          (slang_builtin_vec4_gc, &object->builtin[SLANG_BUILTIN_VEC4],
 
2102
           slang_unit_fragment_builtin, infolog, NULL,
 
2103
           &object->builtin[SLANG_BUILTIN_TARGET]))
2036
2104
         return GL_FALSE;
2037
2105
#endif
2038
2106
 
2039
 
                /* disable language extensions */
2040
 
                grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 0);
 
2107
      /* disable language extensions */
 
2108
      grammar_set_reg8(*id, (const byte *) "parsing_builtin", 0);
2041
2109
      builtins = object->builtin;
2042
 
        }
 
2110
   }
2043
2111
 
2044
 
        /* compile the actual shader - pass-in built-in library for external shader */
2045
 
   return compile_with_grammar (*id, source, &object->unit, type, infolog, builtins);
 
2112
   /* compile the actual shader - pass-in built-in library for external shader */
 
2113
   return compile_with_grammar(*id, source, &object->unit, type, infolog,
 
2114
                               builtins);
2046
2115
}
2047
2116
 
2048
2117
GLboolean
2049
 
_slang_compile (const char *source, slang_code_object *object, slang_unit_type type,
2050
 
                slang_info_log *infolog)
 
2118
_slang_compile(const char *source, slang_code_object * object,
 
2119
               slang_unit_type type, slang_info_log * infolog)
2051
2120
{
2052
2121
   GLboolean success;
2053
2122
   grammar id = 0;
2054
2123
 
2055
 
   _slang_code_object_dtr (object);
2056
 
   _slang_code_object_ctr (object);
 
2124
   _slang_code_object_dtr(object);
 
2125
   _slang_code_object_ctr(object);
2057
2126
 
2058
 
   success = compile_object (&id, source, object, type, infolog);
 
2127
   success = compile_object(&id, source, object, type, infolog);
2059
2128
   if (id != 0)
2060
 
      grammar_destroy (id);
 
2129
      grammar_destroy(id);
2061
2130
   if (!success)
2062
2131
      return GL_FALSE;
2063
2132
 
2064
 
   if (!_slang_build_export_data_table (&object->expdata, &object->unit.vars))
 
2133
   if (!_slang_build_export_data_table(&object->expdata, &object->unit.vars))
2065
2134
      return GL_FALSE;
2066
 
   if (!_slang_build_export_code_table (&object->expcode, &object->unit.funs, &object->unit))
 
2135
   if (!_slang_build_export_code_table
 
2136
       (&object->expcode, &object->unit.funs, &object->unit))
2067
2137
      return GL_FALSE;
2068
2138
 
2069
2139
#if defined(USE_X86_ASM) || defined(SLANG_X86)
2070
2140
   /* XXX: lookup the @main label */
2071
 
   if (!_slang_x86_codegen (&object->machine, &object->assembly, object->expcode.entries[0].address))
 
2141
   if (!_slang_x86_codegen
 
2142
       (&object->machine, &object->assembly,
 
2143
        object->expcode.entries[0].address))
2072
2144
      return GL_FALSE;
2073
2145
#endif
2074
2146
 
2075
2147
   return GL_TRUE;
2076
2148
}
2077