Skip to content

Commit f0602fb

Browse files
committed
Add wf:lazy_coalesce and its parse_transform
1 parent 2e58436 commit f0602fb

File tree

3 files changed

+90
-5
lines changed

3 files changed

+90
-5
lines changed

src/lib/wf_lazy_coalesce.erl

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
-module(wf_lazy_coalesce).
2+
-export([parse_transform/2]).
3+
4+
%% This module is the parse transform for the lazy_coalesce process
5+
6+
parse_transform(Forms, _Options) ->
7+
%dump_forms("lazy.forms", Forms),
8+
Forms2 = process_forms(Forms),
9+
%dump_forms("lazy.newforms", Forms2),
10+
Forms2.
11+
12+
%dump_forms(File, Forms) when is_list(Forms) ->
13+
% FormattedForms = [format_forms(F) || F <- Forms],
14+
% file:write_file(File, FormattedForms).
15+
%
16+
%format_forms(X) ->
17+
% io_lib:format("~p.~n~n", [X]).
18+
19+
process_forms(Forms) when is_list(Forms) ->
20+
[process_forms(F) || F <- Forms];
21+
process_forms(Form) when is_tuple(Form) ->
22+
case process_form(Form) of
23+
{ok, NewForm} ->
24+
NewForm;
25+
no_change ->
26+
List = tuple_to_list(Form),
27+
ProcessedList = process_forms(List),
28+
list_to_tuple(ProcessedList)
29+
end;
30+
process_forms(Form) ->
31+
Form.
32+
33+
process_form({call, LN, {remote, LN2, {atom, LN3, wf}, {atom, LN4, lazy_coalesce}}, [Args = {cons, _, _, _}] }) ->
34+
WrappedArgs = wrap_args(Args),
35+
%io:format("Wrapping wf:lazy_coalesce on ~p~n",[LN4]),
36+
NewForm = {call, LN, {remote, LN2, {atom, LN3, wf}, {atom, LN4, eval_coalesce}}, [WrappedArgs] },
37+
{ok, NewForm};
38+
process_form({call, LN, {remote, LN2, {atom, LN3, wf}, {atom, LN4, lazy_coalesce}}, Args = [_] }) ->
39+
{Line, Col} = case LN of
40+
{L, C} -> {L, C};
41+
L -> {L, 0}
42+
end,
43+
logger:warning("Call to wf:lazy_coalesce at line ~p (column ~p) is not explicitly listing each argument.~nThis cannot be made lazy. Converting it to the plain wf:coalesce/1~n", [Line, Col]),
44+
NewForm = {call, LN, {remote, LN2, {atom, LN3, wf}, {atom, LN4, coalesce}}, Args },
45+
{ok, NewForm};
46+
process_form(_X) ->
47+
no_change.
48+
%% if it's not one of the above things, then dive into it to process it.
49+
%{no_change, X}.
50+
51+
wrap_args({cons, LN, H, T}) ->
52+
%io:format("Found a cons...~n"),
53+
H2 = wrap_arg(H),
54+
T2 = wrap_args(T),
55+
{cons, LN, H2, T2};
56+
wrap_args(Nil = {nil, _}) ->
57+
%io:format("End of List~n"),
58+
Nil.
59+
60+
wrap_arg(Arg = {Type, _, _}) when Type==var;
61+
Type==atom;
62+
Type==integer;
63+
Type==string;
64+
Type==binary;
65+
Type==iolist ->
66+
%% This is a simple term, we can safely pass it through, as wrapping a Fun around it would be more overhead for the VM during runtime
67+
%io:format("Simple Arg (~p). Nothing to format...~n", [Arg]),
68+
Arg;
69+
wrap_arg(Arg) when is_tuple(Arg) ->
70+
LN = element(2, Arg),
71+
ClauseArgs = [],
72+
Guards = [],
73+
Clause = {clause, LN, ClauseArgs, Guards, [Arg]},
74+
%io:format("Wrapping Arg: ~p~n",[Arg]),
75+
WrappedArg = {'fun', LN, {clauses, [Clause]}},
76+
WrappedArg.

src/lib/wf_utils.erl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,14 @@ eval_coalesce([H|T]) when is_function(H, 0) ->
127127
eval_coalesce(T);
128128
X ->
129129
X
130-
end.
130+
end;
131+
eval_coalesce([H|T]) when ?WF_BLANK(H) ->
132+
eval_coalesce(T);
133+
eval_coalesce([H|_]) ->
134+
H.
131135

132136
%%% BASE RECORDS %%%
133137

134-
135138
get_actionbase(Term) -> ?COPY_TO_BASERECORD(actionbase, tuple_size(#actionbase{}), Term).
136139
get_elementbase(Term) -> ?COPY_TO_BASERECORD(elementbase, tuple_size(#elementbase{}), Term).
137140
get_validatorbase(Term) -> ?COPY_TO_BASERECORD(validatorbase, tuple_size(#validatorbase{}), Term).

src/wf.erl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
% vim: ts=4 sw=4 et
22
% Nitrogen Web Framework for Erlang
3-
% Copyright (c) 2008-2010 Rusty Klophaus
3+
% Copyright (c) 2008-2025 Rusty Klophaus
44
% See MIT-LICENSE for licensing information.
55

6-
-module (wf).
6+
-module(wf).
77
-include("wf.hrl").
8-
-compile (export_all).
8+
-compile(export_all).
99

1010

1111
%%% EXPOSE WIRE, UPDATE, FLASH %%%
@@ -135,6 +135,12 @@ f(S, Args) ->
135135
coalesce(L) ->
136136
_Value = wf_utils:coalesce(L).
137137

138+
eval_coalesce(L) ->
139+
_Value = wf_utils:eval_coalesce(L).
140+
141+
lazy_coalesce(L) ->
142+
_Value = coalesce(L).
143+
138144
%%% WF_REDIRECT %%%
139145
redirect(Url) ->
140146
action_redirect:redirect(Url).

0 commit comments

Comments
 (0)