Packages
orb
0.0.24
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/if_else.ex
defmodule Orb.IfElse do
@moduledoc false
defstruct [:result, :condition, :when_true, :when_false]
alias Orb.ToWat.Instructions
# def new(:i32, condition, {:i32_const, a}, {:i32_const, b}) do
# [
# a,
# b,
# condition,
# :select!
# ]
# end
def new(condition, when_true) do
%__MODULE__{
result: nil,
condition: optimize_condition(condition),
when_true: when_true,
when_false: nil
}
end
def new(condition, when_true, when_false) do
%__MODULE__{
result: nil,
condition: optimize_condition(condition),
when_true: when_true,
when_false: when_false
}
end
def new(result, condition, when_true, when_false)
when not is_nil(result) and not is_nil(when_false) do
%__MODULE__{
result: result,
condition: optimize_condition(condition),
when_true: when_true,
when_false: when_false
}
end
def expand(%__MODULE__{} = statement) do
when_true = statement.when_true |> Orb.Constants.expand_if_needed()
when_false = statement.when_false |> Orb.Constants.expand_if_needed()
%{statement | when_true: when_true, when_false: when_false}
end
# TODO: remove this, Orb.Instruction should do this for us.
defp optimize_condition({:i32, :gt_u, {n, 0}}), do: n
defp optimize_condition(condition), do: condition
def detecting_result_type(condition, when_true, when_false) do
result =
case when_true do
# TODO: detect actual type instead of assuming i32
# [{:return, _value}] -> :i32
_ -> nil
end
%__MODULE__{
result: result,
condition: condition,
when_true: when_true,
when_false: when_false
}
end
defimpl Orb.ToWat do
import Orb.ToWat.Helpers
def to_wat(
%Orb.IfElse{
result: result,
condition: condition,
when_true: when_true,
when_false: when_false
},
indent
)
when not is_nil(condition) do
[
Instructions.do_wat(condition, indent),
[
"\n",
indent,
"(if ",
if(result,
do: ["(result ", do_type(result), ")"],
else: ""
),
?\n
],
[" ", indent, "(then", ?\n],
[Instructions.do_wat(when_true, " " <> indent), ?\n],
[" ", indent, ")", ?\n],
if when_false do
[
[" ", indent, "(else", ?\n],
[Instructions.do_wat(when_false, " " <> indent), ?\n],
[" ", indent, ")", ?\n]
]
else
[]
end,
[indent, ")"]
]
end
end
defmodule DSL do
@moduledoc false
import Kernel, except: [if: 2]
defmacro if(condition, [result: result], do: when_true, else: when_false) do
quote do
Orb.IfElse.new(
unquote(result),
unquote(condition),
unquote(Orb.__get_block_items(when_true)),
unquote(Orb.__get_block_items(when_false))
)
end
end
defmacro if(condition, result: result, do: when_true, else: when_false) do
quote do
Orb.IfElse.new(
unquote(result),
unquote(condition),
unquote(when_true),
unquote(when_false)
)
end
end
defmacro if(condition, do: when_true, else: when_false) do
quote do
Orb.IfElse.new(
unquote(condition),
unquote(Orb.__get_block_items(when_true)),
unquote(Orb.__get_block_items(when_false))
)
end
end
defmacro if(condition, do: when_true) do
quote do
Orb.IfElse.new(
unquote(condition),
unquote(Orb.__get_block_items(when_true))
)
end
end
end
end