Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: CI

on:

push:
branches: [ master ]

pull_request:
branches: [ master ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:

build-test:

strategy:
matrix:
os: [ubuntu-latest, macos-latest]
mlcomp: [mlkit, mlton]

runs-on: ${{ matrix.os }}

steps:

- uses: actions/checkout@v2

- name: Setup environment
run: |
echo "OS=$(uname -s | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
echo "RUNHOME=$(echo $HOME)" >> $GITHUB_ENV

- name: Install MLKit and smlpkg
working-directory: ${{ env.RUNHOME }}
run: |
echo "[OS: $OS, HOME: $RUNHOME]"
wget https://github.com/diku-dk/smlpkg/releases/download/v0.1.4/smlpkg-bin-dist-${{env.OS}}.tgz
tar xzf smlpkg-bin-dist-${{env.OS}}.tgz
echo "$HOME/smlpkg-bin-dist-${{env.OS}}/bin" >> $GITHUB_PATH
wget https://github.com/melsman/mlkit/releases/download/v4.5.4/mlkit-bin-dist-${{env.OS}}.tgz
tar xzf mlkit-bin-dist-${{env.OS}}.tgz
echo "$HOME/mlkit-bin-dist-${{env.OS}}/bin" >> $GITHUB_PATH
mkdir -p .mlkit
echo "SML_LIB $HOME/mlkit-bin-dist-${{env.OS}}/lib/mlkit" > .mlkit/mlb-path-map

- name: Check
run: |
mlkit --version
smlpkg --version

- name: Install MLton (linux)
if: ${{ env.OS == 'linux' && matrix.mlcomp == 'mlton' }}
run: |
sudo apt-get install -y mlton
mlton

- name: Install MLton (macos)
if: ${{ env.OS == 'darwin' && matrix.mlcomp == 'mlton' }}
run: |
brew install mlton
mlton

- name: Build
run: MLCOMP=${{ matrix.mlcomp }} make clean all

- name: Run tests
run: MLCOMP=${{ matrix.mlcomp }} make test
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.PHONY: all
all:
$(MAKE) -C lib/github.com/kfl/wpp all

.PHONY: test
test:
$(MAKE) -C lib/github.com/kfl/wpp test

.PHONY: clean
clean:
$(MAKE) -C lib/github.com/kfl/wpp clean
rm -rf MLB *~ .*~
43 changes: 40 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,41 @@
wpp
===
# wpp [![CI](https://github.com/kfl/wpl/workflows/CI/badge.svg)](https://github.com/kfl/wpp/actions)

A Pretty Printer, based on Philip Wadler's "A prettier printer". But heavily modified to be efficient in a strict language.
A Pretty Printer for Standard ML, based on Philip Wadler's "A prettier
printer". But heavily modified to be efficient in a strict language.

## Overview of MLB files

- `lib/github.com/kfl/wpp/wpp.mlb`:

- **signature** [`Wpp`](lib/github.com/kfl/wpp/Wpp.sig)
- **structure** `Wpp`
- **structure** `Utility`

## Use of the package

This library is set up to work well with the SML package manager
[smlpkg](https://github.com/diku-dk/smlpkg). To use the package, in
the root of your project directory, execute the command:

```
$ smlpkg add github.com/kfl/wpp
```

This command will add a _requirement_ (a line) to the `sml.pkg` file in your
project directory (and create the file, if there is no file `sml.pkg`
already).

To download the library into the directory
`lib/github.com/kfl/wpp`, execute the command:

```
$ smlpkg sync
```

You can now reference the `mlb`-file using relative paths from within
your project's `mlb`-files.

Notice that you can choose either to treat the downloaded package as
part of your own project sources (vendoring) or you can add the
`sml.pkg` file to your project sources and make the `smlpkg sync`
command part of your build process.
5 changes: 5 additions & 0 deletions lib/github.com/kfl/wpp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.res
*.exe
*~
*.out
MLB
14 changes: 14 additions & 0 deletions lib/github.com/kfl/wpp/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
MLCOMP ?= mlkit

.PHONY: all
all:
$(MLCOMP) -output wpp.exe wpp.mlb

.PHONY: test
test:
$(MAKE) -C test test

.PHONY: clean
clean:
$(MAKE) -C test clean
rm -rf MLB *~ wpp.exe
2 changes: 1 addition & 1 deletion lib/github.com/kfl/wpp/Wpp.sig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
your choice, the licence can be obtained at
http://www.gnu.org/copyleft/lgpl.html
*)

signature Wpp =
sig
type doc
Expand All @@ -34,7 +35,6 @@ signature Wpp =
val real : real -> doc (* an ML real constant *)
val bool : bool -> doc (* a boolean *)


val toString : int -> doc -> string
val toOutStream : int -> TextIO.outstream -> doc -> unit
val toFile : int -> string -> doc -> unit
Expand Down
18 changes: 8 additions & 10 deletions lib/github.com/kfl/wpp/Wpp.sml
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,27 @@ struct
infixr 6 ^^

datatype doc =
NIL
NIL
| APPEND of doc * doc
| NEST of int * doc
| TEXT of string
| BREAK of int * int
| NEWLINE
| GROUP of doc

fun op^^ p = case p of
(NIL,NIL) => NIL
| (NIL, y) => y
| (x, NIL) => x
| _ => APPEND p
fun op^^ p = case p of
(NIL,NIL) => NIL
| (NIL, y) => y
| (x, NIL) => x
| _ => APPEND p

val empty = NIL
fun nest i x = NEST(i,x)
val text = TEXT
fun break sp off = BREAK(sp, off)
val line = BREAK (1,0)
val newline = NEWLINE
fun group x = GROUP x
fun group x = GROUP x

(*** Derived functions ***)
val concat = List.foldr op^^ empty
Expand All @@ -52,16 +52,14 @@ struct
val real = fromConv Real.toString
fun bool b = if b then text "true" else text "false"



(*** Formating of docs ***)

val nlsize = String.size "\n"
fun spaces outs s i = outs s (StringCvt.padLeft #" " i "")
fun nlspace outs s i = outs s (StringCvt.padRight #" " (i+nlsize) "\n")

local
datatype mode = Flat | Break
datatype mode = Flat | Break

fun fitting [] left = true
| fitting ((i, mode, doc) :: rest) left =
Expand Down
5 changes: 5 additions & 0 deletions lib/github.com/kfl/wpp/test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.res
*.exe
*~
*.out
MLB
31 changes: 31 additions & 0 deletions lib/github.com/kfl/wpp/test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

MLCOMP ?= mlkit

.PHONY: test
test: example.res
cat $^

%.res: %.out
@(diff -aq $< $<.ok > /dev/null 2>&1; \
if [ $$? -eq 0 ]; then \
echo "OK: $*" > $@ \
; else \
if [ -e $<.ok ]; then \
echo "ERR: $* - file $< differs from $<.ok"; \
echo "ERR: $* - file $< differs from $<.ok" > $@ \
; else \
echo "ERR: $* - file $<.ok does not exist"; \
echo "ERR: $* - file $<.ok does not exist" > $@ \
; fi \
; exit 1 \
;fi)

%.out: %.exe
./$< > $@

%.exe: %.mlb %.sml
$(MLCOMP) -output $@ $<

.PHONY: clean
clean:
rm -rf MLB *.out *~ *.exe *.res run
6 changes: 6 additions & 0 deletions lib/github.com/kfl/wpp/test/example.mlb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
local
$(SML_LIB)/basis/basis.mlb
../wpp.mlb
in
example.sml
end
44 changes: 44 additions & 0 deletions lib/github.com/kfl/wpp/test/example.out.ok
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
maxS50:
if (x > y) then (x + 1) else (y * z)

maxS30:
if (x > y)
then (x + 1)
else (y * z)

maxS10:
if (x > y)
then
(x + 1)
else
(y * z)

nestS50:
if (x > y)
then (x + 1)
else if (x > y) then (x + 1) else (y * z)

nestS30:
if (x > y)
then (x + 1)
else
if (x > y)
then (x + 1)
else (y * z)

nestS10:
if (x > y)
then
(x + 1)
else
if
(x
>
y)
then
(x
+
1)
else
(y * z)

62 changes: 62 additions & 0 deletions lib/github.com/kfl/wpp/test/example.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
structure Example =
struct

(*
Small demonstration of how to use Wpp and the utilities.

An often occurring challenge is to format if-then-else nicely, so that
is mainly what we'll demonstrate,
*)

local
structure U = Utility
val $ = U.$
val ^+^ = U.^+^
infix ^+^
in

datatype Ast = Var of string
| Lit of int
| Opr of Ast * string * Ast
| Cond of Ast * Ast * Ast

fun toDoc ast =
case ast of
Var v => $v
| Lit n => Wpp.int n
| Opr(x, opr, y) => U.bin toDoc ($opr) (x, y)
| Cond(test, pos, neg) =>
Wpp.group (U.spread [ U.block 2 ($"if" ^+^ toDoc test)
, U.block 2 ($"then" ^+^ toDoc pos)
, U.block 2 ($"else" ^+^ toDoc neg)])

(* AST for `if (x > y) then x+1 else y*z` *)
val maxEx = Cond(Opr(Var"x", ">", Var"y"),
Opr(Var"x", "+", Lit 1),
Opr(Var"y", "*", Var"z"))
val maxDoc = toDoc maxEx
val maxS50 = Wpp.toString 50 maxDoc (* equals "if (x > y) then (x + 1) else (y * z)\n" *)
val maxS30 = Wpp.toString 30 maxDoc (* equals "if (x > y)\nthen (x + 1)\nelse (y * z)\n" *)
val maxS10 = Wpp.toString 10 maxDoc (* equals "if (x > y)\nthen\n (x + 1)\nelse\n (y * z)\n" *)


val nested = Cond(Opr(Var"x", ">", Var"y"),
Opr(Var"x", "+", Lit 1),
maxEx)
val nestDoc = toDoc nested
val nestS50 = Wpp.toString 50 nestDoc
val nestS30 = Wpp.toString 30 nestDoc
val nestS10 = Wpp.toString 10 nestDoc

fun pr_test t s = print (t ^ ":\n" ^ s ^ "\n")

val () = pr_test "maxS50" maxS50
val () = pr_test "maxS30" maxS30
val () = pr_test "maxS10" maxS10

val () = pr_test "nestS50" nestS50
val () = pr_test "nestS30" nestS30
val () = pr_test "nestS10" nestS10

end
end
7 changes: 7 additions & 0 deletions lib/github.com/kfl/wpp/wpp.mlb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
local
$(SML_LIB)/basis/basis.mlb
in
Wpp.sig
Wpp.sml
Utility.sml
end