Skip to content
Snippets Groups Projects
Commit d751b16d authored by Thorsten Wißmann's avatar Thorsten Wißmann
Browse files

Implement simple REPL

parent b2369796
No related branches found
No related tags found
No related merge requests found
external set_readline_name : string -> unit = "set_readline_name"
external readline : unit -> string option = "readline_stub"
external readline_prompt : string -> string option = "readline_prompt_stub"
external add_history : string -> unit = "add_history_stub"
external connect_to_curses : unit -> unit = "connect_to_curses"
external line_buffer : unit -> string = "line_buffer_stub"
......
......@@ -2,6 +2,7 @@
val set_readline_name : string -> unit
val readline : unit -> string option
val readline_prompt : string -> string option
val add_history : string -> unit
val connect_to_curses : unit -> unit
val line_buffer : unit -> string
......
......@@ -17,6 +17,7 @@ extern "C" {
value set_readline_name(value name);
value readline_stub(value unit);
value readline_prompt_stub(value prompt);
value add_history_stub(value str);
value connect_to_curses(value unit);
value readline_use_ocaml_callback(value unit);
......@@ -62,7 +63,21 @@ value readline_stub(value unit) {
if (line == NULL) {
CAMLreturn( Val_none );
} else {
line_data = caml_alloc_string(strlen(line)+1);
line_data = caml_alloc_string(strlen(line));
strcpy( String_val(line_data), line);
free(line);
CAMLreturn( Val_some( line_data ) );
}
}
value readline_prompt_stub(value prompt) {
CAMLparam1 (prompt);
CAMLlocal1( line_data );
char* line = readline(String_val(prompt));
if (line == NULL) {
CAMLreturn( Val_none );
} else {
line_data = caml_alloc_string(strlen(line));
strcpy( String_val(line_data), line);
free(line);
CAMLreturn( Val_some( line_data ) );
......
open Readline
type binding = string * (unit -> unit)
type settings = {
prompt: string;
bindings: binding list;
}
let session : settings option ref = ref (None)
let bind a b = (a,b)
(* (* for debugging purposes... *)
let cmp a b =
print_endline ("First string: >"^a^"<");
print_endline ("First string: >"^b^"<");
print_endline ("a=b -> >"^(string_of_bool (a = b))^"<");
print_endline ("a==b -> >"^(string_of_bool (a == b))^"<");
print_endline ("a<>b -> >"^(string_of_bool (a <> b))^"<")
*)
let start (settings: settings): unit =
session := Some (settings);
let findBinding (name: string) : binding =
let checkname (n,_) = (name = n) in
List.find checkname (settings.bindings)
in
let rec loop () =
if (!session = None) then ()
else begin
match (readline_prompt settings.prompt) with
| None -> ()
| Some line -> begin
let cmd = Str.split (Str.regexp "[ \n\t]+") line in
(match cmd with
| [] -> ()
| (v::_) when v = "" -> ()
| (name:: args) ->
try
let (_,callback) = findBinding name in
callback()
with Not_found -> begin
let msg = "Command »"^name^"« not found." in
print_endline msg
end
)
end;
loop()
end
in
loop()
let stop () =
session := None
type binding = string * (unit -> unit)
type settings = {
prompt: string;
bindings: binding list;
}
val bind : string -> (unit -> unit) -> binding
val start : settings -> unit
val stop : unit -> unit
......@@ -28,4 +28,14 @@ let main3 () =
Unix.sleep 3;
NCUI.screen_close()
let _ = main3 ()
let main4 () =
let session = {
Repl.prompt = "> ";
Repl.bindings = [
Repl.bind "exit" (fun () -> Repl.stop())
];
}
in
Repl.start session
let _ = main4 ()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment