:- module(pio, [ phrase_from_file/2, % :Grammarbody, +File phrase_from_file/3, % :Grammarbody, +File, +Options phrase_of_from_file/4, % :Grammarbody, :Reader, +File, +Options rider_to_lazy_list/3, % :Reader(Stream, Xs0,Xs),Stream, -LazyList stream_to_lazy_list/2, % :Stream, -LazyList % SWI compatibility run/0 ]). /** Pure, phrase based, Prolog I/O This library provides side effect free I/O. Files can now be processed in a pure side effect free manner with DCGs. Many Prolog predicates only read data from a file, those programs can be made side effect free. @author Ulrich Neumerkel */ :- use_module(library(error)). %% phrase_from_file(:Grammar, +File) is nondet. % % == % ... --> [] | [_], ... . % ?- phrase_from_file((..., "searchstring", ...), myfile). :- op(950,fy, [$]). $(X) :- copy_term_nat(X,Y),numbervars(Y,0,_),portray_clause(call:Y), X, copy_term_nat(X,Z),numbervars(Z,0,_),portray_clause(exit:Z). %$(X) :- % copy_term_nat(X,Y),numbervars(Y,0,_),portray_clause(fail:Y), % fail. :- meta_predicate phrase_from_file(:,+). :- meta_predicate phrase_from_file(:,+,+). % debatable :- meta_predicate phrase_of_from_file(:,:,+,+). :- load_foreign_files([plstream], [], initIO). %run :- phrase_of_from_file("a",swi_read_pending_input,a,[]). run :- setup_call_cleanup( $swi_open(a,read,Stream), ( $rider_to_lazy_list(swi_read_pending_input,Stream,Xs), Xs = "a" ), $swi_close(Stream)). phrase_from_file(Nonterminal, File) :- phrase_from_file(Nonterminal, File, []). phrase_from_file(Nonterminal, File, Options) :- phrase_of_from_file(Nonterminal, swi_read_pending_input, File, Options). phrase_of_from_file(Nonterminal, Reader, File, Options) :- must_be(list, Options), must_be(oneof([[]]), Options), setup_call_cleanup( $swi_open(File, read, Stream), ( rider_to_lazy_list(Reader,Stream, Xs), phrase(Nonterminal, Xs) ), swi_close(Stream)). %% stream_to_lazy_list(+Stream, -Xs) is det. % stream_to_lazy_list(Stream, Xs) :- rider_to_lazy_list(swi_read_pending_input,Stream, Xs). rider_to_lazy_list(Reader,Stream, Xs) :- swi_stream_property(Stream, position(Pos)), freeze(Xs, $step(Reader,Stream, Pos, Xs)). p(_). step(Reader,Stream, Pos, Xs0) :- $swi_set_stream_position(Stream, Pos), ( $swi_at_end_of_stream(Stream) -> Xs0 = [] ; %call(Reader,Stream, Xs0,Xs), $phrase(call(Reader,Stream), Xs0, Xs), $rider_to_lazy_list(Reader,Stream, Xs) ). tokenwise(Method,Stream) --> [Token], {call(Method, Stream, Token)}.