# `Yarnspinnex.Ops`
[🔗](https://github.com/atavistock/yarnspinnex/blob/main/lib/yarnspinnex/ops.ex#L1)

Operator semantics for `Yarnspinnex.Interpreter`: `binop/3` for every binary operator except
`and`/`or` (those short-circuit in the interpreter), `negate/1` for unary minus, `get_field/2`
for `.` access, and `to_text/1` for how values render inside dialogue text.

Dialogue reads scalars. A struct, map, or list reaching a comparison or a line of text is a
missing projection in the host, and every path here says so rather than failing quietly.

# `operator`

```elixir
@type operator() ::
  :+ | :- | :* | :/ | :% | :== | :!= | :&lt; | :&gt; | :&lt;= | :&gt;= | :and | :or | :xor
```

Every binary operator an expression can contain; `and`, `or`, and `xor` are evaluated by the interpreter.

# `add`

```elixir
@spec add(term(), term()) :: number() | String.t()
```

Yarn `+`: numeric addition, or concatenation when either side is a string.

# `binop`

```elixir
@spec binop(operator(), term(), term()) :: term()
```

Applies binary operator `op` to `left` and `right`, raising on unsupported operand types.

# `boolean!`

```elixir
@spec boolean!(term()) :: boolean()
```

Reads a condition as a boolean. `nil` (an unset variable) counts as false; a number, string,
or anything else in a condition is an error, so `$count` must be written `$count > 0`.

# `get_field`

```elixir
@spec get_field(term(), String.t()) :: term()
```

Reads `field` off a plain map or a `Yarnspinnex.Projection`, by string key or atom key; `nil`
for a missing field or a `nil` base.

Domain structs are refused: dialogue reads a view the host builds, not the object itself, so
content never depends on the shape of a schema. Fields whose name begins with `_` are refused
outright, which keeps `__struct__` and Ecto's `__meta__` closed off.

# `negate`

```elixir
@spec negate(term()) :: number()
```

Unary minus; raises on anything but a number.

# `to_text`

```elixir
@spec to_text(term()) :: String.t()
```

Renders a value as dialogue text: whole-number floats print without a decimal point.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
