# `Dmn.Compiler.Tree`
[🔗](https://github.com/FeeJai/BDM/blob/dmn-v0.1.0/apps/dmn/lib/dmn/compiler/tree.ex#L1)

The nodes of `Feel.AST` that the compiler builds, so that the code that maps a boxed expression says what it maps to and not how
a tuple is made.

Every node is given a span, the zero-width one of the part of the model it stands for (`Dmn.Compiler.Source.glue/2`). A name is
a list of tokens (`Feel.AST`), and the tokens of a name of the model are made here (`tokens/1`) so that they join to the
canonical name that the scope of the unit has.

# `span`

```elixir
@type span() :: Feel.Diagnostic.span()
```

# `at`

```elixir
@spec at(span(), Feel.AST.expression(), Feel.AST.expression()) ::
  Feel.AST.expression()
```

`source[index]`, a filter that the analyzer finds to be an index when it is a number.

# `boxed`

```elixir
@spec boxed(Feel.AST.expression()) :: Feel.AST.expression()
```

The node as the node of a boxed expression whose condition has to be a boolean (DMN 1.6, 10.2.1.8 to 10.2.1.10): an `if`, a
filter, a `some` or an `every` that is `null` with an error for a condition that is a value other than a boolean (`meta.boxed`,
`Feel.Runtime.Boxed`, D-212). `null` is taken as false, as it is in the text.

    iex> node = Dmn.Compiler.Tree.if_then_else({0, 0}, Dmn.Compiler.Tree.null({0, 0}), Dmn.Compiler.Tree.null({0, 0}), Dmn.Compiler.Tree.null({0, 0}))
    iex> {:if, %{boxed: true}, _, _, _} = Dmn.Compiler.Tree.boxed(node)

# `call`

```elixir
@spec call(span(), String.t(), [Feel.AST.expression()]) :: Feel.AST.expression()
```

A call of a function by name, with its arguments by position.

# `canonical`

```elixir
@spec canonical(String.t()) :: String.t()
```

The canonical form of a name of the model: what the scope of a unit and the keys of a context call it.

# `context`

```elixir
@spec context(span(), [{String.t(), Feel.AST.expression()}]) :: Feel.AST.expression()
```

A context with the entries `{name, expression}`, in order. The keys are strings, so any name of a model can be one.

# `for_in`

```elixir
@spec for_in(span(), String.t(), Feel.AST.expression(), Feel.AST.expression()) ::
  Feel.AST.expression()
```

# `function`

```elixir
@spec function(
  span(),
  [{String.t(), Feel.AST.type_expression() | nil}],
  Feel.AST.expression()
) ::
  Feel.AST.expression()
```

# `if_then_else`

```elixir
@spec if_then_else(
  span(),
  Feel.AST.expression(),
  Feel.AST.expression(),
  Feel.AST.expression()
) ::
  Feel.AST.expression()
```

# `internal`

```elixir
@spec internal(String.t()) :: String.t()
```

A name that the compiler makes for itself (the key of the result of a context, an alias of an outside value): it begins with
U+0001, a character that XML 1.0 does not allow in a document, so no name, id or text of a model can be, or begin with, one, and no text of FEEL
can write it (the lexer does not read it as a part of a name).

    iex> Dmn.Compiler.Tree.internal("result")
    "result"

# `list`

```elixir
@spec list(span(), [Feel.AST.expression()]) :: Feel.AST.expression()
```

# `meta`

```elixir
@spec meta(span()) :: map()
```

# `name`

```elixir
@spec name(span(), String.t()) :: Feel.AST.expression()
```

# `null`

```elixir
@spec null(span()) :: Feel.AST.expression()
```

# `quantified`

```elixir
@spec quantified(
  span(),
  :some | :every,
  String.t(),
  Feel.AST.expression(),
  Feel.AST.expression()
) :: Feel.AST.expression()
```

# `select`

```elixir
@spec select(span(), Feel.AST.expression(), String.t()) :: Feel.AST.expression()
```

The value of one entry of a context: `source.key`.

# `tokens`

```elixir
@spec tokens(String.t()) :: [String.t(), ...]
```

The tokens of a name, as the lexer of FEEL would split it: the words, and each of the symbols that a name may have as a token
of its own. `Feel.Name.join/1` of them is the canonical form of the name.

    iex> Dmn.Compiler.Tree.tokens("Pre-bureau Risk Category")
    ["Pre", "-", "bureau", "Risk", "Category"]
    iex> Feel.Name.join(Dmn.Compiler.Tree.tokens("a  b - c.d"))
    "a b-c.d"

# `type_name`

```elixir
@spec type_name(span(), String.t()) :: Feel.AST.type_expression()
```

A type by its name: a built-in type or the name of an item definition of the model.

---

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