Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / docs / compiler / README.md
6.2 kB 143 lines
1<!-- 2 SPDX-License-Identifier: Apache-2.0 3 SPDX-FileCopyrightText: 2021 The Gleam contributors 4--> 5 6# Compiler documentation 7 8Hello! Welcome to the documentation for the Gleam compiler. I hope you have fun 9with the project! 10 11<!-- vscode-markdown-toc --> 12* [Project structure](#project-structure) 13* [Compilation flow](#compilation-flow) 14* [Testing](#testing) 15 * [Running the tests](#running-the-tests) 16 * [Snapshot testing](#snapshot-testing) 17 18<!-- vscode-markdown-toc-config 19 numbering=false 20 autoSave=true 21 /vscode-markdown-toc-config --> 22<!-- /vscode-markdown-toc --> 23 24## <a name='Projectstructure'></a>Project structure 25 26The project is made up of several Rust crates (projects): 27 28- `compiler-core`: This project parses, analyses, and compiles Gleam projects. 29 It is entirely pure and has no IO so that is provided by the other Rust crates 30 that wrap this one. 31- `language-server`: This project contains code for the Gleam language server, 32 including autocomplete, code actions, hover and other features. 33- `compiler-cli`: A command line interface that wraps the core compiler and 34 language server, providing IO to files and to the console. 35- `compiler-wasm`: A JavaScript interface to the core compiler via web assembly. 36 Suitable for running in a web browser. 37 38In addition to the Rust code there are these components: 39 40- `Makefile`: A makefile that defines shortcut commands for common tasks when 41 working in the Gleam codebase. Run `make help` to view them. 42- `test`: A collection of (mostly) Gleam projects that serve as integration tests for the 43 compiler. 44- `deny.toml`: Configuration for the `cargo-deny` tool which is used to ensure 45 that the Rust libraries the compiler depends on adhere to our expectations. 46- `containers`: A collection of docker-files used to produce OCI containers for 47 each Gleam release. 48- `.github/workflows`: GitHub Actions workflow definitions, used to build, test, 49 and release new versions of the project. 50- `docs`: You're looking at it pal. 51 52## <a name='Compilationflow'></a>Compilation flow 53 54The process for compiling Gleam modules within the compiler looks roughly like 55this: 56 57```txt 58 Gleam source code .cache binaries 59 ▼ ▼ 60┌────────────────────┐ ┌───────────────────────┐ 61│ Parser │ │ Metadata deserializer │ 62└────────────────────┘ └───────────────────────┘ 63 │ │ 64 Untyped AST Module metadata 65 └─────────┐ ┌────────┘ │ 66 ▼ ▼ │ 67 ┌─────────────────────┐ │ 68 │ Dependency sorter │ │ 69 └─────────────────────┘ │ 70 │ │ 71 Untyped AST │ 72 (sorted by deps) │ 73 ▼ │ 74 ┌───────────────────┐ │ 75 │ Type checker │◄─────┘ 76 └───────────────────┘ 77 78 ┌────── Typed AST ──────┐ 79 ▼ ▼ 80┌────────────────────┐ ┌─────────────────────┐ 81│ Code generator │ │ Metadata serializer │ 82└────────────────────┘ └─────────────────────┘ 83 │ │ 84 │ ▼ 85 Erlang or JavaScript .cache binaries 86 printing algebra 87 88┌────────────────────┐ 89│ Pretty printer │ 90└────────────────────┘ 91 92 93 Erlang or JavaScript 94 source code 95``` 96 97## <a name='Testing'></a>Testing 98 99We like automated tests! They're a great way to verify that the compiler is 100doing what we expect it do as we make changes. 101 102### <a name='Runningthetests'></a>Running the tests 103 104- `make test`: Run all the tests. Worth doing before committing any changes. 105- `make test-watch`: Run the Rust unit tests when files are saved. 106- `make language-test`: Run the cross-platform language integration tests in 107 `test/language`. 108- `make language-test-watch`: Run said tests when files are saved. 109- `make javascript-prelude-test`: Run the unit tests for the JavaScript code 110 that implements the Gleam prelude when compiling to JavaScript. 111- `make javascript-prelude-test-watch`: Run said tests when files are saved. 112 113The `*-watch` commands require the [`watchexec`][watchexec] program to be 114installed. 115 116### <a name='Snapshottesting'></a>Snapshot testing 117 118The compiler makes heavy use of snapshot testing using the 119[`cargo-insta`][cargo-insta] tool. 120 121[cargo-insta]: https://github.com/mitsuhiko/insta 122[watchexec]: https://github.com/watchexec/watchexec 123 124If you're not familiar with snapshot testing instead of writing an input and an 125expected output (as in normal example based tests) you write only the input. The 126snapshot testing tool can then be used to mark any new outputs as accepted and 127saved into the repository as snap files. If an output for one of the tests 128changes then it is considered a failed test and the programmer has the option to 129either reject the new version (as it is an incorrect result) or accept it as the 130new correct output. 131 132This style of testing saves us huge amounts of time as manually updating all the 133expected output when we make changes to the output format of the compiler or 134error messaging is time-consuming and very dull. With snapshot testing it takes 135seconds. 136 137```sh 138# Run the tests 139make test 140 141# Interactively verify changes to the snapshots 142cargo insta review 143```