How do you interchangeably use the Terminal and Emacs REPL?

In the end I ended up using something like this:


let main_repl () =
  let arglen = 2 in
  if arglen = 2 then run_file repl_arg_path
  else if arglen = 1 then run_prompt ()
  else print_endline "For repl testing use arglen 2 or 1"

(* opam exec -- dune exec simple_interpreter /home/jacek/.bashrc *)
let main () =
  let arglen = Array.length Sys.argv in
  if arglen = 2 then run_file Sys.argv.(1)
  else if arglen = 1 then run_prompt ()
  else print_endline "Usage: dune exec simple_interpreter <file path> "

let running_in_repl =
  Sys.argv.(0) |> String.split_on_char '/' |> List.rev |> List.hd = "ocaml"
;;

(* ------------- *)
if running_in_repl then main_repl () else main ()

I’ve used !Sys.interactive in the past myself in similar situations.
I think it is a bit cleaner than running_in_repl, e.g., to support Windows… :person_shrugging:

2 Likes

Thank you! That is what I was looking for.

1 Like

Usually that’s the pattern I use for every program. It allows you to test your executables in the REPL, including witnessing exit codes:

let main : unit -> int = fun () -> …
let () = if !Sys.interactive then () else exit (main ())
1 Like