run_tests.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. #!/bin/sh
  2. #
  3. # Step-2 test runner for M2c (scalars + MC64 backend).
  4. # Usage: ./run_tests.sh (from the m2c directory, after ./build.sh)
  5. #
  6. # Positive tests: compile with M2c, run the newest MC4/*.MC4 under mcint,
  7. # compare the printed ExitCode value with the expectation.
  8. # MGen emits <Module>.MC4 in the current directory; the helpers below
  9. # collect it into MC4/ and run it from there.
  10. #
  11. MCINT="${MCINT:-../m-code-64/mcint}"
  12. mkdir -p MC4
  13. # MGen emits <Module>.MC4 in the current directory; collect_mcd gathers
  14. # strays (e.g. from parse-only checks) into MC4/.
  15. collect_mcd() {
  16. for f in *.MC4; do
  17. [ -f "$f" ] && mv -f "$f" MC4/
  18. done
  19. }
  20. pass=0
  21. fail=0
  22. expect_ok() {
  23. # $1 = test file (no dir) — parse only
  24. name="$1"
  25. out=$(./M2c "tests/$name" 2>&1)
  26. case "$out" in
  27. *"Parsed correctly"*)
  28. echo "ok $name accepted"
  29. pass=$((pass+1)) ;;
  30. *)
  31. echo "FAIL $name: expected accept, got: $out"
  32. fail=$((fail+1)) ;;
  33. esac
  34. collect_mcd
  35. }
  36. expect_fail() {
  37. # $1 = test file, $2 = message text expected in the .LST
  38. name="$1"
  39. want="$2"
  40. out=$(./M2c "tests/$name" 2>&1)
  41. case "$out" in
  42. *"Incorrect source"*) ;;
  43. *)
  44. echo "FAIL $name: expected rejection, got: $out"
  45. collect_mcd
  46. fail=$((fail+1)); return ;;
  47. esac
  48. collect_mcd
  49. lst="tests/$(basename "$name" .mod).LST"
  50. if grep -q "$want" "$lst" 2>/dev/null; then
  51. echo "ok $name rejected with [$want]"
  52. pass=$((pass+1))
  53. else
  54. echo "FAIL $name: [$want] not found in $lst"
  55. fail=$((fail+1))
  56. fi
  57. }
  58. expect_run() {
  59. # $1 = test file, $2 = expected printed ExitCode value
  60. name="$1"
  61. want="$2"
  62. mod=$(head -n 1 "tests/$name" | cut -d' ' -f2 | cut -d';' -f1)
  63. mcd="MC4/$mod.MC4"
  64. rm -f "$mcd" "$mod.MC4"
  65. out=$(./M2c "tests/$name" 2>&1)
  66. case "$out" in
  67. *"Parsed correctly"*) ;;
  68. *)
  69. echo "FAIL $name: M2c rejected it: $out"
  70. fail=$((fail+1)); return ;;
  71. esac
  72. [ -f "$mod.MC4" ] && mv -f "$mod.MC4" "$mcd"
  73. if [ ! -f "$mcd" ]; then
  74. echo "FAIL $name: no $mcd produced"
  75. fail=$((fail+1)); return
  76. fi
  77. got=$("$MCINT" "$mcd" 2>&1 | head -n 1 | tr -d '\r')
  78. if [ "$got" = "$want" ]; then
  79. echo "ok $name -> $got"
  80. pass=$((pass+1))
  81. else
  82. echo "FAIL $name: printed [$got], expected [$want]"
  83. fail=$((fail+1))
  84. fi
  85. }
  86. expect_run_none() {
  87. # $1 = test file — must compile and run with empty output
  88. name="$1"
  89. mod=$(head -n 1 "tests/$name" | cut -d' ' -f2 | cut -d';' -f1)
  90. mcd="MC4/$mod.MC4"
  91. rm -f "$mcd" "$mod.MC4"
  92. out=$(./M2c "tests/$name" 2>&1)
  93. case "$out" in
  94. *"Parsed correctly"*) ;;
  95. *)
  96. echo "FAIL $name: M2c rejected it: $out"
  97. fail=$((fail+1)); return ;;
  98. esac
  99. [ -f "$mod.MC4" ] && mv -f "$mod.MC4" "$mcd"
  100. if [ ! -f "$mcd" ]; then
  101. echo "FAIL $name: no $mcd produced"
  102. fail=$((fail+1)); return
  103. fi
  104. got=$("$MCINT" "$mcd" 2>&1 | head -n 1)
  105. if [ -z "$got" ]; then
  106. echo "ok $name runs silent"
  107. pass=$((pass+1))
  108. else
  109. echo "FAIL $name: unexpected output [$got]"
  110. fail=$((fail+1))
  111. fi
  112. }
  113. expect_run_files() {
  114. # $1 = program module (MC4 base), $2 = expected value, rest = sources
  115. prog="$1"
  116. want="$2"
  117. shift 2
  118. mcd="MC4/$prog.MC4"
  119. rm -f "$mcd" "$prog.MC4"
  120. out=$(./M2c "$@" 2>&1)
  121. case "$out" in
  122. *"Parsed correctly"*) ;;
  123. *)
  124. echo "FAIL $prog: M2c rejected it: $out"
  125. fail=$((fail+1)); return ;;
  126. esac
  127. [ -f "$prog.MC4" ] && mv -f "$prog.MC4" "$mcd"
  128. if [ ! -f "$mcd" ]; then
  129. echo "FAIL $prog: no $mcd produced"
  130. fail=$((fail+1)); return
  131. fi
  132. got=$("$MCINT" "$mcd" 2>&1 | head -n 1 | tr -d '\r')
  133. if [ "$got" = "$want" ]; then
  134. echo "ok $prog -> $got"
  135. pass=$((pass+1))
  136. else
  137. echo "FAIL $prog: printed [$got], expected [$want]"
  138. fail=$((fail+1))
  139. fi
  140. }
  141. expect_fail_files() {
  142. # $1 = message in the failing file's .LST, rest = sources
  143. want="$1"
  144. shift
  145. out=$(./M2c "$@" 2>&1)
  146. case "$out" in
  147. *"Incorrect source"*) ;;
  148. *)
  149. echo "FAIL $*: expected rejection, got: $out"
  150. collect_mcd
  151. fail=$((fail+1)); return ;;
  152. esac
  153. collect_mcd
  154. last=""
  155. for f in "$@"; do last="$f"; done
  156. lst=$(echo "$last" | sed 's/\.[^.]*$/.LST/')
  157. if grep -q "$want" "$lst" 2>/dev/null; then
  158. echo "ok $last rejected with [$want]"
  159. pass=$((pass+1))
  160. else
  161. echo "FAIL $last: [$want] not found in $lst"
  162. fail=$((fail+1))
  163. fi
  164. }
  165. echo "=== Phase-0 tests (still green) ==="
  166. expect_ok ok_minimal.mod
  167. expect_ok ok_nobegin.mod
  168. expect_fail bad_mismatch.mod "name mismatch"
  169. expect_fail bad_syntax.mod "expected"
  170. echo "=== Step-2 run tests (M2c -> mcint) ==="
  171. expect_run_none t_min.mod
  172. expect_run t_arith.mod 7
  173. expect_run t_const.mod 15
  174. expect_run t_bool.mod 42
  175. expect_run t_if.mod 20
  176. expect_run t_case.mod 103
  177. expect_run t_while.mod 55
  178. expect_run t_repeat.mod 55
  179. expect_run t_loop.mod 7
  180. expect_run t_for.mod 85
  181. expect_run t_real.mod 31
  182. expect_run t_char.mod 97
  183. expect_run t_enum.mod 1
  184. expect_run t_full.mod 74
  185. expect_run t_set.mod 15
  186. echo "=== Step-2 rejection tests ==="
  187. expect_fail t_bad_asn.mod "incompatible assignment"
  188. expect_fail t_bad_array.mod "not supported in this phase"
  189. expect_fail t_bad_with.mod "not a RECORD type"
  190. expect_fail t_bad_exit.mod "not supported in this phase"
  191. expect_fail t_bad_const.mod "not supported in this phase"
  192. expect_fail t_bad_deref.mod "not a POINTER type"
  193. echo "=== Step-3 run tests (procedures) ==="
  194. expect_run p_proc.mod 7
  195. expect_run p_params.mod 21
  196. expect_run p_func.mod 42
  197. expect_run p_fact.mod 120
  198. expect_run p_fib.mod 55
  199. expect_run p_varpar.mod 3012
  200. expect_run p_nested.mod 42
  201. expect_run p_forward.mod 1
  202. expect_run p_return.mod 40
  203. expect_run p_local.mod 43
  204. expect_run p_mixed.mod 52
  205. expect_run p_chain.mod 9
  206. expect_run p_empty.mod 3
  207. expect_run p_realfn.mod 5
  208. echo "=== Step-3 rejection tests ==="
  209. expect_fail p_bad_call.mod "invalid procedure call"
  210. expect_fail p_bad_arity.mod "invalid procedure call"
  211. expect_fail p_bad_actual.mod "invalid procedure call"
  212. expect_fail p_bad_proper.mod "invalid procedure call"
  213. expect_fail p_bad_return1.mod "bad RETURN"
  214. expect_fail p_bad_return2.mod "bad RETURN"
  215. expect_fail p_bad_return3.mod "bad RETURN"
  216. expect_fail p_bad_fwd.mod "forward mismatch"
  217. expect_fail p_bad_nobody.mod "forward mismatch"
  218. expect_fail p_bad_undecl.mod "undeclared identifier"
  219. echo "=== Step-4 run tests (composites) ==="
  220. expect_run t_arr.mod 39
  221. expect_run a_mat.mod 134
  222. expect_run a_sieve.mod 129
  223. expect_run a_varpar.mod 150
  224. expect_run a_enum.mod 21
  225. expect_run t_rec.mod 30
  226. expect_run r_nest.mod 135
  227. expect_run t_with.mod 37
  228. expect_run r_varpar.mod 303
  229. expect_run t_ptr.mod 42
  230. expect_run t_ptr0.mod 5
  231. expect_run p_list.mod 21
  232. expect_run t_setop.mod 22
  233. expect_run s_range.mod 21
  234. expect_run t_str.mod 11
  235. echo "=== Step-4 rejection tests ==="
  236. expect_fail a_bad_idx.mod "array index must be integer"
  237. expect_fail a_bad_arr.mod "not an ARRAY type"
  238. expect_fail a_bad_asn.mod "incompatible assignment"
  239. expect_fail r_bad_field.mod "unknown field"
  240. expect_fail r_bad_rec.mod "not a RECORD type"
  241. expect_fail p_bad_new.mod "not a POINTER type"
  242. expect_fail s_bad_elem.mod "set operand mismatch"
  243. expect_fail a_bad_val.mod "not supported in this phase"
  244. expect_fail s_bad_long.mod "incompatible assignment"
  245. expect_fail r_bad_asn.mod "incompatible assignment"
  246. echo "=== Step-5 run tests (open arrays, copy, strings, I/O) ==="
  247. expect_run o_open.mod 150
  248. expect_run c_copy.mod 18
  249. expect_run s_streq.mod 21
  250. expect_run o_val.mod 14
  251. expect_run o_high.mod 14
  252. expect_run c_rec.mod 17
  253. expect_run w_io.mod hi42
  254. expect_run o_open2.mod 286
  255. expect_run c_copy2.mod 9
  256. expect_run s_cmp2.mod 10
  257. expect_run r_copy2.mod 15
  258. expect_run a_subopen.mod 66
  259. expect_run w_str2.mod ok8
  260. expect_run p_newarr.mod 66
  261. expect_run o_char.mod 4
  262. echo "=== Step-5 rejection tests ==="
  263. expect_fail o_bad_open.mod "invalid procedure call"
  264. expect_fail o_bad_high.mod "not an ARRAY type"
  265. expect_fail c_bad_len.mod "incompatible assignment"
  266. expect_fail s_bad_cmp.mod "incompatible comparison"
  267. expect_fail v_bad_var.mod "invalid procedure call"
  268. expect_fail w_bad_int.mod "incompatible assignment"
  269. expect_fail w_bad_str.mod "incompatible assignment"
  270. expect_fail r_bad_open.mod "not supported in this phase"
  271. expect_fail p_bad_dispose.mod "not a POINTER type"
  272. expect_fail s_bad_op.mod "arithmetic operand must be numeric"
  273. echo "=== Step-6 run tests (local MODULEs) ==="
  274. expect_run m_mod.mod 12
  275. expect_run m_multi.mod 7
  276. expect_run m_arr.mod 42
  277. expect_run m_outer.mod 11
  278. expect_run m_const.mod 7
  279. echo "=== Step-6 rejection tests ==="
  280. expect_fail m_bad_priv.mod "undeclared identifier"
  281. expect_fail m_bad_nest.mod "not supported in this phase"
  282. expect_fail m_bad_dup.mod "duplicate identifier"
  283. expect_fail m_bad_exp.mod "duplicate identifier"
  284. expect_fail m_bad_ghost.mod "undeclared identifier"
  285. expect_fail m_bad_end.mod "name mismatch"
  286. echo "=== Step-7 run tests (module procedures) ==="
  287. expect_run m_param.mod 15
  288. expect_run m_varpar.mod 15
  289. expect_run m_func.mod 45
  290. expect_run m_open.mod 10
  291. expect_run m_bare.mod 2
  292. echo "=== Step-7 rejection tests ==="
  293. expect_fail m_bad_arity.mod "invalid procedure call"
  294. expect_fail m_bad_mactual.mod "invalid procedure call"
  295. expect_fail m_bad_mvar.mod "invalid procedure call"
  296. expect_fail m_bad_mfunc.mod "invalid procedure call"
  297. expect_fail m_bad_nope.mod "undeclared identifier"
  298. echo "=== Step-8 run tests (VAR tails) ==="
  299. expect_run v_idx.mod 35
  300. expect_run v_deref.mod 105
  301. expect_run v_field.mod 1031
  302. expect_run v_rec.mod 16
  303. expect_run v_row.mod 21
  304. echo "=== Step-8 rejection tests ==="
  305. expect_fail v_bad_byte.mod "invalid procedure call"
  306. expect_fail v_bad_with.mod "invalid procedure call"
  307. echo "=== Step-9 run tests (type exports + tailed copy) ==="
  308. expect_run t_mint.mod 5
  309. expect_run t_mrec.mod 30
  310. expect_run t_marr.mod 18
  311. expect_run t_mptr.mod 7
  312. expect_run t_menum.mod 11
  313. expect_run c_fcopy.mod 5
  314. expect_run c_row.mod 15
  315. echo "=== Step-9 rejection tests ==="
  316. expect_fail t_bad_mtype.mod "not a type name"
  317. expect_fail t_bad_mghost.mod "undeclared identifier"
  318. expect_fail t_bad_mmod.mod "not supported in this phase"
  319. echo "=== Step-10 run tests (module BEGIN bodies) ==="
  320. expect_run b_init.mod 42
  321. expect_run b_order.mod 111
  322. expect_run b_call.mod 15
  323. expect_run b_mix.mod 110
  324. echo "=== Step-10 rejection tests ==="
  325. expect_fail b_bad_ret.mod "bad RETURN"
  326. expect_fail b_bad_nest.mod "not supported in this phase"
  327. expect_fail b_bad_dup.mod "duplicate identifier"
  328. echo "=== Step-11 run tests (DEFINITION/IMPLEMENTATION/IMPORT) ==="
  329. expect_run_files DBasic 25 tests/d_lib.def tests/d_libimpl.mod tests/d_basic.mod
  330. expect_run_files DFrom 12 tests/d_lib2.def tests/d_lib2impl.mod tests/d_from.mod
  331. expect_run_files DMulti 82 tests/a_lib.def tests/a_libimpl.mod tests/b_lib.def tests/b_libimpl.mod tests/d_multi.mod
  332. expect_run_files DInit 510 tests/l1.def tests/l1impl.mod tests/l2.def tests/l2impl.mod tests/d_init.mod
  333. expect_run_files DFunc 55 tests/f_lib.def tests/f_libimpl.mod tests/d_func.mod
  334. expect_run_files DType 1122 tests/t_lib.def tests/t_libimpl.mod tests/d_type.mod
  335. expect_run_files DCase 25 tests/e_lib.def tests/e_libimpl.mod tests/d_case.mod
  336. echo "=== Step-11 rejection tests ==="
  337. expect_fail_files "undeclared identifier" tests/d_bad_nodef.mod
  338. expect_fail_files "procedure forward mismatch" tests/d_sglib.def tests/d_bad_sig.mod
  339. expect_fail_files "procedure forward mismatch" tests/d_nolib.def tests/d_bad_nobody.mod
  340. expect_fail_files "undeclared identifier" tests/d_bad_imp.mod
  341. expect_fail_files "undeclared identifier" tests/d_lib.def tests/d_libimpl.mod tests/d_bad_exp.mod
  342. expect_fail_files "duplicate identifier" tests/d_duplib.def tests/d_bad_dup.mod
  343. echo "=== $pass passed, $fail failed ==="
  344. test "$fail" = 0