Created
May 16, 2018 18:42
-
-
Save latachz/bdbb24d8b20d7045594135e114924e13 to your computer and use it in GitHub Desktop.
macros.elchemy.ex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Compiled using Elchemy v0.6.6 | |
defmodule Elchemy.Macros do | |
use Elchemy | |
@moduledoc """ | |
This module is responsible for defining and using macros in Plugins system for Elchemy. | |
To use this module you need to import it to your module and use its constructs in the | |
`meta` definition of your module. | |
@docs Macro, Do, macro, use, behaviour | |
""" | |
def use_macro(mod) do | |
module = :"Elixir.#{mod}" | |
quote do | |
use unquote(module) | |
end | |
end | |
def behaviour_macro(mod) do | |
module = :"Elixir.#{mod}" | |
quote do | |
@behaviour unquote(module) | |
end | |
end | |
def strip_meta(mod) do | |
mod | |
|> Module.split | |
|> Enum.drop(-1) | |
|> Module.concat | |
end | |
@typedoc """ | |
Type of macro expression that go into 'meta' function in a module | |
""" | |
@type macro :: :macro | |
@typedoc """ | |
Declares a block that doesn't get evaluated eagerly but rather passed as an AST to be used later in a macro | |
""" | |
@type do__(x) :: {:do, x} | |
@doc """ | |
FFI function that creates a new macro calling an Elixir function that returns Elixir ast. | |
For instance: | |
myMacro = | |
macro "ModuleContainingAstFunction" "ast_function" | |
Notice that the function *always* returns a Macro type so that it can only be used in `meta` definition | |
of a module. That ensures that macros are only called top level, everything in deeper scopes - | |
like inside functions should only be handled using functions. | |
""" | |
@spec macro(String.t, String.t) :: any | |
curry macro/2 | |
def macro(x1, x2) do | |
(Elchemy.XDebug.crash("You can't use macro in a browser")).(x1).(x2) | |
end | |
@doc """ | |
Use macro is a simple wrapper around Elixir.SpecialForms.use | |
""" | |
@spec use(String.t) :: macro | |
curry use/1 | |
def use(x1) do | |
(macro("Elchemy.Macros", "use_macro")).(x1) | |
end | |
@doc """ | |
Use macro is a simple wrapper around @behaviour module attribute. | |
""" | |
@spec behaviour(String.t) :: macro | |
curry behaviour/1 | |
def behaviour(x1) do | |
(macro("Elchemy.Macros", "behaviour_macro")).(x1) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment