nandi/clonimpublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/nandi/clonim.git
git clone ssh://git@rickub.com/nandi/clonim.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

justfile · 90 lines · 3.0 KBMakefile Blame HistoryRaw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# clonim — a Clojure compiler hosted on Nim

bin := "bin/clonim"

# Build the compiler
build:
    nim c --hints:off --warnings:off -o:{{bin}} src/clonim.nim

# Build with optimisations on (compiler and, via -d:release, the programs it emits)
release:
    nim c -d:release --hints:off --warnings:off -o:{{bin}} src/clonim.nim

# Run every example against tests/<name>.expected
test: build
    ./run-tests.sh

# Compile and run a .clj file, e.g. `just run examples/tour.clj`
run file: build
    ./{{bin}} run {{file}}

# Emit the generated Nim for a .clj file without compiling it
emit file: build
    ./{{bin}} emit {{file}}

# Compile a .clj file to a native binary
compile file: build
    ./{{bin}} build {{file}}

# Benchmarks: persistent-collection writes, and lazy early exit
bench: release
    ./{{bin}} run examples/persistent-bench.clj -d
    ./{{bin}} run examples/lazy-bench.clj -d

# Re-record tests/<name>.expected from current output
accept: build
    #!/usr/bin/env bash
    set -euo pipefail
    for f in examples/*.clj; do
      name=$(basename "$f" .clj)
      [ -f "tests/$name.expected" ] || continue
      ./{{bin}} run "$f" > "tests/$name.expected" 2>&1
      echo "recorded $name"
    done

# Remove build output
clean:
    rm -rf bin nimcache bench/bin

# ---------------------------------------------------------------- benchmarks
#
# `just bench` above stays as it was: the two feature benchmarks, run through
# the compiler with timing printed by the programs themselves. What follows
# times whole processes instead, which is the only way to see startup, and can
# put another Clojure toolchain beside clonim.

# `just measure jolt` also builds and times the same programs under jolt, if it
# is installed. Both toolchains get a `hello` binary so startup can be
# subtracted; see bench/measure.py for why the numbers are best-of-N
# round-robin rather than averaged.
# Time bench/*.clj as native binaries, optionally against jolt.
measure mode="solo": release
    #!/usr/bin/env bash
    set -euo pipefail
    mkdir -p bench/bin
    for f in bench/*.clj; do
        name=$(basename "$f" .clj)
        ./{{bin}} build "$f" -o "bench/bin/$name" >/dev/null
    done
    if [ "{{mode}}" != "jolt" ]; then
        exec python3 bench/measure.py
    fi
    if ! command -v jolt >/dev/null; then
        echo "jolt is not installed; running clonim only" >&2
        exec python3 bench/measure.py
    fi
    # jolt builds a namespace, not a file, so mirror each bench into a deps.edn
    # project under a throwaway directory, wrapping the last form in a -main.
    work=$(mktemp -d)
    trap 'rm -rf "$work"' EXIT
    mkdir -p "$work/src"
    echo '{:paths ["src"]}' > "$work/deps.edn"
    for f in bench/*.clj; do
        name=$(basename "$f" .clj)
        { echo "(ns b$name)"
          sed 's/^(println \(.*\))$/(defn -main [\& _] (println \1))/' "$f"
        } > "$work/src/b$name.clj"
        (cd "$work" && jolt build -m "b$name" -o "b$name" --opt >/dev/null)
        cp "$work/b$name" "bench/bin/jolt-$name"
    done
    python3 bench/measure.py --with-jolt