1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
%------------------------------------------------------------------------------%
% Copyright (C) 1999 INRIA/INSA.
%
% Author : Erwan Jahier <jahier@irisa.fr>
%
% define a monitor which is used in control_flow.op
:- import_module list.
:- type my_proc ---> proc_name/arity.
:- type edge ---> edge(my_proc, my_proc).
:- type graph == list(edge).
:- type stack == list(my_proc).
:- type collected_type --->
collected_type(stack, graph).
initialize(collected_type(["main"/2], [])).
filter(Event, AccIn, AccOut, continue) :-
Port = port(Event),
AccIn = collected_type(Stack, Graph),
(
Port = call
->
Proc = ancestor(Stack),
Proc2 = proc_name(Event) / proc_arity(Event),
Edge = edge(Proc, Proc2),
( member(Edge, Graph) ->
AccOut = collected_type([Proc2|Stack], Graph)
;
AccOut = collected_type([Proc2|Stack], [Edge|Graph])
)
;
Port = redo
->
Proc2 = proc_name(Event) / proc_arity(Event),
AccOut = collected_type([Proc2|Stack], Graph)
;
Port = fail
->
AccOut = collected_type(pop(Stack), Graph)
;
Port = exit
->
AccOut = collected_type(pop(Stack), Graph)
;
AccOut = AccIn
).
:- func ancestor(stack::in) = (my_proc::out) is det.
ancestor(Stack) = Anc :-
(
Stack = [],
Anc = "error"/0
;
Stack = [Anc|_]
).
:- func pop(stack::in) = (stack::out) is det.
pop(Stack0) = Stack :-
(
Stack0 = [],
Stack = []
;
Stack0 = [_|Stack]
).
|