/* parser.bison: rayshade yacc.y scripts stripped and adapted for          */
/* inclusion in the VRML library by Philippe Bekaert, february 2001        */

/* yacc.y								   */
/*									   */
/* Copyright (C) 1989, 1991, Craig E. Kolb				   */
/* All rights reserved.							   */
/*									   */
/* This software may be freely copied, modified, and redistributed,	   */
/* provided that this copyright notice is preserved on all copies.	   */
/*									   */
/* You may not distribute this software, in whole or in part, as part of   */
/* any commercial product without the express consent of the authors.	   */
/* 									   */
/* There is no warranty or other guarantee of fitness of this software	   */
/* for any purpose.  It is provided solely "as is".			   */
%{
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define _RAYSHADE_PARSER_SOURCE_

#include "parser.H"

#define yyparse rayshade_parser::yyparse
#define yylex rayshade_parser::yylex
#define yyerror rayshade_parser::yyerror
#define yylval rayshade_parser::yylval
#define yychar rayshade_parser::yychar
#define yydebug rayshade_parser::yydebug
#define yynerrs rayshade_parser::yynerrs

#define YYSTYPE DUPLICATE_YYSTYPE
#define YY_OMIT_DECLS

%}
%union {
	char *s;
	int i;
	float f;
	Vector v;
	Vec2d uv;
	Color c;
	class SFNode* sfnode;
	class MFNode* mfnode;
	class MFVec3f* mfvec3f;
}
%token <f> tFLOAT
%token <s> tSTRING tFILENAME
%token tAPERTURE tAPPLYSURF
%token tBACKGROUND tBLOB tBLOTCH tBOX tBUMP tCONE tCYL tDIRECTIONAL tCURSURF
%token tEXTENDED tEYEP tFBM tFBMBUMP tFOCALDIST tFOG tFOGDECK tFOV tGLOSS tGRID
%token tHEIGHTFIELD tLIGHT tLIST tLOOKP tMARBLE tMAXDEPTH tMIST
%token tJITTER tNOJITTER tDEFINE
%token tOBJECT tOUTFILE  tSKY tDISC tDIFFERENCE tUNION tINTERSECT
%token tPLANE tPOINT tPOLY tROTATE tSPOT tPRINT
%token tSCALE tSCREEN tSPHERE tSURFACE
%token tTHRESH tTRANSLATE tTRANSFORM tTRIANGLE tTRIANGLEUV tUP tEND
%token tTEXTURE tCHECKER tWOOD tCONTRAST tCUTOFF tCLOUD
%token tAMBIENT tDIFFUSE tREFLECT tTRANSP tSPECULAR tSPECPOW
%token tINDEX tATMOSPHERE tNOSHADOW tAREA tTRANSLU tTORUS
%token tEYESEP tSHADOWTRANSP tREPORT tVERBOSE tQUIET tWINDOW tCROP tSTRIPE
%token tMAP tUV tSPHERICAL tCYLINDRICAL tPLANAR
%token tIMAGE tSMOOTH tCOMPONENT tTEXTSURF tRANGE tTILE tSTARTTIME tFRAMELENGTH
%token tNAME tFILTER tGAUSS tBODY tSAMPLE tEXTINCT tWINDY tMOUNT
%token tSHUTTER tFRAMES
%type <sfnode> HeightField Poly Aggregate AggregateDef Primitive PrimType
%type <sfnode> Cone Cylinder Sphere Disc Box Triangle Plane Torus 
%type <sfnode> Blob Plane Torus Blob TransTextObj NamedObject
%type <mfvec3f> Polypoints
%type <v> Polypoint
%type <v> Vector
%type <f> Expr Float ParenExpr MExpr AnimExpr
%type <c> Color
%type <uv> Vec2d
%type <i> IExpr
%type <s> Filename Symtabent
%left '+' '-'
%left '*' '/' '%'
%left UMINUS
%right '^'
%%
Items		: /* empty */
		| Items Item
		;
Item		: Eyep
		| Lookp
		| Up
		| Fov
		| Screen
		| Window
		| Crop
		| Report
		| Aperture
		| Focaldist
		| Eyesep
		| Maxdepth
		| Sample
		| Filter
		| Contrast
		| Cutoff
		| Background
		| Shadowtransp
		| Light
		| SurfDef
		| CurSurf
		| Outfile
		| Instance
		| NameObject
		| GlobalEffects
		| Define
		| Frames
		| Starttime
		| Shutter
		| Framelength
    		| Print
		;
Instance	: TransTextObj
		{
		  AddInstance($1);
		}
                ;
TransTextObj	: NamedObject Transforms Textures
		{
		  $$ = NewNamedObject($1);
		}
		| Primitive Transforms Textures
		{
		  $$ = NewPrimitiveObject($1);
		}
		| Aggregate Transforms Textures
		{
		  $$ = NewAggregateObject($1);
		}
		;
Primitive	: PrimType
		;
PrimType	: Plane
		| Sphere
		| Box
		| Triangle
		| Cylinder
		| Cone
		| Poly
		| HeightField
		| Disc
		| Torus
		| Blob
		;
NameObject	: tNAME tSTRING TransTextObj
		{
		  DefineNamedObject($2, $3);
		}
		;
Aggdefs		: Aggdefs Aggdef
		|
		;
Aggdef		: Instance
		| SurfDef
		| CurSurf
		| NameObject
		;
Textures	: Textures Texture
		|
		;
Texture		: tTEXTURE Texturetype Transforms
		{
		  NotConverted("texture");
		}
		;
Texturetype	: tCHECKER Surface
		| tBLOTCH Expr Surface
		| tBUMP Expr
		| tMARBLE
		| tMARBLE Filename
		| tFBM Expr Expr Expr Expr IExpr Expr
		| tFBM Expr Expr Expr Expr IExpr Expr Filename
		| tFBMBUMP Expr Expr Expr Expr IExpr 
		| tWOOD
		| tGLOSS Expr 
		| tCLOUD Expr Expr Expr IExpr Expr Expr Expr
		| tSKY Expr Expr Expr IExpr Expr Expr
		| ImageText
		| tSTRIPE Surface Expr Expr OptMapping
		| tWINDY Expr Expr Expr Expr IExpr Expr Expr Expr
		| tMOUNT Filename Expr Expr
		;
ImageText	: ImageTextType ImageTextOptions
		;
ImageTextType	: tIMAGE Filename
		;
ImageTextOptions: ImageTextOptions ImageTextOption
		| /* EMPTY */
		;
ImageTextOption: tCOMPONENT SurfCompName
		| tTILE Expr Expr
		| tTEXTSURF Surface
		| tRANGE Expr Expr
		| tSMOOTH
		| Mapping
		;
NamedObject	: tOBJECT Surface tSTRING
		{
		  $$ = LookupNamedObject($3);
		}
		| tOBJECT tSTRING
		{
		  $$ = LookupNamedObject($2);
		}
		;
Transforms	: Transforms PostTransform
		| /* empty */
		;
PostTransform	: TransformType
		;
TransformType	: tSCALE AnimExpr AnimExpr AnimExpr
		{
		  NotConverted("scale");
		}
		| tTRANSLATE AnimExpr AnimExpr AnimExpr
		{
		  NotConverted("translate");
		}
		| tROTATE AnimExpr AnimExpr AnimExpr AnimExpr
		{
		  NotConverted("rotate");
		}
		| tTRANSFORM	AnimExpr AnimExpr AnimExpr
				AnimExpr AnimExpr AnimExpr
				AnimExpr AnimExpr AnimExpr
		{
		  NotConverted("transform");
		}
		| tTRANSFORM	AnimExpr AnimExpr AnimExpr
				AnimExpr AnimExpr AnimExpr
				AnimExpr AnimExpr AnimExpr
				AnimExpr AnimExpr AnimExpr
		{
		  NotConverted("transform");
		}
		;
Eyep		: tEYEP Vector Transforms
		{
		  NotConverted("eyep");
		}
		;
Lookp		: tLOOKP Vector
		{
		  NotConverted("lookp");
		}
		;
Up		: tUP Vector
		{
		  NotConverted("up");
		}
		;
Fov		: tFOV Expr Expr
		{
		  NotConverted("fov");
		}
		| tFOV Expr
		{
		  NotConverted("fov");
		}
		;
Sample		: tSAMPLE IExpr tJITTER
		{ /* not meaningful */ }
		| tSAMPLE IExpr tNOJITTER
		{ /* not meaningful */ }
		| tSAMPLE IExpr
		{ /* not meaningful */ }
		;
Filter		: tFILTER tBOX Expr
		{
		  NotConverted("filter");
		}
		| tFILTER tBOX
		{
		  NotConverted("filter");
		}
		| tFILTER tGAUSS Expr
		{
		  NotConverted("filter");
		}
		| tFILTER tGAUSS
		{
		  NotConverted("filter");
		}
		;
Starttime	: tSTARTTIME Expr
		{
		  NotConverted("starttime");
		}
		;
Frames		: tFRAMES IExpr
		{
		  NotConverted("frames");
		}
		;
Framelength	: tFRAMELENGTH Expr
		{
		  NotConverted("framelength");
		}
		;
Shutter		: tSHUTTER Expr
		{
		  NotConverted("shutter");
		}
		;
Contrast	: tCONTRAST Expr Expr Expr
		{ /* not meaningful */ }
		;
Cutoff		: tCUTOFF Intensity
		{ /* not meaningful */ }
		;
Screen		: tSCREEN IExpr IExpr 
		{ /* not meaningful */ }
		;
Window		: tWINDOW IExpr IExpr IExpr IExpr
		{ /* not meaningful */ }
		;
Crop		: tCROP Expr Expr Expr Expr
		{ /* not meaningful */ }
		;
Report		: tREPORT Verbose Quiet IExpr Filename
		{ /* not meaningful */ }
		| tREPORT Verbose Quiet IExpr
		{ /* not meaningful */ }
		| tREPORT Verbose Quiet Filename
		{ /* not meaningful */ }
		| tREPORT Verbose Quiet
		{ /* not meaningful */ }
		;
Verbose		: tVERBOSE
		{ /* not meaningful */ }
		|
		;
Quiet		: tQUIET
		{ /* not meaningful */ }
		|
		;
Aperture	: tAPERTURE Expr
		{
		  NotConverted("aperture");
		}
		;
Focaldist	: tFOCALDIST Expr
		{
		  NotConverted("focasdist");
		}
		;
Eyesep		: tEYESEP Expr
		{
		  NotConverted("eyesep");
		}
		;
Maxdepth	: tMAXDEPTH IExpr
		{ /* not meaningful */ }
		;
Background	: tBACKGROUND Color
		{
		  NotConverted("background");
		}
		;
Shadowtransp	: tSHADOWTRANSP
		{ /* not meaningful */ }
		;
Light		: LightType
		| LightType tNOSHADOW
		| tLIGHT Intensity tAMBIENT
		{
		  NotConverted("light");
		}
		| Lightdef tAREA Vector Vector IExpr Vector IExpr
		| Lightdef tAREA Vector Vector IExpr Vector IExpr tNOSHADOW
		;
LightType	: Lightdef tPOINT Vector
		| Lightdef tDIRECTIONAL Vector
		| Lightdef tEXTENDED Expr Vector
		| Lightdef tSPOT Vector Vector Expr
		| Lightdef tSPOT Vector Vector Expr Expr Expr
		;
Lightdef	: tLIGHT Intensity
		{
		  NotConverted("light");
		}
		;
CurSurf		: tAPPLYSURF Surface
		{
		  NotConverted("applysurf");
		}
		;
OptSurface	: Surface
		| /* EMPTY */
		;
Surface		: NamedSurf
		| ModifyNamedSurf
		| SurfSpec
		;
NamedSurf	: tSTRING 
		{
		  NotConverted("named surface");
		}
		| tCURSURF
		{
		  NotConverted("named surface");
		}
		;
ModifyNamedSurf : CopyNamedSurf SurfComponent SurfComponents
		| CopyCurSurf SurfComponent SurfComponents
		;
CopyNamedSurf	: tSTRING
		{
		  NotConverted("modify named surface");
		}
		;
CopyCurSurf	: tCURSURF
		{
		  NotConverted("modify current surface");
		}
		;
SurfSpec	: SurfComponent SurfComponents
		;
SurfDef		: tSURFACE tSTRING Surface
		{
		  NotConverted("surface");
		}
		| tSURFACE tSTRING
		{
		  NotConverted("surface");
		}
		;
SurfComponents	: SurfComponents SurfComponent
		| /* EMPTY */
		;
SurfComponent	: Ambient
		| Diffuse
		| Specular
		| Specpow
		| Body
		| Reflect
		| Transp
		| Extinct
		| Index
		| Translu
		| Noshadow
		;
Ambient		: tAMBIENT Color
		;
Diffuse		: tDIFFUSE Color
		;
Specular	: tSPECULAR Color
		;
Body		: tBODY Color
		;
Extinct		: tEXTINCT Expr
		;
Specpow		: tSPECPOW Expr
		;
Reflect		: tREFLECT Expr
		;
Transp		: tTRANSP Expr
		;
Index		: tINDEX Expr
		;
Translu		: tTRANSLU Expr Color Expr
		;
Noshadow	: tNOSHADOW
		{ /* not meaningful */ }
		;
HeightField	: tHEIGHTFIELD Surface Filename
		{
		  $$ = NewHeightField($3);
		}
		| tHEIGHTFIELD Filename
		{
		  $$ = NewHeightField($2);
		}
		;
Poly		: tPOLY OptSurface Polypoints
		{
		  $$ = NewPoly($3);
		}
		;
Polypoints	: /* empty */
		{
		  $$ = new MFVec3f;
		}
		| Polypoints Polypoint
		{
		  SFVec3f v($2.x,$2.y,$2.z);
		  $1->append(v); $$ = $1;
		}
		;
Polypoint	: Vector
		{
		  $$ = $1;
		}
		;
Aggregate	: AggregateDef
		;
AggregateDef	: AggregateCreate Aggdefs tEND
		{
		  $$ = EndAggregate();
		}
		;
AggregateCreate	: AggregateType
		;
AggregateType	: List
		| Grid
		| Csg
		;
List		: tLIST
		{
		  NewList();
		}
		;
Grid		: tGRID IExpr IExpr IExpr
		{
		  NewList();
		}
		;
Csg		: CombineOp
		;
CombineOp	: tUNION
		{
		  NewCSGUnion()
		}
		| tINTERSECT
		{
		  NewCSGIntersect();
		}
		| tDIFFERENCE
		{
		  NewCSGDifference();
		}
    		;
Cone		: tCONE OptSurface Expr Vector Expr Vector
		{
		  $$ = NewCone($3, $4, $5, $6);
		}
		;
Cylinder	: tCYL OptSurface Expr Vector Vector
		{
		  $$ = NewCylinder($3, $4, $5);
		}
		;
Sphere		: tSPHERE OptSurface Expr Vector
		{
		  $$ = NewSphere($3, $4);
		}
		;
Disc		: tDISC OptSurface Expr Vector Vector
		{
		  $$ = NewDisc($3, $4, $5);
		}
		;
Box		: tBOX OptSurface Vector Vector
		{
		  $$ = NewBox($3, $4);
		}
		;
Triangle	: tTRIANGLE OptSurface Vector Vector Vector
		{
		  $$ = NewFlatTriangle($3, $4, $5);
		}
		| tTRIANGLE OptSurface  Vector Vector
					Vector Vector
					Vector Vector
		{
		  $$ = NewSmoothTriangle($3, $4, $5, $6, $7, $8);
		}
		| tTRIANGLEUV OptSurface Vector Vector Vec2d
					 Vector Vector Vec2d
					 Vector Vector Vec2d
		{
		  $$ = NewTexturedTriangle($3, $4, $5, $6, $7, $8, $9, $10, $11);
		}
		;
Plane		: tPLANE OptSurface Vector Vector
		{
		  $$ = NewPlane($3, $4);
		}
		;
Torus		: tTORUS OptSurface Expr Expr Vector Vector
		{
		  $$ = NewTorus($3, $4, $5, $6);
		}
		;
Blob		: tBLOB OptSurface Expr MetaPoints
		{
		  $$ = NewBlob();
		}
		;
MetaPoints	: /* empty */
		| MetaPoints MetaPoint
		;
MetaPoint	: Expr Expr Expr Expr Expr 
		{}
		;
Outfile		: tOUTFILE Filename 
		{ /* not meaningful */ }
		;
GlobalEffects	: tATMOSPHERE Effects
		{
		  NotConverted("atmosphere");
		}
		| tATMOSPHERE IExpr Effects
		{
		  NotConverted("atmosphere");
		}
		;
Effects		: Effects Effect
		|
		;
Effect		: EffectType
		;
EffectType	: tMIST Color Color Expr Expr
		| tFOG Color Color
		| tFOGDECK Expr Expr Vector Expr IExpr Color Color
		;
Color		: Expr Expr Expr
		{
		  $$.r = $1; $$.g = $2; $$.b = $3;
		}
		;
Vector		: Expr Expr Expr
		{
		  $$.x = $1; $$.y = $2; $$.z = $3;
		}
		;
Vec2d		: Expr Expr 
		{
		  $$.u = $1; $$.v = $2;
		}
		;
OptMapping	: Mapping
		| /* EMPTY */
		;
Mapping		: tMAP MapMethod
		;
MapMethod	: tUV
		| tSPHERICAL
		| tSPHERICAL Vector Vector Vector
		| tCYLINDRICAL
		| tCYLINDRICAL Vector Vector Vector
		| tPLANAR
		| tPLANAR Vector Vector Vector
		;
SurfCompName	: tAMBIENT
		| tDIFFUSE
		| tBODY
		| tSPECULAR
		| tREFLECT
		| tTRANSP
		| tSPECPOW
		| tBUMP
		| tINDEX
		;
Intensity	: Expr {}
		| Color {}
		;
Print		: tPRINT Expr
		{ /* not meaningful */ }
                ;
Define		: tDEFINE tSTRING AnimExpr
		{
		  NotConverted("variables and functions");
		}
		;
IExpr		: Expr
		{
		  $$ = (int)$1;
		}
		;
Expr		: Float
		| ParenExpr
		;
AnimExpr	: Float
		| ParenExpr
		;
ParenExpr	: '(' MExpr ')'
		{
		  $$ = $2;
		}
		;
MExpr		: tFLOAT { $$ = $1 }
                | tSTRING 
		{
		  NotConverted("variables and functions"); $$ = 0.;
		}
		| Symtabent '(' MExpr ')'
		{
		  NotConverted("variables and functions"); $$ = 0.;
		}
		| Symtabent '(' MExpr ',' MExpr ')'
		{
		  NotConverted("variables and functions"); $$ = 0.;
		}
		| Symtabent '(' MExpr ',' MExpr ',' MExpr ')'
		{
		  NotConverted("variables and functions"); $$ = 0.;
		}
		| Symtabent '(' MExpr ',' MExpr ',' MExpr ',' MExpr ')'
		{
		  NotConverted("variables and functions"); $$ = 0.;
		}
		| Symtabent
			'(' MExpr ',' MExpr ',' MExpr ',' MExpr ',' MExpr ')'
		{
		  NotConverted("variables and functions"); $$ = 0.;
		}
		| '(' MExpr ')'
		{
		  $$ = $2;
		}
		| MExpr '+' MExpr
		{
		  $$ = $1 + $3;
		}
		| MExpr '-' MExpr
		{
		  $$ = $1 - $3;
		}
		| MExpr '*' MExpr
		{
		  $$ = $1 * $3;
		}
		| MExpr '/' MExpr
		{
		  $$ = $1 / $3;
		}
		| MExpr '%' MExpr
		{
		  $$ = (int)$1 % (int)$3;
		}
		| '-' MExpr %prec UMINUS
		{
		  $$ = -$2;
		}
		| '+' MExpr %prec UMINUS
		{
		  $$ =-$2;
		}
		| MExpr '^' MExpr
		{
		  $$ = pow($1, $3);
		}
		;
Float		: tFLOAT 
		{
		  $$ = $1;
		}
                | '-' tFLOAT {}
		{
		  $$ = -$2;
		}
                | '+' tFLOAT {}
		{
		  $$ = $2;
		}
		;
Filename	: tSTRING
                | tFILENAME
		;
Symtabent	: tSTRING
		;
%%
