| 1 | # Architecture |
| 2 | |
| 3 | This document will outline the code structure of the language's SDK as well as |
| 4 | the compilation pipeline architecture. The major components of the language are: |
| 5 | |
| 6 | - [**Core**][#core] (`src/core`) includes the parser, analysis passes, codegen |
| 7 | backends, and generating all warnings and errors. |
| 8 | - [**Manual Generator**][#manual] (`src/manual`) is a custom static site |
| 9 | generator used for building the SDK's documentation site. |
| 10 | |
| 11 | Keep in mind that **code is the best documentation for specific details**, and |
| 12 | this document aims to give an overall explainer of the codebase as a whole. |
| 13 | |
| 14 | General code style is to sort the file's contents by importance. Most files will |
| 15 | start with an overview comment, followed by the root struct fields, and then |
| 16 | important companion types and functions, then helpers. Imports and tests are not |
| 17 | as important to a reader, so those are placed at the end of the file. |
| 18 | |
| 19 | An example of this organization is `src/core/Tokenizer.zig`, which opens with |
| 20 | the tokenizer state, and then `pub fn tokenize` to bring attention to the flow |
| 21 | of tokenization. The `Token` struct is directly after this, since it is |
| 22 | important, but not as important as visualizing _how_ the tokenizer works. |
| 23 | |
| 24 | ## Testing |
| 25 | |
| 26 | Aside from tests written using Zig's test runner, there are a large set of tests |
| 27 | within `test` which are ran using a custom test runner binary. It categorizes |
| 28 | compiler tests into these categories: |
| 29 | |
| 30 | - **Analysis Tests** (`test/analysis/*`) verify the semantic analysis engine, |
| 31 | and must not emit any runtime `Air`. Some analysis tests may expect certain |
| 32 | compile errors. |
| 33 | - **Behavior Tests** (`test/behavior/*`) generate code to be executed at |
| 34 | runtime, testing both the semantic analysis pass as well as the code |
| 35 | generation backend. |
| 36 | - **Transform Error Tests** (`test/transform_error`) confirm that the transform |
| 37 | pass errors are correct. A passing `Hir` fails the test. |
| 38 | |
| 39 | All compiler tests can be run with `./build test`, or the test suite can be |
| 40 | filtered using flags, see `./build test -- --help` |
| 41 | |
| 42 | To run Zig tests for an associated module, use `./build test-{name}`, or run |
| 43 | `./build test-all` to run all tests in the codebase. |
| 44 | |
| 45 | ## Core |
| 46 | |
| 47 | The `core` module contains most of the compiler: |
| 48 | |
| 49 | - Tokenizing and Parsing files. (`Tokenizer.zig`, `Parse.zig`, `Ast.zig`) |
| 50 | - Transform Pass, moving from Ast to an untyped intermediate representation |
| 51 | (`Transform.zig`, `Hir.zig`) |
| 52 | - Semantic Analysis, resolving all types and comptime values. (`Sema.zig`) |
| 53 | - Intern Pool, storing and de-duplicating objects in a compilation. |
| 54 | (`InternPool.zig`) |
| 55 | - JavaScript Code Generation (`js/Js.zig`) |
| 56 | |
| 57 | Note that components like the formatter and module fetching code are not here. |
| 58 | Keeping this module as small as possible is important for keeping compile times |
| 59 | low. Using `./build compiler -- --help` instead of the fully featured binary |
| 60 | will allow for faster and more focused iteration. |
| 61 | |
| 62 | ## Manual |