defmodule Mix.Tasks.Compile.Peg do @moduledoc """ Compile peg template file into parser module """ use Mix.Task require EEx @recursive true def run(_) do attr_list_delims = Application.get_env( :slime, :attr_list_delims, %{"[" => "]", "(" => ")", "{" => "}"} ) grammar = EEx.eval_file("src/slime_parser.peg.eex", attr_list_delims: attr_list_delims) if contents_changed?("src/slime_parser.peg", grammar) do compile_grammar("src/slime_parser.peg", grammar) else :ok end end defp contents_changed?(file, expected) do case File.read(file) do {:ok, contents} -> contents != expected _ -> true end end defp compile_grammar(file, grammar) do File.write!(file, grammar) peg = file |> Path.expand() |> String.to_charlist() case :neotoma.file(peg, transform_module: :slime_parser_transform) do :ok -> :ok {:error, reason} -> Mix.shell().error("Failed to compile: #{inspect(reason)}") exit(:normal) end end end