/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4 -*- */

/* Scanner for the Faust language */

%{
#include "tree.hh"
#include "faustparser.hpp"
#if defined(WIN32)
#if !defined(__MINGW32__) && !defined(__MSYS__)
// We don't want to include compatibility.hh here, since it pulls in whole lot
// of unneeded stuff which breaks other things, so here's some stuff to make
// MSVC happy.
#include <io.h>
#define isatty _isatty
#define fileno _fileno
#define YY_NO_UNISTD_H
#endif
#else
#include "compatibility.hh"
#include "errormsg.hh"

#define YY_FATAL_ERROR lexerror
#endif

#define register		// suppress the deprecated 'register' warning

%}

DIGIT    [0-9]
ID       _*[a-zA-Z][_a-zA-Z0-9]*
LETTER   [a-zA-Z]
NUMBER   ({DIGIT}+"."{DIGIT}*|"."{DIGIT}+|{DIGIT}+)
WSPACE   [ \t\n]
TMACRO   \\{ID}(\[(\ *({ID}|{NUMBER}),?\ *)\])?(\{(\ *({ID}|{NUMBER}),?\ *)*\})*
NSID	 {ID}("::"{ID})*

%option yylineno
%option nounput
%x comment
%x doc
%x lst



%%


"/*"							BEGIN(comment);
<comment>[^*\x0a\x0d]*			/* eat anything that's not a '*' 		*/
<comment>"*"+[^*/\x0a\x0d]*		/* eat up '*'s not followed by '/'s 	*/
<comment>\x0a\x0d				/* no need to increment yylineno here 	*/
<comment>\x0a					/* no need to increment yylineno here 	*/
<comment>\x0d					/* no need to increment yylineno here 	*/
<comment>"*"+"/"				BEGIN(INITIAL);

"<mdoc>"						{ BEGIN(doc); return BDOC; }
<doc>.							return DOCCHAR; /* char by char, may be slow ?? */
<doc>\n							return DOCCHAR; /* keep newline chars */
<doc>"<notice/>"				return NOTICE;  /* autoclosing tag */
<doc>"<notice />"				return NOTICE;  /* autoclosing tag */
<doc>"<listing"					{ BEGIN(lst);		return BLST; } /* autoclosing tag */
<doc>"<equation>"				{ BEGIN(INITIAL); 	return BEQN; }
"</equation>"					{ BEGIN(doc); 		return EEQN; }
<doc>"<diagram>"				{ BEGIN(INITIAL); 	return BDGM; }
"</diagram>"					{ BEGIN(doc); 		return EDGM; }
<doc>"<metadata>"				{ BEGIN(INITIAL); 	return BMETADATA; }
"</metadata>"					{ BEGIN(doc); 		return EMETADATA; }
<doc>"</mdoc>"					{ BEGIN(INITIAL); 	return EDOC; }

<lst>"true"						return LSTTRUE;
<lst>"false"					return LSTFALSE;
<lst>"dependencies"				return LSTDEPENDENCIES;
<lst>"mdoctags"					return LSTMDOCTAGS;
<lst>"distributed"				return LSTDISTRIBUTED;
<lst>"="						return LSTEQ;
<lst>"\""						return LSTQ;
<lst>"/>"						{ BEGIN(doc); 	return ELST; }


{DIGIT}+    		return INT;

{DIGIT}+"f"                             return FLOAT;
{DIGIT}+"."{DIGIT}*                     return FLOAT;
{DIGIT}+"."{DIGIT}*"f"                  return FLOAT;
{DIGIT}+"."{DIGIT}*e[-+]?{DIGIT}+       return FLOAT;
{DIGIT}+"."{DIGIT}*e[-+]?{DIGIT}+"f"    return FLOAT;
{DIGIT}+e[-+]?{DIGIT}+                  return FLOAT;
{DIGIT}+e[-+]?{DIGIT}+"f"               return FLOAT;
"."{DIGIT}+                             return FLOAT;
"."{DIGIT}+"f"                          return FLOAT;
"."{DIGIT}+e[-+]?{DIGIT}+               return FLOAT;
"."{DIGIT}+e[-+]?{DIGIT}+"f"            return FLOAT;

":"   		return SEQ;
","   		return PAR;
"<:"   		return SPLIT;
"+>"   		return MIX;
":>"   		return MIX;
"~"   		return REC;

"+"   		return ADD;
"-"   		return SUB;
"*"   		return MUL;
"/"   		return DIV;
"%"   		return MOD;
"@"			return FDELAY;
"'"			return DELAY1;

"&"   		return AND;
"|"   		return OR;
"xor"       return XOR;

"<<"   		return LSH;
">>"   		return RSH;

"<"   		return LT;
"<="   		return LE;
">"   		return GT;
">="   		return GE;
"=="   		return EQ;
"!="   		return NE;

"_"			return WIRE;
"!"			return CUT;

";"			return ENDDEF;
"="			return DEF;
"("			return LPAR;
")"			return RPAR;
"{"			return LBRAQ;
"}"			return RBRAQ;
"["			return LCROC;
"]"			return RCROC;

"\\"		return LAMBDA;
"."			return DOT;
"with"		return WITH;
"letrec"	return LETREC;
"where"		return WHERE;

"mem"		return MEM;
"prefix"	return PREFIX;

"int"		return INTCAST;
"float"		return FLOATCAST;
"any"		return NOTYPECAST;

"rdtable"	return RDTBL;
"rwtable"	return RWTBL;

"select2"	return SELECT2;
"select3"	return SELECT3;

"ffunction"	return FFUNCTION;
"fconstant" return FCONSTANT;
"fvariable" return FVARIABLE;

"button"	return BUTTON;
"checkbox"	return CHECKBOX;
"vslider"	return VSLIDER;
"hslider"	return HSLIDER;
"nentry"	return NENTRY;
"vgroup"	return VGROUP;
"hgroup"	return HGROUP;
"tgroup"	return TGROUP;
"vbargraph"	return VBARGRAPH;
"hbargraph"	return HBARGRAPH;
"soundfile" return SOUNDFILE;

"attach"	return ATTACH;

"acos"		return ACOS;
"asin"		return ASIN;
"atan"		return ATAN;
"atan2"		return ATAN2;

"cos"		return COS;
"sin"		return SIN;
"tan"		return TAN;

"exp"		return EXP;
"log"		return LOG;
"log10"		return LOG10;
"^"         return POWOP;
"pow"       return POWFUN;
"sqrt"		return SQRT;

"abs"		return ABS;
"min"		return MIN;
"max"		return MAX;

"fmod"		return FMOD;
"remainder"	return REMAINDER;

"floor"		return FLOOR;
"ceil"		return CEIL;
"rint"		return RINT;

"seq"		return ISEQ;
"par"		return IPAR;
"sum"		return ISUM;
"prod"		return IPROD;

"inputs"	return INPUTS;
"outputs"	return OUTPUTS;

"import"	return IMPORT;
"component" return COMPONENT;
"library"   return LIBRARY;
"environment"   return ENVIRONMENT;

"waveform"  return WAVEFORM;
"route"     return ROUTE;
"enable"   	return ENABLE;
"control"   return CONTROL;

"declare"	return DECLARE;

"case"		return CASE;
"=>"		return ARROW;

"assertbounds" return ASSERTBOUNDS;
"lowest"  return LOWEST;
"highest"  return HIGHEST;

"singleprecision" return FLOATMODE;
"doubleprecision"  return DOUBLEMODE;
"quadprecision"    return QUADMODE;
"fixedpointprecision"    return FIXEDPOINTMODE;


"::"{NSID}   	return IDENT;
{NSID}   		return IDENT;

"\""[^\"]*"\""	return STRING;

"<"{LETTER}*"."{LETTER}">"	return FSTRING;
"<"{LETTER}*">"				return FSTRING;


"//"[^\x0a\x0d]*	/* eat up one-line comments */

[ \t\x0a\x0d]+		/* eat up whitespace */

<<EOF>>		yyterminate();

.           printf("extra text is : %s\n", yytext); return EXTRA;


%%
int yywrap() { return 1; }
