Current section

Files

Jump to
orb lib orb defw_dsl.ex
Raw

lib/orb/defw_dsl.ex

defmodule Orb.DefwDSL do
defmacro wasm_mode(mode) do
mode = Macro.expand_literals(mode, __CALLER__)
Module.put_attribute(__CALLER__.module, :wasm_mode, mode)
end
defmacro defw(call, do: block) do
define(call, :public, nil, [], block, __CALLER__)
end
defmacro defw(call, locals, do: block) when is_list(locals) do
define(call, :public, nil, locals, block, __CALLER__)
end
defmacro defw(call, result, do: block) do
define(call, :public, result, [], block, __CALLER__)
end
defmacro defw(call, result, locals, do: block) when is_list(locals) do
define(call, :public, result, locals, block, __CALLER__)
end
defmacro defwi(call, do: block) do
define(call, :internal, nil, [], block, __CALLER__)
end
defmacro defwi(call, locals, do: block) when is_list(locals) do
define(call, :internal, nil, locals, block, __CALLER__)
end
defmacro defwi(call, result, do: block) do
define(call, :internal, result, [], block, __CALLER__)
end
defmacro defwi(call, result, locals, do: block) when is_list(locals) do
define(call, :internal, result, locals, block, __CALLER__)
end
defmacro defwp(call, do: block) do
define(call, :private, nil, [], block, __CALLER__)
end
defmacro defwp(call, locals, do: block) when is_list(locals) do
define(call, :private, nil, locals, block, __CALLER__)
end
defmacro defwp(call, result, do: block) do
define(call, :private, result, [], block, __CALLER__)
end
defmacro defwp(call, result, locals, do: block) when is_list(locals) do
define(call, :private, result, locals, block, __CALLER__)
end
defp define(call, visibility, result, locals, block, env) do
func_visibility =
case visibility do
:internal -> :private
other -> other
end
def_kind =
case visibility do
:public -> :def
:internal -> :def
:private -> :defp
end
ex_def = define_elixir_def(call, def_kind, result, env)
wasm =
Orb.DSL.__define_func(call, func_visibility, [result: result, locals: locals], block, env)
quote do
unquote(ex_def)
Orb.wasm do
unquote(wasm)
end
end
end
defp define_elixir_def(call, def_kind, result, %Macro.Env{file: file}) do
{name, func_args} = Macro.decompose_call(call)
{_, meta, _} = call
# arity = length(args)
def_args =
case func_args do
[] ->
[]
[keywords] ->
for {keyword, _type} <- keywords do
Macro.var(keyword, nil)
end
multiple when is_list(multiple) ->
raise CompileError,
line: meta[:line],
file: file,
description:
"Cannot define function with multiple arguments, use keyword list instead."
end
def_call = {name, meta, def_args}
quote do
unquote(def_kind)(unquote(def_call)) do
Orb.Instruction.typed_call(
unquote(result),
case {@wasm_func_prefix, unquote(name)} do
{nil, name} -> name
{prefix, name} -> "#{prefix}.#{name}"
end,
unquote(def_args)
)
end
end
end
end