# Contributing 

We welcome contributions to this project! 
Whether you're fixing bugs or improving documentation, your help is appreciated. 
Please follow the guidelines below to ensure a smooth contribution process.

In this stage we have two versions of MoonBit parser implementations:

- The OCaml implementation, which is the reference implementation used in the MoonBit toolchain.
- The MoonBit implementation, which is this project.

This project aims to follow the behavior of MoonBit's OCaml parser implementation 
when the input source has no syntax errors. 

## Exploring the AST

You can explore the AST structure using the online AST explorer, it show the 
AST generated by this repo's parser in the right pane.

https://moonbit-community.github.io/astexplorer/

## Dumping AST from OCaml Implementation

The moonbit toolchain allows you dump the AST in JSON format, we verify the 
parsers behaviors by comparing the AST output against the OCaml implementation, 
by using the snapshot tests. If the output differs, it could be a bug in this repo. 

You need to install the moonbit toolchain first, please refer to the 
[moonbitlang.com](https://www.moonbitlang.com/download/).

After installing the toolchain, you can dump the AST from a `.mbt` file by running:

```bash
mooninfo -dump-ast path/to/your_file.mbt -o output.json
```

It will call the `~/.moon/bin/mooninfo` executable, and generate the AST in `output.json` 
file at the current directory. 

If the command fails, you can trying to install the nightly build of moonbit toolchain, by running:

```bash 
curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash -s nightly
```

## Find Bugs & Report Issues 

Now that you have the AST dumped from the toolchain, and the AST shown in the AST explorer,
you can compare the two ASTs to see if there are any differences. If the below conditions 
are met, it might be a bug in this repo:

- The input source code is free of syntax errors.
- The input source code does not use any experimental features or deprecated syntax.
- The output JSON differs when comparing `output_json1.stringify(indent=2)` and `output_json2.stringify(indent=2)`.

You can report issues and provide a minimal reproducible example to help us investigate the problem. 

## Fixing Bugs

After the issue is reported and confirmed as a bug, you can consider contributing a fix!

- Keep the code style consistent with the existing codebase.

- A focused, minimal PR is preferred.

- Add a test to verify the fixed and avoid regressions.

- After committing the PR, ensure the CI passes successfully.

Feel free to ping the maintainers if your PR has been waiting too long.

## Adding Test Cases

1. Add a minimal reproducible input `your_test_file.mbt` in the `test/manual_test/__snapshot__` directory.

2. Add the expected AST output file dumped from the OCaml implementation as `your_test_file.json` to `test/manual_test/__snapshot__`.

3. Add test entry to `test/manual_test/driver.mbt` file, ensure the test name is same as the file name. for example:

    ```mbt
    test "your_test" (t : @test.Test) {
      t.run()
    }
    ```
    
    The `t.run()` will trying to read the input file specified by the test name, 
    `__snapshot__/your_test.mbt` in the same directory, runing the parser and comparing 
    the output AST against the expected AST in `__snapshot__/your_test.json` file.

4. Run the test `moon test`, or click `test` button above the test block to verify the test case passes.


