structure Tokens = Tokens

type pos = int
type svalue = Tokens.svalue
type ('a, 'b) token = ('a, 'b) Tokens.token
type lexresult = (svalue, pos) token

exception Error
val pos = ref 1
fun inc x = x := ((!x) + 1)
val error = fn x => (print("ERROR (Line "^(Int.toString (!pos))^"): " ^ x ^ "\n"); raise Error)
val eof = fn () => Tokens.EOF(!pos, !pos)

%%

%header (functor ImpLexFun(structure Tokens : Imp_TOKENS));

alpha = [A-Za-z];
digit = [0-9];
ws = [\ \t];


%%
\n	=> (inc pos; lex());
{ws}+ 	=> (lex());
"+"	=> (Tokens.PLUS(!pos, !pos));
"-"	=> (Tokens.MINUS(!pos, !pos));
"*"	=> (Tokens.TIMES(!pos, !pos));
"("	=> (Tokens.LPAREN(!pos, !pos));
")"	=> (Tokens.RPAREN(!pos, !pos));
"{"	=> (Tokens.LBRACE(!pos, !pos));
"}"	=> (Tokens.RBRACE(!pos, !pos));
"="	=> (Tokens.EQUALS(!pos, !pos));
"<="	=> (Tokens.LESSEQ(!pos, !pos));
":="	=> (Tokens.ASSIGN(!pos, !pos));
";"     => (Tokens.SEMI(!pos, !pos));
"true" 	=> (Tokens.TRUE(!pos, !pos));
"false" => (Tokens.FALSE(!pos, !pos));
"not"	=> (Tokens.NOT(!pos, !pos));
"and"	=> (Tokens.AND(!pos, !pos));
"or"	=> (Tokens.OR(!pos, !pos));
"skip"	=> (Tokens.SKIP(!pos, !pos));
"if"	=> (Tokens.IF(!pos, !pos));
"then"	=> (Tokens.THEN(!pos, !pos));
"else"	=> (Tokens.ELSE(!pos, !pos));
"while"	=> (Tokens.WHILE(!pos, !pos));
"break" => (Tokens.BREAK(!pos, !pos));
{alpha}+ => (Tokens.LOC(yytext, !pos, !pos));
~?{digit}+ => (case (Int.fromString yytext) of NONE => (error "Bad integer")
				              | SOME n => (Tokens.INT(n, !pos, !pos)));
.	=> (error ("Invalid character found during lexing: " ^ yytext));
