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)
fun string_to_cstring s = "\""^(String.concat (List.map Char.toCString (String.explode s)))^"\""
%%

%header (functor LambdaSimpleLexFun(structure Tokens : LambdaSimple_TOKENS));

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


%%
\n|\013|\010	
        => (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));
"iszero" => (Tokens.ISZERO(!pos, !pos));
"#t"     => (Tokens.TRUE(!pos, !pos));
"#f"     => (Tokens.FALSE(!pos, !pos));
"fn"     => (Tokens.FN(!pos, !pos));
"if"     => (Tokens.IF(!pos, !pos));

{alpha}+ => (Tokens.VAR(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: " ^ (string_to_cstring yytext)));

