Configurando o projeto
Para iniciarmos o projeto, primeiro precisamos certificar-nos de que o mesmo possui uma configuração adequada, o que envolve o uso de dependências, nome do software, versão do software, dados dos mantenedores e outras coisas.
Neste capítulo, trataremos das configurações básicas do projeto. Isso envolve a criação de certos diretórios, configurações do projeto Rust, e scripts de compilação.
1. Árvore do projeto
O primeiro passo para criarmos os arquivos de projeto é construirmos a árvore do projeto. Isso envolve a criação de alguns diretórios.
Para um projeto Rust, teremos, no diretório-raiz, um diretório src
,
que conterá todos os arquivos de código do projeto.
Ademais, em src
, também teremos mais alguns diretórios, cujos nomes
designam módulos homônimos no projeto.
O comando de console a seguir cria recursivamente esses diretórios, ignorando-os caso já existam.
mkdir -p \ src/core \ src/axioms \ src/printing \ src/evaluator \ src/reader
2. Configurando a crate
O programa cargo
é o gerenciador de pacotes da linguagem Rust. Cada
projeto é empacotado em estruturas chamadas crates, e um projeto pode
especificar dependências de outras crates também.
O interpretador de Majestic Lisp é construído sob a crate
majestic-lisp
. Como dependências, utiliza:
rust-gc
1, um coletor de lixo simples, estilo mark-and-sweep;colored
2, uma biblioteca de colorização de output no console;rustyline
3, uma implementação delibreadline
para Rust.float-cmp
,rustf8,
comfy-table
,bimap
, para associarmos certas informações a seus nomes e ainda assim realizarmos pesquisas em ambos os tipos de informação.
A seguir, especificamos o arquivo Cargo.toml
, incluído na raiz do
projeto. Esse arquivo determina a configuração para o uso da
ferramenta cargo
.
[package] name = "majestic-lisp" version = "0.4.2" authors = ["Lucas S. Vieira <lucasvieira@protonmail.com>"] description = "Lisp dialect built with Rust as a literate program" license = "MIT" keywords = ["lisp", "language", "dialect", "interpreter"] readme = "README.org" edition = "2018" build = "build.rs" [features] dumb_terminal = ["colored/no-color"] [build-dependencies] chrono = "0.4.19" [dev-dependencies] regex = "1.4.2" [dependencies] gc = { version = "0.4.0", features = ["derive"] } rand = { version = "0.7" } colored = "2.0" rustyline = "6.3.0" rustyline-derive = "0.3.1" float-cmp = "0.8.0" rustf8 = "0.9.1" num-derive = "0.3.3" num-traits = "0.2.14" stacker = "0.1" bimap = "0.6.2" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] comfy-table = "1.4.2"
Outra configuração muito importante a ser feita é deixarmos claro que
pretendemos usar, para compilação, o canal nightly
do compilador, já
que utilizaremos recursos que ainda estão instáveis em Rust. Para
tanto, basta adicionarmos o canal e a data da versão do mesmo em um
arquivo rust-toolchain
:
nightly
3. Configuração para exportação de WebAssembly
A configuração a seguir (arquivo wapm.toml
) determina a configuração
necessária para a publicação do pacote do Majestic Lisp no WAPM.io. Dessa forma,
o projeto poderá também ser utilizado no WebAssembly.sh.
[package] name = "luksamuk/majestic-lisp" version = "0.4.2" description = "Lisp dialect built with Rust as a literate program" license = "MIT" license-file = "LICENSE" repository = "https://github.com/luksamuk/majestic-lisp" wasmer-extra-flags = "--enable-bulk-memory" [[module]] name = "majestic" source = "./target/wasm32-wasi/release/majestic-lisp.wasm" abi = "wasi" [module.interfaces] wasi = "0.1.0-unstable" [[command]] name = "majestic" module = "majestic" package = "luksamuk/majestic-lisp"
4. Compilação
Para compilarmos o projeto, podemos criar um arquivo Makefile
que
acelerará esse processo.
Arquivos Makefile
são normalmente utilizados pela ferramenta GNU
Make. De forma subjacente, utilizaremos o compilador de Rust e a
ferramenta cargo
para compilarmos o projeto.
Por enquanto, algumas das características necessárias para compilar o projeto encontram-se nas ferramentas instáveis de Rust, também conhecidas pelo nome nightly.
Podemos executar o comando de console
rustup install nightly-x86_64-unknown-linux-gnu
para instalar a toolchain necessária para a compilação do projeto.
Caso você queira também testar o interpretador com WASI
(WebAssembly
System Interface)4, instale a ferramenta cargo-wasi
:
cargo install cargo-wasi
Caso você queira também compilar para RISC-V 64-bit, instale a ferramenta
cross
. Note que você precisará ter instalado o Docker ou o Podman para
usá-la:
cargo install cross
A seguir, especificamos um arquivo Makefile
, de nome homônimo, no
diretório-raiz do projeto.
PROFILE= OBJTYPE=`uname -m` all: bin buildall: bin wasm win64 riscv64 release: PROFILE += --release release: buildall release-bin: PROFILE += --release release-bin: bin release-wasm: PROFILE += --release release-wasm: wasm release-win64: PROFILE += --release release-win64: win64 release-riscv64: PROFILE += --release release-riscv64: riscv64
bin: cargo build ${PROFILE} install: release-bin man/man1/majestic.1 install -m 755 target/release/majestic-lisp ${PREFIX}/bin/majestic install -m 644 man/man1/majestic.1 ${PREFIX}/share/man/man1/ uninstall: rm -f ${PREFIX}/bin/majestic rm -f ${PREFIX}/share/man/man1/majestic.1 test: cargo test test-verbose: cargo test -- --nocapture bench: cargo bench run: cargo run ${PROFILE} wasm: cargo wasi build ${PROFILE} win64: cargo build ${PROFILE} --target \ "x86_64-pc-windows-gnu" \ --features dumb_terminal riscv64: cross build ${PROFILE} --target "riscv64gc-unknown-linux-gnu" wasmrun: cargo wasi run ${PROFILE} winerun: win64 wineconsole \ ./target/x86_64-pc-windows-gnu/debug/majestic-lisp.exe \ 2>/dev/null
present: @majestic -l "examples/helper.maj"