llm
Download
69 lines 2.7 KiBMarkdownModified 2026-09-28 raw

Embedding Files

_embed_ bakes a file's contents into the compiled binary at compile time, so the program doesn't need the file on disk when it runs:

func main()
    logo := _embed_ ./logo.png
    >> logo : [Byte]

The path is relative to the source file doing the embedding. An embed is a [Byte] by default, but can be embedded as a Text (checked for valid UTF8 at compile time) or a CString (checked for no NUL bytes at compile time) by giving it that type:

motd : Text = _embed_ ./motd.txt

Embedding Directories

Embedding a directory embeds every file in it, recursively, as a table mapping each file's relative path to its contents:

func main()
    assets := _embed_ ./assets
    >> assets : {Path:[Byte]}
    say(assets[(./style.css)]!.length)

    pages : {Path:Text} = _embed_ ./pages
    for path, contents in pages.entries()
        say("$path: $(contents.length) graphemes")

Keys are the files' paths relative to the embedded directory, in the same normalized form path literals compile to, so a literal like (./inner/file.txt) looks its entry up directly. Entries iterate in sorted path order, and the table compiles deterministically.

As with single files, a directory embeds as {Path:[Byte]} by default and can be embedded as {Path:Text} instead, in which case every file in it must be valid UTF8, or as {Path:CString}, in which case no file in it may contain a NUL byte. Both are checked at compile time, and the error names the file that failed.

A few rules about which files a directory embed includes:

  • Dotfiles (and dot-directories) are not included. To embed one, name it explicitly: _embed_ ./config/.env.
  • Symbolic links are silently skipped, since they could point outside the directory or form a cycle.
  • A directory with no embeddable files is a compile-time error, as is a missing file or directory.

Embedded paths must be relative (starting with ./ or ../) — an absolute or home-based path is machine-specific and could never travel with the program's sources, so it's a compile-time error. Relative paths may reach anywhere, including above the source file: no directory is privileged.

Embedded files are tracked as build dependencies: editing, adding, removing, or renaming a file under an embedded directory causes the module embedding it to recompile. They are also included in the compiled binary's embedded source archive (see Compilation), whose src/ tree is rooted at the deepest directory containing every source and embedded file — so a module embedding ../file.txt simply roots the extracted tree one level higher, and tomo source <program> -o <dir> always extracts a project that rebuilds into the same program.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
# Embedding Files

`_embed_` bakes a file's contents into the compiled binary at compile time, so
the program doesn't need the file on disk when it runs:

```tomo
func main()
    logo := _embed_ ./logo.png
    >> logo : [Byte]
```

The path is relative to the source file doing the embedding. An embed is a
`[Byte]` by default, but can be embedded as a `Text` (checked for valid UTF8 at
compile time) or a `CString` (checked for no `NUL` bytes at compile time) by
giving it that type:

```tomo
motd : Text = _embed_ ./motd.txt
```

## Embedding Directories

Embedding a directory embeds every file in it, recursively, as a table mapping
each file's relative path to its contents:

```tomo
func main()
    assets := _embed_ ./assets
    >> assets : {Path:[Byte]}
    say(assets[(./style.css)]!.length)

    pages : {Path:Text} = _embed_ ./pages
    for path, contents in pages.entries()
        say("$path: $(contents.length) graphemes")
```

Keys are the files' paths relative to the embedded directory, in the same
normalized form path literals compile to, so a literal like
`(./inner/file.txt)` looks its entry up directly. Entries iterate in sorted
path order, and the table compiles deterministically.

As with single files, a directory embeds as `{Path:[Byte]}` by default and can
be embedded as `{Path:Text}` instead, in which case every file in it must be
valid UTF8, or as `{Path:CString}`, in which case no file in it may contain a
`NUL` byte. Both are checked at compile time, and the error names the file
that failed.

A few rules about which files a directory embed includes:

- Dotfiles (and dot-directories) are **not** included. To embed one, name it
  explicitly: `_embed_ ./config/.env`.
- Symbolic links are silently skipped, since they could point outside the
  directory or form a cycle.
- A directory with no embeddable files is a compile-time error, as is a
  missing file or directory.

Embedded paths must be relative (starting with `./` or `../`) — an absolute or
home-based path is machine-specific and could never travel with the program's
sources, so it's a compile-time error. Relative paths may reach anywhere,
including above the source file: no directory is privileged.

Embedded files are tracked as build dependencies: editing, adding, removing,
or renaming a file under an embedded directory causes the module embedding it
to recompile. They are also included in the compiled binary's embedded source
archive (see [Compilation](compilation.md)), whose `src/` tree is rooted at
the deepest directory containing every source and embedded file — so a module
embedding `../file.txt` simply roots the extracted tree one level higher, and
`tomo source <program> -o <dir>` always extracts a project that rebuilds into
the same program.