summaryrefslogtreecommitdiff
path: root/src/interactive.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/interactive.ml')
-rw-r--r--src/interactive.ml68
1 files changed, 66 insertions, 2 deletions
diff --git a/src/interactive.ml b/src/interactive.ml
index 12a1be64..0fad3caf 100644
--- a/src/interactive.ml
+++ b/src/interactive.ml
@@ -48,21 +48,85 @@
(* SUCH DAMAGE. *)
(**************************************************************************)
+open Ast
+open Ast_util
+open Printf
+
let opt_interactive = ref false
let opt_emacs_mode = ref false
let opt_suppress_banner = ref false
let env = ref Type_check.initial_env
-let ast = ref (Ast.Defs [])
+let ast = ref (Defs [])
let arg str =
("<" ^ str ^ ">") |> Util.yellow |> Util.clear
let command str =
- (":" ^ str) |> Util.green |> Util.clear
+ str |> Util.green |> Util.clear
+
+type action =
+ | ArgString of string * (string -> action)
+ | ArgInt of string * (int -> action)
+ | Action of (unit -> unit)
let commands = ref []
+
+let reflect_typ action =
+ let open Type_check in
+ let rec arg_typs = function
+ | ArgString (_, next) -> string_typ :: arg_typs (next "")
+ | ArgInt (_, next) -> int_typ :: arg_typs (next 0)
+ | Action _ -> []
+ in
+ function_typ (arg_typs action) unit_typ no_effect
+
+let generate_help name help action =
+ let rec args = function
+ | ArgString (hint, next) -> arg hint :: args (next "")
+ | ArgInt (hint, next) -> arg hint :: args (next 0)
+ | Action _ -> []
+ in
+ let args = args action in
+ let help = match String.split_on_char ':' help with
+ | [] -> assert false
+ | (prefix :: splits) ->
+ List.map (fun split ->
+ match String.split_on_char ' ' split with
+ | [] -> assert false
+ | (subst :: rest) ->
+ if Str.string_match (Str.regexp "^[0-9]+") subst 0 then
+ let num_str = Str.matched_string subst in
+ let num_end = Str.match_end () in
+ let punct = String.sub subst num_end (String.length subst - num_end) in
+ List.nth args (int_of_string num_str) ^ punct ^ " " ^ String.concat " " rest
+ else
+ command (":" ^ subst) ^ " " ^ String.concat " " rest
+ ) splits
+ |> String.concat ""
+ |> (fun rest -> prefix ^ rest)
+ in
+ sprintf "%s %s - %s" Util.(name |> green |> clear) (String.concat ", " args) help
+let run_action cmd argument action =
+ let args = String.split_on_char ',' argument in
+ let rec call args action =
+ match args, action with
+ | (x :: xs), ArgString (hint, next) ->
+ call xs (next (String.trim x))
+ | (x :: xs), ArgInt (hint, next) ->
+ let x = String.trim x in
+ if Str.string_match (Str.regexp "^[0-9]+$") x 0 then
+ call xs (next (int_of_string x))
+ else
+ print_endline (sprintf "%s argument %s must be an non-negative integer" (command cmd) (arg hint))
+ | _, Action act ->
+ act ()
+ | _, _ ->
+ print_endline (sprintf "Bad arguments for %s, see (%s %s)" (command cmd) (command ":help") (command cmd))
+ in
+ call args action
+
let register_command ~name:name ~help:help action =
commands := (":" ^ name, (help, action)) :: !commands