diff --git a/main.ml b/main.ml index d6f12dc..9ca60af 100644 --- a/main.ml +++ b/main.ml @@ -1,31 +1,44 @@ open Printf +exception Reset_line (* used to indicate ^C is pressed *) + +let version = "%%VERSION%%" + let error_to_string e = try raise e with | Parser.Expected t -> sprintf "expected %s" t | Parser.Unexpected_token t -> sprintf "unexpected token \"%s\"" t - | Failure f -> f + | Failure f -> sprintf "error on %s" f | Division_by_zero -> "cannot divide by zero" | _ -> raise e let print_error e = printf "error: %s\n" @@ error_to_string e -(* simple REPL *) -let rec repl () : unit = +(* read-eval-print *) +let rep () : unit = printf "> "; let line = read_line () in - if line <> "quit" then begin - (try - line - |> Lex.tokenize - |> Parser.parse - |> Eval.eval - |> Ast.typ_to_string - |> printf "%s\n" - with - | e -> print_error e); - repl () - end + if line = "quit" then raise Exit; + line + |> Lex.tokenize + |> Parser.parse + |> Eval.eval + |> Ast.typ_to_string + |> printf "%s\n" -let () = repl () +let init_repl () = + let sigintf _ = raise Reset_line in + Sys.(set_signal sigint (Signal_handle sigintf)) + +(* simple REPL with error handling *) +let rec repl () : unit = + try rep (); repl () with + | Exit | End_of_file -> () + | Reset_line -> printf "\n"; repl () + | e -> print_error e; repl () + +let () = + init_repl (); + printf "Configurable Evaluator %s\n" version; (* banner *) + repl ()