Skip to content

Commit

Permalink
Merge pull request #93 from moonbitlang/update-moon-tutorial-2
Browse files Browse the repository at this point in the history
update build system tutorial
  • Loading branch information
bzy-debug authored Oct 23, 2023
2 parents 6e154a0 + 1737233 commit 6437eac
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 42 deletions.
Binary file modified imgs/after_watch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified imgs/before_watch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
129 changes: 87 additions & 42 deletions moon_build_system_tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@ Before you begin with this tutorial, make sure you have installed the following:
Usage: moon <COMMAND>
Commands:
build Build the current package
check Check the current package, but don't build object files
run Run WebAssembly module
clean Remove the target directory
new Create a new moonbit package
bench Generate build matrix for benchmarking
fmt Format moonbit
version Print version info and exit
help Print this message or the help of the given subcommand(s)
build Build the current package
check Check the current package, but don't build object files
run Run WebAssembly module
clean Remove the target directory
new Create a new moonbit package
bench Generate build matrix for benchmarking
fmt Format moonbit
version Print version info and exit
test Run the tests
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-h, --help Print help
```
2. **Moonbit Language** plugin in Visual Studio Code: You can install it from the VS Code marketplace. This plugin provides a rich development environment for MoonBit, including functionalities like syntax highlighting, code completion, and more.
Expand All @@ -51,23 +52,25 @@ After creating the new module, your directory structure should resemble the foll
.
├── lib
│ ├── hello.mbt
│ └── moon.pkg
│ └── moon.pkg.json
├── main
│ ├── main.mbt
│ └── moon.pkg
└── moon.mod
│ └── moon.pkg.json
└── moon.mod.json
```

Here's a brief explanation of the directory structure:

- `lib` and `main` directories: These are packages in the module. Each package can contain multiple `.mbt` files, which are the source code files in MoonBit language. However, regardless of the number of `.mbt` files in a package, they all share a common `moon.pkg` file.
- `lib` and `main` directories: These are packages in the module. Each package can contain multiple `.mbt` files, which are the source code files in MoonBit language. However, regardless of the number of `.mbt` files in a package, they all share a common `moon.pkg.json` file.

- `moon.pkg` is package descriptor. It defines the properties of the package, such as its name, and the packages it imports.
- `moon.pkg.json` is package descriptor. It defines the properties of the package, such as its name, and the packages it imports.

- `moon.mod` is used to identify a directory as a MoonBit module. It contains the module's name:
- `moon.mod.json` is used to identify a directory as a MoonBit module. It contains the module's name:

```go
module "hello"
```json
{
"name": "hello"
}
```

## Checking Your Project
Expand All @@ -87,16 +90,16 @@ Our `hello` module contains two packages: `lib` and `main`.
The `lib` package contains a `hello.mbt` file:

```rust
pub func hello() -> String {
pub fn hello() -> String {
"Hello, world!\n"
}
```

The `main` package contains a `main.mbt` file:

```rust
func init {
print(@lib.hello())
fn init {
println(@lib.hello())
}
```

Expand All @@ -110,15 +113,18 @@ Hello, world!
## Package Importing

In the MoonBit's build system, a module's name is used to reference its internal packages.
To import the `lib` package in `main/main.mbt`, you need to specify it in `main/moon.pkg`:

```go
package main
To import the `lib` package in `main/main.mbt`, you need to specify it in `main/moon.pkg.json`:

import "hello/lib"
```json
{
"name": "main",
"import": {
"hello/lib": ""
}
}
```

Here, `import "hello/lib"` specifies that the `lib` package from the `hello` module is to be imported.
Here, `"hello/lib": ""` specifies that the `lib` package from the `hello` module is to be imported, and `""` means that `lib` has no name alias.

## Creating and Using a New Package

Expand All @@ -133,7 +139,7 @@ Now, you can create new files under `lib/fib`:
`a.mbt`:

```rust
pub func fib(n : Int) -> Int {
pub fn fib(n : Int) -> Int {
match n {
0 => 0
1 => 1
Expand All @@ -145,7 +151,7 @@ pub func fib(n : Int) -> Int {
`b.mbt`:

```rust
pub func fib2(num : Int) -> Int {
pub fn fib2(num : Int) -> Int {
fn aux(n, acc1, acc2) {
match n {
0 => acc1
Expand All @@ -158,10 +164,12 @@ pub func fib2(num : Int) -> Int {
}
```

`moon.pkg`:
`moon.pkg.json`:

```
package fib
```json
{
"name": "fib"
}
```

After creating these files, your directory structure should look like this:
Expand All @@ -172,28 +180,34 @@ After creating these files, your directory structure should look like this:
│ ├── fib
│ │ ├── a.mbt
│ │ ├── b.mbt
│ │ └── moon.pkg
│ │ └── moon.pkg.json
│ ├── hello.mbt
│ └── moon.pkg
│ └── moon.pkg.json
├── main
│ ├── main.mbt
│ └── moon.pkg
└── moon.mod
│ └── moon.pkg.json
└── moon.mod.json
```

In the `main/moon.pkg` file, add the following line:
In the `main/moon.pkg.json` file, import package `hello/lib/fib`:

```go
import "hello/lib/fib"
```json
{
"name": "main",
"import": {
"hello/lib": "",
"hello/lib/fib": ""
}
}
```

This line imports the `fib` package, which is part of the `lib` package in the `hello` module. After doing this, you can use the `lib/fib` package in `main/main.mbt`. Replace the file content of `main/main.mbt` to:
This line imports the `fib` package, which is part of the `lib` package in the `hello` module. After doing this, you can use the `fib` package in `main/main.mbt`. Replace the file content of `main/main.mbt` to:

```rust
func init {
fn init {
let a = @fib.fib(10)
let b = @fib.fib2(11)
print("fib(10) = \(a), fib(11) = \(b)\n")
println("fib(10) = \(a), fib(11) = \(b)")
}
```

Expand All @@ -203,3 +217,34 @@ To execute your program, specify the path to the `main` package:
$ moon run ./main
fib(10) = 55, fib(11) = 89
```

## Adding tests

In the last, let's add some tests to verify our fib implementation.

First, inside the `lib/fib` directory, create a file named `fib_test.mbt` and paste the following code:

```rust
fn assert_eq[T: Eq](lhs: T, rhs: T) {
if lhs != rhs {
abort("")
}
}

fn init {
assert_eq(fib(1), 1)
assert_eq(fib(2), 1)
assert_eq(fib(3), 2)
assert_eq(fib(4), 3)
assert_eq(fib(5), 5)
}
```

This code tests the first five terms of the Fibonacci sequence.

Finally, use the command `moon test` which scans the module, identifying and running all files ending with `_test.mbt`. If everything works, you'll see:

```bash
$ moon test
test lib/fib ... ok
```

0 comments on commit 6437eac

Please sign in to comment.