ref: d7a4ae651e8334955ad39c4adf02e36b6c99ec2f
dir: /loader.pl/
:- module(loader, []). start(Args) :- catch((load_module_from_file('/sys/lib/prolog/repl.pl'), ReplLoaded = true), E, (print_exception(E), ReplLoaded = false)), ( ReplLoaded = true-> repl:repl(Args) ). print_exception(E) :- write('Caught exception while loading /sys/lib/prolog/repl.pl: '), write(E), nl. load_module_from_file(File) :- ( atom_concat(_, '.pl', File) -> open(File, read, Stream) ; atom_concat(File, '.pl', File1), open(File1, read, Stream) ), read_and_handle_terms(Stream, user, Module), close(Stream), run_initialization_goals(Module). run_initialization_goals(Module) :- ( retract(initialization_goals(Module, Goal)), Module:catch(Goal, E, loader:print_initialization_goal_error(Module, Goal, E)), fail % Backtrack to find more goals ; true ). print_initialization_goal_error(Module, Goal, Exception) :- write('Initialization goal threw exception:'), nl, write(' Module: '), write(Module), nl, write(' Goal: '), write(Goal), nl, write(' Exception: '), write(Exception), nl, nl. read_and_handle_terms(Stream, Module0, Module) :- ( read_one_term(Stream, Term, Singles) -> handle_term(Term, Singles, Module0, Module1), read_and_handle_terms(Stream, Module1, Module) ; Module = Module0 ). read_one_term(Stream, Term, Singles) :- consume_whitespace(Stream), peek_char(Stream, NextCh), NextCh \= end_of_file, read_term(Stream, Term, [singletons(Singletons)]), singleton_names(Singletons, Singles). whitespace(' '). whitespace(' '). whitespace(' '). consume_whitespace(S) :- peek_char(S, Ch), ( whitespace(Ch) -> get_char(S, _), consume_whitespace(S) ; true ). singleton_names([], []). singleton_names([Name = _|Rest0], Names) :- singleton_names(Rest0, Rest), ( atom_concat('_', _, Name) -> Names = Rest ; Names = [Name|Rest] ). handle_term(:- Directive, _, Module, NewModule) :- !, handle_directive(Directive, Module, NewModule). handle_term(Head :- Body, Singles, Module, Module) :- !, handle_clause(Head, Body, Singles, Module). handle_term(Head --> Body, Singles, Module, Module) :- !, write('DCG RULE: '), write(Head --> Body), nl. handle_term(Head, Singles, Module, Module) :- handle_clause(Head, true, Singles, Module). handle_clause(Head, Body, Singletons, Module) :- functor(Head, Name, Arity), PredicateIndicator = Name / Arity, warn_singletons(PredicateIndicator, Singletons), Module:'$insert_clause'(Head :- Body). handle_directive(dynamic(PI), Module, Module) :- is_nonvar(PI), ( list(PI) -> [First|Rest] = PI, handle_directive(dynamic(First), Module, Module), handle_directive(dynamic(Rest), Module, Module) ; is_predicate_indicator(PI), Name / Arity = PI, functor(Tmp, Name, Arity), Module:asserta(Tmp), Module:retract(Tmp) ). handle_directive(op(Priority, Specifier, Operator), Module, Module) :- Module:op(Priority, Specifier, Operator). handle_directive(initialization(T), Module, Module) :- loader:assertz(initialization_goals(Module, T)). handle_directive(include(F), Module, NewModule) :- open(F, read, S), read_and_handle_terms(S, Module, NewModule), close(S). handle_directive(ensure_loaded(F), Module, Module) :- ensure_load(F). handle_directive(module(NewModule, Exports), Module, NewModule) :- is_atom(NewModule), '$new_empty_module'(NewModule). % Do something about the exports as well. handle_directive(D, Module, Module) :- write('Cannot handle directive: '), write(D), nl. warn_singletons(_, []). warn_singletons(PI, Singles) :- write('Warning: singleton variables in '), write(PI), write(': '), write(Singles), write('.'), nl. ensure_loads(_) :- fail. ensure_load(F) :- ( ensure_loads(F) -> true ; loader:asserta(ensure_loads(F)), load_module_from_file(F) ).