defmodule Dec do alias Dec.Pipeline, as: Pipeline defmacro __using__(_) do quote do import Dec, only: [dec: 2] end end defmacro dec(head, do: block) do {:__block__, _, [dec | statements]} = block dec_fun = make_dec_fn(dec) base_fun = {:fn, [], [{:->, [], [[], {:__block__, [], statements}]}]} expr = quote do unquote(dec_fun).(unquote(base_fun)).() end quote do Kernel.def(unquote(head), do: unquote(expr)) end end def make_dec_fn({:|>, _, _} = ppln) do {dec, items} = ppln |> Pipeline.split() {:dec, arg1, arg2} = dec arg_name = :base_function f = {arg_name, arg1, arg2} ppln = Pipeline.combine(items, f) {:fn, [], [{:->, [], [[f], ppln]}]} end def make_dec_fn({:@, _, [{:dec, _, [{:fn, _, _} = dec_fun]}]}) do dec_fun end defmacro make_dec_fun(do: ppln) do # for interactive testing only make_dec_fn(ppln) end end