1 %{
2 //////////////////////////////////////////////////////////////////////
3 //
4 //                             Pixie
5 //
6 // Copyright � 1999 - 2003, Okan Arikan
7 //
8 // Contact: okan@cs.utexas.edu
9 //
10 //	This library is free software; you can redistribute it and/or
11 //	modify it under the terms of the GNU Lesser General Public
12 //	License as published by the Free Software Foundation; either
13 //	version 2.1 of the License, or (at your option) any later version.
14 //
15 //	This library is distributed in the hope that it will be useful,
16 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
17 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 //	Lesser General Public License for more details.
19 //
20 //	You should have received a copy of the GNU Lesser General Public
21 //	License along with this library; if not, write to the Free Software
22 //	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 //
24 ///////////////////////////////////////////////////////////////////////
25 ///////////////////////////////////////////////////////////////////////
26 //
27 //  File				:	sl.y
28 //  Classes				:	-
29 //  Description			:	This is the parser file for CShader
30 //
31 ////////////////////////////////////////////////////////////////////////
32 #undef alloca
33 #include <math.h>
34 #include <string.h>
35 
36 #include "common/global.h"
37 #include "common/containers.h"
38 #include "shader.h"
39 #include "slcode.h"
40 #include "error.h"
41 #include "renderer.h"
42 #include "dso.h"
43 #include "ri_config.h"
44 
45 /////////////////////////////////////////////////////////////////////////////////////
46 //   First some temporary data structures used during the script parsing
47 
48 
49 // Some forward definitions
50 		void							slerror(const char *);		// Forward definition for stupid yacc
51 		int								sllex(void );				// Forward definition for stupid yacc
52 
53 		const	char					*initLabel	=	"#!Init";	// The label for the init
54 		const	char					*codeLabel	=	"#!Code";	// The label for the code
55 
56 typedef struct TSlVariable {
57 	char			name[64];
58 	int				index;
59 	int				multiplicity;
60 	EVariableType	type;
61 	EVariableClass	container;
62 	int				uniform;
63 	CVariable		*variable;
64 	TSlVariable		*next;
65 } TSlVariable;
66 
67 typedef struct TSlLabel {
68 	char			name[64];
69 	int				index;
70 	TArgument		*argument;
71 	TSlLabel		*next;
72 } TSlLabel;
73 
74 typedef struct {
75 	ESlCode			entryPoint;
76 	const char		*name;
77 	int				nargs;
78 	unsigned int	usedParameters;
79 } TSlOpcode;
80 
81 typedef struct {
82 	ESlCode			entryPoint;
83 	const char		*name;
84 	const char		*prototype;
85 	unsigned int	usedParameters;
86 } TSlFunction;
87 
88 #define	DEFOPCODE(name,text,nargs,expr_pre,expr,expr_update,expr_post,params)			{OPCODE_##name,text,nargs,params},
89 #define	DEFSHORTOPCODE(name,text,nargs,expr_pre,expr,expr_update,expr_post,params)		{OPCODE_##name,text,nargs,params},
90 #define	DEFLINKOPCODE(name,text,nargs)													{OPCODE_##name,text,nargs,0},
91 #define	DEFFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par)
92 #define	DEFLIGHTFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par)
93 #define	DESHORTFFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par)
94 #define	DEFLINKFUNC(name,text,prototype,par)
95 
96 static	TSlOpcode	opcodes[]	=	{
97 #include "scriptOpcodes.h"
98 {	OPCODE_NOP	,	NULL	,	0	}
99 };
100 
101 #undef DEFOPCODE
102 #undef DEFSHORTOPCODE
103 #undef DEFLINKOPCODE
104 #undef DEFFUNC
105 #undef DEFLIGHTFUNC
106 #undef DEFSHORTFUNC
107 #undef DEFLINKFUNC
108 
109 #define	DEFOPCODE(name,text,nargs,expr_pre,expr,expr_update,expr_post)
110 #define	DEFSHORTOPCODE(name,text,nargs,expr_pre,expr,expr_update,expr_post)
111 #define DEFLINKOPCODE(name,text,nargs)
112 #define	DEFFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par)			{FUNCTION_##name,text,prototype,par},
113 #define	DEFLIGHTFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par)		{FUNCTION_##name,text,prototype,par},
114 #define	DEFSHORTFUNC(name,text,prototype,expr_pre,expr,expr_update,expr_post,par)		{FUNCTION_##name,text,prototype,par},
115 #define	DEFLINKFUNC(name,text,prototype,par)											{FUNCTION_##name,text,prototype,par},
116 static	TSlFunction		functions[]	=	{
117 #include "scriptFunctions.h"
118 {	OPCODE_NOP	,	NULL	,	NULL	}
119 };
120 
121 
122 #undef DEFOPCODE
123 #undef DEFSHORTOPCODE
124 #undef DEFLINKOPCODE
125 #undef DEFFUNC
126 #undef DEFSHORTFUNC
127 #undef DEFLINKFUNC
128 
129 
130 		////////////////////////////////////////////////////////////////////////////////////////////////////
131 		//
132 		//	This structure holds the compiling context
133 		//
134 		//
135 		typedef struct {
136 				const char				*name;					// Name of the file being parsed
137 				int						passNumber;				// Current pass number (we make 2 passes)
138 				int						parsingInit;			// TRUE if we're parsing the init code
139 				int						numErrors;				// Number of errors encountered during parse
140 				int						accessorType;			// Accessor type for _interpolatable_ parameters
141 
142 				// Pass 1
143 				int						numCode;				// The number of code blocks
144 				int						numArgument;			// The number of argument blocks
145 				int						numConstants;			// The number of constants
146 				int						numVariables;			// The number of variables (local + parameters)
147 				int						numStrings;				// The number of strings
148 
149 				int						constantSize;			// Total size required by the constants
150 				int						varyingSize;			// Total size required by the variables
151 
152 				int						shaderType;				// Type of the shader
153 
154 				int						uniform;				// TRUE if the current expression is uniform
155 				int						opcodeUniform;			// TRUE if the opcode/function is uniform
156 
157 				// Pass 2
158 				EVariableType			currentParameterType;	// The type of the current parameter
159 				int						currentParameterMutable;// TRUE if the current parameter is global or writable
160 				EVariableClass			currentParameterClass;	// The container class of the current parameter
161 				int						currentConstant;
162 				int						currentVariable;
163 				int						currentString;
164 
165 				int						currentConstantSize;
166 				int						currentVaryingSize;
167 
168 				float					*currentArray;			// Array items go here as we read them
169 				char					**currentStringArray;	// If the array is string, we this pointer instead
170 				int						numArrayItemsRemaining;	// Number of array items we're still expecting to read
171 
172 				char					currentOpcode[64];		// Holds the opcode being parsed
173 				char					currentPrototype[64];	// Holds the prototype being parsed
174 				int						currentArgument;		// The current argument number
175 				unsigned int			usedParameters;			// Used parameters by this shader
176 				TCode					*currentOpcodePlace;	// Points to the code that should holds the opcode
177 				TArgument				*currentArgumentPlace;	// Points to the current argument that should hold the argument
178 
179 				int						codeEntryPoint;			// Indices in the code array for corresponding entry points
180 				int						initEntryPoint;
181 
182 				char					*memory;				// The memory base for the area that's allocated
183 				TCode					*code;					// Code blocks
184 				TArgument				*arguments;				// Argument blocks
185 				char					*constants;				// Constants blocks
186 				int						*varyingSizes;			// Holds the size of each varying in codes
187 				char					**strings;				// Strings defined
188 				void					**constantEntries;		// Where the constant entries are stored
189 
190 				TSlVariable				*definedVariables;		// List of defined variables
191 				TSlLabel				*labelReferences;		// List of label references
192 				TSlLabel				*labelDefinitions;		// List of label definitions
193 		} TShaderData;
194 
195 		TShaderData						currentData;
196 
197 									///////////////////////////////////////////////////////////////////////
198 									// Function				:	numComponents
199 									// Description			:	Returns the number of codes that a particular type takes
200 									// Return Value			:	Size in codes
201 									// Comments				:
numComponents(EVariableType type)202 		static	int					numComponents(EVariableType type) {
203 										switch(type) {
204 										case TYPE_FLOAT:
205 											return	1;
206 											break;
207 										case TYPE_COLOR:
208 											return	3;
209 											break;
210 										case TYPE_VECTOR:
211 											return	3;
212 											break;
213 										case TYPE_NORMAL:
214 											return	3;
215 											break;
216 										case TYPE_POINT:
217 											return	3;
218 											break;
219 										case TYPE_MATRIX:
220 											return	16;
221 											break;
222 										case TYPE_QUAD:
223 											return	4;
224 											break;
225 										case TYPE_DOUBLE:
226 											return	2;
227 											break;
228 										case TYPE_STRING:
229 											return	1;
230 											break;
231 										case TYPE_INTEGER:
232 											return	1;
233 											break;
234 										default:
235 											slerror("Unknown type (bug)");
236 											break;
237 										}
238 
239 										return 0;
240 									}
241 
242 
243 									///////////////////////////////////////////////////////////////////////
244 									// Function				:	newVariable
245 									// Description			:	Add a new variable/parameter
246 									// Return Value			:	The default area if available
247 									// Comments				:
newVariable(char * name,EVariableType type,int numItems,int parameter)248 		static	void				*newVariable(char *name,EVariableType type,int numItems,int parameter) {
249 										const int	numComp			=	numComponents(type);
250 
251 										switch(currentData.passNumber) {
252 										case 1:
253 											currentData.numVariables++;
254 											if (type == TYPE_STRING)
255 												currentData.varyingSize		+=	numItems*numComp*sizeof(char*);
256 											else
257 												currentData.varyingSize		+=	numItems*numComp*sizeof(float);
258 											break;
259 										case 2:
260 											{
261 												// Create a new variable
262 												TSlVariable	*cVariable	=	new TSlVariable;
263 
264 												strcpy(cVariable->name,name);
265 												cVariable->multiplicity	=	numItems;
266 												cVariable->type			=	type;
267 												cVariable->container	=	currentData.currentParameterClass;
268 												cVariable->uniform		=	currentData.uniform;
269 												cVariable->variable		=	NULL;
270 												cVariable->index		=	currentData.currentVariable;
271 
272 												if (type == TYPE_STRING)
273 													currentData.varyingSizes[currentData.currentVariable]	=	numItems*numComp*sizeof(char*);
274 												else
275 													currentData.varyingSizes[currentData.currentVariable]	=	numItems*numComp*sizeof(float);
276 
277 												if (cVariable->uniform)	currentData.varyingSizes[currentData.currentVariable]	=	-currentData.varyingSizes[currentData.currentVariable];
278 
279 												currentData.currentVariable++;
280 												if (type == TYPE_STRING)
281 													currentData.currentVaryingSize	+=	numItems*numComp*sizeof(char*);
282 												else
283 													currentData.currentVaryingSize	+=	numItems*numComp*sizeof(float);
284 
285 
286 												cVariable->next					=	currentData.definedVariables;
287 												currentData.definedVariables	=	cVariable;
288 
289 												// Here's the trick part ...
290 												// If this is a parameter, allocate a parameter entry and make sure it points to the right location
291 												if (parameter) {
292 													CVariable	*newVariable;
293 													CVariable	*gVariable;
294 
295 													newVariable					=	new CVariable;
296 													strcpy(newVariable->name,name);
297 													newVariable->type			=	type;
298 													newVariable->container		=	currentData.currentParameterClass;
299 													newVariable->numItems		=	numItems;
300 													newVariable->numFloats		=	numItems*numComp;
301 													newVariable->entry			=	cVariable->index;
302 													newVariable->usageMarker	=	0;
303 													newVariable->storage		=	currentData.currentParameterMutable	? STORAGE_MUTABLEPARAMETER : STORAGE_PARAMETER;
304 													if (type == TYPE_STRING) 	newVariable->defaultValue	=	new char*[numItems*numComp];
305 													else						newVariable->defaultValue	=	new float[numItems*numComp];
306 													newVariable->accessor		=	currentData.accessorType;
307 													newVariable->next			=	NULL;
308 													cVariable->variable			=	newVariable;
309 
310 													// Is this a global variable ?
311 													gVariable					=	CRenderer::retrieveVariable(name);
312 													if (gVariable != NULL)	{
313 														if (gVariable->storage == STORAGE_GLOBAL) {
314 															// If the variable is actually defined
315 
316 															if (newVariable->type == gVariable->type &&
317 																newVariable->numItems == gVariable->numItems &&
318 																newVariable->numFloats == gVariable->numFloats &&
319 																!(cVariable->uniform ^ ((gVariable->container == CONTAINER_UNIFORM) || (gVariable->container == CONTAINER_CONSTANT)))
320 																) {
321 
322 																// And it matchces the current definition
323 
324 																newVariable->storage						=	STORAGE_GLOBAL;
325 																currentData.varyingSizes[cVariable->index]	=	0;		// It takes up no space in the cache
326 
327 																// Note: the variable index will be re-pointed at the global when init is run
328 															}
329 															/*else {
330 																// This mismatches the predeclared variable.  Issue warning, and continue
331 																warning(CODE_CONSISTENCY,"Parameter \"%s\" in shader \"%s\" mismatches predeclared variable\n",gVariable->name,currentData.name);
332 															}*/
333 														}
334 													} //If so, then lets ensure we don't delete it by taking a copy
335 
336 													return	newVariable->defaultValue;
337 												}
338 											}
339 											break;
340 										default:
341 											break;
342 										}
343 
344 										return NULL;
345 									}
346 
347 									///////////////////////////////////////////////////////////////////////
348 									// Function				:	addStringReference
349 									// Description			:	Add a reference to a string
350 									// Return Value			:	-
351 									// Comments				:
addStringReference(char ** items,int numItems)352 		static	void				addStringReference(char **items,int numItems) {
353 										int	i;
354 
355 										switch(currentData.passNumber) {
356 										case 1:
357 											currentData.numArgument		+=	1;							// Add one argument
358 											currentData.numConstants	+=	1;							// We have one more constant
359 											currentData.numStrings		+=	numItems;					// Reserve numItems strings
360 											currentData.constantSize	+=	numItems*sizeof(char *);	// This is the final constant size we consume
361 											break;
362 										case 2:
363 											assert(currentData.currentConstant < 65535);
364 
365 											char	**dest;
366 
367 											currentData.currentArgumentPlace->numItems									=	numItems;
368 											currentData.currentArgumentPlace->bytesPerItem								=	sizeof(char *);
369 											currentData.currentArgumentPlace->index										=	(unsigned short) currentData.currentConstant;
370 											currentData.currentArgumentPlace->accessor									=	SL_IMMEDIATE_OPERAND;
371 											currentData.currentArgumentPlace->varyingStep								=	0;
372 											currentData.constantEntries[currentData.currentConstant]					=	currentData.constants + currentData.currentConstantSize;
373 											dest																		=	(char **) currentData.constantEntries[currentData.currentConstant];
374 											currentData.currentConstant++;
375 											currentData.currentArgumentPlace++;
376 											currentData.currentArgument++;
377 											currentData.currentConstantSize	+=	numItems*sizeof(char *);
378 
379 											// Acturally record the strings
380 											for (i=0;i<numItems;i++)
381 												dest[i]	=	currentData.strings[currentData.currentString++]	=	strdup(items[i]);
382 
383 											break;
384 										default:
385 											break;
386 										}
387 									}
388 
389 
390 									///////////////////////////////////////////////////////////////////////
391 									// Function				:	addFloatReference
392 									// Description			:	Add a reference to a float
393 									// Return Value			:	-
394 									// Comments				:
addFloatReference(float * items,int numItems)395 		static	void				addFloatReference(float *items,int numItems) {
396 										int	i;
397 										switch(currentData.passNumber) {
398 											case 1:
399 												currentData.numArgument		+=	1;
400 												currentData.numConstants	+=	1;
401 												currentData.constantSize	+=	numItems*sizeof(float);
402 												break;
403 											case 2:
404 												assert(currentData.currentConstant < 65536);
405 
406 												float	*dest;
407 
408 												currentData.currentArgumentPlace->numItems						=	numItems;
409 												currentData.currentArgumentPlace->bytesPerItem					=	sizeof(float);
410 												currentData.currentArgumentPlace->index							=	(unsigned short) currentData.currentConstant;
411 												currentData.currentArgumentPlace->accessor						=	SL_IMMEDIATE_OPERAND;
412 												currentData.currentArgumentPlace->varyingStep					=	0;
413 												currentData.constantEntries[currentData.currentConstant]		=	currentData.constants + currentData.currentConstantSize;
414 												dest															=	(float *) currentData.constantEntries[currentData.currentConstant];
415 												currentData.currentConstant++;
416 												currentData.currentArgumentPlace++;
417 												currentData.currentArgument++;
418 												currentData.currentConstantSize	+=	numItems*sizeof(float);
419 
420 												for (i=0;i<numItems;i++) dest[i]	=	items[i];
421 
422 												break;
423 											default:
424 												break;
425 											}
426 										}
427 
428 										///////////////////////////////////////////////////////////////////////
429 										// Function				:	addVariableReference
430 										// Description			:	Add a reference to a variable/parameter
431 										// Return Value			:	-
432 										// Comments				:
addVariableReference(char * name)433 		static	void					addVariableReference(char *name) {
434 											CVariable		*var;
435 											TSlVariable		*cVariable;
436 
437 											switch(currentData.passNumber) {
438 											case 1:
439 												currentData.numArgument	+=	1;
440 												break;
441 											case 2:
442 												currentData.currentArgument++;
443 
444 												// Search the variables
445 												for (cVariable=currentData.definedVariables;cVariable!=NULL;cVariable=cVariable->next) {
446 													if (strcmp(cVariable->name,name) == 0) {
447 
448 														// If this is a global parameter, let the next section deal with it
449 														if (cVariable->variable) {
450 															// in init, we treat the global as a parameter, but in the init phase, it's a local varying
451 															if ((cVariable->variable->storage == STORAGE_GLOBAL) && !currentData.parsingInit) continue;
452 														}
453 
454 														assert(cVariable->index < 65536);
455 														assert((cVariable->multiplicity*numComponents(cVariable->type)) < 256);
456 
457 														currentData.currentArgumentPlace->index			=	(unsigned short) cVariable->index;
458 														currentData.currentArgumentPlace->numItems		=	(char) (cVariable->multiplicity*numComponents(cVariable->type));
459 														currentData.currentArgumentPlace->bytesPerItem	=	(cVariable->type == TYPE_STRING ? sizeof(char *) : sizeof(float));
460 														currentData.currentArgumentPlace->accessor		=	SL_VARYING_OPERAND;
461 														currentData.currentArgumentPlace->varyingStep	=	(cVariable->uniform ? 0 : currentData.currentArgumentPlace->numItems);
462 														currentData.currentArgumentPlace++;
463 
464 														if (cVariable->uniform == FALSE)
465 															currentData.opcodeUniform									=	FALSE;
466 
467 														return;
468 													}
469 												}
470 
471 												var	=	CRenderer::retrieveVariable(name);
472 
473 												if (var != NULL) {
474 													currentData.usedParameters										|=	var->usageMarker;
475 
476 													assert(var->entry < 65536);
477 													assert(var->numFloats < 256);
478 
479 													currentData.currentArgumentPlace->index			=	(unsigned short) var->entry;
480 													currentData.currentArgumentPlace->numItems		=	(char) var->numFloats;
481 													currentData.currentArgumentPlace->bytesPerItem	=	(var->type == TYPE_STRING ? sizeof(char *) : sizeof(float));
482 													currentData.currentArgumentPlace->accessor		=	SL_GLOBAL_OPERAND;
483 
484 													if ((var->container != CONTAINER_UNIFORM) || (var->container != CONTAINER_CONSTANT)) {
485 														currentData.opcodeUniform						=	FALSE;
486 														currentData.currentArgumentPlace->varyingStep	=	currentData.currentArgumentPlace->numItems;
487 													} else {
488 														currentData.currentArgumentPlace->varyingStep	=	0;
489 													}
490 
491 													currentData.currentArgumentPlace++;
492 												} else {
493 													slerror("Unknown variable");
494 												}
495 
496 												break;
497 											default:
498 												break;
499 											}
500 										}
501 
502 										///////////////////////////////////////////////////////////////////////
503 										// Function				:	setOpcode
504 										// Description			:	Find/Set an opcode/function
505 										// Return Value			:	-
506 										// Comments				:
setOpcode()507 		static	void					setOpcode() {
508 											switch(currentData.passNumber) {
509 											case 1:
510 												break;
511 											case 2:
512 												// Is this an opcode or function
513 												if (currentData.currentPrototype[0] == '~') {
514 													ESlCode	opcode;
515 													int		i;
516 
517 													for(i=0;opcodes[i].name != NULL;i++) {
518 														if (strcmp(opcodes[i].name,currentData.currentOpcode) == 0)
519 															if (opcodes[i].nargs == currentData.currentArgument) {
520 																opcode	=	opcodes[i].entryPoint;
521 																break;
522 															}
523 													}
524 
525 													if (opcodes[i].name == NULL)
526 														slerror("Unknown opcode");
527 													else {
528 														assert((currentData.currentArgument+2) < 256);
529 														assert((currentData.opcodeUniform) < 256);
530 
531 														// Save the opcode
532 														currentData.usedParameters						|=	opcodes[i].usedParameters;
533 														currentData.currentOpcodePlace->opcode			=	(int) opcode;
534 														currentData.currentOpcodePlace->numArguments	=	(unsigned char) (currentData.currentArgument);
535 														currentData.currentOpcodePlace->uniform			=	(unsigned char) (currentData.opcodeUniform);
536 														currentData.currentOpcodePlace++;
537 													}
538 												} else {
539 													int			i;
540 													ESlCode		opcode;
541 
542 													for(i=0;functions[i].name != NULL;i++) {
543 														if (strcmp(functions[i].name,currentData.currentOpcode) == 0) {
544 															if (strcmp(functions[i].prototype,currentData.currentPrototype) == 0) {
545 																currentData.usedParameters	|=	functions[i].usedParameters;
546 																opcode						=	functions[i].entryPoint;
547 																break;
548 															} else {
549 																// Do a pattern match
550 
551 
552 																// The return types must match exactly
553 																if (functions[i].prototype[0] != currentData.currentPrototype[0]) continue;
554 
555 																{
556 																	int		j,k,t;
557 
558 																	t	=	FALSE;
559 
560 																	for (j=2,k=2;(currentData.currentPrototype[j] != '\0') && (functions[i].prototype[k] != '\0');j++,k++) {
561 																		// Do the current parameters match
562 																		if (currentData.currentPrototype[j] == functions[i].prototype[k]) continue;
563 																		// Does the function match any parameter ?
564 																		else if (functions[i].prototype[k] == '.') continue;
565 																		// Is the current parameter a * or + ?
566 																		else if ((functions[i].prototype[k] == '+') || (functions[i].prototype[k] == '*')) {
567 																			k-=2;
568 																			j--;
569 																			continue;
570 																		// Is the current parameter a parameter list ?
571 																		} else if (functions[i].prototype[k] == '!') {
572 																			if ((currentData.currentPrototype[j] == 's') || (currentData.currentPrototype[j] == 'S')) {
573 																				j++;
574 																				k--;
575 																			} else {
576 																				t	=	TRUE;
577 																				break;
578 																			}
579 																		} else {
580 																			t	=	TRUE;
581 																			break;
582 																		}
583 																	}
584 
585 
586 																	if (t == FALSE) {
587 																		if (
588 																				((functions[i].prototype[k] == '\0') && (currentData.currentPrototype[j] == '\0')) ||
589 																				((functions[i].prototype[k] == '+') || (functions[i].prototype[k] == '*')) ||
590 																				(functions[i].prototype[k] == '!') ||
591 																				(functions[i].prototype[k+1] == '*')) {
592 																			// We found our function/opcode
593 																			currentData.usedParameters	|=	functions[i].usedParameters;
594 																			opcode	=	functions[i].entryPoint;
595 																			break;
596 																		} else {
597 																			continue;
598 																		}
599 																	}
600 																}
601 															}
602 														}
603 													}
604 
605 													// Save the opcode
606 													if (functions[i].name != NULL) {
607 														assert((currentData.currentArgument+2) < 256);
608 														assert(currentData.opcodeUniform < 256);
609 
610 														currentData.currentOpcodePlace->opcode				=	(int) opcode;
611 														currentData.currentOpcodePlace->numArguments		=	(unsigned char) (currentData.currentArgument);
612 														currentData.currentOpcodePlace->uniform				=	(unsigned char) (currentData.opcodeUniform);
613 														currentData.currentOpcodePlace++;
614 													} else {
615 														// Allright, we could not find the function, check the DSO shaders
616 														CDSO	*dso;
617 
618 														// See if this is a DSO function
619 														if ((dso = CRenderer::getDSO(currentData.currentOpcode,currentData.currentPrototype)) != NULL) {
620 
621 															// We have the DSO
622 															if (currentData.currentPrototype[0] == 'o')		currentData.currentOpcodePlace->opcode	=	FUNCTION_DSO_VOID;
623 															else											currentData.currentOpcodePlace->opcode	=	FUNCTION_DSO;
624 
625 															currentData.currentOpcodePlace->numArguments	=	(unsigned char) (currentData.currentArgument);
626 															currentData.currentOpcodePlace->uniform			=	(unsigned char) (currentData.opcodeUniform);
627 															currentData.currentOpcodePlace->dso				=	dso;
628 															currentData.currentOpcodePlace++;
629 														} else {
630 															slerror("Unknown function");
631 														}
632 													}
633 												}
634 												break;
635 											default:
636 												break;
637 											}
638 										}
639 
640 
641 									///////////////////////////////////////////////////////////////////////
642 									// Function				:	newLabel
643 									// Description			:	Create a new label definition/reference
644 									// Return Value			:	-
645 									// Comments				:
newLabel(const char * name,int reference)646 		static	void				newLabel(const char *name,int reference) {
647 										switch(currentData.passNumber) {
648 										case 1:
649 											if (reference)
650 												currentData.numArgument++;
651 											break;
652 										case 2:
653 											{
654 												TSlLabel	*cLabel	=	new TSlLabel;
655 
656 												strcpy(cLabel->name,name);
657 												cLabel->index	=	(int) (currentData.currentOpcodePlace - currentData.code);
658 
659 												if (reference) {
660 													cLabel->next					=	currentData.labelReferences;
661 													currentData.labelReferences		=	cLabel;
662 													cLabel->argument				=	currentData.currentArgumentPlace++;
663 													currentData.currentArgument++;
664 												} else {
665 													TSlLabel	*tLabel;
666 
667 													for (tLabel=currentData.labelDefinitions;tLabel!=NULL;tLabel=tLabel->next) {
668 														if (strcmp(tLabel->name,cLabel->name) == 0) {
669 															slerror("Duplicate label definition\n");
670 														}
671 													}
672 
673 													cLabel->argument				=	NULL;
674 													cLabel->next					=	currentData.labelDefinitions;
675 													currentData.labelDefinitions	=	cLabel;
676 												}
677 											}
678 											break;
679 										default:
680 											break;
681 										}
682 									}
683 
684 									// Some forward references
685 		void						reset();
686 		void						alloc();
687 		CShader						*shaderCreate(const char *);
688 		int							getVariable(char *);
689 		int							getOpcode(char *,int);
690 		int							getFunction(char *,char *,int *ps = NULL);
691 		void						*newVariable(char *,int,int,int,int m=1);
692 		TSlLabel					*newLabelDef(char *,int);
693 		TSlLabel					*newLabelRef(char *,int);
694 %}
695 %union slval {
696 	float	real;
697 	char	*string;
698 	matrix	m;
699 	vector	v;
700 }
701 
702 // Some tokens
703 %token	 SCRL_PARAMETERS
704 %token	 SCRL_VARIABLES
705 %token	 SCRL_OUTPUT
706 %token	 SCRL_VARYING
707 %token	 SCRL_UNIFORM
708 %token	 SCRL_FLOAT
709 %token	 SCRL_COLOR
710 %token	 SCRL_VECTOR
711 %token	 SCRL_NORMAL
712 %token	 SCRL_POINT
713 %token	 SCRL_MATRIX
714 %token	 SCRL_STRING
715 
716 %token	 SCRL_SURFACE
717 %token	 SCRL_DISPLACEMENT
718 %token	 SCRL_IMAGER
719 %token	 SCRL_LIGHTSOURCE
720 %token	 SCRL_VOLUME
721 %token	 SCRL_GENERIC
722 
723 %token	 SCRL_DSO
724 
725 %token	 SCRL_INIT
726 %token	 SCRL_CODE
727 
728 %token	 SCRL_DOT
729 %token	 SCRL_COLON
730 %token	 SCRL_EQUAL
731 %token	 SCRL_OPEN_PARANTHESIS
732 %token	 SCRL_CLOSE_PARANTHESIS
733 %token	 SCRL_OPEN_SQR_PARANTHESIS
734 %token	 SCRL_CLOSE_SQR_PARANTHESIS
735 %token	 SCRL_COMMA
736 %token   SCRL_NL
737 
738 %token<string>	SCRL_TEXT_VALUE
739 %token<string>	SCRL_IDENTIFIER_VALUE
740 %token<string>	SCRL_LABEL_VALUE
741 %token<real>	SCRL_FLOAT_VALUE
742 %type<v>		slVectorIn
743 %type<v>		slVector
744 %type<v>		slVectorValue
745 %%
746 start:
747 				slType
748 				slParameterDefinitions
749 				slVariableDefinitions
750 				slInit
751 				slCode
752 				slEmptySpace
753 				;
754 
755 slEmptySpace:
756 				|
757 				SCRL_NL
758 				slEmptySpace
759 				;
760 
761 slVectorIn:		SCRL_EQUAL
762 				SCRL_TEXT_VALUE
763 				SCRL_FLOAT_VALUE
764 				{
765 					$$[0]	=	$3;
766 					$$[1]	=	$3;
767 					$$[2]	=	$3;
768 				}
769 				|
770 				SCRL_EQUAL
771 				SCRL_TEXT_VALUE
772 				SCRL_OPEN_SQR_PARANTHESIS
773 				SCRL_FLOAT_VALUE
774 				SCRL_FLOAT_VALUE
775 				SCRL_FLOAT_VALUE
776 				SCRL_CLOSE_SQR_PARANTHESIS
777 				{
778 					$$[0]	=	$4;
779 					$$[1]	=	$5;
780 					$$[2]	=	$6;
781 				}
782 				|
783 				SCRL_EQUAL
784 				SCRL_FLOAT_VALUE
785 				{
786 					$$[0]	=	$2;
787 					$$[1]	=	$2;
788 					$$[2]	=	$2;
789 				}
790 				|
791 				SCRL_EQUAL
792 				SCRL_OPEN_SQR_PARANTHESIS
793 				SCRL_FLOAT_VALUE
794 				SCRL_FLOAT_VALUE
795 				SCRL_FLOAT_VALUE
796 				SCRL_CLOSE_SQR_PARANTHESIS
797 				{
798 					$$[0]	=	$3;
799 					$$[1]	=	$4;
800 					$$[2]	=	$5;
801 				}
802 				|
803 				{
804 					$$[0]	=	0;
805 					$$[1]	=	0;
806 					$$[2]	=	0;
807 				}
808 				;
809 
810 slVector:		slVectorIn
811 				{
812 					$$[0]	=	$1[0];
813 					$$[1]	=	$1[1];
814 					$$[2]	=	$1[2];
815 				}
816 				;
817 
818 slType:
819 				SCRL_SURFACE
820 				SCRL_NL
821 				{
822 					currentData.shaderType		=	SL_SURFACE;
823 					currentData.accessorType 	=	ACCESSOR_SURFACE;
824 				}
825 				|
826 				SCRL_DISPLACEMENT
827 				SCRL_NL
828 				{
829 					currentData.shaderType		=	SL_DISPLACEMENT;
830 					currentData.accessorType	=	ACCESSOR_DISPLACEMENT;
831 				}
832 				|
833 				SCRL_LIGHTSOURCE
834 				SCRL_NL
835 				{
836 					currentData.shaderType		=	SL_LIGHTSOURCE;
837 					// Note: we don't set accessorType because you can't interpolate into
838 					// light shader parameters
839 				}
840 				|
841 				SCRL_VOLUME
842 				SCRL_NL
843 				{
844 					currentData.shaderType		=	SL_ATMOSPHERE;
845 					currentData.accessorType	=	ACCESSOR_ATMOSPHERE;
846 					// Note: we can assume the accessor is atmosphere as that's the only
847 					// volume shader that can be interpolated into
848 				}
849 				|
850 				SCRL_IMAGER
851 				SCRL_NL
852 				{
853 					currentData.shaderType		=	SL_IMAGER;
854 				}
855 				;
856 
857 slParameterDefinitions:
858 				SCRL_PARAMETERS
859 				SCRL_COLON
860 				SCRL_NL
861 				slParameters
862 				;
863 
864 slParameters:
865 				slParameters
866 				slParameter
867 				SCRL_NL
868 				|
869 				;
870 
871 slContainer:
872 				SCRL_UNIFORM
873 				{
874 					currentData.currentParameterClass	=	CONTAINER_UNIFORM;
875 					currentData.currentParameterMutable	=	FALSE;
876 					currentData.uniform					=	TRUE;
877 				}
878 				|
879 				SCRL_VARYING
880 				{
881 					currentData.currentParameterClass	=	CONTAINER_VARYING;
882 					currentData.currentParameterMutable	=	FALSE;
883 					currentData.uniform					=	FALSE;
884 				}
885 				|
886 				SCRL_OUTPUT
887 				SCRL_UNIFORM
888 				{
889 					currentData.currentParameterClass	=	CONTAINER_UNIFORM;
890 					currentData.currentParameterMutable	=	TRUE;
891 					currentData.uniform					=	TRUE;
892 				}
893 				|
894 				SCRL_OUTPUT
895 				SCRL_VARYING
896 				{
897 					currentData.currentParameterClass	=	CONTAINER_VARYING;
898 					currentData.currentParameterMutable	=	TRUE;
899 					currentData.uniform					=	FALSE;
900 				}
901 				|
902 				SCRL_OUTPUT
903 				{
904 					currentData.currentParameterClass	=	CONTAINER_UNIFORM;
905 					currentData.currentParameterMutable	=	TRUE;
906 					currentData.uniform					=	TRUE;
907 				}
908 				|
909 				{
910 					currentData.currentParameterClass	=	CONTAINER_UNIFORM;
911 					currentData.currentParameterMutable	=	FALSE;
912 					currentData.uniform					=	TRUE;
913 				}
914 				;
915 
916 
917 slParameter:
918 				slContainer
919 				slAParameter
920 				;
921 
922 
923 slAParameter:
924 				slFloatParameter
925 				|
926 				slStringParameter
927 				|
928 				slColorParameter
929 				|
930 				slVectorParameter
931 				|
932 				slNormalParameter
933 				|
934 				slPointParameter
935 				|
936 				slMatrixParameter
937 				;
938 
939 
940 slFloatParameter:
941 				SCRL_FLOAT
942 				SCRL_IDENTIFIER_VALUE
943 				SCRL_EQUAL
944 				SCRL_FLOAT_VALUE
945 				{
946 					float	*def	=	(float *) newVariable($2,TYPE_FLOAT,1,TRUE);
947 
948 					if (def != NULL) {
949 						def[0]	=	$4;
950 					}
951 				}
952 				|
953 				SCRL_FLOAT
954 				SCRL_IDENTIFIER_VALUE
955 				{
956 					float	*def	=	(float *) newVariable($2,TYPE_FLOAT,1,TRUE);
957 
958 					if (def != NULL) {
959 						def[0]		=	0;
960 					}
961 				}
962 				|
963 				SCRL_FLOAT
964 				SCRL_IDENTIFIER_VALUE
965 				SCRL_OPEN_SQR_PARANTHESIS
966 				SCRL_FLOAT_VALUE
967 				SCRL_CLOSE_SQR_PARANTHESIS
968 				SCRL_EQUAL
969 				{
970 					float	*def	=	(float *) newVariable($2,TYPE_FLOAT,(int) $4,TRUE);
971 
972 					if (def != NULL) {
973 						int	i;
974 
975 						for (i=0;i<(int) $4;i++)
976 							def[i]	=	0;
977 
978 						currentData.currentArray = def;
979 					}
980 
981 					currentData.numArrayItemsRemaining = (int) $4;
982 				}
983 				slFloatArrayInitializer
984 				|
985 				SCRL_FLOAT
986 				SCRL_IDENTIFIER_VALUE
987 				SCRL_OPEN_SQR_PARANTHESIS
988 				SCRL_FLOAT_VALUE
989 				SCRL_CLOSE_SQR_PARANTHESIS
990 				{
991 					float	*def	=	(float *) newVariable($2,TYPE_FLOAT,(int) $4,TRUE);
992 
993 					if (def != NULL) {
994 						int	i;
995 
996 						for (i=0;i<(int) $4;i++)
997 							def[i]	=	0;
998 					}
999 				}
1000 				;
1001 
1002 
1003 slFloatArrayInitializer:
1004 				SCRL_OPEN_SQR_PARANTHESIS
1005 				slFloatArrayInitializerItems
1006 				SCRL_CLOSE_SQR_PARANTHESIS
1007 				{
1008 					if(currentData.numArrayItemsRemaining){
1009 						slerror("Wrong number of items in array initializer\n");
1010 					}
1011 				}
1012 				;
1013 
1014 slFloatArrayInitializerItems:
1015 				slFloatArrayInitializerItems
1016 				SCRL_FLOAT_VALUE
1017 				{
1018 					if(currentData.numArrayItemsRemaining > 0){
1019 						if(currentData.currentArray){
1020 							*currentData.currentArray++ = $2;
1021 						}
1022 						currentData.numArrayItemsRemaining--;
1023 					} else{
1024 						slerror("Wrong number of items in array initializer\n");
1025 					}
1026 				}
1027 				|
1028 				;
1029 
1030 
1031 slStringParameter:
1032 				SCRL_STRING
1033 				SCRL_IDENTIFIER_VALUE
1034 				{
1035 					char	**def	=	(char **) newVariable($2,TYPE_STRING,1,TRUE);
1036 
1037 					switch(currentData.passNumber) {
1038 					case 1:
1039 						currentData.numStrings++;
1040 						break;
1041 					case 2:
1042 						if (def != NULL) {
1043 							*def	=	currentData.strings[currentData.currentString++]	=	strdup("*");
1044 						}
1045 						break;
1046 					default:
1047 						break;
1048 					}
1049 				}
1050 				|
1051 				SCRL_STRING
1052 				SCRL_IDENTIFIER_VALUE
1053 				SCRL_EQUAL
1054 				SCRL_TEXT_VALUE
1055 				{
1056 					char	**def	=	(char **) newVariable($2,TYPE_STRING,1,TRUE);
1057 
1058 					switch(currentData.passNumber) {
1059 					case 1:
1060 						currentData.numStrings++;
1061 						break;
1062 					case 2:
1063 						if (def != NULL) {
1064 							*def	=	currentData.strings[currentData.currentString++]	=	strdup($4);
1065 						}
1066 						break;
1067 					default:
1068 						break;
1069 					}
1070 				}
1071 				|
1072 				SCRL_STRING
1073 				SCRL_IDENTIFIER_VALUE
1074 				SCRL_OPEN_SQR_PARANTHESIS
1075 				SCRL_FLOAT_VALUE
1076 				SCRL_CLOSE_SQR_PARANTHESIS
1077 				SCRL_EQUAL
1078 				{
1079 					char	**def	=	(char **) newVariable($2,TYPE_STRING,(int) $4,TRUE);
1080 
1081 					switch(currentData.passNumber) {
1082 					case 1:
1083 						currentData.numStrings += (int) $4;
1084 						break;
1085 					case 2:
1086 						if (def != NULL) {
1087 							int	i;
1088 
1089 							for (i=0;i<(int) $4;i++)
1090 								def[i]	=	NULL;
1091 
1092 							currentData.currentStringArray = def;
1093 						}
1094 						break;
1095 					default:
1096 						break;
1097 					}
1098 
1099 					currentData.numArrayItemsRemaining = (int) $4;
1100 				}
1101 				slStringArrayInitializer
1102 				|
1103 				SCRL_STRING
1104 				SCRL_IDENTIFIER_VALUE
1105 				SCRL_OPEN_SQR_PARANTHESIS
1106 				SCRL_FLOAT_VALUE
1107 				SCRL_CLOSE_SQR_PARANTHESIS
1108 				{
1109 					char	**def	=	(char **) newVariable($2,TYPE_STRING,(int) $4,TRUE);
1110 
1111 					if (def != NULL) {
1112 						int	i;
1113 
1114 						for (i=0;i<(int) $4;i++)
1115 							def[i]	=	NULL;
1116 					}
1117 				}
1118 
1119 slStringArrayInitializer:
1120 				SCRL_OPEN_SQR_PARANTHESIS
1121 				slStringArrayInitializerItems
1122 				SCRL_CLOSE_SQR_PARANTHESIS
1123 				{
1124 					if(currentData.numArrayItemsRemaining){
1125 						slerror("Wrong number of items in array initializer\n");
1126 					}
1127 				}
1128 				;
1129 
1130 slStringArrayInitializerItems:
1131 				slStringArrayInitializerItems
1132 				SCRL_TEXT_VALUE
1133 				{
1134 					if(currentData.numArrayItemsRemaining > 0){
1135 						if(currentData.currentArray){
1136 							*currentData.currentStringArray++	=	currentData.strings[currentData.currentString++]	=	strdup($2);
1137 						}
1138 						currentData.numArrayItemsRemaining--;
1139 					}
1140 					else{
1141 						slerror("Wrong number of items in array initializer\n");
1142 					}
1143 				}
1144 				|
1145 				;
1146 
1147 
1148 slColorParameter:
1149 				SCRL_COLOR
1150 				SCRL_IDENTIFIER_VALUE
1151 				{
1152 					currentData.currentParameterType	=	TYPE_COLOR;
1153 				}
1154 				slVector
1155 				{
1156 					float	*def	=	(float *) newVariable($2,currentData.currentParameterType,1,TRUE);
1157 
1158 					if (def != NULL) {
1159 						movvv(def,$4);
1160 					}
1161 				}
1162 				|
1163 				SCRL_COLOR
1164 				SCRL_IDENTIFIER_VALUE
1165 				SCRL_OPEN_SQR_PARANTHESIS
1166 				SCRL_FLOAT_VALUE
1167 				SCRL_CLOSE_SQR_PARANTHESIS
1168 				SCRL_EQUAL
1169 				{
1170 					float	*def	=	(float *) newVariable($2,TYPE_COLOR,(int) $4,TRUE);
1171 
1172 					if(def != NULL)
1173 						currentData.currentArray = def;
1174 					currentData.numArrayItemsRemaining = (int) $4;
1175 				}
1176 				slVectorArrayInitializer
1177 				|
1178 				SCRL_COLOR
1179 				SCRL_IDENTIFIER_VALUE
1180 				SCRL_OPEN_SQR_PARANTHESIS
1181 				SCRL_FLOAT_VALUE
1182 				SCRL_CLOSE_SQR_PARANTHESIS
1183 				{
1184 					float	*def	=	(float *) newVariable($2,TYPE_COLOR,(int) $4,TRUE);
1185 				}
1186 				;
1187 
1188 slVectorParameter:
1189 				SCRL_VECTOR
1190 				SCRL_IDENTIFIER_VALUE
1191 				{
1192 					currentData.currentParameterType	=	TYPE_VECTOR;
1193 				}
1194 				slVector
1195 				{
1196 					float	*def	=	(float *) newVariable($2,currentData.currentParameterType,1,TRUE);
1197 
1198 					if (def != NULL) {
1199 						movvv(def,$4);
1200 					}
1201 				}
1202 				|
1203 				SCRL_VECTOR
1204 				SCRL_IDENTIFIER_VALUE
1205 				SCRL_OPEN_SQR_PARANTHESIS
1206 				SCRL_FLOAT_VALUE
1207 				SCRL_CLOSE_SQR_PARANTHESIS
1208 				SCRL_EQUAL
1209 				{
1210 					float	*def	=	(float *) newVariable($2,TYPE_VECTOR,(int) $4,TRUE);
1211 
1212 					if(def != NULL) {
1213 						currentData.currentArray = def;
1214 					}
1215 
1216 					currentData.numArrayItemsRemaining = (int) $4;
1217 				}
1218 				slVectorArrayInitializer
1219 				|
1220 				SCRL_VECTOR
1221 				SCRL_IDENTIFIER_VALUE
1222 				SCRL_OPEN_SQR_PARANTHESIS
1223 				SCRL_FLOAT_VALUE
1224 				SCRL_CLOSE_SQR_PARANTHESIS
1225 				{
1226 					float	*def	=	(float *) newVariable($2,TYPE_VECTOR,(int) $4,TRUE);
1227 				}
1228 				;
1229 
1230 slNormalParameter:
1231 				SCRL_NORMAL
1232 				SCRL_IDENTIFIER_VALUE
1233 				{
1234 					currentData.currentParameterType	=	TYPE_NORMAL;
1235 				}
1236 				slVector
1237 				{
1238 					float	*def	=	(float *) newVariable($2,currentData.currentParameterType,1,TRUE);
1239 
1240 					if (def != NULL) {
1241 						movvv(def,$4);
1242 					}
1243 				}
1244 				|
1245 				SCRL_NORMAL
1246 				SCRL_IDENTIFIER_VALUE
1247 				SCRL_OPEN_SQR_PARANTHESIS
1248 				SCRL_FLOAT_VALUE
1249 				SCRL_CLOSE_SQR_PARANTHESIS
1250 				SCRL_EQUAL
1251 				{
1252 					float	*def	=	(float *) newVariable($2,TYPE_NORMAL,(int) $4,TRUE);
1253 
1254 					if(def != NULL) {
1255 						currentData.currentArray = def;
1256 					}
1257 
1258 					currentData.numArrayItemsRemaining = (int) $4;
1259 				}
1260 				slVectorArrayInitializer
1261 				|
1262 				SCRL_NORMAL
1263 				SCRL_IDENTIFIER_VALUE
1264 				SCRL_OPEN_SQR_PARANTHESIS
1265 				SCRL_FLOAT_VALUE
1266 				SCRL_CLOSE_SQR_PARANTHESIS
1267 				{
1268 					float	*def	=	(float *) newVariable($2,TYPE_NORMAL,(int) $4,TRUE);
1269 				}
1270 				;
1271 
1272 slPointParameter:
1273 				SCRL_POINT
1274 				SCRL_IDENTIFIER_VALUE
1275 				{
1276 					currentData.currentParameterType	=	TYPE_POINT;
1277 				}
1278 				slVector
1279 				{
1280 					float	*def	=	(float *)newVariable($2,currentData.currentParameterType,1,TRUE);
1281 
1282 					if (def != NULL) {
1283 						movvv(def,$4);
1284 					}
1285 				}
1286 				|
1287 				SCRL_POINT
1288 				SCRL_IDENTIFIER_VALUE
1289 				SCRL_OPEN_SQR_PARANTHESIS
1290 				SCRL_FLOAT_VALUE
1291 				SCRL_CLOSE_SQR_PARANTHESIS
1292 				SCRL_EQUAL
1293 				{
1294 					float	*def	=	(float *) newVariable($2,TYPE_POINT,(int) $4,TRUE);
1295 
1296 					if(def != NULL) {
1297 						currentData.currentArray = def;
1298 					}
1299 
1300 					currentData.numArrayItemsRemaining = (int) $4;
1301 				}
1302 				slVectorArrayInitializer
1303 				|
1304 				SCRL_POINT
1305 				SCRL_IDENTIFIER_VALUE
1306 				SCRL_OPEN_SQR_PARANTHESIS
1307 				SCRL_FLOAT_VALUE
1308 				SCRL_CLOSE_SQR_PARANTHESIS
1309 				{
1310 					float 	*def	=	(float *) newVariable($2,TYPE_POINT,(int) $4,TRUE);
1311 				}
1312 				;
1313 
1314 slVectorValue:	SCRL_TEXT_VALUE
1315 				SCRL_FLOAT_VALUE
1316 				{
1317 					$$[0]	=	$2;
1318 					$$[1]	=	$2;
1319 					$$[2]	=	$2;
1320 				}
1321 				|
1322 				SCRL_TEXT_VALUE
1323 				SCRL_OPEN_SQR_PARANTHESIS
1324 				SCRL_FLOAT_VALUE
1325 				SCRL_FLOAT_VALUE
1326 				SCRL_FLOAT_VALUE
1327 				SCRL_CLOSE_SQR_PARANTHESIS
1328 				{
1329 					$$[0]	=	$3;
1330 					$$[1]	=	$4;
1331 					$$[2]	=	$5;
1332 				}
1333 				|
1334 				SCRL_FLOAT_VALUE
1335 				{
1336 					$$[0]	=	$1;
1337 					$$[1]	=	$1;
1338 					$$[2]	=	$1;
1339 				}
1340 				|
1341 				SCRL_OPEN_SQR_PARANTHESIS
1342 				SCRL_FLOAT_VALUE
1343 				SCRL_FLOAT_VALUE
1344 				SCRL_FLOAT_VALUE
1345 				SCRL_CLOSE_SQR_PARANTHESIS
1346 				{
1347 					$$[0]	=	$2;
1348 					$$[1]	=	$3;
1349 					$$[2]	=	$4;
1350 				}
1351 				;
1352 
1353 
1354 slVectorArrayInitializer:
1355 				SCRL_OPEN_SQR_PARANTHESIS
1356 				slVectorArrayInitializerItems
1357 				SCRL_CLOSE_SQR_PARANTHESIS
1358 				{
1359 					if(currentData.numArrayItemsRemaining){
1360 						slerror("Wrong number of items in array initializer\n");
1361 					}
1362 				}
1363 				;
1364 
1365 slVectorArrayInitializerItems:
1366 				slVectorArrayInitializerItems
1367 				slVectorValue
1368 				{
1369 
1370 					if(currentData.numArrayItemsRemaining > 0){
1371 						if(currentData.currentArray){
1372 							movvv(currentData.currentArray,$2);
1373 							currentData.currentArray += 3;
1374 						}
1375 						currentData.numArrayItemsRemaining--;
1376 					} else{
1377 						slerror("Wrong number of items in array initializer\n");
1378 					}
1379 				}
1380 				|
1381 				;
1382 
1383 
1384 slMatrixParameter:
1385 				SCRL_MATRIX
1386 				SCRL_IDENTIFIER_VALUE
1387 				SCRL_EQUAL
1388 				SCRL_OPEN_SQR_PARANTHESIS
1389 				SCRL_FLOAT_VALUE
1390 				SCRL_FLOAT_VALUE
1391 				SCRL_FLOAT_VALUE
1392 				SCRL_FLOAT_VALUE
1393 				SCRL_FLOAT_VALUE
1394 				SCRL_FLOAT_VALUE
1395 				SCRL_FLOAT_VALUE
1396 				SCRL_FLOAT_VALUE
1397 				SCRL_FLOAT_VALUE
1398 				SCRL_FLOAT_VALUE
1399 				SCRL_FLOAT_VALUE
1400 				SCRL_FLOAT_VALUE
1401 				SCRL_FLOAT_VALUE
1402 				SCRL_FLOAT_VALUE
1403 				SCRL_FLOAT_VALUE
1404 				SCRL_FLOAT_VALUE
1405 				SCRL_CLOSE_SQR_PARANTHESIS
1406 				{
1407 					float	*def	=	(float *) newVariable($2,TYPE_MATRIX,1,TRUE);
1408 
1409 					if (def != NULL) {
1410 						def[0]		=	$5;
1411 						def[1]		=	$6;
1412 						def[2]		=	$7;
1413 						def[3]		=	$8;
1414 						def[4]		=	$9;
1415 						def[5]		=	$10;
1416 						def[6]		=	$11;
1417 						def[7]		=	$12;
1418 						def[8]		=	$13;
1419 						def[9]		=	$14;
1420 						def[10]		=	$15;
1421 						def[11]		=	$16;
1422 						def[12]		=	$17;
1423 						def[13]		=	$18;
1424 						def[14]		=	$19;
1425 						def[15]		=	$20;
1426 					}
1427 				}
1428 				|
1429 				SCRL_MATRIX
1430 				SCRL_IDENTIFIER_VALUE
1431 				SCRL_EQUAL
1432 				SCRL_FLOAT_VALUE
1433 				{
1434 					float	*def	=	(float *) newVariable($2,TYPE_MATRIX,1,TRUE);
1435 
1436 					if (def != NULL) {
1437 						def[0]		=	$4;
1438 						def[1]		=	0;
1439 						def[2]		=	0;
1440 						def[3]		=	0;
1441 						def[4]		=	0;
1442 						def[5]		=	$4;
1443 						def[6]		=	0;
1444 						def[7]		=	0;
1445 						def[8]		=	0;
1446 						def[9]		=	0;
1447 						def[10]		=	$4;
1448 						def[11]		=	0;
1449 						def[12]		=	0;
1450 						def[13]		=	0;
1451 						def[14]		=	0;
1452 						def[15]		=	1;
1453 					}
1454 				}
1455 				|
1456 				SCRL_MATRIX
1457 				SCRL_IDENTIFIER_VALUE
1458 				{
1459 					float	*def	=	(float *) newVariable($2,TYPE_MATRIX,1,TRUE);
1460 
1461 					if (def != NULL) {
1462 						def[0]		=	1;
1463 						def[1]		=	0;
1464 						def[2]		=	0;
1465 						def[3]		=	0;
1466 						def[4]		=	0;
1467 						def[5]		=	1;
1468 						def[6]		=	0;
1469 						def[7]		=	0;
1470 						def[8]		=	0;
1471 						def[9]		=	0;
1472 						def[10]		=	1;
1473 						def[11]		=	0;
1474 						def[12]		=	0;
1475 						def[13]		=	0;
1476 						def[14]		=	0;
1477 						def[15]		=	1;
1478 					}
1479 				}
1480 				|
1481 				SCRL_MATRIX
1482 				SCRL_IDENTIFIER_VALUE
1483 				SCRL_OPEN_SQR_PARANTHESIS
1484 				SCRL_FLOAT_VALUE
1485 				SCRL_CLOSE_SQR_PARANTHESIS
1486 				SCRL_EQUAL
1487 				{
1488 					float	*def	=	(float *) newVariable($2,TYPE_MATRIX,(int) $4,TRUE);
1489 
1490 					if (def != NULL) {
1491 						int	i;
1492 
1493 						for (i=0;i<((int) $4)*16;i++)
1494 							def[i]	=	0;
1495 
1496 						currentData.currentArray = def;
1497 					}
1498 
1499 					currentData.numArrayItemsRemaining = (int) $4;
1500 				}
1501 				slMatrixArrayInitializer
1502 				|
1503 				SCRL_MATRIX
1504 				SCRL_IDENTIFIER_VALUE
1505 				SCRL_OPEN_SQR_PARANTHESIS
1506 				SCRL_FLOAT_VALUE
1507 				SCRL_CLOSE_SQR_PARANTHESIS
1508 				{
1509 					float	*def	=	(float *) newVariable($2,TYPE_MATRIX,(int) $4,TRUE);
1510 
1511 					if (def != NULL) {
1512 						int	i;
1513 
1514 						for (i=0;i<((int) $4)*16;i++)
1515 							def[i]	=	0;
1516 					}
1517 				}
1518 				;
1519 
1520 
1521 slMatrixArrayInitializer:
1522 				SCRL_OPEN_SQR_PARANTHESIS
1523 				slMatrixArrayInitializerItems
1524 				SCRL_CLOSE_SQR_PARANTHESIS
1525 				{
1526 					if(currentData.numArrayItemsRemaining){
1527 						slerror("Wrong number of items in array initializer\n");
1528 					}
1529 				}
1530 				;
1531 
1532 slMatrixArrayInitializerItems:
1533 				slMatrixArrayInitializerItems
1534 				SCRL_OPEN_SQR_PARANTHESIS
1535 				SCRL_FLOAT_VALUE
1536 				SCRL_FLOAT_VALUE
1537 				SCRL_FLOAT_VALUE
1538 				SCRL_FLOAT_VALUE
1539 				SCRL_FLOAT_VALUE
1540 				SCRL_FLOAT_VALUE
1541 				SCRL_FLOAT_VALUE
1542 				SCRL_FLOAT_VALUE
1543 				SCRL_FLOAT_VALUE
1544 				SCRL_FLOAT_VALUE
1545 				SCRL_FLOAT_VALUE
1546 				SCRL_FLOAT_VALUE
1547 				SCRL_FLOAT_VALUE
1548 				SCRL_FLOAT_VALUE
1549 				SCRL_FLOAT_VALUE
1550 				SCRL_FLOAT_VALUE
1551 				SCRL_CLOSE_SQR_PARANTHESIS
1552 				{
1553 					if(currentData.numArrayItemsRemaining > 0){
1554 						if(currentData.currentArray){
1555 							currentData.currentArray[0] = $3;
1556 							currentData.currentArray[1] = $4;
1557 							currentData.currentArray[2] = $5;
1558 							currentData.currentArray[3] = $6;
1559 							currentData.currentArray[4] = $7;
1560 							currentData.currentArray[5] = $8;
1561 							currentData.currentArray[6] = $9;
1562 							currentData.currentArray[7] = $10;
1563 							currentData.currentArray[8] = $11;
1564 							currentData.currentArray[9] = $12;
1565 							currentData.currentArray[10] = $13;
1566 							currentData.currentArray[11] = $14;
1567 							currentData.currentArray[12] = $15;
1568 							currentData.currentArray[13] = $16;
1569 							currentData.currentArray[14] = $17;
1570 							currentData.currentArray[15] = $18;
1571 
1572 							currentData.currentArray += 16;
1573 						}
1574 						currentData.numArrayItemsRemaining--;
1575 					}
1576 					else{
1577 						slerror("Wrong number of items in array initializer\n");
1578 					}
1579 				}
1580 				|
1581 				slMatrixArrayInitializerItems
1582 				SCRL_FLOAT_VALUE
1583 				{
1584 					if(currentData.numArrayItemsRemaining > 0){
1585 						if(currentData.currentArray){
1586 							currentData.currentArray[0] = $2;
1587 							currentData.currentArray[1] = 0;
1588 							currentData.currentArray[2] = 0;
1589 							currentData.currentArray[3] = 0;
1590 							currentData.currentArray[4] = 0;
1591 							currentData.currentArray[5] = $2;
1592 							currentData.currentArray[6] = 0;
1593 							currentData.currentArray[7] = 0;
1594 							currentData.currentArray[8] = 0;
1595 							currentData.currentArray[9] = 0;
1596 							currentData.currentArray[10] = $2;
1597 							currentData.currentArray[11] = 0;
1598 							currentData.currentArray[12] = 0;
1599 							currentData.currentArray[13] = 0;
1600 							currentData.currentArray[14] = 0;
1601 							currentData.currentArray[15] = 1;
1602 
1603 							currentData.currentArray += 16;
1604 						}
1605 						currentData.numArrayItemsRemaining--;
1606 					}
1607 					else{
1608 						slerror("Wrong number of items in array initializer\n");
1609 					}
1610 				}
1611 				|
1612 				;
1613 
1614 
1615 slVariableDefinitions:
1616 				SCRL_VARIABLES
1617 				SCRL_COLON
1618 				SCRL_NL
1619 				slVariables
1620 				;
1621 
1622 slVariables:
1623 				slVariables
1624 				slVariable
1625 				SCRL_NL
1626 				|
1627 				;
1628 
1629 slVariable:
1630 				slContainer
1631 				slFloatVariable
1632 				|
1633 				slContainer
1634 				slStringVariable
1635 				|
1636 				slContainer
1637 				slColorVariable
1638 				|
1639 				slContainer
1640 				slVectorVariable
1641 				|
1642 				slContainer
1643 				slNormalVariable
1644 				|
1645 				slContainer
1646 				slPointVariable
1647 				|
1648 				slContainer
1649 				slMatrixVariable
1650 				;
1651 
1652 
1653 slFloatVariable:
1654 				SCRL_FLOAT
1655 				SCRL_IDENTIFIER_VALUE
1656 				{
1657 					newVariable($2,TYPE_FLOAT,1,FALSE);
1658 				}
1659 				|
1660 				SCRL_FLOAT
1661 				SCRL_IDENTIFIER_VALUE
1662 				SCRL_OPEN_SQR_PARANTHESIS
1663 				SCRL_FLOAT_VALUE
1664 				SCRL_CLOSE_SQR_PARANTHESIS
1665 				{
1666 					newVariable($2,TYPE_FLOAT,(int) $4,FALSE);
1667 				}
1668 				;
1669 
1670 slStringVariable:
1671 				SCRL_STRING
1672 				SCRL_IDENTIFIER_VALUE
1673 				{
1674 					newVariable($2,TYPE_STRING,1,FALSE);
1675 				}
1676 				|
1677 				SCRL_STRING
1678 				SCRL_IDENTIFIER_VALUE
1679 				SCRL_OPEN_SQR_PARANTHESIS
1680 				SCRL_FLOAT_VALUE
1681 				SCRL_CLOSE_SQR_PARANTHESIS
1682 				{
1683 					newVariable($2,TYPE_STRING,(int) $4,FALSE);
1684 				}
1685 				;
1686 
1687 slVectorVariable:
1688 				SCRL_VECTOR
1689 				SCRL_IDENTIFIER_VALUE
1690 				{
1691 					newVariable($2,TYPE_VECTOR,1,FALSE);
1692 				}
1693 				|
1694 				SCRL_VECTOR
1695 				SCRL_IDENTIFIER_VALUE
1696 				SCRL_OPEN_SQR_PARANTHESIS
1697 				SCRL_FLOAT_VALUE
1698 				SCRL_CLOSE_SQR_PARANTHESIS
1699 				{
1700 					newVariable($2,TYPE_VECTOR,(int) $4,FALSE);
1701 				}
1702 				;
1703 
1704 slColorVariable:
1705 				SCRL_COLOR
1706 				SCRL_IDENTIFIER_VALUE
1707 				{
1708 					newVariable($2,TYPE_COLOR,1,FALSE);
1709 				}
1710 				|
1711 				SCRL_COLOR
1712 				SCRL_IDENTIFIER_VALUE
1713 				SCRL_OPEN_SQR_PARANTHESIS
1714 				SCRL_FLOAT_VALUE
1715 				SCRL_CLOSE_SQR_PARANTHESIS
1716 				{
1717 					newVariable($2,TYPE_COLOR,(int) $4,FALSE);
1718 				}
1719 				;
1720 
1721 slNormalVariable:
1722 				SCRL_NORMAL
1723 				SCRL_IDENTIFIER_VALUE
1724 				{
1725 					newVariable($2,TYPE_NORMAL,1,FALSE);
1726 				}
1727 				|
1728 				SCRL_NORMAL
1729 				SCRL_IDENTIFIER_VALUE
1730 				SCRL_OPEN_SQR_PARANTHESIS
1731 				SCRL_FLOAT_VALUE
1732 				SCRL_CLOSE_SQR_PARANTHESIS
1733 				{
1734 					newVariable($2,TYPE_NORMAL,(int) $4,FALSE);
1735 				}
1736 				;
1737 
1738 slPointVariable:
1739 				SCRL_POINT
1740 				SCRL_IDENTIFIER_VALUE
1741 				{
1742 					newVariable($2,TYPE_POINT,1,FALSE);
1743 				}
1744 				|
1745 				SCRL_POINT
1746 				SCRL_IDENTIFIER_VALUE
1747 				SCRL_OPEN_SQR_PARANTHESIS
1748 				SCRL_FLOAT_VALUE
1749 				SCRL_CLOSE_SQR_PARANTHESIS
1750 				{
1751 					newVariable($2,TYPE_POINT,(int) $4,FALSE);
1752 				}
1753 				;
1754 
1755 slMatrixVariable:
1756 				SCRL_MATRIX
1757 				SCRL_IDENTIFIER_VALUE
1758 				{
1759 					newVariable($2,TYPE_MATRIX,1,FALSE);
1760 				}
1761 				|
1762 				SCRL_MATRIX
1763 				SCRL_IDENTIFIER_VALUE
1764 				SCRL_OPEN_SQR_PARANTHESIS
1765 				SCRL_FLOAT_VALUE
1766 				SCRL_CLOSE_SQR_PARANTHESIS
1767 				{
1768 					newVariable($2,TYPE_MATRIX,(int) $4,FALSE);
1769 				}
1770 				;
1771 
1772 slInit:			SCRL_INIT
1773 				SCRL_NL
1774 				{
1775 					currentData.parsingInit	=	TRUE;
1776 					newLabel(initLabel,FALSE);
1777 				}
1778 				slShaderLine
1779 				;
1780 
1781 slCode:			SCRL_CODE
1782 				SCRL_NL
1783 				{
1784 					currentData.parsingInit	=	FALSE;
1785 					newLabel(codeLabel,FALSE);
1786 				}
1787 				slShaderLine
1788 				;
1789 
1790 slShaderLine:
1791 				slShaderLine
1792 				slStatement
1793 				SCRL_NL
1794 				|
1795 				slShaderLine
1796 				slLabelDefinition
1797 				SCRL_NL
1798 				|
1799 				slShaderLine
1800 				slDSO
1801 				SCRL_NL
1802 				|
1803 				;
1804 
1805 
1806 slDSO:			SCRL_DSO
1807 				SCRL_IDENTIFIER_VALUE
1808 				{
1809 					char	*dsoName	=	$2;
1810 
1811 					switch(currentData.passNumber) {
1812 					case 1:
1813 						currentData.numCode++;					// opcode
1814 						break;
1815 					case 2:
1816 						strcpy(currentData.currentOpcode,$2);
1817 						currentData.currentArgument					=	0;
1818 						currentData.currentOpcodePlace->arguments	=	currentData.currentArgumentPlace;
1819 						currentData.currentPrototype[0]				=	'~';
1820 						currentData.opcodeUniform					=	TRUE;
1821 						break;
1822 					default:
1823 						break;
1824 					}
1825 				}
1826 				SCRL_OPEN_PARANTHESIS
1827 				SCRL_TEXT_VALUE
1828 				SCRL_CLOSE_PARANTHESIS
1829 				slOperandList
1830 				{
1831 					switch(currentData.passNumber) {
1832 					case 1:
1833 						break;
1834 					case 2:
1835 						// Set the opcode here
1836 						CDSO	*dso;
1837 
1838 						if ((dso = CRenderer::getDSO($2,$5)) != NULL) {
1839 							// Save the DSO opcode
1840 							if ($5[0] == 'o')	currentData.currentOpcodePlace->opcode		=	FUNCTION_DSO_VOID;
1841 							else				currentData.currentOpcodePlace->opcode		=	FUNCTION_DSO;
1842 
1843 							assert(currentData.opcodeUniform < 256);
1844 
1845 							currentData.currentOpcodePlace->numArguments	=	(unsigned char) (currentData.currentArgument);
1846 							currentData.currentOpcodePlace->uniform			=	(unsigned char) (currentData.opcodeUniform);
1847 							currentData.currentOpcodePlace->dso				=	dso;
1848 							currentData.currentOpcodePlace++;
1849 						} else {
1850 							slerror("Failed to locate DSO function\n");
1851 						}
1852 						break;
1853 					default:
1854 						break;
1855 					}
1856 				}
1857 				;
1858 
1859 slOpcode:
1860 				SCRL_IDENTIFIER_VALUE
1861 				{
1862 					switch(currentData.passNumber) {
1863 					case 1:
1864 						currentData.numCode++;		// opcode
1865 						break;
1866 					case 2:
1867 						strcpy(currentData.currentOpcode,$1);
1868 						currentData.currentArgument					=	0;
1869 						currentData.currentOpcodePlace->arguments	=	currentData.currentArgumentPlace;
1870 						currentData.currentPrototype[0]				=	'~';
1871 						currentData.opcodeUniform					=	TRUE;
1872 						break;
1873 					default:
1874 						break;
1875 					}
1876 				}
1877 				|
1878 				SCRL_SURFACE
1879 				{
1880 					switch(currentData.passNumber) {
1881 					case 1:
1882 						currentData.numCode++;		// opcode
1883 						break;
1884 					case 2:
1885 						strcpy(currentData.currentOpcode,"surface");
1886 						currentData.currentArgument					=	0;
1887 						currentData.currentOpcodePlace->arguments	=	currentData.currentArgumentPlace;
1888 						currentData.currentPrototype[0]				=	'~';
1889 						currentData.opcodeUniform					=	TRUE;
1890 						break;
1891 					default:
1892 						break;
1893 					}
1894 				}
1895 				|
1896 				SCRL_DISPLACEMENT
1897 				{
1898 					switch(currentData.passNumber) {
1899 					case 1:
1900 						currentData.numCode++;		// opcode
1901 						break;
1902 					case 2:
1903 						strcpy(currentData.currentOpcode,"displacement");
1904 						currentData.currentArgument					=	0;
1905 						currentData.currentOpcodePlace->arguments	=	currentData.currentArgumentPlace;
1906 						currentData.currentPrototype[0]				=	'~';
1907 						currentData.opcodeUniform					=	TRUE;
1908 						break;
1909 					default:
1910 						break;
1911 					}
1912 				}
1913 				;
1914 
1915 slOperandList:
1916 				slOperand
1917 				slOperandList
1918 				{
1919 				}
1920 				|
1921 				{
1922 				}
1923 				;
1924 
1925 slStatement:
1926 				slOpcode
1927 				slOperandList
1928 				{
1929 					setOpcode();
1930 				}
1931 				;
1932 
1933 slLabelDefinition:
1934 				SCRL_LABEL_VALUE
1935 				SCRL_COLON
1936 				{
1937 					newLabel($1,FALSE);
1938 				}
1939 				;
1940 
1941 slOperand:
1942 				SCRL_TEXT_VALUE
1943 				{
1944 					char	*str	=	$1;
1945 
1946 					addStringReference(&str,1);
1947 				}
1948 				|
1949 				SCRL_LABEL_VALUE
1950 				{
1951 					newLabel($1,TRUE);
1952 				}
1953 				|
1954 				SCRL_IDENTIFIER_VALUE
1955 				{
1956 					addVariableReference($1);
1957 				}
1958 				|
1959 				SCRL_FLOAT_VALUE
1960 				{
1961 					addFloatReference(&$1,1);
1962 				}
1963 				|
1964 				SCRL_OPEN_PARANTHESIS
1965 				SCRL_FLOAT_VALUE
1966 				SCRL_COMMA
1967 				SCRL_FLOAT_VALUE
1968 				SCRL_COMMA
1969 				SCRL_FLOAT_VALUE
1970 				SCRL_CLOSE_PARANTHESIS
1971 				{
1972 					vector	tmp;
1973 
1974 					tmp[0]	=	$2;
1975 					tmp[1]	=	$4;
1976 					tmp[2]	=	$6;
1977 
1978 					addFloatReference(tmp,3);
1979 				}
1980 				|
1981 				SCRL_OPEN_PARANTHESIS
1982 				SCRL_FLOAT_VALUE
1983 				SCRL_COMMA
1984 				SCRL_FLOAT_VALUE
1985 				SCRL_COMMA
1986 				SCRL_FLOAT_VALUE
1987 				SCRL_COMMA
1988 				SCRL_FLOAT_VALUE
1989 				SCRL_COMMA
1990 				SCRL_FLOAT_VALUE
1991 				SCRL_COMMA
1992 				SCRL_FLOAT_VALUE
1993 				SCRL_COMMA
1994 				SCRL_FLOAT_VALUE
1995 				SCRL_COMMA
1996 				SCRL_FLOAT_VALUE
1997 				SCRL_COMMA
1998 				SCRL_FLOAT_VALUE
1999 				SCRL_COMMA
2000 				SCRL_FLOAT_VALUE
2001 				SCRL_COMMA
2002 				SCRL_FLOAT_VALUE
2003 				SCRL_COMMA
2004 				SCRL_FLOAT_VALUE
2005 				SCRL_COMMA
2006 				SCRL_FLOAT_VALUE
2007 				SCRL_COMMA
2008 				SCRL_FLOAT_VALUE
2009 				SCRL_COMMA
2010 				SCRL_FLOAT_VALUE
2011 				SCRL_COMMA
2012 				SCRL_FLOAT_VALUE
2013 				SCRL_CLOSE_PARANTHESIS
2014 				{
2015 					matrix	tmp;
2016 
2017 					tmp[element(0,0)]	=	$2;
2018 					tmp[element(0,1)]	=	$4;
2019 					tmp[element(0,2)]	=	$6;
2020 					tmp[element(0,3)]	=	$8;
2021 					tmp[element(1,0)]	=	$10;
2022 					tmp[element(1,1)]	=	$12;
2023 					tmp[element(1,2)]	=	$14;
2024 					tmp[element(1,3)]	=	$16;
2025 					tmp[element(2,0)]	=	$18;
2026 					tmp[element(2,1)]	=	$20;
2027 					tmp[element(2,2)]	=	$22;
2028 					tmp[element(2,3)]	=	$24;
2029 					tmp[element(3,0)]	=	$26;
2030 					tmp[element(3,1)]	=	$28;
2031 					tmp[element(3,2)]	=	$30;
2032 					tmp[element(3,3)]	=	$32;
2033 
2034 					addFloatReference(tmp,16);
2035 				}
2036 				|
2037 				SCRL_OPEN_PARANTHESIS
2038 				SCRL_TEXT_VALUE
2039 				SCRL_CLOSE_PARANTHESIS
2040 				{
2041 					strcpy(currentData.currentPrototype,$2);
2042 				}
2043 				;
2044 
2045 %%
2046 #include "lex.sl.cpp"
2047 
2048 int	slLineno	=	0;
2049 
2050 ///////////////////////////////////////////////////////////////////////
2051 // Function				:	slerror
2052 // Description			:	Parser error function
2053 // Return Value			:
2054 // Comments				:
slerror(const char * s)2055 void	slerror(const char *s) {
2056 	warning(CODE_BADFILE,"Error in shader \"%s\" (%d) (\"%s\") (v%d.%d.%d)\n",currentData.name,slLineno,s,VERSION_RELEASE,VERSION_BETA,VERSION_ALPHA);
2057 	currentData.numErrors++;
2058 }
2059 
2060 
2061 ///////////////////////////////////////////////////////////////////////
2062 // Function				:	parseShader
2063 // Description			:	Parse a shader
2064 // Return Value			:	Parsed shader if successful
2065 // Comments				:
parseShader(const char * shaderName,const char * name)2066 CShader	*parseShader(const char *shaderName,const char *name) {
2067 	YY_BUFFER_STATE	oldState;
2068 
2069 	FILE	*fin;
2070 
2071 	fin						=	fopen(name,"r");
2072 
2073 	if (fin == NULL) return NULL;
2074 
2075 	oldState				=	YY_CURRENT_BUFFER;
2076 	sl_switch_to_buffer(sl_create_buffer( fin, YY_BUF_SIZE ) );
2077 
2078 	slLineno				=	0;
2079 
2080 	slin					=	fin;
2081 
2082 	reset();
2083 	currentData.name		=	name;
2084 	currentData.passNumber	=	1;
2085 
2086 	// The first pass
2087 	memBegin(CRenderer::globalMemory);
2088 	slparse();
2089 	memEnd(CRenderer::globalMemory);
2090 
2091 	if (currentData.numErrors != 0) {
2092 		sl_delete_buffer( YY_CURRENT_BUFFER );
2093 		fclose(fin);
2094 		sl_switch_to_buffer( oldState );
2095 		return NULL;
2096 	}
2097 
2098 	slLineno				=	0;
2099 
2100 	fseek(fin,0,SEEK_SET);
2101 	alloc();
2102 	currentData.passNumber				=	2;
2103 
2104 	// The second pass
2105 	memBegin(CRenderer::globalMemory);
2106 	slparse();
2107 	memEnd(CRenderer::globalMemory);
2108 
2109 	if (currentData.numErrors != 0) {
2110 		reset();
2111 		sl_delete_buffer( YY_CURRENT_BUFFER );
2112 		fclose(fin);
2113 		sl_switch_to_buffer( oldState );
2114 		return NULL;
2115 	} else {
2116 		CShader	*cShader	=	shaderCreate(shaderName);
2117 		reset();
2118 		sl_delete_buffer( YY_CURRENT_BUFFER );
2119 		fclose(fin);
2120 		sl_switch_to_buffer( oldState );
2121 		return cShader;
2122 	}
2123 }
2124 
2125 ///////////////////////////////////////////////////////////////////////
2126 // Function				:	reset
2127 // Description			:	Deallocate any previously allocated memory for the shader
2128 // Return Value			:	-
2129 // Comments				:
reset()2130 void	reset() {
2131 	if (currentData.strings != NULL) {
2132 		int	i;
2133 
2134 		for (i=0;i<currentData.numStrings;i++)
2135 			if (currentData.strings[i] != NULL)
2136 				free(currentData.strings[i]);
2137 	}
2138 
2139 
2140 	if (currentData.definedVariables != NULL) {
2141 		TSlVariable	*cVar,*nVar;
2142 
2143 		for (cVar=currentData.definedVariables;cVar != NULL;) {
2144 			nVar	=	cVar->next;
2145 			delete cVar;
2146 			cVar	=	nVar;
2147 
2148 			// FIXME: Clear the parameter if not NULL
2149 		}
2150 	}
2151 
2152 
2153 	if (currentData.labelDefinitions != NULL) {
2154 		TSlLabel	*cLabel,*nLabel;
2155 
2156 		for (cLabel=currentData.labelDefinitions;cLabel != NULL;) {
2157 			nLabel	=	cLabel->next;
2158 			delete cLabel;
2159 			cLabel	=	nLabel;
2160 		}
2161 	}
2162 
2163 	if (currentData.labelReferences != NULL) {
2164 		TSlLabel	*cLabel,*nLabel;
2165 
2166 		for (cLabel=currentData.labelReferences;cLabel != NULL;) {
2167 			nLabel	=	cLabel->next;
2168 			delete cLabel;
2169 			cLabel	=	nLabel;
2170 		}
2171 	}
2172 
2173 	if (currentData.memory != NULL)		delete [] currentData.memory;
2174 
2175 	// Clear currentData
2176 	memset(&currentData,0,sizeof(TShaderData));
2177 }
2178 
2179 ///////////////////////////////////////////////////////////////////////
2180 // Function				:	alloc
2181 // Description			:	Allocate required space for the shader
2182 // Return Value			:
2183 // Comments				:
alloc()2184 void	alloc() {
2185 	char	*mem;
2186 
2187 	currentData.memory	=	(char *) allocate_untyped(	currentData.numCode*sizeof(TCode)	+
2188 														currentData.numArgument*sizeof(TArgument)	+
2189 														currentData.constantSize +
2190 														currentData.numConstants*sizeof(void *) +
2191 														currentData.numVariables*sizeof(int) +
2192 														currentData.numStrings*sizeof(char *));
2193 
2194 	mem		=	currentData.memory;
2195 
2196 	if (currentData.numCode != 0) {
2197 		currentData.code						=	(TCode *) mem;
2198 		currentData.currentOpcodePlace			=	currentData.code;
2199 		mem										+=	currentData.numCode*sizeof(TCode);
2200 	}
2201 
2202 	if (currentData.numArgument != 0) {
2203 		currentData.arguments					=	(TArgument *) mem;
2204 		currentData.currentArgumentPlace		=	currentData.arguments;
2205 		mem										+=	currentData.numArgument*sizeof(TArgument);
2206 	}
2207 
2208 	if (currentData.constantSize != 0) {
2209 		currentData.constants					=	mem;
2210 		mem										+=	currentData.constantSize;
2211 	}
2212 
2213 	if (currentData.numConstants != 0) {
2214 		currentData.constantEntries				=	(void **) mem;
2215 		mem										+=	currentData.numConstants*sizeof(void *);
2216 	}
2217 
2218 	if (currentData.numVariables != 0) {
2219 		currentData.varyingSizes				=	(int *) mem;
2220 		mem										+=	currentData.numVariables*sizeof(int);
2221 	}
2222 
2223 	if (currentData.numStrings != 0) {
2224 		int	i;
2225 
2226 		currentData.strings						=	(char **) mem;
2227 		mem										+=	currentData.numStrings*sizeof(char *);
2228 
2229 		for (i=0;i<currentData.numStrings;i++) {
2230 			currentData.strings[i]				=	NULL;
2231 		}
2232 	}
2233 }
2234 
2235 ///////////////////////////////////////////////////////////////////////
2236 // Function				:	shaderCreate
2237 // Description			:	Parse successful, allocate the shader
2238 // Return Value			:
2239 // Comments				:
shaderCreate(const char * shaderName)2240 CShader	*shaderCreate(const char *shaderName) {
2241 	CShader	*cShader;
2242 
2243 	// Sanity check for the shaders
2244 	assert(currentData.numConstants		==	currentData.currentConstant);
2245 	assert(currentData.numVariables		==	currentData.currentVariable);
2246 	assert(currentData.numStrings		==	currentData.currentString);
2247 	assert(currentData.constantSize		==	currentData.currentConstantSize);
2248 	assert(currentData.varyingSize		==	currentData.currentVaryingSize);
2249 	assert((currentData.currentOpcodePlace - currentData.code)			== currentData.numCode);
2250 	assert((currentData.currentArgumentPlace - currentData.arguments)	== currentData.numArgument);
2251 
2252 	// Fix the labels
2253 	{
2254 		TSlLabel	*cLabel,*nLabel;
2255 
2256 		for (cLabel = currentData.labelReferences;cLabel != NULL;cLabel = cLabel->next) {
2257 			for (nLabel = currentData.labelDefinitions;nLabel != NULL;nLabel = nLabel->next) {
2258 				if (strcmp(cLabel->name,nLabel->name) == 0) {
2259 					cLabel->argument->index	=	nLabel->index;
2260 					break;
2261 				}
2262 			}
2263 
2264 			if (nLabel == NULL) {
2265 				slerror("Label not found");
2266 				return NULL;
2267 			}
2268 		}
2269 
2270 		for (cLabel = currentData.labelDefinitions;cLabel != NULL;cLabel = cLabel->next) {
2271 			if (strcmp(cLabel->name,codeLabel) == 0) {
2272 				currentData.codeEntryPoint	=	cLabel->index;
2273 			}
2274 
2275 			if (strcmp(cLabel->name,initLabel) == 0) {
2276 				currentData.initEntryPoint	=	cLabel->index;
2277 			}
2278 		}
2279 	}
2280 
2281 	cShader								=	new CShader(shaderName);
2282 
2283 	cShader->memory						=	currentData.memory;
2284 
2285 	cShader->codeArea					=	currentData.code;
2286 
2287 	cShader->constantEntries			=	currentData.constantEntries;
2288 	cShader->varyingSizes				=	currentData.varyingSizes;
2289 
2290 	cShader->strings					=	currentData.strings;
2291 
2292 	cShader->numStrings					=	currentData.numStrings;
2293 	cShader->numVariables				=	currentData.numVariables;
2294 
2295 	cShader->codeEntryPoint				=	currentData.codeEntryPoint;
2296 	cShader->initEntryPoint				=	currentData.initEntryPoint;
2297 
2298 	cShader->usedParameters				=	currentData.usedParameters;
2299 
2300 	cShader->type						=	currentData.shaderType;
2301 
2302 	{
2303 		TSlVariable	*cVar;
2304 		int			i,numGlobals=0;
2305 
2306 		cShader->parameters				=	NULL;
2307 		i								=	0;
2308 		while(currentData.definedVariables != NULL) {
2309 			cVar							=	currentData.definedVariables;
2310 			currentData.definedVariables	=	cVar->next;
2311 
2312 			// Is this a parameter ?
2313 			if (cVar->variable != NULL) {
2314 				cVar->variable->next	=	cShader->parameters;
2315 				cShader->parameters		=	cVar->variable;
2316 				if (cVar->variable->storage == STORAGE_GLOBAL ||
2317 					cVar->variable->storage == STORAGE_MUTABLEPARAMETER)
2318 						numGlobals++;
2319 			}
2320 
2321 			// Delete the variable
2322 			delete cVar;
2323 			i++;
2324 		}
2325 
2326 		cShader->numGlobals	=	numGlobals;
2327 	}
2328 
2329 	cShader->analyse();
2330 
2331 
2332 	currentData.memory					=	NULL;
2333 	currentData.code					=	NULL;
2334 	currentData.constants				=	NULL;
2335 	currentData.varyingSizes			=	NULL;
2336 	currentData.strings					=	NULL;
2337 	currentData.constantEntries			=	NULL;
2338 
2339 
2340 	return cShader;
2341 }
2342 
2343 
2344 extern	void		convertColorFrom(float *out,const float *in,ECoordinateSystem s);
2345 
2346