Packages
orb
0.0.25
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/func.ex
defmodule Orb.Func do
@moduledoc false
alias Orb.Constants
defstruct name: nil,
exported_names: [],
params: [],
result: nil,
local_types: [],
body: [],
source_module: nil,
table_elem_indices: []
def __add_table_elem(f = %__MODULE__{}, elem_index) do
update_in(f.table_elem_indices, fn refs -> [elem_index | refs] end)
end
def expand(%__MODULE__{} = func) do
body = func.body |> Enum.map(&Constants.expand_if_needed/1)
%{func | body: body}
end
defimpl Orb.ToWat do
alias Orb.ToWat.Instructions
import Orb.ToWat.Helpers
def to_wat(
%Orb.Func{
name: name,
exported_names: exported_names,
params: params,
result: result,
local_types: local_types,
body: body,
table_elem_indices: table_elem_indices
},
indent
) do
[
[
indent,
[
~s{(func $},
to_string(name),
for exported_name <- Enum.reverse(exported_names) do
[~s{ (export "}, to_string(exported_name), ~s{")}]
end
],
Enum.map(
for(param <- params, do: Orb.ToWat.to_wat(param, "")) ++
if(result, do: [["(result ", do_type(result), ")"]], else: []),
fn s -> [" ", s] end
),
"\n"
],
for {id, type} <- local_types do
[
" ",
indent,
"(local $",
to_string(id),
" ",
do_type(type),
")\n"
]
end,
Enum.map(body, &[Instructions.do_wat(&1, " " <> indent), "\n"]),
[indent, ")\n"],
for elem_index <- table_elem_indices do
[indent, "(elem (i32.const ", to_string(elem_index), ") $", to_string(name), ")\n"]
end
]
end
end
defmodule Param do
@moduledoc false
defstruct [:name, :type]
defimpl Orb.ToWat do
import Orb.ToWat.Helpers
def to_wat(%Param{name: nil, type: type}, indent) do
[
indent,
"(param ",
do_type(type),
?)
]
end
def to_wat(%Param{name: name, type: type}, indent) do
[
indent,
"(param $",
to_string(name),
" ",
do_type(type),
?)
]
end
end
end
defmodule Type do
@moduledoc false
defstruct [:name, :params, :result]
def new(name, params, result) do
# params = [:i32]
%__MODULE__{
name: name,
params: params,
result: result
}
end
@doc false
def params_from_call_args(args, env, line) do
case args do
[args] when is_list(args) ->
for {name, type} <- args do
%Orb.Func.Param{name: name, type: Macro.expand_literals(type, env)}
end
[] ->
[]
[_ | _] ->
raise CompileError,
line: line,
file: env.file,
description:
"Cannot define function with multiple arguments, use keyword list instead."
end
end
defimpl Orb.ToWat do
import Orb.ToWat.Helpers
def to_wat(%Type{name: name, params: params, result: result}, indent) do
[
indent,
"(func",
case name do
nil -> []
name -> [" $", to_string(name)]
end,
case params do
nil ->
[]
params when is_list(params) ->
for param <- params, do: [" ", Orb.ToWat.to_wat(param, "")]
params ->
[
" ",
Orb.ToWat.to_wat(%Param{name: nil, type: params}, "")
]
end,
case result do
nil ->
[]
result ->
[
" (result ",
do_type(result),
")"
]
end,
?)
]
end
end
end
end