]> Repositorios git - scryer-prolog.git/commitdiff
Enhanced command line
authornotoria <[email protected]>
Fri, 1 May 2020 13:57:50 +0000 (15:57 +0200)
committernotoria <[email protected]>
Fri, 1 May 2020 14:19:06 +0000 (16:19 +0200)
src/prolog/toplevel.pl

index 7072017ddd46fbfd2ac806a976288db4ead21260..05cb6b6eb01d98950ad39e8a07242e9e660b72ed 100644 (file)
 
-:- module('$toplevel', ['$repl'/1, consult/1, use_module/1, use_module/2]).
+:- module('$toplevel', ['$repl'/1, consult/1, use_module/1, use_module/2,
+                        argv/1]).
 
 :- use_module(library(charsio)).
 :- use_module(library(lists)).
 :- use_module(library(si)).
 
+:- dynamic(argv/1).
+
 '$repl'([_|Args]) :-
-    maplist(use_list_of_modules, Args),
-    false.
-'$repl'(_) :- repl.
+    \+ argv(_),
+    delegate_task(Args, []),
+    repl.
+'$repl'(_) :-
+    (   \+ argv(_) -> asserta(argv([]))
+    ;   true
+    ),
+    repl.
+
+delegate_task([], []).
+delegate_task([], Goals0) :-
+    asserta(argv([])),
+    reverse(Goals0, Goals),
+    run_goals(Goals),
+    repl.
+delegate_task([Arg0|Args], Goals0) :-
+    (   member(Arg0, ["-h", "--help"]) -> print_help(Args)
+    ;   member(Arg0, ["-v", "--version"]) -> print_version(Args)
+    ;   member(Arg0, ["-g", "--goal"]) -> gather_goal(g, Args, Goals0)
+    ;   member(Arg0, ["-t", "--toplevel"]) -> gather_goal(t, Args, Goals0)
+    ;   atom_chars(Mod, Arg0),
+        asserta(argv(Args)),
+        catch(use_module(Mod), E, print_exception(E)),
+        reverse(Goals0, Goals),
+        run_goals(Goals),
+        repl
+    ),
+    delegate_task(Args, Goals0).
+
+print_help(Args) :-
+    write('Usage: scryer-prolog [OPTIONS] FILE [ARGUMENTS]'),
+    nl, nl,
+    write('Options:'), nl,
+    write('   -h, --help           '),
+    write('Display this message'), nl,
+    write('   -v, --version        '),
+    write('Print version information and exit'), nl,
+    write('   -g, --goal GOAL      '),
+    write('Run the query GOAL'), nl,
+    write('   -t, --toplevel GOAL  '),
+    % write('                        '),
+    write('Run the query GOAL and halt'), nl,
+    halt.
+
+print_version(Args) :-
+    write('v0.8.120'), nl, % TODO: Something better is required here.
+    halt.
+
+gather_goal(Type, Args0, Goals) :-
+    length(Args0, N),
+    (   N < 1 ->
+            % throw(error(resource_error(not_enough_argument), run_goal/1))
+            write('caught: '),
+            write(error(resource_error(not_enough_argument), gather_goal/3)),
+            nl,
+            halt
+    ;   true
+    ),
+    [Goal1|Args] = Args0,
+    (   Type = g -> Goal = g(Goal1)
+    ;   Type = t -> Goal = t(Goal1)
+    ;   write('caught: '),
+        write(error(domain_error(not_arg_type, Type), gather_goal/3)), nl,
+        halt
+    ),
+    delegate_task(Args, [Goal|Goals]).
+
+ends_with_dot(Ls0) :-
+        reverse(Ls0, Ls),
+        layout_and_dot(Ls).
 
-use_list_of_modules(Mod0) :-
-    atom_chars(Mod, Mod0),
-    catch(use_module(Mod), E, print_exception(E)).
+layout_and_dot(['.'|_]).
+layout_and_dot([C|Cs]) :-
+        char_type(C, layout),
+        layout_and_dot(Cs).
+
+run_goals([]).
+run_goals([g(Goal0)|Goals]) :-
+    (   ends_with_dot(Goal0) -> Goal1 = Goal0
+    ;   append(Goal0, ".", Goal1)
+    ),
+    read_term_from_chars(Goal1, Goal),
+    (   catch(Goal, E, print_exception_warning(E))
+    ;   write('Warning: initialization failed for '),
+        write(Goal0), nl
+    ),
+    run_goals(Goals).
+run_goals([t(Goal0)|_]) :-
+    (   ends_with_dot(Goal0) -> Goal1 = Goal0
+    ;   append(Goal0, ".", Goal1)
+    ),
+    read_term_from_chars(Goal1, Goal),
+    (   catch(Goal, E, print_exception_warning(E))
+    ;   write('Warning: initialization failed for '),
+        write(Goal0), nl
+    ),
+    halt.
+run_goals([Goal|_]) :-
+    write('caught: '),
+    write(error(domain_error(not_arg_type, Goal), run_goals/1)), nl,
+    halt.
+
+print_exception_warning(E) :-
+    (  E == error('$interrupt_thrown', repl) -> nl % print the
+                                                   % exception on a
+                                                   % newline to evade
+                                                   % "^C".
+    ;  true
+    ),
+    write_term('Warning: ', [quoted(false), max_depth(20)]),
+    writeq(E),
+    nl.
 
 repl :-
     catch(read_and_match, E, print_exception(E)),