/* lex.l,v 1.3 1995/04/08 19:53:03 explorer Exp */

/* 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 "libcommon/common.h"
#include "rayshade.h"
#ifdef STDC_HEADERS
#include <string.h>
#else
#include <strings.h>
#endif
#ifdef	ultrix
extern char *index _PROTO((const char *__s, int __c));
#endif
#include "liblight/light.h"
#include "libsurf/atmosphere.h"
#include "libsurf/surface.h"
#include "libtext/texture.h"
#include "libobj/geom.h"
#include "libobj/ifs.h"
#include "libobj/mountain.h"
#include "libobj/fractalobject.h"
#include "symtab.h"
#include "y.tab.h"

static void handlehash _PROTO((void));
static void skipcomments _PROTO((void));

extern int yylineno;
extern char yyfilename[];
%}

alpha	[a-zA-Z]
special	[\.\_]
digit	[0-9]
exp	[Ee][-+]?{digit}+
ident	{alpha}({alpha}|{digit}|{special})*
filename "/"?"/"?(("."|".."|{ident})"/")*{ident}
text	"\""[^\"]*"\""

%p 15000
%e 2500
%n 900

%%
[ \t\n]			;
^#			handlehash();
"/*"			skipcomments();
ambient			return tAMBIENT;
aperture		return tAPERTURE;
applysurf		return tAPPLYSURF;
area			return tAREA;
at			return tAT;
atmosphere		return tATMOSPHERE;
background		return tBACKGROUND;
bezier			return tBEZIER;
blob			return tBLOB;
cblob			return tCBLOB;
blotch			return tBLOTCH;
body			return tBODY;
box			return tBOX;
bspline			return tBSPLINE;
bump			return tBUMP;
cardinal		return tCARDINAL;
checker			return tCHECKER;
cloud			return tCLOUD;
coeffs			return tCOEFFS;
cone			return tCONE;
component		return tCOMPONENT;
contrast		return tCONTRAST;
crop			return tCROP;
cursurf			return tCURSURF;
cutoff			return tCUTOFF;
cylinder		return tCYL;
cylindrical		return tCYLINDRICAL;
define			return tDEFINE;
diffuse			return tDIFFUSE;
difference		return tDIFFERENCE;
directional		return tDIRECTIONAL;
disc			return tDISC;
end			return tEND;
extended		return tEXTENDED;
extinct			return tEXTINCT;
eyep			return tEYEP;
eyesep			return tEYESEP;
false			return tFALSE;
filter			return tFILTER;
fbm			return tFBM;
fbmbump			return tFBMBUMP;
flame			return tFLAME;
focaldist		return tFOCALDIST;
fog			return tFOG;
fogdeck			return tFOGDECK;
fov			return tFOV;
fracland		return tFRACLAND;
framelength		return tFRAMELENGTH;
frames			return tFRAMES;
gauss			return tGAUSS;
gloss			return tGLOSS;
gradient		return tGRADIENT;
grid			return tGRID;
hermite			return tHERMITE;
heightfield		return tHEIGHTFIELD;
image			return tIMAGE;
index			return tINDEX;
intersect		return tINTERSECT;
jitter			return tJITTER;
light			return tLIGHT;
linear			return tLINEAR;
list			return tLIST;
log			return tLOG;
lookp			return tLOOKP;
map			return tMAP;
marble			return tMARBLE;
matrix			return tMATRIX;
maxdepth		return tMAXDEPTH;
mount			return tMOUNT;
mist			return tMIST;
name			return tNAME;
nojitter		return tNOJITTER;
noshadow		return tNOSHADOW;
object			return tOBJECT;
outfile			return tOUTFILE;
patch			return tPATCH;   /* bicubic patch surface */
plane			return tPLANE;
planar			return tPLANAR;
point			return tPOINT;
poly			return tPOLY;
polygon			return tPOLY;
print			return tPRINT;
projector		return tPROJECTOR;
quiet			return tQUIET;
radial			return tRADIAL;
random			return tRANDOM;
range			return tRANGE;
reflect			return tREFLECT;
reflective		return tREFLECT;
report			return tREPORT;
resolution		return tSCREEN; /* A synonym for screen */
revlog			return tREVLOG;
rotate			return tROTATE;
rotspline		return tROTSPLINE;  /* Rotated cubic spline */
sample			return tSAMPLE;
scale			return tSCALE;
screen			return tSCREEN;
shadowtransp		return tSHADOWTRANSP;
shutter			return tSHUTTER;
sky			return tSKY;
smooth			return tSMOOTH;
sphere			return tSPHERE;
spherical		return tSPHERICAL;
specular		return tSPECULAR;
specpow			return tSPECPOW;
spot			return tSPOT;
starttime		return tSTARTTIME;
stripe			return tSTRIPE;
surface			return tSURFACE;
sweptsph		return tSWEPTSPH;
textsurf		return tTEXTSURF;
texture			return tTEXTURE;
tile			return tTILE;
torus			return tTORUS;
transform		return tTRANSFORM;
translate		return tTRANSLATE;
translu			return tTRANSLU;
translucency		return tTRANSLU;
transp			return tTRANSP;
transparent		return tTRANSP;
triangle		return tTRIANGLE;
triangleuv		return tTRIANGLEUV;
true			return tTRUE;
union			return tUNION;
up			return tUP;
uv			return tUV;
verbose			return tVERBOSE;
window			return tWINDOW;
windy			return tWINDY;
wood			return tWOOD;
xbezier			return tXBEZIER;
ybezier			return tYBEZIER;
zbezier			return tZBEZIER;
xcoeffs			return tXCOEFFS;
ycoeffs			return tYCOEFFS;
zcoeffs			return tZCOEFFS;
normalweighting		return tNORMALWEIGHTING;
minsize			return tMINSIZE;
lowpass			return tLOWPASS;
highpass		return tHIGHPASS;
ifs			return tIFS;
constant		return tCONSTANT;
bounding		return tBOUNDING;
fpoints			return tFPOINTS;
ftriangles		return tFTRIANGLES;
fentities		return tFENTITIES;
fentity			return tENTITY;
fractalobject		return tFRACTALOBJECT;
mountain		return tMOUNTAIN;
cubicspin		return tCUBICSPIN;

"=="			return tEQUAL;
"!="			return tNOTEQUAL;
"<"			return tLESSTHAN;
"<="			return tLESSEQUAL;
">"			return tGREATERTHAN;
">="			return tGREATEREQUAL;
"&&"			return tAND;
"||"			return tOR;

{digit}+ |
{digit}+"."{digit}*({exp})? |
{digit}*"."{digit}+({exp})? |
{digit}+{exp}		{yylval.d = atof(yytext); return tFLOAT;}
"$"{ident}		{yylval.c = strsave(yytext); return tENVVAR;}
{ident}			{yylval.c = strsave(yytext); return tIDENT;}
{filename}		{yylval.c = strsave(yytext); return tFILENAME;}
{text}			{
			  /* Remove quotes of text */
			  yylval.c = strsave(yytext + 1);
			  yylval.c[strlen(yylval.c) - 1] = '\0';
			  return tTEXT;
			}
.			return yytext[0];

%%
#ifdef yywrap
#undef yywrap
#endif
int
yywrap()
{
  return 1;
}

/*
 * Skip over comments.
 */
static void
skipcomments()
{
  char	c;

  while (1) {
    while (input() != '*')
      ;
    if ((c = input()) == '/')
      return;
    unput(c);
  }
}

/*
 * Deal with ccp-produced lines of the form:
 * # n "filename"
 * and
 * # n
 * Where filename is the name of the file being processed, and n is
 * the current line number in that file.
 */
static void
handlehash()
{
  char	buf[BUFSIZ];
  int	i;

  /*
   * Read the entire line into buf.
   */
  for (i = 0; (buf[i] = input()) != '\n'; i++)
    ;
  unput(buf[i]);		/* To make sure consecutive # lines work. */
  buf[i] = '\0';		/* Replace newline with EOS */

  /*
   * Complain if the line was not of the form #n "filename"
   */
  if ((i = sscanf(buf,"%d \"%[^\"]s\"", &yylineno, yyfilename)) == 0 &&
      (i = sscanf(buf," line %d \"%[^\"]s\"",&yylineno,yyfilename)) == 0) {
    RLerror(RL_PANIC, "Unknown '#' control (%s).\n",buf);
    exit(1);
  }
  if (i == 1 && (index(buf,'"') != (char *)NULL)) {
    /*
     * Filename was given as ""
     */
    (void)strcpy(yyfilename, "stdin");
  }
  yylineno--;  /* The newline we unput will increment yylineno */
}
