# Demo projects 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. **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. | Project | What it is for | | --- | --- | | [`hello/`](hello/) | The smallest thing that is still interesting: a struct, an enum, a match, a labelled argument, string interpolation | | [`shapes/`](shapes/) | A library plus a program: traits, generics, a custom error, and five tests to run from the **Test** menu item | | [`syntax-tour/`](syntax-tour/) | Every construct the scanner recognises, in one file that compiles. Open it to see what each colour means | ## Trying one ```bash cd demos/hello turbo-moonbit main.mbt ``` The status bar should read `LSP: ready` at the right-hand end — `moon.mod` is beside the file, so the server starts here. Then: - `Alt-M` opens the **MoonBit** menu. The first time, it offers only **Create tools file**; choose it, and the nine commands appear. - **Run** asks which package to run. In `hello` and `syntax-tour` the answer is `.`; in `shapes` it is `cmd/main`. - **Test** works in `shapes`, which is the one with tests. From a shell instead: ```bash moon check # type-check, no output files moon fmt # format in place moon run . # or `moon run cmd/main` in shapes moon test # shapes only ``` ## hello A greeting printed a few times, in three tones. It is deliberately short enough to read in one screen. 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. ## shapes 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. 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. `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. ## syntax-tour One file, `tour.mbt`, holding every construct the MoonBit scanner recognises — and one it gets wrong on purpose. 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. **One line is coloured wrongly, and is kept and labelled rather than avoided:** ```moonbit let nested = "answer: \{if true { "yes" } else { "no" }}" ``` 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. ## A note on `_build/` `moon` writes its output into a `_build/` directory beside each `moon.mod`. Those are gitignored. `moon clean` removes them.