corpus.sh 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/bin/sh
  2. # Runs the V3 compiler (compiler/M2) over a corpus of standard Modula-2
  3. # sources and reports how many compile cleanly.
  4. #
  5. # Each source is copied into a scratch tree (so its .LST listing never
  6. # touches the corpus) and compiled alone. A file with 0 errors is a
  7. # pass. Failures are split into:
  8. # CRASH -- M2 died (rc >= 128): a real compiler bug
  9. # LIB -- the file imports a module outside V3's known stdlib set
  10. # (gm2's StrIO/NumberIO/STextIO/...), so "undeclared" is
  11. # expected and not a language gap
  12. # LANG -- otherwise: a genuine parse/semantic gap in V3
  13. #
  14. # Usage: ./corpus.sh [corpus-dir ...]
  15. cd "$(dirname "$0")"
  16. ROOT="$(cd ../.. && pwd)"
  17. M2="$ROOT/compiler/M2"
  18. WORK=/tmp/opencode/v3corpus
  19. KNOWN="SYSTEM SysIO TextIO Strings Math Conversions RealIO ProgramArgs IOChan Files Storage WholeIO CharClass SysClock"
  20. [ -x "$M2" ] || { echo "compiler/M2 missing -- run compiler/build.sh"; exit 1; }
  21. [ "$#" -gt 0 ] || set -- \
  22. "$HOME/Projets/Projets-Modula2/MyWork/gcc-git/gcc/testsuite/gm2/pim/pass" \
  23. "$HOME/Projets/Projets-Modula2/MyWork/gcc-git/gcc/testsuite/gm2/iso/run/pass"
  24. known() { for k in $KNOWN; do [ "$1" = "$k" ] && return 0; done; return 1; }
  25. rm -rf "$WORK"; mkdir -p "$WORK"; : > "$WORK/results.txt"
  26. n=0
  27. for dir in "$@"; do
  28. find "$dir" -maxdepth 1 \( -iname '*.mod' -o -iname '*.def' \) 2>/dev/null | sort |
  29. while read -r f; do
  30. n=$((n+1))
  31. w="$WORK/f$n"; mkdir -p "$w"; base=$(basename "$f")
  32. cp "$f" "$w/$base"
  33. # if this is an IMPLEMENTATION, compile its sibling DEFINITION first
  34. files="$w/$base"
  35. case "$base" in
  36. *.mod|*.MOD)
  37. sib="$(echo "$base" | sed -E 's/\.[^.]*$/.def/')"
  38. [ -f "$dir/$sib" ] || sib="$(echo "$base" | sed -E 's/\.[^.]*$/.DEF/')"
  39. if [ -f "$dir/$sib" ]; then cp "$dir/$sib" "$w/$sib"; files="$w/$sib $w/$base"; fi
  40. ;;
  41. esac
  42. "$M2" $files >/dev/null 2>&1
  43. rc=$?
  44. lst="$w/$(echo "$base" | sed 's/\.[^.]*$//').LST"
  45. if [ "$rc" -ge 128 ]; then echo "CRASH||$f" >> "$WORK/results.txt"; continue; fi
  46. if [ ! -f "$lst" ]; then echo "LANG|no listing|$f" >> "$WORK/results.txt"; continue; fi
  47. e=$(grep -oE '[0-9]+ errors?' "$lst" | head -1 | grep -oE '[0-9]+')
  48. [ -z "$e" ] && e=-1
  49. if [ "$e" = 0 ]; then echo "OK||$f" >> "$WORK/results.txt"; continue; fi
  50. # classify: does it import a module outside the known set?
  51. names=$( { sed -nE 's/^[[:space:]]*FROM[[:space:]]+([A-Za-z][A-Za-z0-9_]*).*/\1/p' "$w/$base"
  52. sed -nE 's/^[[:space:]]*IMPORT[[:space:]]+(.*)/\1/p' "$w/$base" | sed 's/;.*//' | tr ',' '\n'
  53. } | sed -E 's/[[:space:]]//g' | grep -E '^[A-Za-z][A-Za-z0-9_]*$' )
  54. lib=0
  55. for m in $names; do known "$m" || lib=1; done
  56. m=$(grep -E '^\*\*\*\*\*' "$lst" | head -1 | sed -E 's/^\*\*\*\*\* *\^? *//; s/^\*\*\*\*\*//')
  57. if [ "$lib" = 1 ]; then echo "LIB|$m|$f" >> "$WORK/results.txt"
  58. else echo "LANG|$m|$f" >> "$WORK/results.txt"; fi
  59. done
  60. done
  61. total=$(wc -l < "$WORK/results.txt")
  62. cnt() { grep -c "^$1" "$WORK/results.txt" 2>/dev/null || true; }
  63. echo "total : $total"
  64. echo "compile-OK : $(cnt OK)"
  65. echo "CRASH : $(cnt CRASH)"
  66. echo "LIB (needs a gm2 library): $(cnt LIB)"
  67. echo "LANG (V3 gap) : $(cnt LANG)"
  68. echo "=== LANG error kinds (top) ==="
  69. grep '^LANG' "$WORK/results.txt" | cut -d'|' -f2 | sed -E 's/[0-9]+/N/g' | sort | uniq -c | sort -rn | head -15
  70. echo "=== LANG files (first 40) ==="
  71. grep '^LANG' "$WORK/results.txt" | head -40 | sed -E 's/^LANG\|([^|]*)\|/ [\1] /'