-
Notifications
You must be signed in to change notification settings - Fork 123
/
atts.pl
114 lines (99 loc) · 3.56 KB
/
atts.pl
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
:- module(atts, [op(1199, fx, attribute),
term_attributed_variables/2]).
:- use_module(library(dcgs)).
:- use_module(library(error)).
:- use_module(library(terms)).
/* represent the list of attributes belonging to a variable,
of a particular module, as a list of terms of the form
Module:put_atts(V, ListOfAtts). */
'$default_attr_list'(Module, V) -->
( { Module:get_atts(V, Attributes) } ->
'$default_attr_list'(Attributes, Module, V)
; []
).
'$default_attr_list'([PG | PGs], Module, AttrVar) -->
[Module:put_atts(AttrVar, PG)],
'$default_attr_list'(PGs, Module, AttrVar).
'$default_attr_list'([], _, _) --> [].
'$absent_attr'(V, Module, Attr) :-
( '$get_from_attr_list'(V, Module, Attr) ->
false
; true
).
'$copy_attr_list'(L, _Module, []) :- var(L), !.
'$copy_attr_list'([Module0:Att|Atts], Module, CopiedAtts) :-
( Module0 == Module ->
CopiedAtts = [Att|CopiedAtts0],
'$copy_attr_list'(Atts, Module, CopiedAtts0)
; '$copy_attr_list'(Atts, Module, CopiedAtts)
).
user:term_expansion(Term0, Terms) :-
nonvar(Term0),
Term0 = (:- attribute Atts),
nonvar(Atts),
prolog_load_context(module, Module),
phrase(expand_terms(Atts, Module), Terms).
expand_terms(Atts, Module) -->
put_attrs_var_check,
put_attrs(Atts, Module),
get_attrs_var_check(Module),
get_attrs(Atts, Module).
put_attrs_var_check -->
[(put_atts(Var, Attr) :- nonvar(Var),
throw(error(uninstantiation_error(Var), put_atts/2))),
(put_atts(Var, Attr) :- var(Attr),
throw(error(instantiation_error, put_atts/2)))].
get_attrs_var_check(Module) -->
[(get_atts(Var, Attr) :- nonvar(Var),
throw(error(uninstantiation_error(Var), get_atts/2))),
(get_atts(Var, Attr) :- var(Attr),
!,
'$get_attr_list'(Var, Ls),
nonvar(Ls),
atts:'$copy_attr_list'(Ls, Module, Attr))].
put_attrs(Name/Arity, Module) -->
put_attr(Name, Arity, Module),
[(put_atts(Var, Attr) :- lists:maplist(Module:put_atts(Var), Attr), !)].
put_attrs((Name/Arity, Atts), Module) -->
{ nonvar(Atts) },
put_attr(Name, Arity, Module),
put_attrs(Atts, Module).
get_attrs(Name/Arity, Module) -->
get_attr(Name, Arity, Module).
get_attrs((Name/Arity, Atts), Module) -->
{ nonvar(Atts) },
get_attr(Name, Arity, Module),
get_attrs(Atts, Module).
put_attr(Name, Arity, Module) -->
{ functor(Attr, Name, Arity) },
[(put_atts(V, +Attr) :-
!,
'$put_to_attr_list'(V, Module, Attr)),
(put_atts(V, Attr) :-
!,
'$put_to_attr_list'(V, Module, Attr)),
(put_atts(V, -Attr) :-
!,
'$del_from_attr_list'(V, Module, Attr))].
get_attr(Name, Arity, Module) -->
{ functor(Attr, Name, Arity) },
[(get_atts(V, +Attr) :-
!,
functor(Attr, _, _),
atts:'$get_from_attr_list'(V, Module, Attr)),
(get_atts(V, Attr) :-
!,
functor(Attr, _, _),
atts:'$get_from_attr_list'(V, Module, Attr)),
(get_atts(V, -Attr) :-
!,
functor(Attr, _, _),
atts:'$absent_attr'(V, Module, Attr))].
user:goal_expansion(Term, M:put_atts(Var, Attr)) :-
nonvar(Term),
Term = put_atts(Var, M, Attr).
user:goal_expansion(Term, M:get_atts(Var, Attr)) :-
nonvar(Term),
Term = get_atts(Var, M, Attr).
term_attributed_variables(Term, Vars) :-
'$term_attributed_variables'(Term, Vars).