34
35:- module(term_info,
36 [ get_term_info/6,
37 with_source_file/3,
38 fetch_term_info/4
39 ]). 40
41:- use_module(library(apply)). 42:- use_module(library(lists)). 43:- use_module(library(option)). 44:- use_module(library(prolog_source)). 45:- use_module(library(clambda)). 46:- use_module(library(module_files)). 47:- use_module(library(transpose)). 48:- init_expansors. 49
50:- meta_predicate
51 with_source_file(+, -, 0),
52 get_term_info(+, ?, ?, 1, -, +),
53 transverse_apply_2(1, +, ?, ?, ?). 54
55get_term_info(M, Pattern, Term, AllChk, File, Options) :-
56 module_files(M, Files),
57 member(File, Files),
58 call(AllChk, File),
59 get_term_info_file(Pattern, Term, File, Options).
60
61ti_open_source(Path, In) :-
62 b_setval(ti_open_source, yes),
63 prolog_open_source(Path, In),
64 b_setval(ti_open_source, no).
65
66with_source_file(File, In, Goal) :-
67 prolog_canonical_source(File, Path),
68 print_message(informational, format("Reading ~w", Path)),
69 setup_call_cleanup(ti_open_source(Path, In),
70 Goal,
71 prolog_close_source(In)).
72
73fetch_term_info(Pattern, Term, Options, In) :-
74 ( ( option(line(Line), Options),
75 nonvar(Line)
76 ->seek(In, 0, bof, _),
77 prolog_source:seek_to_line(In, Line),
78 once(get_term_info_fd(In, Pattern, Term, Options))
79 ; get_term_info_fd(In, Pattern, Term, Options)
80 )
81 ; fail 82 ).
83
84get_term_info_file(Pattern, Term, File, Options) :-
85 with_source_file(File, In, fetch_term_info(Pattern, Term, Options, In)).
86
87get_term_info_fd(In, PatternL, TermL, Options1) :-
88 is_list(PatternL),
89 !,
90 foldl(\ (H-D)^O1^O^select_option(H, O1, O, D),
91 [subterm_positions(TermPos)-TermPos,
92 term_position(Pos)-Pos,
93 comments(Comments)-Comments,
94 variable_names(VN)-VN,
95 module(M)-M
96 ], Options1, OptionT),
97 PatternL = [_|PatternT],
98 length(PatternT, TN),
99 length(TSPVCMLL, TN),
100 maplist(get_term_info_each(In, OptionT), TSPVCMLL),
101 transpose(TSPVCMLL, TSPVCMLT),
102 maplist(append, TSPVCMLT, TSPVCMT, TSPVCMH),
103 transverse_apply_2(get_term_info_each(In, OptionT), TSPVCMH, TSPVCMT,
104 [TermL, TermPosL, [Pos|_], VNL, CommentsL, ModuleL],
105 [_, TermPosE, _, _, _, _]),
106 maplist(subsumes_term, PatternL, TermL),
107 append(CommentsL, Comments),
108 append(VNL, VN),
109 TermPosL = [TermPosI|_],
110 arg(2, TermPosE, To),
111 findall(From, ( Comments = [StreamPos-_|_],
112 stream_position_data(char_count, StreamPos, From)
113 ; arg(1, TermPosI, From)
114 ),
115 FromL),
116 min_list(FromL, From),
117 [M|_] = ModuleL, 118 TermPos = list_position(From, To, TermPosL, none).
119get_term_info_fd(In, Pattern, Term, Options1) :-
120 should_set_line(SetLine, Options1),
121 select_option(module(M), Options1, Options, M),
122 repeat,
123 '$current_source_module'(OM),
124 read_term(In, Term, [module(OM)|Options]),
125 ( Term == end_of_file
126 ->!,
127 fail
128 ; true
129 ),
130 set_line(SetLine),
131 ( member(ModDecl, [(:- module(M, _)), (:- module(M, _, _))]),
132 subsumes_term(ModDecl, Term),
133 Term = ModDecl
134 ->'$set_source_module'(_, M)
135 ; true
136 ),
137 subsumes_term(Pattern, Term).
138
139should_set_line(posline(Pos, Line), Options) :-
140 option(term_position(Pos), Options),
141 option(line(Line), Options),
142 !.
143should_set_line(no, _).
144
145set_line(no).
146set_line(posline(Pos, Line)) :-
147 stream_position_data(line_count, Pos, Line).
148
149transverse_apply(_, ListL, ListT, ListL, EL, EL) :- maplist(=([]), ListT).
150transverse_apply(Apply, ListH1, ListT, ListL, _, EL) :-
151 maplist(\ [_|L]^L^true, ListH1, ListH),
152 transverse_apply_2(Apply, ListH, ListT, ListL, EL).
153
154transverse_apply_2(Apply, ListH, ListT1, ListL, EL) :-
155 call(Apply, EL1),
156 maplist(\ E^[E|L]^L^true, EL1, ListT1, ListT),
157 transverse_apply(Apply, ListH, ListT, ListL, EL1, EL).
158
159get_term_info_each(In, Options, [T, S, P, V, C, M]) :-
160 '$current_source_module'(OM),
161 read_term(In, T, [subterm_positions(S), term_position(P), variable_names(V),
162 comments(C), module(OM)|Options]),
163 T \== end_of_file,
164 ( member(ModDecl, [(:- module(M, _)), (:- module(M, _, _))]),
165 subsumes_term(ModDecl, T),
166 T = ModDecl
167 ->'$set_source_module'(_, M)
168 ; M = OM
169 ).
170
171:- public read_terms/3. 172
173read_terms(In, TermOptsL, Options) :-
174 read_terms_opts(TermOptsL, In, Options, TermOptsL1, TermOptsT),
175 read_terms_opts_rec(In, Options, TermOptsL1, TermOptsT, TermOptsL).
176
177read_terms_opts([], _, _, TermOptsT, TermOptsT).
178read_terms_opts([_|T], In, Options1, [TermOpts|TermOptsL], TermOptsT) :-
179 read_term_opts(In, Options1, TermOpts),
180 read_terms_opts(T, In, Options1, TermOptsL, TermOptsT).
181
182read_term_opts(In, Options1, Term-Options) :-
183 copy_term(Options1, Options),
184 read_term(In, Term, Options).
185
186read_terms_opts_rec(_, _, TermOptsL, [], TermOptsL).
187read_terms_opts_rec(In, Options1, [_|TermOptsL1 ], [TermOpts|TermOptsT], TermOptsL) :-
188 read_term_opts(In, Options1, TermOpts),
189 read_terms_opts_rec(In, Options1, TermOptsL1, TermOptsT, TermOptsL)