Modules e packages
Um arquivo é um module
Os diretórios formam o caminho. As declarações são privadas ao seu module, a não ser que sejam marcadas com pub:
use std.io; // module namespace: io.read_fd(..)
use std.io.{read_fd, write_fd}; // items directly
use std.io.{read_fd as read}; // an item under another name
use std.io as sio; // a module under another name
use std.str.*; // all public itemsstd resolve para a biblioteca padrão; as outras raízes resolvem relativas ao diretório do arquivo de entrada e à raiz do package. Ciclos são um erro. Um programa é uma árvore de modules com exatamente um fn main no module raiz.
Um nome, um significado. O que acontece quando dois bindings querem o mesmo nome é fixado pela forma do import, nunca pela ordem:
| Os dois bindings | O que acontece |
|---|---|
use a.{f} e use b.{f} | erro no segundo import |
use a.{f} e fn f aqui | erro no import |
use a.* e fn f aqui | a declaração ganha |
use a.* e use b.{f} | o import do item ganha |
use a.* e use b.*, os dois com f | erro onde f é usado, e só ali |
Um tipo é um nome do seu module: dois modules podem declarar cada um um pub struct S; quem importa e precisa dos dois importa cada um sob um alias, dentro das chaves.
Reexports: pub use
pub use importa um nome e o torna um nome público do module que o escreve, então um package pode apresentar uma única porta de entrada, quaisquer que sejam os arquivos em que o código dele está:
// shapes.talor - the package's root module
pub use shapes.geometry.{Point, origin}; // items
pub use shapes.geometry.{Point as P}; // an item under another name
pub use shapes.geometry.*; // every public item of the module// main.talor
use shapes.{Point, origin};O nome reexportado é a mesma declaração, não uma cópia: shapes.Point e shapes.geometry.Point são um tipo só. Só itens públicos podem ser reexportados, e só itens: pub use a.b; nomeando um module é recusado.
Um package no disco
Um package é um diretório com um arquivo talor.mod na raiz. O manifest é feito de linhas:
name myapp
version 0.1.0
program myapp src/main.talor
require greet file:// ../greet
require util path libs/util| Diretiva | Significado |
|---|---|
name | um identificador |
version | <major>.<minor>.<patch> |
program | um executável e o module em que ele começa |
library | o module que alcança quem importa este package |
require | o nome de uma dependência, a fonte de onde ela vem, e o que essa fonte recebe |
registry | uma URL: o registry padrão deste package |
warn | uma categoria de aviso e o nível em que ela é reportada |
As fontes são path (um diretório dentro do package), file:// (um caminho em qualquer lugar, copiado para a cache), git e registry - essas duas últimas precisam da rede, e packages diz em que pé isso está - e workspace, que não recebe nada: o package depende do nome, e o build de que ele faz parte diz de onde o nome vem, pelo require desse nome no próprio package raiz. Um require escrito duas vezes é recusado.
Um package declara todo package que usa: um use cujo primeiro nome não é nem um dos modules do próprio package nem std precisa de um require com esse nome.
Um use a.b.c nomeia o arquivo a/b/c.talor, procurado nesta ordem: ao lado do arquivo que escreveu o use, sob a raiz do require cujo nome é a, e depois sob cada raiz -L. O primeiro arquivo que existe ganha.
Os comandos
talor build [<dir>] [--check] [--release] [--target <triple>] [--target-os <name>]
talor run <file.talor> [-L <dir>] [--release] [-- args...]
talor test <file.talor> -o <out.ll>buildlê o manifest e faz o link de cadaprogramem<dir>/build/; o link é pulado quando o IR não mudou. Semtalor.lock, ele resolve as linhasrequiree escreve um, e com um lock ele o lê e nunca o muda.--checkcompila e não faz o link.runé um programa, compilado e executado em um passo só: o comando responde o que o programa respondeu,--encerra os argumentos do comando e começa os do programa, e nada sobrevive à execução.- O conjunto fechado de targets é
linux/macos/windowsemx86_64/aarch64.--target-osé como uma declaração sob#[os("macos")]é compilada em uma máquina Linux.