Current section
Files
Jump to
Current section
Files
lib/cliex_map/function_list.ex
defmodule CliexMap.FunctionList do
use CliexMap.Types
alias CliexMap.Builtins
alias CliexMap.Fn
@moduledoc ~S"""
Wraps a list of functions
"""
@type t :: %__MODULE__{functions: list()}
defstruct functions: []
# TODO: replace with Fn.t
@spec add_function(t(), Fn.t()) :: t()
def add_function(%__MODULE__{functions: functions} = myself, fun) do
%{myself | functions: [fun | functions]}
end
@spec add_sexp(t(), list()) :: t()
def add_sexp(%__MODULE__{functions: functions} = myself, s_exp) do
%{myself | functions: [_make_s_exp_fun(s_exp) | functions]}
end
@spec new(Fn.t()) :: t()
def new(function) do
%__MODULE__{functions: [function]}
end
@spec _make_builtin_application(atom(), list()) :: Fn.t
defp _make_builtin_application(fun_name, args) do
Fn.new(
fn arg, ctxt ->
actual_args = _rearrange_args(arg, args, args)
apply(Builtins, fun_name, [ctxt, actual_args])
end,
"built_in #{fun_name}(#{Enum.join(args, ",")})"
)
end
@spec _make_s_exp_fun(list()) :: Fn.t
defp _make_s_exp_fun(fun_name_and_args)
defp _make_s_exp_fun([:+ | args]) do
_make_builtin_application(:_add, args)
end
defp _make_s_exp_fun([:- | args]) do
_make_builtin_application(:_sub, args)
end
defp _make_s_exp_fun([:* | args]) do
_make_builtin_application(:_mul, args)
end
defp _make_s_exp_fun([fun_name | args]) do
# IO.inspect(args, label: :s_exp_args)
_make_builtin_application(fun_name, args)
end
@spec _rearrange_args(any(), list(), list()) :: list()
defp _rearrange_args(arg, args, stack, hd \\ [])
defp _rearrange_args(arg, args, [], _hd), do: [arg | args]
defp _rearrange_args(arg, _args, [:_ | rest], hd), do: Enum.reverse(hd) ++ [arg | rest]
defp _rearrange_args(arg, args, [h | rest], hd), do: _rearrange_args(arg, args, rest, [h | hd])
end
# SPDX-License-Identifier: Apache-2.0