Current section

Files

Jump to
orb lib orb control.ex
Raw

lib/orb/control.ex

defmodule Orb.Control do
import Orb.DSL, only: [__expand_identifier: 2, __get_block_items: 1]
@doc """
Declare a block, useful for structured control flow.
"""
defmacro block(identifier, result_type \\ nil, do: block) do
identifier = __expand_identifier(identifier, __CALLER__)
result_type = Macro.expand_literals(result_type, __CALLER__)
block_items = __get_block_items(block)
block_items =
Macro.prewalk(block_items, fn
{{:., _, [{:__aliases__, _, [identifier]}, :break]}, _, []} ->
quote do: %Orb.Block.Branch{identifier: unquote(identifier)}
{{:., _, [{:__aliases__, _, [identifier]}, :break]}, _, [[if: condition]]} ->
quote do: %Orb.Block.Branch{
identifier: unquote(identifier),
if: unquote(condition)
}
other ->
other
end)
quote do
%Orb.Block{
identifier: unquote(identifier),
result: unquote(result_type),
body: unquote(block_items)
}
end
end
@doc """
Break from a block.
"""
def break(identifier), do: %Orb.Block.Branch{identifier: __expand_identifier(identifier, __ENV__)}
@doc """
Break from a block if a condition is true.
"""
def break(identifier, if: condition),
do: %Orb.Block.Branch{identifier: __expand_identifier(identifier, __ENV__), if: condition}
def return(), do: :return
end