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/ |
The smallest thing that is still interesting: a struct, an enum, a match, a labelled argument, string interpolation |
shapes/ |
A library plus a program: traits, generics, a custom error, and five tests to run from the Test menu item |
syntax-tour/ |
Every construct the scanner recognises, in one file that compiles. Open it to see what each colour means |
Trying one
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-Mopens 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
helloandsyntax-tourthe answer is.; inshapesit iscmd/main. - Test works in
shapes, which is the one with tests.
From a shell instead:
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:
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 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
|