From: J.J. Tolton Date: Fri, 7 Nov 2025 00:02:30 +0000 (-0500) Subject: -t custom toplevel option X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=768f7ce9a77db599950288b0d1027b561657c319;p=scryer-prolog.git -t custom toplevel option - Add -t FLAG to specify custom toplevel (arity 0 predicate) - Default toplevel is 'repl' if -t is not specified - Using `-t halt` achieves original goal of guaranteed termination - Custom toplevels enable flexible exit strategies (e.g., server mode) - Update help text to document -t flag Examples: scryer-prolog -t halt program.pl # Exits after execution scryer-prolog -t my_repl program.pl # Custom REPL scryer-prolog program.pl # Default REPL Co-Authored-By: J.J.'s Robot --- diff --git a/src/toplevel.pl b/src/toplevel.pl index 0727aee0..18f5c799 100644 --- a/src/toplevel.pl +++ b/src/toplevel.pl @@ -16,6 +16,7 @@ :- dynamic(disabled_init_file/0). :- dynamic(started/0). +:- dynamic(custom_toplevel/1). load_scryerrc :- ( '$home_directory'(HomeDir) -> @@ -53,7 +54,13 @@ start_repl :- ; true ), (\+ disabled_init_file -> load_scryerrc ; true), - repl. + start_toplevel. + +start_toplevel :- + ( custom_toplevel(Goal) -> + user:call(Goal) + ; repl + ). args_consults_goals([], [], []). args_consults_goals([Arg|Args], Consults, Goals) :- @@ -71,12 +78,13 @@ delegate_task([], Goals0) :- args_consults_goals(Goals1, Consults, Goals), run_goals(Consults), run_goals(Goals), - repl. + start_toplevel. delegate_task([Arg0|Args], Goals0) :- ( ( member(Arg0, ["-h", "--help"]) -> print_help ; member(Arg0, ["-v", "--version"]) -> print_version ; member(Arg0, ["-g", "--goal"]) -> gather_goal(g, Args, Goals0) + ; member(Arg0, ["-t"]) -> gather_toplevel(Args, Goals0) ; member(Arg0, ["-f"]) -> disable_init_file ; member(Arg0, ["--no-add-history"]) -> ignore_machine_arg ), @@ -96,6 +104,8 @@ print_help :- write('Print version information and exit'), nl, write(' -g, --goal GOAL '), write('Run the query GOAL'), nl, + write(' -t GOAL '), + write('Use GOAL as custom toplevel (arity 0 predicate)'), nl, write(' -f '), write('Fast startup. Do not load initialization file (~/.scryerrc)'), nl, write(' --no-add-history '), @@ -117,6 +127,17 @@ gather_goal(Type, Args0, Goals) :- Gs =.. [Type, Gs1], delegate_task(Args, [Gs|Goals]). +gather_toplevel(Args0, Goals0) :- + length(Args0, N), + ( N < 1 -> print_help, halt + ; true + ), + [TopLevel|Args] = Args0, + atom_chars(Goal, TopLevel), + retractall(custom_toplevel(_)), + asserta(custom_toplevel(Goal)), + delegate_task(Args, Goals0). + disable_init_file :- asserta('disabled_init_file'). @@ -154,7 +175,7 @@ run_goals([g(Gs0)|Goals]) :- !, Exception, ( write_term(Goal, [variable_names(VNs),double_quotes(DQ)]), write(' causes: '), - write_term(Exception, [double_quotes(DQ)]), nl % halt? + write_term(Exception, [double_quotes(DQ)]), nl ) ) -> true ; write('% Warning: initialization failed for: '),