Current section

Files

Jump to
argx lib parser.ex
Raw

lib/parser.ex

defmodule Argx.Parser do
@moduledoc false
@allowed_fun_types [:def, :defp]
###
def parse_fun(block) do
block |> _parse_fun(%{})
end
defp _parse_fun({type, _, fun}, acc) when type in @allowed_fun_types do
fun |> _parse_fun(acc)
end
defp _parse_fun([{:when, _, fa_guard}, [{:do, block}]], acc) do
fa_guard
|> _parse_fun(acc)
|> Map.put(:block, block)
end
defp _parse_fun([fa, [{:do, block}]], acc) do
fa
|> _parse_fun(acc)
|> Map.put(:block, block)
|> Map.put(:guard, true)
end
defp _parse_fun([fa, guard], acc) do
fa
|> _parse_fun(acc)
|> Map.put(:guard, guard)
end
defp _parse_fun({f, _, [{_, _, nil} | _] = a}, acc) do
acc
|> Map.put(:f, f)
|> Map.put(:a, a)
end
defp _parse_fun({f, _, nil}, acc) do
acc
|> Map.put(:f, f)
|> Map.put(:a, [])
end
defp _parse_fun({:__block__, _, []}, _) do
raise "not found function"
end
defp _parse_fun({:__block__, _, [_ | _]}, _) do
raise "only support one function"
end
defp _parse_fun(_, _) do
raise "parse function error"
end
###
def parse_configs(configs, acc \\ nil)
def parse_configs([config | rest], nil) do
acc = %{} |> Map.merge(config_rule(config))
rest |> parse_configs(acc)
end
def parse_configs({:configs, _, [config | rest]}, nil) do
acc = %{} |> Map.merge(config_rule(config))
rest |> parse_configs(acc)
end
def parse_configs(config, nil) do
%{} |> Map.merge(config_rule(config))
end
def parse_configs([config | rest], acc) do
acc = acc |> Map.merge(config_rule(config, acc))
rest |> parse_configs(acc)
end
def parse_configs([], acc) do
acc
end
def parse_configs(_, _) do
raise "configs syntax error"
end
defp config_rule(config, acc \\ nil)
defp config_rule({:__aliases__, _, [name]}, acc) do
names = (acc && acc |> Map.get(:__names__)) || []
%{:__names__ => [name | names]}
end
defp config_rule({field, _, config}, _acc) do
%{field => config}
end
defp config_rule(_, _) do
%{}
end
###
def parse_defconfig_name({:__aliases__, _, [name]}) do
name
end
def parse_defconfig_name(_) do
raise "invalid name, such as: NameRule"
end
end