%{

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "types.h"
#include "node_basic.h"
#include "str.h"
#include "free.h"
#include "civic.tab.h"
#include "globals.h"
#include "ctinfo.h"
#include "yyerror.h"


#define FILTER(token) \
  global.col += yyleng;  \
  return( token);

#define LINEBUF_SIZE 256
#define YY_NO_UNPUT
#define YY_NO_INPUT

int parse_int(const char* str)
{
    char *end;
    long num = strtol(str, &end, 10);
    if (end == str || *end != '\0' || errno == ERANGE
        || num > INT32_MAX || num < INT32_MIN)
        yyerror("Integer constant out of range.");
    return (int)num;
}

float parse_float(const char* str)
{
    char *end;
    float num = strtof(str, &end);
    if (end == str || *end != '\0' || errno == ERANGE)
        yyerror("Integer constant out of range.");
    return num;
}

%}

%p 6000 /* set positions to 6000 */
%e 2000 /* set nodes to 1100 */
%option noyywrap
%option nounput


%%

"["                                                {  FILTER(  BRACKET_L);  }
"]"                                                {  FILTER(  BRACKET_R);  }
"{"                                                {  FILTER(  BRACE_L);  }
"}"                                                {  FILTER(  BRACE_R);  }
"("                                                {  FILTER(  PAREN_L);  }
")"                                                {  FILTER(  PAREN_R);  }
","                                                {  FILTER(  COMMA);  }
";"                                                {  FILTER(  SEMICOLON);  }

"-"                                                {  FILTER(  MINUS);  }
"+"                                                {  FILTER(  PLUS);    }
"*"                                                {  FILTER(  STAR);    }
"/"                                                {  FILTER(  SLASH);    }
"%"                                                {  FILTER(  PERCENT);    }

"!"                                                {  FILTER(  NOT);  }
"<="                                               {  FILTER(  LE);        }
"<"                                                {  FILTER(  LT);        }
">="                                               {  FILTER(  GE);        }
">"                                                {  FILTER(  GT);        }
"=="                                               {  FILTER(  EQ);        }
"!="                                               {  FILTER(  NE);        }
"&&"                                               {  FILTER(  AND);        }
"||"                                               {  FILTER(  OR);        }

"?"                                                {  FILTER(  QUESMARK);}
":"                                                {  FILTER(  COLON);}

"="                                                {  FILTER(  LET);        }

"true"                                             {  FILTER(  TRUEVAL);  }
"false"                                            {  FILTER(  FALSEVAL);  }

"void"                                             {  FILTER (VOID); }

"bool"                                             {  yylval.ctype = TY_bool;
                                                      FILTER (TYPE);
                                                   }

"int"                                              {  yylval.ctype = TY_int;
                                                      FILTER (TYPE);
                                                   }

"float"                                            {  yylval.ctype = TY_float;
                                                      FILTER (TYPE);
                                                   }

"return" { FILTER (RETURN); }
"for" { FILTER (FOR); }
"do" { FILTER (DO); }
"while" { FILTER (WHILE); }
"if" { FILTER (IF); }
"else" { FILTER (ELSE); }
"extern" { FILTER (EXTERN); }
"export" { FILTER (EXPORT); }

[A-Za-z][A-Za-z0-9_]*                              {  yylval.id  =  STRcpy(yytext);
                                                      FILTER(  ID);
                                                   }

[0-9]*\.[0-9]*([eE][+-]?[0-9]+)?                   {  yylval.cflt = parse_float(yytext);
                                                      FILTER  (FLOAT);
                                                   }


[0-9]+                                             {  yylval.cint=parse_int(yytext);
                                                      FILTER(  NUM);
                                                   }

"/*"([^*]|(\*+[^*/]))*\*+\/                        {}
"//".*$                                            {}
"#".*$                                             {}

\n.*                                               {  global.line  +=  1;
                                                      global.col = 0;
                                                      yyless(1);
                                                   }
[ \t]                                              { global.col += yyleng; }
