packages feed

rewrite-inspector-0.1.0.7: README.md

# Rewrite Inspector

A terminal user-interface (TUI) for inspecting steps taken by a rewriting process.
Useful for the optimization phase of a compiler, or even evaluators of small languages.

Available on [![Hackage](https://img.shields.io/hackage/v/rewrite-inspector.svg)](http://hackage.haskell.org/package/rewrite-inspector)

## Usage Instructions
To use the library, the user's type of language expressions
must be an instance of the `Diff` typeclass.

Let's see an example for a simple language for arithmetic expressions.
```haskell
data Expr = N Int | Expr :+: Expr deriving (Eq, Show)
```

We first need to give the type of contexts, which navigate to a certain sub-term:
```haskell
data ExprContext = L | R deriving (Eq, Show)
```

We can then give the instance for the `Diff` typeclass, by providing the following:
1. `readHistory`: A way to read the rewrite history from file (for this example, always return a constant history).
2. `ppr'`: A pretty-printing for (for this example, the type of annotations is just the type of contexts)
3. `patch`: A way to patch a given expression at some context.

Below is the complete definition of our instance:
```haskell
instance Diff Expr where
  type Ann     Expr = ExprContext
  type Options Expr = ()
  type Ctx     Expr = ExprContext

  readHistory _ = return [ HStep { _ctx    = [L]
                                 , _bndrS  = "top"
                                 , _name   = "adhocI"
                                 , _before = N 1
                                 , _after  = N 11 :+: N 12
                                 }
                         , HStep { _ctx    = [L, L]
                                 , _bndrS  = "top"
                                 , _name   = "adhocII"
                                 , _before = N 11
                                 , _after  = N 111 :+: N 112
                                 }
                         , HStep { _ctx    = []
                                 , _bndrS  = "top"
                                 , _name   = "normalization"
                                 , _before = N 1 :+: (N 2 :+: N 3)
                                 , _after  = ((N 111 :+: N 112) :+: N 12)
                                         :+: (N 2 :+: N 3)
                                 }
                         ]

  ppr' _    (N n)      = pretty n
  ppr' opts (e :+: e') = hsep [ annotate L (ppr' opts e)
                              , "+"
                              , annotate R (ppr' opts e')
                              ]

  patch _ []     e' = e'
  patch curE (c:cs) e' = let go e = patch e cs e' in
    case (curE, c) of
      (l :+: r, L) -> go l :+: r
      (l :+: r, R) -> l :+: go r
      _            -> error "patch"
```

Finally, we are ready to run our TUI to inspect the rewriting steps with proper
highlighting (`.ini` files are used to provide styling directives):
```haskell
main :: IO ()
main = runTerminal @Expr "examples/expr/theme.ini"
```

For more examples, check the ![examples](https://github.com/omelkonian/rewrite-inspector/raw/master/examples/) folder.

## Features
The features depicted below have been recorded on the optimizing phase of the
![Cλash compiler](https://github.com/clash-lang/clash-compiler/).

1. Use `Ctrl-p` to show/hide keyboard controls:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/controls.gif)

2. Syntax highlighting:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/syntax.gif)

3. Navigate through the rewriting steps with highlighted diffs:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/steps.gif)

4. Also navigate through all top-level binders:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/binders.gif)

5. Hide extraneous code output, suc as uniques/types/qualifiers:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/hiding.gif)

6. Individual and grouped scrolling for code panes, both vertically and horizontally:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/scrolling.gif)

7. Move to next transformation with the given step number:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/stepno.gif)

8. Move to next transformation with the given name:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/trans.gif)

9. Search for string occurrences within source code:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/search.gif)

10. Inside code panes, the line width is dynamically adjusted depending on available space:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/dynamic.gif)

11. User-configurable colour theme:
![](https://github.com/omelkonian/rewrite-inspector/raw/master/gifs/theme.gif)