aboutsummaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rw-r--r--bin/main.ml80
1 files changed, 64 insertions, 16 deletions
diff --git a/bin/main.ml b/bin/main.ml
index eb212d2..26375da 100644
--- a/bin/main.ml
+++ b/bin/main.ml
@@ -44,30 +44,78 @@ let run_file path =
| Ok statements -> (
match run_statements statements with Ok () -> () | Error () -> exit 1)
+let declarations statements =
+ List.filter
+ (function Sol.Ast.Directive ("Query", _) -> false | _ -> true)
+ statements
+
+(* Feeding statements into the session: declarations accumulate,
+ queries answer immediately, and a failure changes nothing, so the
+ session only ever holds an admitted program. *)
+let feed history statements =
+ match run_statements (history @ statements) with
+ | Ok () -> history @ declarations statements
+ | Error () -> history
+
+let strip_quotes s =
+ let n = String.length s in
+ if n >= 2 && s.[0] = '"' && s.[n - 1] = '"' then String.sub s 1 (n - 2)
+ else s
+
+let load_file history argument =
+ let path = strip_quotes argument in
+ match In_channel.with_open_text path In_channel.input_all with
+ | exception Sys_error message ->
+ prerr_endline message;
+ history
+ | contents -> (
+ match Sol.Front.parse_string contents with
+ | Error message ->
+ prerr_endline (path ^ ": " ^ message);
+ history
+ | Ok statements ->
+ let next = feed history statements in
+ if next != history then
+ Printf.printf "loaded %s: %d declarations, %d queries run.\n" path
+ (List.length (declarations statements))
+ (List.length statements - List.length (declarations statements));
+ next)
+
let repl () =
- print_endline "Sol. Statements accumulate; Query expression: ... runs.";
+ print_endline
+ "Sol. Statements accumulate; Query expression: ... runs; :help for commands.";
let rec loop history =
print_string "sol> ";
flush stdout;
match In_channel.input_line stdin with
| None -> ()
- | Some line when String.trim line = "" -> loop history
| Some line -> (
- match Sol.Front.parse_string line with
- | Error message ->
- prerr_endline message;
+ let line = String.trim line in
+ match String.index_opt line ' ' with
+ | _ when line = "" -> loop history
+ | _ when line = ":quit" -> ()
+ | _ when line = ":reset" ->
+ print_endline "session cleared.";
+ loop []
+ | _ when line = ":help" ->
+ print_endline
+ ":load FILE bring a program into the session (atomic: a rejected file changes nothing)\n\
+ :reset clear the session\n\
+ :quit leave";
+ loop history
+ | Some i when String.sub line 0 i = ":load" ->
+ loop
+ (load_file history
+ (String.trim (String.sub line i (String.length line - i))))
+ | _ when String.length line > 0 && line.[0] = ':' ->
+ prerr_endline "unknown command; :help lists them.";
loop history
- | Ok statements -> (
- let declarations =
- List.filter
- (function
- | Sol.Ast.Directive ("Query", _) -> false
- | _ -> true)
- statements
- in
- match run_statements (history @ statements) with
- | Ok () -> loop (history @ declarations)
- | Error () -> loop history))
+ | _ -> (
+ match Sol.Front.parse_string line with
+ | Error message ->
+ prerr_endline message;
+ loop history
+ | Ok statements -> loop (feed history statements)))
in
loop []