/* SI 413 Fall 2011
 * spl.lpp
 * This is a scanner specification for the SPL programming language.
 * The semantic values are wither leaves in the AST or operator codes.
 */

%{
#include <iostream>
#include <cstdlib>
using namespace std;
#include "value.hpp"
#include "ast.hpp"
#include "spl.tab.hpp"

// Returns the type of comparison operator that we are seeing.
Oper getCompOp(const char* text) {
  switch(text[0]) {
    case '=': return EQ;
    case '!': return NE;
    case '>': return (text[1] == '=' ? GE : GT);
    case '<': return (text[1] == '=' ? LE : LT);
    default: exit(1); // never reached
  }
}
%}

%option noyywrap

%%

[0-9]+     {yylval.exp = new Num(atoi(yytext)); return NUM;}
true|false {yylval.exp = new BoolExp(yytext[0] == 't'); return BOOL;}
[+-]       {yylval.op = (yytext[0] == '+' ? ADD : SUB); return OPA;}
[*/]       {yylval.op = (yytext[0] == '*' ? MUL : DIV); return OPM;}
and|or     {yylval.op = (yytext[0] == 'a' ? AND : OR); return BOP;}
not        {yylval.op = NOTOP; return NOT;}
":="       {return ASN;}
"("        {return LP;}
")"        {return RP;}
"{"        {return LC;}
"}"        {return RC;}
";"        {return STOP;}
[><=]|([><!]=) {yylval.op = getCompOp(yytext); return COMP;}
if         {return IF;}
else       {return ELSE;}
while      {return WHILE;}
read       {return READ;}
write      {return WRITE;}
lambda     {return LAMBDA;}
new        {return NEW;}
[a-zA-Z0-9_]+ {yylval.id = new Id(yytext); return ID;}
<<EOF>>  { return 0; }
[ \t\n]+ { }
"#".*    { }
.        { cerr << "Unrecognized token!" << endl; exit(1); }
%%