defmodule Mix.Tasks.Clje.Eval do @moduledoc """ Evaluate a CljElixir expression from the command line. ## Usage mix clje.eval '(+ 1 2)' mix clje.eval '(defn greet [name] (str "hello " name))' '(greet "world")' Multiple expressions are evaluated in sequence, with bindings persisting. The result of the last expression is printed. """ use Mix.Task @shortdoc "Evaluate CljElixir expressions" @impl Mix.Task def run([]) do Mix.shell().error("Usage: mix clje.eval '' [...]") System.halt(1) end def run(exprs) do Mix.Task.run("compile") Mix.Task.run("app.start") {result, _bindings} = Enum.reduce(exprs, {nil, []}, fn expr, {_prev, bindings} -> case CljElixir.Compiler.eval_string(expr, bindings: bindings) do {:ok, result, new_bindings} -> {result, new_bindings} {:error, diagnostics} -> Enum.each(diagnostics, fn diag -> Mix.shell().error("#{diag.severity}: #{diag.message}") end) System.halt(1) end end) IO.puts(CljElixir.Printer.pr_str(result)) end end