diff --git a/lib/pure.ex b/lib/pure.ex
index 204457b..1ee9d18 100644
--- a/lib/pure.ex
+++ b/lib/pure.ex
@@ -28,12 +28,9 @@ defmodule Pure do
"""
def is_guard?(quoted, env) do
{erl, _, _, _env} = :elixir.quoted_to_erl(quoted, env)
- IO.inspect(erl, limit: :infinity)
- if :erl_lint.is_guard_test(erl) do
- true
- else
- false
- end
+ result = :erl_lint.is_guard_test(erl)
+ IO.inspect([:is_guard?, quoted, result])
+ result
end
@doc """
@@ -54,7 +51,7 @@ defmodule Pure do
## Examples
- iex> Pure.string_is_match?("{a, b} = File.read(:stdin)", __ENV__)
+ iex> Pure.string_is_match?("{a, b} = {1, 2}", __ENV__)
true
"""
def string_is_match?(str, env) when is_binary(str) do
@@ -71,22 +68,51 @@ defmodule Pure do
true
"""
def is_match?(quoted, env) do
- IO.inspect(quoted)
{erl, _, _, _env} = :elixir.quoted_to_erl(quoted, env)
- IO.inspect(erl, limit: :infinity)
+ #IO.inspect(erl)
case erl do
{:match, _, a, b} ->
a_is_pattern? = :pure.is_pattern_expr(a)
b_is_guard? = :erl_lint.is_guard_test(b)
- IO.inspect([a: a, is_pattern?: a_is_pattern?])
- IO.inspect([b: b, is_guard?: b_is_guard?])
- a_is_pattern? && b_is_guard?
- _ -> false
+ result = a_is_pattern? && b_is_guard?
+ IO.inspect([:is_match?, quoted,
+ a: a, is_pattern?: a_is_pattern?,
+ b: b, is_guard?: b_is_guard?,
+ result: result])
+ result
+ _ ->
+ IO.inspect([:is_match?, quoted, false])
+ false
end
end
- def is_pure?(q) do
- is_guard?(q, __ENV__) || is_match?(q, __ENV__)
+ def is_pure?(quoted = {:__block__, _, block}, env) do
+ is_pure_block?(quoted, env, block, [])
+ end
+ def is_pure?(quoted, env) do
+ result = is_guard?(quoted, env) || is_match?(quoted, env)
+ IO.inspect([:is_pure?, quoted, result])
+ result
+ end
+
+ def is_pure_block?(quoted, _env, [], _acc) do
+ IO.inspect([:is_pure?, quoted, true])
+ true
+ end
+ def is_pure_block?(quoted, env, [first | rest], acc) do
+ env = env_eval(env, {:__block__, 1, Enum.reverse(acc)})
+ if is_pure?(first, env) do
+ is_pure_block?(quoted, env, rest, [first | acc])
+ else
+ IO.inspect([:is_pure?, quoted, false])
+ false
+ end
+ end
+
+ def env_eval(env, quoted) do
+ IO.inspect([:env_eval, quoted])
+ {env1, _} = Code.eval_quoted(quote do unquote(quoted); __ENV__ end, [], env)
+ env1
end
defmacro eval(str) when is_binary(str) do
@@ -96,15 +122,8 @@ defmodule Pure do
Pure.eval(unquote(q))
end
end
- defmacro eval(q = {:__block__, _, l}) when is_list(l) do
- if Enum.all?(l, fn i ->
- is_pure?(i)
- end) do
- q
- end
- end
defmacro eval(q) do
- if is_pure?(q) do
+ if is_pure?(q, __ENV__) do
q
else
raise ArgumentError, "not a pure expression: #{Macro.to_string(q)}"