| 📦 Turbo MoonBit cc1f595 k33g 11h ago | 1 | # Demo projects |
| 2 | |
| 3 | Three small MoonBit projects to open in Turbo MoonBit. They exist to be *edited*, not just read: each one is a real `moon` module, so opening any file in it starts `moon-lsp` in that directory and the MoonBit menu's commands work on it. |
| 4 | |
| 5 | **All three compile with no errors and no warnings**, pass `moon fmt` without being rewritten, and were run before being committed. That is the whole point — a colouring demo that does not build is a screenshot. |
| 6 | |
| 7 | | Project | What it is for | |
| 8 | | --- | --- | |
| 9 | | [`hello/`](hello/) | The smallest thing that is still interesting: a struct, an enum, a match, a labelled argument, string interpolation | |
| 10 | | [`shapes/`](shapes/) | A library plus a program: traits, generics, a custom error, and five tests to run from the **Test** menu item | |
| 11 | | [`syntax-tour/`](syntax-tour/) | Every construct the scanner recognises, in one file that compiles. Open it to see what each colour means | |
| 12 | |
| 13 | ## Trying one |
| 14 | |
| 15 | ```bash |
| 16 | cd demos/hello |
| 17 | turbo-moonbit main.mbt |
| 18 | ``` |
| 19 | |
| 20 | The status bar should read `LSP: ready` at the right-hand end — `moon.mod` is beside the file, so the server starts here. Then: |
| 21 | |
| 22 | - `Alt-M` opens the **MoonBit** menu. The first time, it offers only **Create tools file**; choose it, and the nine commands appear. |
| 23 | - **Run** asks which package to run. In `hello` and `syntax-tour` the answer is `.`; in `shapes` it is `cmd/main`. |
| 24 | - **Test** works in `shapes`, which is the one with tests. |
| 25 | |
| 26 | From a shell instead: |
| 27 | |
| 28 | ```bash |
| 29 | moon check # type-check, no output files |
| 30 | moon fmt # format in place |
| 31 | moon run . # or `moon run cmd/main` in shapes |
| 32 | moon test # shapes only |
| 33 | ``` |
| 34 | |
| 35 | ## hello |
| 36 | |
| 37 | A greeting printed a few times, in three tones. It is deliberately short enough to read in one screen. |
| 38 | |
| 39 | What it shows: `struct` with `derive(Eq)`, an `enum` and a `match` over it, a hand-written `impl Show … with fn output` (which is what `derive(Show)` was deprecated in favour of), a labelled argument with a default — `tone~ : Tone = Plain`, passed as `greet(g, tone=Loud)` — and `\{…}` interpolation. |
| 40 | |
| 41 | ## shapes |
| 42 | |
| 43 | A library package at the root and a program under `cmd/main` that imports it. This is the layout `moon new` produces, and the one most real projects have. |
| 44 | |
| 45 | What it shows: `pub(open) trait Area`, two implementations, generic functions bounded by a trait — `pub fn[T : Area] total(…)` — a `pub suberror` and `raise`, `guard … else { raise … }`, `try`/`catch`/`noraise`, `Option` with `Some`/`None`, and package qualifiers (`@shapes.Circle`) everywhere, because the program is in a different package from the library. |
| 46 | |
| 47 | `pub(all)` rather than `pub` on the two structs is not decoration: `pub` alone makes a type read-only from outside its package, so `cmd/main` could not construct one. |
| 48 | |
| 49 | ## syntax-tour |
| 50 | |
| 51 | One file, `tour.mbt`, holding every construct the MoonBit scanner recognises — and one it gets wrong on purpose. |
| 52 | |
| 53 | What it shows: all five quoted forms (`"…"`, `b"…"`, `re"…"`, `'c'`, `b'c'`), both multi-line string prefixes (`#|` literal, `$|` interpolating), every numeric form and suffix the grammar allows, `1..=5` and `0..<3` (which is where a scanner that swallowed any dot after a number would go wrong), traits and `extend`, `suberror` and error handling, a `for` loop carrying accumulators with `break` and `continue`, tuples and `.0`, the pipe operator, and both kinds of attribute — a built-in `#deprecated("…")` and a user-defined `#custom.note(…)`, each taking its whole line. |
| 54 | |
| 55 | **One line is coloured wrongly, and is kept and labelled rather than avoided:** |
| 56 | |
| 57 | ```moonbit |
| 58 | let nested = "answer: \{if true { "yes" } else { "no" }}" |
| 59 | ``` |
| 60 | |
| 61 | A string nested inside an interpolation ends the outer literal as far as the scanner is concerned, so `yes` and `no` come out as identifiers. Finding the real end needs the parser rather than the scanner. [`reference/languages.md`](../docs/en/reference/languages.md) says so, and a test pins it, so it is a known boundary rather than a surprise. |
| 62 | |
| 63 | ## A note on `_build/` |
| 64 | |
| 65 | `moon` writes its output into a `_build/` directory beside each `moon.mod`. Those are gitignored. `moon clean` removes them. |