# `Linx.NFT.Compiler`
[🔗](https://github.com/oshlabs/linx/blob/v0.2.0/lib/linx/nft/compiler.ex#L1)

AST → `%Linx.Netfilter.Ruleset{}` translation.

Walks the AST produced by `Linx.NFT.Parser` and calls into the
validator-setter surface on `Linx.Netfilter.Ruleset` (and
friends) — the **same** surface the pipeline DSL uses. There's
no parallel validation here; if a chain hook is invalid for its
family, or a set element doesn't match the key type, the
validator-setter raises and we propagate the failure as a
`Linx.NFT.ParseError` with the AST node's `{file, line, column}`.

## Supported

The slice of the AST that covers the canonical examples in
`docs/netfilter/EXAMPLES.md`:

  * **Tables** in every family, with optional `comment`.
  * **Chains** with base headers (`type`/`hook`/`priority`/
    `policy`/`device`) and rules.
  * **Rules** with tag + comment, comprising matches and a
    terminal verdict (plus optional `counter` / `log` / NAT /
    `reject`).
  * **Matches** on the common headers — `tcp/udp dport/sport`
    against integer / range / inline-set / `@set_ref`,
    `ip/ip6 saddr/daddr` against address / CIDR / `@set_ref`,
    `meta iif/oif/iifname/oifname/mark`, `ct state`.
  * **Verdicts** — accept / drop / continue / return / queue /
    `jump <chain>` / `goto <chain>` / `reject [with ...]`.
  * **Actions** — `counter`, `log`, `dnat to <addr>[:port]`,
    `snat to`, `masquerade`, `redirect`.
  * **Sets / maps / vmaps** — declarations with `type`, `flags`,
    `timeout`, `gc-interval`, `size`, `elements`.

## Not yet supported (raises a clear ParseError)

  * `limit`, `meta mark set`, `ct ... set` — no setter `%Expr{}`
    yet on the Linx side. Pipeline DSL can construct them; the
    compiler will pick them up once they're added.
  * Named objects (`counter` / `quota` / `limit` blocks at table
    level) — declaration OK, but the underlying `%Object{}`
    shapes vary per kind; defer to a follow-up.
  * Flowtables — same reason.
  * `include` and `define` — file-merging and binding semantics
    are not yet implemented (use `Linx.NFT.parse_file/1`).
  * `#{...}` interpolation — only meaningful from the
    `~NFT` sigil; the compiler is called from there with a
    separate path that emits runtime code.

Each deferred case raises `Linx.NFT.ParseError` pointing at the
AST node's source location with a message naming the missing
feature, so users see exactly what the parser accepted but the
compiler hasn't wired up yet.

# `compile`

```elixir
@spec compile(
  [tuple()],
  keyword()
) :: {:ok, Linx.Netfilter.Ruleset.t()} | {:error, Linx.NFT.ParseError.t()}
```

Compiles a list of top-level AST items (the output of
`Linx.NFT.Parser.parse/2`) into a `%Linx.Netfilter.Ruleset{}`.

## Options

  * `:file` — source filename for error messages
    (default `"nofile"`).
  * `:source` — original source binary for snippet rendering
    (default `""`).

Returns `{:ok, %Ruleset{}}` or `{:error, %ParseError{}}`.

---

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