I would like to “expand” every macros in a Macro.prewalk/2 using the __CALLER__
context.
Basically, I’m trying to create a macro that create a new module with a function and a guard inside.
Here is a simplified example of what I’m trying to achieve:
defmodule DSL do
defmacro deffunction({:when, _, [name, guards]}) do
quote do
defmodule CustomModule do
def unquote(name)(var!(arg1)) when unquote(guards) do
IO.inspect(:ok)
end
end
end
end
end
defmodule MyApp do
import DSL, only: [deffunction: 1]
defguard is_true(value) when value == "1"
deffunction :my_function when is_true(arg1)
end
Sadly, this piece of code doesn’t compile and I have the following error:
** (CompileError) test.exs:36: cannot find or invoke local is_true/1 inside guards. Only macros can be invoked in a guards and they must be defined before their invocation. Called as: is_true(arg1)
It doesn’t work because CustomModule
is generated like this:
defmodule CustomModule do
def my_function(arg1) when is_true(arg1) do
IO.inspect(:ok)
end
end
Instead, I’d like to expand the is_true/1
macro to output something like this
defmodule CustomModule do
def my_function(arg1) when arg1 == "1" do
IO.inspect(:ok)
end
end
I tried Macro.expand(guards, __CALLER__)
inside my deffunction/1
macro but it doesn’t work and generate the same AST:
{:is_true, [line: 41], [{:arg1, [line: 41], nil}]}