# `Yarnspinnex.Parser.Expression`
[🔗](https://github.com/atavistock/yarnspinnex/blob/main/lib/yarnspinnex/parser/expression.ex#L1)

Parses a Yarn expression (as found inside `{...}` interpolation, `<<if
...>>`, `<<set ... = ...>>`, and command arguments) into a small, plain
data AST that `Yarnspinnex.Interpreter` evaluates against the cursor's
variables. Tokenizing is delegated to `Yarnspinnex.Parser.Lexer`; this
module only builds the AST from the resulting tokens.

# `ast`

```elixir
@type ast() ::
  number()
  | String.t()
  | boolean()
  | {:var, String.t()}
  | {:field, ast(), String.t()}
  | {:call, String.t(), [ast()]}
  | {:not, ast()}
  | {:neg, ast()}
  | {:binop, Yarnspinnex.Ops.operator(), ast(), ast()}
```

A bare number, string, or boolean evaluates to itself; everything else is a tagged tuple.

# `parse!`

```elixir
@spec parse!(String.t()) :: ast()
```

Parses expression source into an AST, raising on invalid syntax.

# `precedence`

```elixir
@spec precedence(Yarnspinnex.Ops.operator()) :: non_neg_integer()
```

How tightly binary operator `op` binds: a higher number binds tighter.

# `subexpressions`

```elixir
@spec subexpressions(ast()) :: [ast()]
```

`ast` and every expression nested inside it, outermost first.

---

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