Skip to content

Commit

Permalink
Use three element tuples for strings and integers
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Feb 12, 2022
1 parent 246111e commit 9f4752a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
24 changes: 12 additions & 12 deletions lib/nimble_parsec.ex
Expand Up @@ -1979,56 +1979,56 @@ defmodule NimbleParsec do
end

@doc false
def __runtime_string__(_rest, acc, context, _line, _offset, _min, _max, _type) do
def __runtime_string__(rest, acc, context, _line, _offset, _min, _max, _type) do
ast = quote(do: List.to_string(unquote(reverse_now_or_later(acc))))
{[ast], context}
{:{}, [], [rest, [ast], context]}
end

@doc false
def __compile_string__(_rest, acc, context, _line, _offset, _count, type) when is_list(acc) do
def __compile_string__(rest, acc, context, _line, _offset, _count, type) when is_list(acc) do
acc =
for entry <- :lists.reverse(acc) do
{:"::", [], [entry, type]}
end

{[{:<<>>, [], acc}], context}
{:{}, [], [rest, [{:<<>>, [], acc}], context]}
end

def __compile_string__(_rest, acc, context, _line, _offset, _count, _type) do
def __compile_string__(rest, acc, context, _line, _offset, _count, _type) do
ast = quote(do: List.to_string(unquote(reverse_now_or_later(acc))))
{[ast], context}
{:{}, [], [rest, [ast], context]}
end

@doc false
def __runtime_integer__(_rest, acc, context, _line, _offset, min, _max)
def __runtime_integer__(rest, acc, context, _line, _offset, min, _max)
when is_integer(min) and min > 0 do
ast =
quote do
[head | tail] = unquote(reverse_now_or_later(acc))
[:lists.foldl(fn x, acc -> x - ?0 + acc * 10 end, head, tail)]
end

{ast, context}
{:{}, [], [rest, ast, context]}
end

def __runtime_integer__(_rest, acc, context, _line, _offset, _min, _max) do
def __runtime_integer__(rest, acc, context, _line, _offset, _min, _max) do
ast =
quote do
[head | tail] = unquote(reverse_now_or_later(acc))
[:lists.foldl(fn x, acc -> x - ?0 + acc * 10 end, head - ?0, tail)]
end

{ast, context}
{:{}, [], [rest, ast, context]}
end

@doc false
def __compile_integer__(_rest, acc, context, _line, _offset, _count) when is_list(acc) do
def __compile_integer__(rest, acc, context, _line, _offset, _count) when is_list(acc) do
ast =
acc
|> quoted_ascii_to_integer(1)
|> Enum.reduce(&{:+, [], [&2, &1]})

{[ast], context}
{:{}, [], [rest, [ast], context]}
end

defp reverse_now_or_later(list) when is_list(list), do: :lists.reverse(list)
Expand Down
7 changes: 6 additions & 1 deletion lib/nimble_parsec/compiler.ex
Expand Up @@ -417,19 +417,24 @@ defmodule NimbleParsec.Compiler do
end
end

# TODO: Deprecate two element tuple return that is not error
defp apply_traverse_mfa(mfargs, args, rest) do
case apply_mfa(mfargs, args) do
{:{}, _, [_, _, _]} = res ->
res

{acc, context} when acc != :error ->
# IO.warn(
# "Returning a two-element tuple {acc, context} in pre_traverse/post_traverse is deprecated, " <>
# "please return {rest, acc, context} instead"
# )

{:{}, [], [rest, acc, context]}

{:error, context} ->
{:error, context}

quoted ->
# TODO: Deprecate two element tuple return that is not error
quote generated: true do
case unquote(quoted) do
{_, _, _} = res -> res
Expand Down

0 comments on commit 9f4752a

Please sign in to comment.