Packages
orb
0.0.33
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
0.0.51
0.0.49
0.0.48
0.0.47
0.0.46
0.0.45
0.0.44
0.0.43
0.0.42
0.0.41
0.0.40
0.0.39
0.0.38
0.0.37
0.0.36
0.0.35
0.0.34
0.0.33
0.0.32
0.0.31
0.0.30
0.0.28
0.0.27
0.0.26
0.0.25
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
retired
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
DSL for WebAssembly
Current section
Files
Jump to
Current section
Files
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)
# TODO: is there some way to do this using normal Elixir modules?
# I think we can define a module inline.
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: Orb.Control.Return.new()
end