# `Grammar.VM.CharCompiler`
[🔗](https://github.com/joetjen/ichor/blob/v0.3.0/lib/grammar/vm/char_compiler.ex#L1)

Compiles every token in a grammar (character-level: `Literal`,
`CharClass`, `Any`, and `RuleRef` to another token -- the only node
shapes an *ordinary* token body can contain) into one linked
`Grammar.VM.Program`, run by `Grammar.VM.Tokenizer`.

A token whose entire body is a `Grammar.IR.CustomLexeme`
(`@native(...)` at token position) is pulled out separately instead of
compiled to bytecode -- there's nowhere for a `{:call, name}` from
another token to jump into for it (see that module's own moduledoc for
why it can't be composed inside a larger token expression or
referenced from one), so `Grammar.VM.Tokenizer` dispatches to it directly
by name via the second map this returns.

# `custom_lexeme`

```elixir
@type custom_lexeme() :: {module :: module(), function :: atom(), deps :: [atom()]}
```

# `compile`

```elixir
@spec compile(%{required(atom()) =&gt; Grammar.IR.expr()}) ::
  {Grammar.VM.Program.t(), %{required(atom()) =&gt; custom_lexeme()}}
```

---

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