# `Statifier.Machine.Content.Script`
[🔗](https://github.com/riddler/statifier-ex/blob/v2.0.0/lib/statifier/machine/content/script.ex#L1)

A compiled `<script>` executable-content node (spec 5.8, ADR-0026) - the
interned counterpart to `Statifier.Document.Script`.

`program` is `Statifier.Machine.program()` - a compiled predicator
*statement* program, `Machine.expr()`'s sibling and never one of its
arms - or `{:invalid, Compiler.Error.t()}` when the body failed to
compile (`Statifier.Compiler.build_content_node/2`'s `%Document.Script{}`
clause): compilation
happens once at load, but a body outside predicator's statement grammar
(an ECMAScript body this engine cannot parse) defers its failure to
`execute/2`, exactly the way `Statifier.Machine.Content.Assign`'s
`value` field and `Statifier.Machine.Data`'s `value` field already defer
theirs, rather than rejecting the whole document at load time.
`node_location` is this node's own `Statifier.Parser.Location` span.

## Why a `<script>` may create a new top-level root, unlike `<assign>`

`Statifier.Machine.Content.Assign`'s `check_root/3`
(`assign.ex:162-173`) refuses to write a root no `<datamodel>` already
declares - `<assign>`'s `location` attribute is a *reference* to a
location the document must already have (spec 5.9.2's "cannot be
evaluated to yield a valid location"). A predicator assignment
*statement*, by contrast, is a declaration and a write in one: `x = 1`
inside a `<script>` body both introduces `x` and gives it a value, the
same way a bare assignment does in the languages spec 5.8 anticipates.
W3C `test302` and `test304` assert exactly this - `Var1` appears in no
`<datamodel>` in either document, and the pass state is reached anyway.
`execute/2` below therefore gets no `check_root/3` equivalent: this is a
deliberate asymmetry with `<assign>`, not an oversight, and
`Statifier.Evaluator.execute/2`'s own moduledoc records the same
reasoning on the write side.

Its `Statifier.ExecutableContent` implementation lives right below the
struct: this file is the whole node, top to bottom, with no dispatcher
anywhere else in the tree.

# `program`

```elixir
@type program() ::
  Statifier.Machine.program() | {:invalid, Statifier.Compiler.Error.t()}
```

# `t`

```elixir
@type t() :: %Statifier.Machine.Content.Script{
  c_index: non_neg_integer(),
  node_location: Statifier.Parser.Location.t(),
  program: program()
}
```

---

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