1:- module(
2 da_source,
3 [
4 da_source_subterm_span/5,
5 da_source_layout_span/4,
6 da_source_clause_cached_reference/2,
7 da_source_clause_reference/2,
8 da_clause_decompiled/4,
9 qualified/3,
10 da_source_file_offsets_line_column_pairs/3
11 ]
12 ). 13
14:- use_module(library(lists)). 15:- use_module(library(option)). 16:- use_module(library(prolog_clause)).
25:- predicate_options(da_source_subterm_span/5, 5, [pass_to(da_source_layout_span/4, 4)]).
29:- det(da_source_subterm_span/5). 30da_source_subterm_span(File, Layout, SubTermPositionPath, SubTermSpan, Options) :-
31 da_source_subterm_layout(Layout, SubTermPositionPath, SubTermLayout),
32 da_source_layout_span(File, SubTermLayout, SubTermSpan, Options).
37:- det(da_source_subterm_layout/3). 38da_source_subterm_layout(Layout, _Path, Layout) :-
39 var(Layout),
40 !.
41da_source_subterm_layout(term_position(_, _, _, _, PosL), [A|T], SPos) :-
42 nth1(A, PosL, Pos),
43 !,
44 da_source_subterm_layout(Pos, T, SPos).
45da_source_subterm_layout(brace_term_position(_,_,Pos), [1|T], SPos) :-
46 !,
47 da_source_subterm_layout(Pos, T, SPos).
48da_source_subterm_layout(parentheses_term_position(_,_,Pos), Path, SPos) :-
49 !,
50 da_source_subterm_layout(Pos, Path, SPos).
51da_source_subterm_layout(Layout, _Path, Layout).
52
53
54:- predicate_options(da_source_layout_span/4, 4, [port(atom)]).
58:- det(da_source_layout_span/4). 59da_source_layout_span(File, Layout, SourceSpan, Options) :-
60 option(port(Port), Options, call),
61 da_source_layout_port_span(File, Layout, Port, SourceSpan).
66:- det(da_source_layout_port_span/4). 67da_source_layout_port_span(File, Layout, Port, span(File, SL, SC, EL, EC)) :-
68 entry_port(Port),
69 !,
70 arg(1, Layout, SO),
71 arg(2, Layout, EO),
72 da_source_file_offsets_line_column_pairs(File, [SO, EO], [SL-SC, EL-EC]).
73da_source_layout_port_span(File, Layout, Port, span(File, SL, SC, EL, EC)) :-
74 exit_port(Port),
75 !,
76 arg(2, Layout, SO),
77 succ(SO, EO),
78 da_source_file_offsets_line_column_pairs(File, [SO, EO], [SL-SC, EL-EC]).
79da_source_layout_port_span(File, Layout, _Port, SourceSpan) :-
80 da_source_layout_functor_span(File, Layout, SourceSpan).
81
82
83entry_port(call) :- !.
84entry_port(cut_call(_)) :- !.
85entry_port(redo(0)) :- !.
86
87exit_port(fail) :- !.
88exit_port(exit) :- !.
89exit_port(cut_exit(_)) :- !.
90exit_port(exception(_)) :- !.
95:- det(da_source_layout_functor_span/3). 96da_source_layout_functor_span(File, SO-EO, span(File, SL, SC, EL, EC)) :-
97 !,
98 da_source_file_offsets_line_column_pairs(File, [SO, EO], [SL-SC, EL-EC]).
99da_source_layout_functor_span(File, term_position(_, _, SO, EO, _), span(File, SL, SC, EL, EC)) :-
100 da_source_file_offsets_line_column_pairs(File, [SO, EO], [SL-SC, EL-EC]).
105:- det(da_source_file_offsets_line_column_pairs/3). 106da_source_file_offsets_line_column_pairs(path(File), Offsets, Pairs) :-
107 !,
108 setup_call_cleanup(
109 ( prolog_clause:try_open_source(File, Stream),
110 set_stream(Stream, newline(detect))
111 ),
112 da_source_stream_offsets_line_column_pairs(Stream, Offsets, Pairs),
113 close(Stream)).
114da_source_file_offsets_line_column_pairs(reference(0), Offsets, Pairs) :- !, findall(0-0, member(_, Offsets), Pairs).
115da_source_file_offsets_line_column_pairs(reference(SourceReference), Offsets, Pairs) :-
116 da_source_clause_cached_reference(ClauseRef, SourceReference), 117 da_clause_decompiled(ClauseRef, Module, DecompiledClause, _),
118 setup_call_cleanup(new_memory_file(MemFile),
119 ( setup_call_cleanup(open_memory_file(MemFile, write, MemOut),
120 portray_clause(MemOut, DecompiledClause, [module(Module)]),
121 close(MemOut)),
122 setup_call_cleanup(open_memory_file(MemFile, read, MemIn),
123 da_source_stream_offsets_line_column_pairs(MemIn, Offsets, Pairs),
124 close(MemIn))),
125 free_memory_file(MemFile)).
130da_source_stream_offsets_line_column_pairs(_Stream, [], []) :- !.
131da_source_stream_offsets_line_column_pairs(Stream, [H0|T0], [Line-Column|T]) :-
132 da_source_stream_offset_line_column(Stream, H0, Line, Column),
133 da_source_stream_offsets_line_column_pairs(Stream, T0, T).
139da_source_stream_offset_line_column(Stream, Offset, Line, Column) :-
140 var(Offset),
141 !,
142 line_count(Stream, CurrentLine),
143 ( CurrentLine == Line
144 -> character_count(Stream, CurrentOffset),
145 Offset is CurrentOffset + Column
146 ; skip_line(Stream),
147 da_source_stream_offset_line_column(Stream, Offset, Line, Column)
148 ).
149da_source_stream_offset_line_column(Stream, Offset, Line, Column) :-
150 character_count(Stream, CurrentOffset),
151 ( CurrentOffset == Offset
152 -> line_count(Stream, Line),
153 line_position(Stream, Column)
154 ; get_code(Stream, _),
155 da_source_stream_offset_line_column(Stream, Offset, Line, Column)
156 ).
161:- det(da_source_clause_reference/2). 162da_source_clause_reference(ClauseRef, SourceReference) :-
163 ( da_source_clause_cached_reference(ClauseRef, LastReference)
164 -> succ(LastReference, SourceReference)
165 ; random_between(0, 16777216, SourceReference)
166 ),
167 asserta(da_source_clause_cached_reference(ClauseRef, SourceReference)).
172:- dynamic da_source_clause_cached_reference/2.
177:- det(da_clause_decompiled/4). 178da_clause_decompiled(ClauseRef, Module, DecompiledClause, VariablesOffset) :-
179 '$clause'(Head0, Body, ClauseRef, VariablesOffset),
180 qualified(Head0, Module, Head),
181 ( Body == true
182 -> DecompiledClause = Head
183 ; DecompiledClause = (Head :- Body)
184 ).
185
186
187qualified(Module:UnqualifiedGoal, Module, UnqualifiedGoal) :-
188 !.
189qualified('<meta-call>'(_Module0:Goal), Module, UnqualifiedGoal) :-
190 qualified(Goal, Module, UnqualifiedGoal),
191 !.
192qualified('<meta-call>'(Goal), Module, UnqualifiedGoal) :-
193 qualified(Goal, Module, UnqualifiedGoal),
194 !.
195
196qualified(UnqualifiedGoal, user, UnqualifiedGoal)
DAP library module for reasoning about Prolog sources
This module contains predicates for retrieving information about the spans and layouts of Prolog source terms for debugging purposes.
*/