Packages
orb
0.0.39
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.
```elixir
defmodule Example do
use Orb
defw example do
Control.block Validate do
Validate.break(if: i < 0)
# Do something with i
end
end
end
```
"""
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),
push_type: unquote(result_type),
body: Orb.InstructionSequence.new(unquote(block_items))
}
end
end
@doc """
Break from a block.
```elixir
defmodule Example do
use Orb
defw example do
Control.block Validate do
# Other code…
Control.break(Validate)
end
end
end
```
"""
def break(identifier),
do: %Orb.Block.Branch{identifier: __expand_identifier(identifier, __ENV__)}
@doc """
Break from a block if a condition is true.
```elixir
defmodule Example do
use Orb
defw example do
Control.block Validate do
Validate.break(if: i < 0)
# Do something with i
end
end
end
```
"""
def break(identifier, if: condition),
do: %Orb.Block.Branch{identifier: __expand_identifier(identifier, __ENV__), if: condition}
def return(), do: Orb.Control.Return.new()
end