%{
//////////////////////////////////////////////////////////////////////
//
//                             Pixie
//
// Copyright © 1999 - 2003, Okan Arikan
//
// Contact: okan@cs.berkeley.edu
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
//
//  File				:	sl.y
//  Classes				:	-
//  Description			:	This is the parser file for CShader
//
////////////////////////////////////////////////////////////////////////
#undef alloca
#include <math.h>
#include <string.h>

#include "common/algebra.h"
#include "common/os.h"
#include "sdr.h"


/////////////////////////////////////////////////////////////////////////////////////
//   First some temporary data structures used during the script parsing


// Some forward definitions
		void							sdrerror(char *);			// Forward definition for stupid yacc
		int								sdrlex(void );				// Forward definition for stupid yacc

///////////////////////////////////////////////////////////////////////
// Function				:
// Description			:
// Return Value			:
// Comments				:
// Date last edited		:
static	void	processEscapes(char *str) {
	char	*cstr;

	while((cstr = strchr(str,'\\')) != NULL) {
		switch(cstr[1]) {
		case 'n':
			cstr[0]	=	'\n';
			break;
		case 't':
			cstr[0]	=	'\t';
			break;
		case 'r':
			cstr[0]	=	'\r';
			break;
		default:
			if (((cstr[1] >= 'a') && (cstr[1] <= 'z')) || ((cstr[1] >= 'A') && (cstr[1] <= 'Z'))) {
				// Unrecognised escape sequence
				sdrerror("Unrecognised escape sequence");
			} else {
				cstr[0]	=	cstr[1];
			}
		}

		{
			int i;

			for (i=2;cstr[i] != '\0';i++) {
				cstr[i-1]	=	cstr[i];
			}

			cstr[i-1]	=	cstr[i];
		}
	}
}



		TSdrParameter	*parameters;
		TSdrParameter	*currentParameter;
		ESdrShaderType	shaderType;

%}
%union slval {
	float			real;
	char			string[64];
	matrix			m;
	vector			v;
	TSdrParameter *parameter;
}

// Some tokens
%token	 SCRL_PARAMETERS
%token	 SCRL_VARIABLES
%token	 SCRL_OUTPUT
%token	 SCRL_VARYING
%token	 SCRL_VERTEX
%token	 SCRL_UNIFORM
%token	 SCRL_BOOLEAN
%token	 SCRL_FLOAT
%token	 SCRL_COLOR
%token	 SCRL_VECTOR
%token	 SCRL_NORMAL
%token	 SCRL_POINT
%token	 SCRL_MATRIX
%token	 SCRL_STRING

%token	 SCRL_SURFACE
%token	 SCRL_DISPLACEMENT
%token	 SCRL_IMAGER
%token	 SCRL_LIGHTSOURCE
%token	 SCRL_VOLUME
%token	 SCRL_GENERIC

%token	 SCRL_DSO

%token	 SCRL_DOT
%token	 SCRL_COLON
%token	 SCRL_EQUAL
%token	 SCRL_OPEN_PARANTHESIS
%token	 SCRL_CLOSE_PARANTHESIS
%token	 SCRL_OPEN_SQR_PARANTHESIS
%token	 SCRL_CLOSE_SQR_PARANTHESIS
%token	 SCRL_COMMA
%token   SCRL_NL

%token<string>	SCRL_TEXT_VALUE
%token<string>	SCRL_IDENTIFIER_VALUE
%token<string>	SCRL_LABEL_VALUE
%token<real>	SCRL_FLOAT_VALUE
%type<string>	slGlobalParameterContainer
%type<string>	slGlobalParameterType
%type<v>		slVectorIn
%type<v>		slVector
%%
start:		
			slType	
			slParameterDefinitions
			slVariableDefinitions
			slCode
			;

slVectorIn:	SCRL_EQUAL
			SCRL_TEXT_VALUE
			SCRL_FLOAT_VALUE
			{
				currentParameter->space						=	strdup($2);
				currentParameter->defaultValue.vector		=	new float[3];
				currentParameter->defaultValue.vector[0]	=	$3;
				currentParameter->defaultValue.vector[1]	=	$3;
				currentParameter->defaultValue.vector[2]	=	$3;
			}
			|
			SCRL_EQUAL
			SCRL_TEXT_VALUE
			SCRL_OPEN_SQR_PARANTHESIS
			SCRL_FLOAT_VALUE
			SCRL_FLOAT_VALUE
			SCRL_FLOAT_VALUE
			SCRL_CLOSE_SQR_PARANTHESIS
			{
				currentParameter->space						=	strdup($2);
				currentParameter->defaultValue.vector		=	new float[3];
				currentParameter->defaultValue.vector[0]	=	$4;
				currentParameter->defaultValue.vector[1]	=	$5;
				currentParameter->defaultValue.vector[2]	=	$6;
			}
			|
			SCRL_EQUAL
			SCRL_FLOAT_VALUE
			{
				currentParameter->defaultValue.vector		=	new float[3];
				currentParameter->defaultValue.vector[0]	=	$2;
				currentParameter->defaultValue.vector[1]	=	$2;
				currentParameter->defaultValue.vector[2]	=	$2;
			}
			|
			SCRL_EQUAL
			SCRL_OPEN_SQR_PARANTHESIS
			SCRL_FLOAT_VALUE
			SCRL_FLOAT_VALUE
			SCRL_FLOAT_VALUE
			SCRL_CLOSE_SQR_PARANTHESIS
			{
				currentParameter->defaultValue.vector		=	new float[3];
				currentParameter->defaultValue.vector[0]	=	$3;
				currentParameter->defaultValue.vector[1]	=	$4;
				currentParameter->defaultValue.vector[2]	=	$5;
			}
			|
			{
				currentParameter->defaultValue.vector		=	NULL;
			}
			;

slVector:	slVectorIn
			{
			}
			;
			
slContainer:	SCRL_UNIFORM
				{
				}
				|
				SCRL_VARYING
				{
				}
				|
				{
				}
				;

slType:
		SCRL_SURFACE
		SCRL_NL
		{
			shaderType	=	SHADER_SURFACE;
		}
	|
		SCRL_DISPLACEMENT
		SCRL_NL
		{
			shaderType	=	SHADER_DISPLACEMENT;
		}
	|
		SCRL_LIGHTSOURCE
		SCRL_NL
		{
			shaderType	=	SHADER_LIGHT;
		}
	|
		SCRL_VOLUME
		SCRL_NL
		{
			shaderType	=	SHADER_VOLUME;
		}
	|
		SCRL_IMAGER
		SCRL_NL
		{
			shaderType	=	SHADER_IMAGER;
		}
		;

slParameterDefinitions:
		SCRL_PARAMETERS
		SCRL_COLON
		SCRL_NL
		slParameters
		;

slParameters:
		slParameter
		SCRL_NL
		slParameters
		{
		}
	|
		{
		}
		;

slParameter:
		{
			currentParameter						=	new TSdrParameter;
			currentParameter->space					=	NULL;
			currentParameter->numItems				=	1;
			currentParameter->defaultValue.string	=	NULL;
		}
		slGlobalParameter
		{
			currentParameter->next	=	parameters;
			parameters				=	currentParameter;
		}
	|
		{
			currentParameter						=	new TSdrParameter;
			currentParameter->space					=	NULL;
			currentParameter->numItems				=	1;
			currentParameter->defaultValue.string	=	NULL;
		}
		slRegularParameter
		{
			currentParameter->next	=	parameters;
			parameters				=	currentParameter;
		}
		;

slRegularParameter:
		slFloatParameter
	|
		slStringParameter
	|
		slColorParameter
	|
		slVectorParameter
	|
		slNormalParameter
	|
		slPointParameter
	|
		slMatrixParameter
		;

slGlobalParameter:
		slGlobalParameterContainer
		slGlobalParameterType
		SCRL_IDENTIFIER_VALUE
		{
			currentParameter->name					=	strdup($3);
		}
		slGlobalParameterInit
		{
		}
		;

		// Ignore the init for the time being
slGlobalParameterInit:
		SCRL_EQUAL
		SCRL_FLOAT_VALUE
		{
			currentParameter->defaultValue.scalar	=	$2;
		}
		|
		SCRL_EQUAL
		SCRL_TEXT_VALUE
		{
			currentParameter->defaultValue.string	=	strdup($2);
		}
		|
		SCRL_EQUAL
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
			currentParameter->defaultValue.vector		=	new float[3];
			currentParameter->defaultValue.vector[0]	=	$3;
			currentParameter->defaultValue.vector[1]	=	$4;
			currentParameter->defaultValue.vector[2]	=	$5;
		}
		|
		{
			currentParameter->defaultValue.string	=	NULL;
		}
		;

slGlobalParameterType:
		SCRL_FLOAT
		{
			currentParameter->type	=	TYPE_FLOAT;
		}
		|
		SCRL_VECTOR
		{
			currentParameter->type	=	TYPE_VECTOR;
		}
		|
		SCRL_NORMAL
		{
			currentParameter->type	=	TYPE_NORMAL;
		}
		|
		SCRL_COLOR
		{
			currentParameter->type	=	TYPE_COLOR;
		}
		|
		SCRL_POINT
		{
			currentParameter->type	=	TYPE_POINT;
		}
		|
		SCRL_MATRIX
		{
			currentParameter->type	=	TYPE_MATRIX;
		}
		|
		SCRL_STRING
		{
			currentParameter->type	=	TYPE_STRING;
		}
		;

slGlobalParameterContainer:
		SCRL_UNIFORM
		{
			currentParameter->container	=	CONTAINER_UNIFORM;
		}
		|
		SCRL_VARYING
		{
			currentParameter->container	=	CONTAINER_VARYING;
		}
		|
		SCRL_VERTEX
		{
			currentParameter->container	=	CONTAINER_VERTEX;
		}
		|
		SCRL_OUTPUT
		SCRL_UNIFORM
		{
			currentParameter->container	=	CONTAINER_UNIFORM;
		}
		|
		SCRL_OUTPUT
		SCRL_VARYING
		{
			currentParameter->container	=	CONTAINER_VARYING;
		}
		|
		SCRL_OUTPUT
		SCRL_VERTEX
		{
			currentParameter->container	=	CONTAINER_VERTEX;
		}
		|
		SCRL_OUTPUT
		{
			currentParameter->container	=	CONTAINER_UNIFORM;
		}
		;

slFloatParameter:
		SCRL_FLOAT
		SCRL_IDENTIFIER_VALUE
		SCRL_EQUAL
		SCRL_FLOAT_VALUE
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_FLOAT;
			currentParameter->name					=	strdup($2);
			currentParameter->defaultValue.scalar	=	$4;
			currentParameter->numItems				=	1;
		}
	|
		SCRL_FLOAT
		SCRL_IDENTIFIER_VALUE
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_FLOAT;
			currentParameter->name					=	strdup($2);
			currentParameter->defaultValue.scalar	=	0;
			currentParameter->numItems				=	1;
		}
	|
		SCRL_FLOAT
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_FLOAT;
			currentParameter->name					=	strdup($2);
			currentParameter->defaultValue.scalar	=	0;
			currentParameter->numItems				=	(int) $4;
		}
		;

slStringParameter:
		SCRL_STRING
		SCRL_IDENTIFIER_VALUE
		SCRL_EQUAL
		SCRL_TEXT_VALUE
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_STRING;
			currentParameter->name					=	strdup($2);
			currentParameter->defaultValue.string	=	strdup($4);
			currentParameter->numItems				=	1;
		}
	|
		SCRL_STRING
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_STRING;
			currentParameter->name					=	strdup($2);
			currentParameter->defaultValue.string	=	NULL;
			currentParameter->numItems				=	(int) $4;
		}


slColorParameter:
		SCRL_COLOR
		SCRL_IDENTIFIER_VALUE
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_COLOR;
			currentParameter->name					=	strdup($2);
			currentParameter->numItems				=	1;
		}
		slVector
		{
		}
		|
		SCRL_COLOR
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_COLOR;
			currentParameter->name					=	strdup($2);
			currentParameter->defaultValue.scalar	=	0;
			currentParameter->numItems				=	(int) $4;
		}
		;

slVectorParameter:
		SCRL_VECTOR
		SCRL_IDENTIFIER_VALUE
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_VECTOR;
			currentParameter->name					=	strdup($2);
			currentParameter->numItems				=	1;
		}
		slVector
		{
		}
		|
		SCRL_VECTOR
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_VECTOR;
			currentParameter->name					=	strdup($2);
			currentParameter->defaultValue.scalar	=	0;
			currentParameter->numItems				=	(int) $4;
		}
		;

slNormalParameter:
		SCRL_NORMAL
		SCRL_IDENTIFIER_VALUE
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_NORMAL;
			currentParameter->name					=	strdup($2);
			currentParameter->numItems				=	1;
		}
		slVector
		{
		}
		|
		SCRL_NORMAL
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_NORMAL;
			currentParameter->name					=	strdup($2);
			currentParameter->defaultValue.scalar	=	0;
			currentParameter->numItems				=	(int) $4;
		}
		;

slPointParameter:
		SCRL_POINT
		SCRL_IDENTIFIER_VALUE
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_POINT;
			currentParameter->name					=	strdup($2);
			currentParameter->numItems				=	1;
		}
		slVector
		{
		}
		|
		SCRL_POINT
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
			currentParameter->container				=	CONTAINER_UNIFORM;
			currentParameter->type					=	TYPE_POINT;
			currentParameter->name					=	strdup($2);
			currentParameter->defaultValue.scalar	=	0;
			currentParameter->numItems				=	(int) $4;
		}
		;

slMatrixParameter:
		SCRL_MATRIX
		SCRL_IDENTIFIER_VALUE
		SCRL_EQUAL
		SCRL_OPEN_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_PARANTHESIS
		{
			currentParameter->container					=	CONTAINER_UNIFORM;
			currentParameter->type						=	TYPE_MATRIX;
			currentParameter->name						=	strdup($2);
			currentParameter->defaultValue.matrix		=	new float[16];
			currentParameter->defaultValue.matrix[0]	=	$5;
			currentParameter->defaultValue.matrix[1]	=	$6;
			currentParameter->defaultValue.matrix[2]	=	$7;
			currentParameter->defaultValue.matrix[3]	=	$8;
			currentParameter->defaultValue.matrix[4]	=	$9;
			currentParameter->defaultValue.matrix[5]	=	$10;
			currentParameter->defaultValue.matrix[6]	=	$11;
			currentParameter->defaultValue.matrix[7]	=	$12;
			currentParameter->defaultValue.matrix[8]	=	$13;
			currentParameter->defaultValue.matrix[9]	=	$14;
			currentParameter->defaultValue.matrix[10]	=	$15;
			currentParameter->defaultValue.matrix[11]	=	$16;
			currentParameter->defaultValue.matrix[12]	=	$17;
			currentParameter->defaultValue.matrix[13]	=	$18;
			currentParameter->defaultValue.matrix[14]	=	$19;
			currentParameter->defaultValue.matrix[15]	=	$20;
			currentParameter->numItems					=	1;
		}
	|
		SCRL_MATRIX
		SCRL_IDENTIFIER_VALUE
		SCRL_EQUAL
		SCRL_FLOAT_VALUE
		{
			currentParameter->container					=	CONTAINER_UNIFORM;
			currentParameter->type						=	TYPE_MATRIX;
			currentParameter->name						=	strdup($2);
			currentParameter->defaultValue.matrix		=	new float[16];
			currentParameter->defaultValue.matrix[0]	=	$4;
			currentParameter->defaultValue.matrix[1]	=	0;
			currentParameter->defaultValue.matrix[2]	=	0;
			currentParameter->defaultValue.matrix[3]	=	0;
			currentParameter->defaultValue.matrix[4]	=	0;
			currentParameter->defaultValue.matrix[5]	=	$4;
			currentParameter->defaultValue.matrix[6]	=	0;
			currentParameter->defaultValue.matrix[7]	=	0;
			currentParameter->defaultValue.matrix[8]	=	0;
			currentParameter->defaultValue.matrix[9]	=	0;
			currentParameter->defaultValue.matrix[10]	=	$4;
			currentParameter->defaultValue.matrix[11]	=	0;
			currentParameter->defaultValue.matrix[12]	=	0;
			currentParameter->defaultValue.matrix[13]	=	0;
			currentParameter->defaultValue.matrix[14]	=	0;
			currentParameter->defaultValue.matrix[15]	=	$4;
			currentParameter->numItems					=	1;
		}
	|
		SCRL_MATRIX
		SCRL_IDENTIFIER_VALUE
		{
			currentParameter->container					=	CONTAINER_UNIFORM;
			currentParameter->type						=	TYPE_MATRIX;
			currentParameter->name						=	strdup($2);
			currentParameter->defaultValue.matrix		=	new float[16];
			currentParameter->defaultValue.matrix[0]	=	1;
			currentParameter->defaultValue.matrix[1]	=	0;
			currentParameter->defaultValue.matrix[2]	=	0;
			currentParameter->defaultValue.matrix[3]	=	0;
			currentParameter->defaultValue.matrix[4]	=	0;
			currentParameter->defaultValue.matrix[5]	=	1;
			currentParameter->defaultValue.matrix[6]	=	0;
			currentParameter->defaultValue.matrix[7]	=	0;
			currentParameter->defaultValue.matrix[8]	=	0;
			currentParameter->defaultValue.matrix[9]	=	0;
			currentParameter->defaultValue.matrix[10]	=	1;
			currentParameter->defaultValue.matrix[11]	=	0;
			currentParameter->defaultValue.matrix[12]	=	0;
			currentParameter->defaultValue.matrix[13]	=	0;
			currentParameter->defaultValue.matrix[14]	=	0;
			currentParameter->defaultValue.matrix[15]	=	1;
			currentParameter->numItems					=	1;
		}
	|
		SCRL_MATRIX
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
			currentParameter->container					=	CONTAINER_UNIFORM;
			currentParameter->type						=	TYPE_MATRIX;
			currentParameter->name						=	strdup($2);
			currentParameter->defaultValue.scalar		=	0;
			currentParameter->numItems					=	(int) $4;
		}
		;

slVariableDefinitions:
		SCRL_VARIABLES
		SCRL_COLON
		SCRL_NL
		slVariables
		;

slVariables:
		slVariable
		SCRL_NL
		slVariables
	|
		;

slVariable:
		slContainer
		slBooleanVariable
	|
		slContainer
		slFloatVariable
	|
		slContainer
		slStringVariable
	|
		slContainer
		slColorVariable
	|
		slContainer
		slVectorVariable
	|
		slContainer
		slNormalVariable
	|
		slContainer
		slPointVariable
	|
		slContainer
		slMatrixVariable
		;

slBooleanVariable:
		SCRL_BOOLEAN
		SCRL_IDENTIFIER_VALUE
		{
		}
	|
		SCRL_BOOLEAN
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
		}
		;


slFloatVariable:
		SCRL_FLOAT
		SCRL_IDENTIFIER_VALUE
		{
		}
	|
		SCRL_FLOAT
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
		}
		;

slStringVariable:
		SCRL_STRING
		SCRL_IDENTIFIER_VALUE
		{
		}
	|
		SCRL_STRING
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
		}
		;

slVectorVariable:
		SCRL_VECTOR
		SCRL_IDENTIFIER_VALUE
		{
		}
	|
		SCRL_VECTOR
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
		}
		;

slColorVariable:
		SCRL_COLOR
		SCRL_IDENTIFIER_VALUE
		{
		}
	|
		SCRL_COLOR
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
		}
		;

slNormalVariable:
		SCRL_NORMAL
		SCRL_IDENTIFIER_VALUE
		{
		}
	|
		SCRL_NORMAL
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
		}
		;

slPointVariable:
		SCRL_POINT
		SCRL_IDENTIFIER_VALUE
		{
		}
	|
		SCRL_POINT
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
		}
		;

slMatrixVariable:
		SCRL_MATRIX
		SCRL_IDENTIFIER_VALUE
		{
		}
	|
		SCRL_MATRIX
		SCRL_IDENTIFIER_VALUE
		SCRL_OPEN_SQR_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_SQR_PARANTHESIS
		{
		}
		;

slCode:
		slStatement
		SCRL_NL
		slCode
	|
		slLabelDefinition
		SCRL_NL
		slCode
	|
		slDSO
		SCRL_NL
		slCode
	|
		;


slDSO:	SCRL_DSO
		SCRL_IDENTIFIER_VALUE
		{
		}
		SCRL_OPEN_PARANTHESIS
		SCRL_TEXT_VALUE
		SCRL_CLOSE_PARANTHESIS
		slOperandList
		{
		}
		;

slOpcode:
		SCRL_IDENTIFIER_VALUE
		{
		}
		;

slOperandList:
		slOperand
		slOperandList
		{
		}
		|
		{
		}
		;

slStatement:
		slOpcode
		slOperandList
		{
		}
		;

slLabelDefinition:
		SCRL_LABEL_VALUE
		SCRL_COLON
		{
		}
		;

slOperand:
		SCRL_TEXT_VALUE
		{
		}
	|
		SCRL_LABEL_VALUE
		{
		}
	|
		SCRL_IDENTIFIER_VALUE
		{
		}
	|
		SCRL_FLOAT_VALUE
		{
		}
	|
		SCRL_OPEN_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_PARANTHESIS
		{
		}
	|
		SCRL_OPEN_PARANTHESIS
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_COMMA
		SCRL_FLOAT_VALUE
		SCRL_CLOSE_PARANTHESIS
		{
		}
		|
		SCRL_OPEN_PARANTHESIS
		SCRL_TEXT_VALUE
		SCRL_CLOSE_PARANTHESIS
		{
		}
		;

%%
#include "lex.sdr.cpp"

int	slLineno	=	0;

///////////////////////////////////////////////////////////////////////
// Function				:	slerror
// Description			:	Parser error function
// Return Value			:
// Comments				:
// Date last edited		:	5/20/2003
void			sdrerror(char *s) {
}


///////////////////////////////////////////////////////////////////////
// Function				:	sdrGet
// Description			:	Parse a shader
// Return Value			:
// Comments				:
// Date last edited		:	5/20/2003
TSdrShader		*sdrGet(const char *in,const char *searchpath) {
	TSdrShader		*cShader;
	char			tmp[512];
	const	char	*currentPath;
	char			*dest;

	memoryManagerInit();

	sdrin	=	NULL;

	if (searchpath != NULL) {
		for (dest=tmp,currentPath=searchpath;;) {
			if ((*currentPath == '\0') || (*currentPath == ':')) {		// End of the current path

				if ((dest - tmp) > 0) {		// Do we have anything to record ?
					dest--;

					if ((*dest == '/') || (*dest == '\\')) {	// The last character has to be a slash
						dest++;
					} else {
						dest++;
						*dest++	=	'/';
					}

					sprintf(dest,in);
					if (strstr(dest,".sdr") == NULL) {
						strcat(dest,".sdr");
					}

					osFixSlashes(tmp);

					if (strncmp(tmp,"\\\\",2) == 0) {
						tmp[1]	=	tmp[2];
						tmp[2]	=	':';
						tmp[3]	=	'\\';

						sdrin	=	fopen(tmp+1,"r");
					} else {
						sdrin	=	fopen(tmp,"r");
					}

					if (sdrin != NULL)	break;
				}

				dest			=	tmp;

				if (*currentPath == '\0')	break;

				currentPath++;
			} else if (*currentPath == '%') {
				const	char	*endOfCurrentPath	=	strchr(currentPath+1,'%');
				char			environmentVariable[OS_MAX_PATH_LENGTH];

				if (endOfCurrentPath!=NULL) {
					const	int		environmentLength	=	endOfCurrentPath - currentPath - 1;
					const	char	*value;

					strncpy(environmentVariable,currentPath+1,environmentLength);
					environmentVariable[environmentLength]	=	'\0';

					value		=	osEnvironment(environmentVariable);
					if (value != NULL) {
						strcpy(dest,value);
						dest	+=	strlen(value);
					}

					currentPath	=	endOfCurrentPath+1;
				} else {
					currentPath++;
				}
			} else if ((*currentPath == '@') || (*currentPath == '&')) {
				currentPath++;
			} else {
				*dest++	=	*currentPath++;
			}
		}
	} else {
		sdrin	=	fopen(in,"r");
	}

	if (sdrin == NULL)	return NULL;

	parameters	=	NULL;

	sdrparse();

	fclose(sdrin);

	cShader	=	new TSdrShader;

	cShader->name		=	strdup(in);
	cShader->type		=	shaderType;
	cShader->parameters	=	parameters;

	return cShader;
}

///////////////////////////////////////////////////////////////////////
// Function				:	sdrDelete
// Description			:	Delete a shader
// Return Value			:
// Comments				:
// Date last edited		:	5/20/2003
void			sdrDelete(TSdrShader *cShader) {
	TSdrParameter	*cParameter;

	while((cParameter = cShader->parameters) != NULL) {
		cShader->parameters	=	cParameter->next;

		free(cParameter->name);
		if (cParameter->space != NULL) {
			free(cParameter->space);
		}

		if (cParameter->numItems == 1) {
			switch(cParameter->type) {
			case TYPE_FLOAT:
				break;
			case TYPE_VECTOR:
			case TYPE_NORMAL:
			case TYPE_POINT:
			case TYPE_COLOR:
				if (cParameter->defaultValue.vector != NULL) {
					delete [] cParameter->defaultValue.vector;
				}
				break;
			case TYPE_MATRIX:
				if (cParameter->defaultValue.matrix != NULL) {
					delete [] cParameter->defaultValue.matrix;
				}
				break;
			case TYPE_STRING:
				if (cParameter->defaultValue.string != NULL) {
					free(cParameter->defaultValue.string);
				}
				break;
			}
		}

		delete cParameter;
	}

	free(cShader->name);
	delete cShader;

	memoryManagerTini();
}

