defmodule Egglog.Commands do @moduledoc """ Parsed egglog commands. `Egglog.Commands` is a small native-backed handle returned by `Egglog.parse/1` or `Egglog.Program.parse/1`. Use it when the same command sequence will be run repeatedly and you want egglog parsing to happen once. The commands are still executed by native egglog; this module only keeps the parsed AST resource alive. The original source is retained as well, so query-local inspection helpers such as `Egglog.Program.eval/4` and `Egglog.Program.lookup/5` can inspect parsed command input without requiring callers to keep a second copy of the string. """ alias Egglog.{Common, Native} @enforce_keys [:ref, :count] defstruct [:ref, :count, :source] @opaque t :: %__MODULE__{ ref: reference(), count: non_neg_integer(), source: String.t() | nil } @doc """ Parses egglog source into a reusable command handle. """ @spec parse(String.t()) :: {:ok, t()} | {:error, term()} def parse(source) when is_binary(source) do case Native.parse_program(source) do {:ok, ref, count} -> {:ok, %__MODULE__{ref: ref, count: count, source: source}} {:error, reason, message} -> {:error, {reason, message}} end end @doc """ Bang variant of `parse/1`. """ @spec parse!(String.t()) :: t() def parse!(source) when is_binary(source) do source |> parse() |> Common.bang("failed to parse egglog commands") end end