Current section
Files
Jump to
Current section
Files
lib/guesswork/ast/assign.ex
defmodule Guesswork.Ast.Assign do
@moduledoc """
A simple assignment of a value to a variable.
"""
defstruct [:binding, :value]
alias Guesswork.Ast.Variable
alias Guesswork.Ast.Term
alias Guesswork.Ast.Statement.Opts
alias Guesswork.Answer
alias Guesswork.Answer.Binding
alias Guesswork.Telemetry.EventHandler
@type t() :: %__MODULE__{binding: Variable.t() | Term.entity(), value: Term.entity()}
@spec new(Variable.t(), Term.entity()) :: t()
def new(variable, value), do: %__MODULE__{binding: variable, value: value}
defimpl Guesswork.Ast.Term do
alias Guesswork.Ast.Assign
def concrete?(%Assign{binding: %Variable{}}), do: false
def concrete?(_), do: true
def get_variables(%Assign{binding: %Variable{} = variable}), do: [variable]
def get_variables(_), do: []
end
defimpl Guesswork.Ast.Statement do
alias Guesswork.Ast.Assign
def simplify(statement) do
statement
end
def substitute(%Assign{binding: binding} = statement, env) do
case Map.fetch(env, binding) do
:error -> statement
{:ok, value} -> %Assign{statement | binding: value}
end
end
def resolve(
%Assign{binding: %Variable{display: display}, value: value},
negated,
%Opts{query_id: query_id}
) do
:telemetry.execute(EventHandler.assignment_event_name(), %{count: 1}, %{query_id: query_id})
[
%Answer{
tests: [],
bindings: %{display => Binding.new(value, negated)},
query_id: query_id
}
]
end
def resolve(
%Assign{binding: bound, value: value},
negated,
%Opts{query_id: query_id}
)
when bound == value != negated,
do: [Answer.new(query_id)]
def resolve(_statement, _negated, _opts), do: []
end
end