Crates.io | pax-compiler |
lib.rs | pax-compiler |
version | 0.38.3 |
source | src |
created_at | 2022-09-13 01:45:22.886745 |
updated_at | 2024-10-24 23:14:35.979344 |
description | Compiler APIs for parsing and building Pax projects into application executables |
homepage | https://pax.dev/ |
repository | https://www.github.com/paxproject/pax |
max_upload_size | |
id | 664091 |
size | 10,524,506 |
This document describes the high-level architecture of pax-compiler.
For more information refer to our docs.
Roughly it can be broken down into three steps:
The main entry-point for all of this is perform_build
found in lib.rs
.
Pax projects decorate their associated Rust with a special macro #[derive(Pax)]
. These macros generate code to dynamically analyze their tagged structs. They each add a parse_to_manifest
function for every #[derive(Pax)]
tagged struct. This parse_to_manifest
function (template found here) stores its associated structs information in a ParsingContext object and calls parse_to_manifest
on its Pax Template dependencies. It utilizes logic in parsing.rs
and relies on our pest grammar (pax.pest
) to understand the template dependencies. For the root struct (tagged #[main]
e.g. here), we generate a binary target as well that starts the process and writes the accumulated information into a Pax Manifest and serializes it to stdout. This binary (named parser
) is kicked off (run_parser_binary
) as our first step of the compilation process to generate the Manifest in the lib.rs/perform_build
function.
Next we generate the Pax Cartridge. This work is roughly two steps: compiling expressions and generating the cartridge code. The former involves parsing Paxel (Pax's expression language) and generating the equivalent rust code. This work lives in expressions.rs
. Once expressions are compiled, the second step is generating the cartridge code. This lives in the code_generation
module. We utilize Tera templates for the code-gen and the bulk of this work is translating a Pax Manifest into a Tera context. The main entry point is generate_and_overwrite_cartridge
in code_generation/mod.rs
.
The last step of this process involves building our target platform (e.g. Web/MacOS/..) scaffolding (see chassis) with our cartridge included. This work lives in the building
module. This mainly involves building the generated cartridge, loading it into our specific chassis and then building that chassis. Currently we support 3 targets (Web/MacOS/iOS). We load our cartridge as WASM for Web and as .dylib
s for our Apple targets.
The main consumers of pax-compiler
are pax-cli
and pax-macro
. pax-cli
is the CLI that Pax user's invoke to build Pax projects. pax-macro
is the crate the defines the #[derive(Pax)]
macro that we use for dynamic analysis of the Pax Project (see Step 1).