shithub: pprolog

ref: 88841b194dc86c9392a813f9b8b0cf16857acb93
dir: pprolog/loader.pl

View raw version
:- module(loader, []).

load_module_from_file(File) :-
	write('Loading file: '),
	write(File),
	nl,
	( atom_concat(_, '.pl', File)
	-> open(File, read, Stream)
	; atom_concat(File, '.pl', File1),
	  open(File1, read, Stream)
	),
	read_and_handle_terms(Stream, user, _),
	close(Stream),
	write('Loaded file: '),
	write(File),
	nl.

read_and_handle_terms(Stream, Module0, Module) :-
	( read_one_term(Stream, Term)
	-> handle_term(Term, Module0, Module1),
	   read_and_handle_terms(Stream, Module1, Module)
	; Module = Module0
	).

read_one_term(Stream, Term) :-
	consume_whitespace(Stream),
	peek_char(Stream, NextCh),
	NextCh \= end_of_file,
	read_term(Stream, Term, []).

whitespace(' ').
whitespace('	').
whitespace('
').

consume_whitespace(S) :-
	peek_char(S, Ch),
	( whitespace(Ch)
	-> get_char(S, _), consume_whitespace(S)
	; true
	).

handle_term(:- Directive, Module, NewModule) :-
	!,
	handle_directive(Directive, Module, NewModule).
handle_term(Head :- Body, Module, Module) :-
	!,
	Module:assertz(Head :- Body).
handle_term(Head --> Body, Module, Module) :-
	!,
	write('DCG RULE: '),
	write(Head --> Body),
	nl.
handle_term(Head, Module, Module) :-
	Module:assertz(Head).

handle_directive(op(Priority, Specifier, Operator), Module, Module) :-
	Module:op(Priority, Specifier, Operator).
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(D, Module, Module) :-
	write('Cannot handle directive: '),
	write(D),
	nl.

ensure_loads(_) :- fail.

ensure_load(F) :-
	( ensure_loads(F)
	-> true
	; asserta(ensure_loads(F)), load_module_from_file(F)
	).