plum

#treesitter#compiler#wasm

git clone https://git.pyrossh.dev/plum

A statically typed, imperative programming language inspired by rust, python


scripts/test-examples.sh
408b9c0 1
#!/usr/bin/env bash
408b9c0 2
#
408b9c0 3
# Integration test: compiles and runs every examples/*.plum file through the
408b9c0 4
# REAL toolchain — the `plum` CLI binary (which resolves `import`s against
408b9c0 5
# --lib-path, unlike plum-checker/plum-wasm-codegen's unit tests, which parse
408b9c0 6
# and compile a single file directly) and, if available, an external
408b9c0 7
# `wasmtime` runtime.
408b9c0 8
#
408b9c0 9
# This exists because the unit tests alone missed a real bug: examples/basics.plum
408b9c0 10
# had an `import std/io` where libs/std/io.plum doesn't exist. The unit tests
408b9c0 11
# never noticed since they don't touch plum-core's loader/import resolution at
408b9c0 12
# all — only compiling and running through the actual CLI catches that class
408b9c0 13
# of problem.
408b9c0 14
#
408b9c0 15
# Usage: scripts/test-examples.sh
408b9c0 16
# Exit code is 0 if every example compiled (and, where checked, ran) correctly.
408b9c0 17
408b9c0 18
set -uo pipefail
408b9c0 19
408b9c0 20
cd "$(dirname "${BASH_SOURCE[0]}")/.."
408b9c0 21
408b9c0 22
WORKDIR=$(mktemp -d)
408b9c0 23
trap 'rm -rf "$WORKDIR"' EXIT
408b9c0 24
408b9c0 25
echo "Building plum-cli..."
408b9c0 26
if ! cargo build -p plum-cli --quiet 2>"$WORKDIR/build.log"; then
408b9c0 27
  echo "FAIL: plum-cli failed to build" >&2
408b9c0 28
  cat "$WORKDIR/build.log" >&2
408b9c0 29
  exit 1
408b9c0 30
fi
408b9c0 31
PLUM_BIN="target/debug/plum"
408b9c0 32
408b9c0 33
HAVE_WASMTIME=0
408b9c0 34
if command -v wasmtime >/dev/null 2>&1; then
408b9c0 35
  HAVE_WASMTIME=1
408b9c0 36
else
408b9c0 37
  echo "note: wasmtime CLI not found on PATH — will compile every example but skip running them" >&2
408b9c0 38
fi
408b9c0 39
408b9c0 40
# Examples that export `main` and are expected to run without trapping. Kept
408b9c0 41
# in sync with plum-wasm-codegen/tests/examples_test.rs.
408b9c0 42
has_main() {
408b9c0 43
  case "$1" in
408b9c0 44
    basics|closures|match|methods) return 0 ;;
408b9c0 45
    *) return 1 ;;
408b9c0 46
  esac
408b9c0 47
}
408b9c0 48
408b9c0 49
# Expected `main` return value for examples whose result is asserted in
408b9c0 50
# plum-wasm-codegen/tests/examples_test.rs. Empty means "just don't trap"
408b9c0 51
# (e.g. basics.plum's main returns Unit, not a value to compare).
408b9c0 52
expected_value() {
408b9c0 53
  case "$1" in
408b9c0 54
    closures) echo 120 ;;
408b9c0 55
    match) echo 5 ;;
408b9c0 56
    methods) echo 10 ;;
408b9c0 57
    *) echo "" ;;
408b9c0 58
  esac
408b9c0 59
}
408b9c0 60
408b9c0 61
failed=0
408b9c0 62
passed=0
408b9c0 63
408b9c0 64
for src in examples/*.plum; do
408b9c0 65
  name=$(basename "$src" .plum)
408b9c0 66
  wasm="$WORKDIR/$name.wasm"
408b9c0 67
408b9c0 68
  printf '%-14s compile ... ' "$name"
408b9c0 69
  if ! "$PLUM_BIN" compile "$src" -o "$wasm" >"$WORKDIR/$name.compile.log" 2>&1; then
408b9c0 70
    echo "FAIL"
408b9c0 71
    sed 's/^/    /' "$WORKDIR/$name.compile.log"
408b9c0 72
    failed=$((failed + 1))
408b9c0 73
    continue
408b9c0 74
  fi
408b9c0 75
  echo "ok"
408b9c0 76
408b9c0 77
  if [ "$HAVE_WASMTIME" -eq 1 ] && has_main "$name"; then
408b9c0 78
    printf '%-14s run     ... ' "$name"
408b9c0 79
    if output=$(wasmtime run --invoke main "$wasm" 2>"$WORKDIR/$name.run.log"); then
408b9c0 80
      expected=$(expected_value "$name")
408b9c0 81
      if [ -n "$expected" ] && [ "$output" != "$expected" ]; then
408b9c0 82
        echo "FAIL (expected $expected, got '$output')"
408b9c0 83
        failed=$((failed + 1))
408b9c0 84
        continue
408b9c0 85
      fi
408b9c0 86
      if [ -n "$output" ]; then
408b9c0 87
        echo "ok (-> $output)"
408b9c0 88
      else
408b9c0 89
        echo "ok"
408b9c0 90
      fi
408b9c0 91
    else
408b9c0 92
      echo "FAIL (trapped)"
408b9c0 93
      sed 's/^/    /' "$WORKDIR/$name.run.log"
408b9c0 94
      failed=$((failed + 1))
408b9c0 95
      continue
408b9c0 96
    fi
408b9c0 97
  fi
408b9c0 98
408b9c0 99
  passed=$((passed + 1))
408b9c0 100
done
408b9c0 101
408b9c0 102
echo
408b9c0 103
echo "$passed passed, $failed failed"
408b9c0 104
[ "$failed" -eq 0 ]