Current section

Files

Jump to
zig_parser lib zig.parser for.ex
Raw

lib/zig.parser/for.ex

defmodule Zig.Parser.For do
defstruct [:block, :label, :else, :location, inline: false, iterators: [], captures: []]
alias Zig.Parser.Block
def post_traverse(rest, [{:ForStatement, [:for | args]} | rest_args], context, _, _) do
{rest, [parse(args) | rest_args], context}
end
def parse([:LPAREN | rest]), do: parse_iteration(%__MODULE__{}, rest)
defp parse_iteration(for_struct, [:COMMA | rest]) do
parse_iteration(for_struct, rest)
end
defp parse_iteration(for_struct, [:RPAREN, :| | rest]) do
for_struct
|> Map.update!(:iterators, &Enum.reverse/1)
|> parse_capture(rest)
end
defp parse_iteration(for_struct, [item, :DOT2, item2 | rest])
when item2 in [:RPAREN, :COMMA] do
for_struct
|> Map.update!(:iterators, &[{:.., item} | &1])
|> parse_iteration([item2 | rest])
end
defp parse_iteration(for_struct, [item, :DOT2, item2 | rest]) do
for_struct
|> Map.update!(:iterators, &[{:.., item, item2} | &1])
|> parse_iteration(rest)
end
defp parse_iteration(for_struct, [item | rest]) do
for_struct
|> Map.update!(:iterators, &[item | &1])
|> parse_iteration(rest)
end
defp parse_capture(for_struct, [:COMMA | rest]) do
parse_capture(for_struct, rest)
end
defp parse_capture(for_struct, [:|, block = %Block{} | rest]) do
for_struct
|> Map.update!(:captures, &Enum.reverse/1)
|> Map.replace!(:block, block)
|> parse_else(rest)
end
defp parse_capture(for_struct, [:*, capture | rest]) do
for_struct
|> Map.update!(:captures, &[{:*, capture} | &1])
|> parse_capture(rest)
end
defp parse_capture(for_struct, [capture | rest]) do
for_struct
|> Map.update!(:captures, &[capture | &1])
|> parse_capture(rest)
end
defp parse_else(for_struct, []), do: for_struct
defp parse_else(for_struct, [:else, %Block{} = block]) do
Map.replace!(for_struct, :else, block)
end
end