22
33-export ([all /0 , init_per_suite /1 , end_per_suite /1 ]).
44-export ([
5+ guards /1 ,
56 consult /1 ,
67 beam_to_string /1 ,
78 parse_tree /1 ,
@@ -47,7 +48,7 @@ all() ->
4748 [parse_maybe , parse_maybe_else ]
4849 end ,
4950 Excluded = ? EXCLUDED_FUNS ++ DisabledMaybeTests ,
50- [F || {F , _ } <- Exports , not lists :member (F , Excluded )].
51+ [F || {F , 1 } <- Exports , not lists :member (F , Excluded )].
5152
5253-spec init_per_suite (config ()) -> config ().
5354init_per_suite (Config ) ->
@@ -69,6 +70,133 @@ enabled_features() ->
6970% % Test Cases
7071% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7172
73+ -spec guards (config ()) -> ok .
74+ guards (_Config ) ->
75+ % % One guard
76+ [[#{type := atom , attrs := #{value := single_guard }}]] =
77+ extract_guards (<<" f() -> case x of x when single_guard -> x end." >>),
78+ % % Join with , - and - andalso
79+ [
80+ [
81+ #{type := atom , attrs := #{value := first_guard }},
82+ #{type := atom , attrs := #{value := second_guard }}
83+ ]
84+ ] = extract_guards (<<" f() -> case x of x when first_guard, second_guard -> x end." >>),
85+ [
86+ [
87+ #{
88+ type := op ,
89+ content := [
90+ #{type := atom , attrs := #{value := first_guard }},
91+ #{type := atom , attrs := #{value := second_guard }}
92+ ],
93+ attrs := #{operation := 'andalso' }
94+ }
95+ ]
96+ ] =
97+ extract_guards (<<" f() -> case x of x when first_guard andalso second_guard -> x end." >>),
98+ [
99+ [
100+ #{
101+ type := op ,
102+ content := [
103+ #{type := atom , attrs := #{value := first_guard }},
104+ #{type := atom , attrs := #{value := second_guard }}
105+ ],
106+ attrs := #{operation := 'and' }
107+ }
108+ ]
109+ ] = extract_guards (<<" f() -> case x of x when first_guard and second_guard -> x end." >>),
110+ % % Join with ; - or - orelse
111+ [
112+ [#{type := atom , attrs := #{value := first_guard }}],
113+ [#{type := atom , attrs := #{value := second_guard }}]
114+ ] = extract_guards (<<" f() -> case x of x when first_guard; second_guard -> x end." >>),
115+ [
116+ [
117+ #{
118+ type := op ,
119+ content := [
120+ #{type := atom , attrs := #{value := first_guard }},
121+ #{type := atom , attrs := #{value := second_guard }}
122+ ],
123+ attrs := #{operation := 'orelse' }
124+ }
125+ ]
126+ ] =
127+ extract_guards (<<" f() -> case x of x when first_guard orelse second_guard -> x end." >>),
128+ [
129+ [
130+ #{
131+ type := op ,
132+ content := [
133+ #{type := atom , attrs := #{value := first_guard }},
134+ #{type := atom , attrs := #{value := second_guard }}
135+ ],
136+ attrs := #{operation := 'or' }
137+ }
138+ ]
139+ ] = extract_guards (<<" f() -> case x of x when first_guard or second_guard -> x end." >>),
140+ % % Combine ...
141+ [
142+ [#{type := atom , attrs := #{value := first_guard }}],
143+ [
144+ #{type := atom , attrs := #{value := second_guard }},
145+ #{type := atom , attrs := #{value := third_guard }}
146+ ]
147+ ] = extract_guards (
148+ <<" f() -> case x of x when first_guard; second_guard, third_guard -> x end." >>
149+ ),
150+ [
151+ [
152+ #{
153+ type := op ,
154+ content := [
155+ #{type := atom , attrs := #{value := first_guard }},
156+ #{
157+ type := op ,
158+ content := [
159+ #{type := atom , attrs := #{value := second_guard }},
160+ #{type := atom , attrs := #{value := third_guard }}
161+ ],
162+ attrs := #{operation := 'andalso' }
163+ }
164+ ],
165+ attrs := #{operation := 'orelse' }
166+ }
167+ ]
168+ ] =
169+ extract_guards (
170+ <<
171+ " f() ->\n "
172+ " case x of x when first_guard orelse second_guard andalso third_guard -> x end.\n "
173+ " "
174+ >>
175+ ),
176+ [
177+ [
178+ #{
179+ type := op ,
180+ content := [
181+ #{type := atom , attrs := #{value := first_guard }},
182+ #{
183+ type := op ,
184+ content := [
185+ #{type := atom , attrs := #{value := second_guard }},
186+ #{type := atom , attrs := #{value := third_guard }}
187+ ],
188+ attrs := #{operation := 'and' }
189+ }
190+ ],
191+ attrs := #{operation := 'or' }
192+ }
193+ ]
194+ ] =
195+ extract_guards (
196+ <<" f() -> case x of x when first_guard or second_guard and third_guard -> x end." >>
197+ ),
198+ ok .
199+
72200-spec consult (config ()) -> ok .
73201consult (_Config ) ->
74202 [{a }, {b }] = ktn_code :consult (" {a}. {b}." ),
@@ -203,3 +331,19 @@ parse_generators(_Config) ->
203331shuffle (List ) ->
204332 Items = [{rand :uniform (), X } || X <- List ],
205333 [X || {_ , X } <- lists :sort (Items )].
334+
335+ extract_guards (Source ) ->
336+ extract_guards ([ktn_code :parse_tree (Source )], []).
337+
338+ extract_guards ([], Guards ) ->
339+ Guards ;
340+ extract_guards ([Node | Nodes ], Guards ) ->
341+ extract_guards (
342+ ktn_code :content (Node ) ++
343+ lists :flatten ([maps :values (maps :get (node_attrs , Node , #{}))]) ++
344+ Nodes ,
345+ case ktn_code :node_attr (guards , Node ) of
346+ undefined -> Guards ;
347+ Gs -> Guards ++ Gs
348+ end
349+ ).
0 commit comments