Skip to content

Commit

Permalink
FEAT: various improvements and fixes (#11)
Browse files Browse the repository at this point in the history
* FEAT: option to suppress warnings; dump generated code; various fixes

* replace regex matching w/ json output
better output format and performance

* Adds basic LP utility (#3)

* Update README.md
  • Loading branch information
notch1p authored Aug 19, 2024
1 parent 9f9a238 commit e8210ba
Show file tree
Hide file tree
Showing 4 changed files with 422 additions and 155 deletions.
146 changes: 93 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,89 +2,129 @@

This is a Markdown linter for MoonBit. It gathers all MoonBit codes in Markdown, checks them using MoonBit's compiler, and reports any diagnostics.

# Prerequisites
## Prerequisites

To use the MoonBit Markdown Linter, you need to install the [MoonBit compiler](https://www.moonbitlang.com/download/).

# Install
## Install

```
npm install -g @moonbit/markdown-linter
```

# Usage
## Usage

## Check Syntax and Type Errors
### Examples

Create a markdown file `fib.md`, write some MoonBit code in code block:
`mdlint` checks for possible errors in your moonbit code inside markdown documents:

# Fibonacci
````markdown
// test.md

Calculate the nth Fibonacci number using recursion and pattern matching.

```moonbit
fn fib(n : Int) -> Int {
match n {
0 => 0
1 => true // type error here
_ => fib(n - 1) + fib(n - 2)
}
}
```
```moonbit // defaults to normal
fn id[T : Eq](x : T) -> T {
x
}
```

Check it by MoonBit markdown linter.
```moonbit expr
id(5)
```

```moonbit no-check
// this is not moonbit at all
unsafe def gcd_unsafe: ℕ -> ℕ -> ℕ
| a, 0 => a
| a, b + 1 => gcd_unsafe (b + 1) (a % (b + 1))
```
$ mdlint fib.md
fib.md:6:4-6:7 Warning 001: Unused function 'fib'
fib.md:9:14-9:18 Expr Type Mismatch
has type : Bool
wanted : Int

```moonbit enclosed
fn fib(n : Int) -> Int {
match n {
0 => 0
1 => true // type error here
_ => fib(n - 1) + fib(n - 2)
}
}
```
````

## Run Inline Test or Evaluate Expression
Use `mdlint test.md` to check (the actual output is colored):

In file identity.md:
<img width="322" alt="image" src="https://github.com/user-attachments/assets/f636666e-fdd5-4c3d-a69f-ebb1a3303885">

# Identity

```moonbit
fn id[T : Eq](x : T) -> T {
x
}
```
The line number is correctly mapped to that in the markdown document, this is especially useful for debugging. Note that for multiple markdown files, each of them results in a independent project.

### Environments

As seen above, `mdlint` supports several code environments including

You can also write expression directly.
- `normal`: codeblocks marked w/ `normal` are copied as-is to generate moonbit project. Default behavior. Linting is performed.
- `expr`: codeblocks marked w/ `expr` are wrapped inside a `println()`, this environment only supports [expressions](https://www.moonbitlang.com/docs/syntax#expressions-and-statements). Linting is performed.
- `no-check`: codeblocks marked w/ `no-check` are ignored, not included in the generated project at all. Linting is NOT performed, suitable for writing pcode.
- `enclose`: codeblocks marked w/ `enclose` are enclosed inside a `init()`. Mainly used to avoid naming conflicts. Linting is performed.

```moonbit expr
id(5)
```
### Flags

Test function `id`.
#### --suppress

```moonbit
test "id" {
if id(5) != 5 { return Result::Err("test failed") }
It's common to write not-so-well-formed code (e.g. Unused variables) for demonstration purposes, not production. It would be annoying if the compiler keeps complaining about those trivial problems. `mdlint` acknowledges that and provides `--suppress,-s` to suppress specific compiler error/warning in the output. It can be parsed inline:

````
```moonbit enclosed -e1001 -e1002
fn fib(n : Int) -> Int {
match n {
0 => 0
1 => true // type error here
_ => fib(n - 1) + fib(n - 2)
}
```
}
```
````

Run test and evaluate the expression by `mdlint`:
or provided through cli:

```bash
mdlint -s=e1001,e1002 test.md # use comma-separated list
```
$ mdlint identity.md
5
running 1 tests in package identity
test identity::id ... ok

test result: 1 passed; 0 failed
- the special `-s=all-warnings` suppresses all warnings from `moon`.
- the `--ignore,-i` specifically ignores all error codes from codeblocks, useful for temporarily enabling error/warnings suppressed before.

#### --dump

`--dump,-d` dumps the project generated from the corresponding markdown document in the same directory with the extension `.proj`. e.g. `test.md` results in `test.md.proj`.

#### -f

A project generated by `mdlint` typically has the structure

```
.
├── README.md
├── lib
│ ├── fib.mbt
│ └── moon.pkg.json
├── moon.mod.json
├── moon.pkg.json
└── top.mbt
```

the `-f` flag is used to specify which moonbit source file the code should be copied to. This flag can only be parsed inline:

## Disable check
````markdown
// fib() now goes into lib/fib.mbt

You can also disable checking for some code block by sepcifying `no-check`.
```moonbit -e1001 -f=fib.mbt
fn fib(n : Int) -> Int {
match n {
0 => 0
1 => true // type error here
_ => fib(n - 1) + fib(n - 2)
}
}
```
````

```moonbit no-check
// some pseudo code
fn id(x : T) -> T
fn succ(x : T) -> T
```
By default, codeblocks are copied to `top.mbt`. If `-f` is provided with a value other than `top.mbt` (such as `fib.mbt`), `mdlint` would place that codeblock inside `lib/*.mbt`. This hopefully provides very basic literate programming utility.
Loading

0 comments on commit e8210ba

Please sign in to comment.