64 lines
1.7 KiB
Prolog
64 lines
1.7 KiB
Prolog
:- module(diag, [wam_instructions/2]).
|
|
|
|
/** Diagnostics library
|
|
|
|
The predicate `wam_instructions/2` _decompiles_ a predicate so that
|
|
we can inspect its Warren Abstract Machine (WAM) instructions.
|
|
In this way, we can verify and reason about compiled programs,
|
|
and detect opportunities for optimization.
|
|
|
|
For example, we have:
|
|
|
|
```
|
|
?- use_module(library(lists)).
|
|
true.
|
|
?- use_module(library(diag)).
|
|
true.
|
|
?- use_module(library(format)).
|
|
true.
|
|
?- wam_instructions(append/3, Is),
|
|
maplist(portray_clause, Is).
|
|
switch_on_term(1,external(1),external(2),external(6),fail).
|
|
try_me_else(4).
|
|
get_constant(level(shallow),[],x(1)).
|
|
get_value(x(2),3).
|
|
proceed.
|
|
trust_me(0).
|
|
get_list(level(shallow),x(1)).
|
|
unify_variable(x(4)).
|
|
unify_variable(x(1)).
|
|
get_list(level(shallow),x(3)).
|
|
unify_value(x(4)).
|
|
unify_variable(x(3)).
|
|
execute(append,3).
|
|
Is = [switch_on_term(1,external(1),external(2),external(6),fail)|...].
|
|
```
|
|
*/
|
|
|
|
|
|
:- use_module(library(error)).
|
|
|
|
%% wam_instructions(+PI, -Instrs)
|
|
%
|
|
% _Instrs_ are the WAM instructions corresponding to predicate indicator _PI_.
|
|
|
|
wam_instructions(Clause, Listing) :-
|
|
( nonvar(Clause) ->
|
|
( Clause = Name / Arity ->
|
|
fetch_instructions(user, Name, Arity, Listing)
|
|
; Clause = Module : (Name / Arity) ->
|
|
fetch_instructions(Module, Name, Arity, Listing)
|
|
)
|
|
; throw(error(instantiation_error, wam_instructions/2))
|
|
).
|
|
|
|
|
|
fetch_instructions(Module, Name, Arity, Listing) :-
|
|
must_be(atom, Module),
|
|
must_be(atom, Name),
|
|
must_be(integer, Arity),
|
|
( Arity >= 0 ->
|
|
'$wam_instructions'(Module, Name, Arity, Listing)
|
|
; throw(error(domain_error(not_less_than_zero, Arity), wam_instructions/2))
|
|
).
|