run_tests.sh 11 KB

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