run_tests.sh 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. #!/bin/sh
  2. # Step-1 regression: M2 -> gen_ssa/*.ssa -> qbe -> cc -> exit code.
  3. # Usage: ./run_tests.sh (from the compiler directory)
  4. pass=0; fail=0
  5. SHIM="../runtime/syslib/shim.c"
  6. modof() {
  7. sed -n 's/^MODULE \([A-Za-z_][A-Za-z0-9_]*\).*/\1/p' "tests/$1" | head -n 1
  8. }
  9. expect_run() {
  10. # $1 = test file (no dir), $2 = expected exit code
  11. name="$1"; want="$2"; mod=$(modof "$name")
  12. rm -f "gen_ssa/$mod.ssa" "gen_ssa/$mod.s" "gen_ssa/$mod"
  13. if ./M2 "tests/$name" 2>&1 | grep -q "Parsed correctly"; then :; else
  14. fail=$((fail+1)); echo "FAIL(run): $name rejected"; return
  15. fi
  16. if [ ! -f "gen_ssa/$mod.ssa" ]; then
  17. fail=$((fail+1)); echo "FAIL(run): $name no gen_ssa/$mod.ssa"; return
  18. fi
  19. if ! qbe -o "gen_ssa/$mod.s" "gen_ssa/$mod.ssa" 2> "gen_ssa/$mod.qbeerr"; then
  20. fail=$((fail+1)); echo "FAIL(run): $name qbe:"; cat "gen_ssa/$mod.qbeerr"; return
  21. fi
  22. if ! cc "gen_ssa/$mod.s" "$SHIM" -o "gen_ssa/$mod" 2> "gen_ssa/$mod.ccerr"; then
  23. fail=$((fail+1)); echo "FAIL(run): $name cc:"; cat "gen_ssa/$mod.ccerr"; return
  24. fi
  25. timeout 10 "gen_ssa/$mod" > /dev/null 2>&1; got=$?
  26. if [ "$got" = "$want" ]; then
  27. pass=$((pass+1)); echo "PASS(run): $name -> $got"
  28. else
  29. fail=$((fail+1)); echo "FAIL(run): $name got $got want $want"
  30. fi
  31. }
  32. expect_fail() {
  33. # $1 = test file, $2 = message text expected in the .LST
  34. name="$1"; want="$2"
  35. if ./M2 "tests/$name" 2>&1 | grep -q "Incorrect source"; then :; else
  36. fail=$((fail+1)); echo "FAIL(fail): $name accepted"; return
  37. fi
  38. lst="tests/$(basename "$name" .mod).LST"
  39. if grep -q "$want" "$lst" 2>/dev/null; then
  40. pass=$((pass+1)); echo "PASS(fail): $name [$want]"
  41. else
  42. fail=$((fail+1)); echo "FAIL(fail): [$want] not found in $lst"
  43. fi
  44. }
  45. mkdir -p gen_ssa
  46. expect_run t_minimal.mod 0
  47. expect_run t_exit.mod 7
  48. expect_run t_arith.mod 25
  49. expect_run showcase1.mod 50
  50. expect_run t_types.mod 8
  51. expect_run showcase2.mod 71
  52. expect_run t_if.mod 25
  53. expect_run t_while.mod 55
  54. expect_run t_repeat.mod 55
  55. expect_run t_loop.mod 55
  56. expect_run t_for.mod 85
  57. expect_run t_case.mod 103
  58. expect_run t_setcase.mod 42
  59. expect_run t_varsame.mod 42
  60. expect_run t_bareproc.mod 42
  61. expect_run t_variantext.mod 42
  62. expect_run t_bool.mod 42
  63. expect_run t_real.mod 31
  64. expect_run t_lfloat.mod 42
  65. expect_run t_array.mod 108
  66. expect_run t_multidim.mod 42
  67. expect_run t_multidim_local.mod 42
  68. expect_run t_open2d.mod 42
  69. expect_run t_open2d_high.mod 42
  70. expect_run t_open2d_size.mod 42
  71. expect_run t_open1d_size_adr.mod 42
  72. expect_run t_open_row_adr.mod 42
  73. expect_run t_record_multidim.mod 42
  74. expect_run t_record_multidim_ctor.mod 42
  75. expect_run t_record_multidim_const.mod 42
  76. expect_run t_record_multidim_arrctor.mod 42
  77. expect_run t_open2d_adr.mod 42
  78. expect_run t_open2d_value.mod 42
  79. expect_run t_open3d.mod 42
  80. expect_run t_open3d_row.mod 42
  81. expect_run t_open_row_to_1d.mod 42
  82. expect_run t_open_flatten_byte.mod 42
  83. expect_run t_open2d_nested.mod 42
  84. expect_run t_subrange.mod 42
  85. expect_run t_emptychar.mod 42
  86. expect_run t_system.mod 42
  87. expect_run t_proctype2.mod 42
  88. expect_run t_byte.mod 42
  89. expect_run t_word16.mod 42
  90. expect_run t_packedset.mod 42
  91. expect_run t_ptrchain.mod 42
  92. expect_run t_addreq.mod 42
  93. expect_run t_wide_set.mod 42
  94. expect_run t_big_ops.mod 42
  95. expect_run t_finally.mod 43
  96. expect_run t_finally_return.mod 43
  97. expect_run t_finally_except.mod 42
  98. expect_run t_finally_local.mod 43
  99. expect_run t_except_parse.mod 42
  100. expect_run t_except_throw.mod 42
  101. expect_run t_except_retry.mod 42
  102. expect_run t_except_return.mod 43
  103. expect_run t_except_nested.mod 42
  104. expect_run t_except_module.mod 42
  105. expect_run t_except_signal.mod 42
  106. expect_fail t_retry_bad.mod "RETRY outside EXCEPT"
  107. expect_run t_smallgaps.mod 42
  108. expect_run t_ctor1.mod 0
  109. expect_run t_ctor2.mod 0
  110. expect_run t_ctor3.mod 0
  111. expect_run t_ctor4.mod 0
  112. expect_run t_ctor5.mod 0
  113. expect_run t_ctor6.mod 0
  114. expect_run t_ctor7.mod 42
  115. expect_run t_minmax.mod 42
  116. expect_run t_minmax2.mod 42
  117. expect_run t_setops.mod 42
  118. expect_run t_ptrfwd.mod 42
  119. expect_run t_libc.mod 42
  120. expect_run t_libc2.mod 42
  121. expect_run t_variant2.mod 42
  122. expect_run t_addrptr.mod 42
  123. expect_run t_nestedmod.mod 42
  124. expect_run t_nestidx.mod 42
  125. expect_run t_proctype.mod 42
  126. expect_run t_compat.mod 42
  127. expect_run t_constfold.mod 42
  128. expect_run t_resultsfx.mod 42
  129. expect_run t_coroutine.mod 42
  130. expect_fail t_fwdvar.mod "undeclared identifier"
  131. expect_fail t_fwdsel.mod "undeclared identifier"
  132. expect_fail t_fwdprop.mod "undeclared identifier"
  133. expect_run t_fwdproc.mod 7
  134. expect_run t_fwdok.mod 42
  135. expect_run t_emptystat.mod 42
  136. expect_run t_highlen.mod 18
  137. expect_run t_builtins.mod 42
  138. expect_run t_long.mod 42
  139. expect_run t_truncfloat.mod 42
  140. expect_run t_enumidx.mod 42
  141. expect_run t_setenum.mod 42
  142. expect_run t_setconst.mod 42
  143. expect_run t_constbuiltin.mod 42
  144. expect_run t_constreal.mod 42
  145. expect_run t_constlong.mod 42
  146. expect_run t_procaddr.mod 42
  147. expect_run t_convert.mod 42
  148. expect_run t_builtinname.mod 42
  149. expect_run t_setword.mod 42
  150. expect_run t_procval.mod 42
  151. expect_run t_real64.mod 42
  152. expect_run t_shiftneg.mod 42
  153. expect_run t_unicode.mod 31
  154. expect_run t_charbounds.mod 3
  155. expect_run t_record.mod 160
  156. expect_run t_recarr.mod 42
  157. expect_run t_recptr.mod 42
  158. expect_run t_nestarr.mod 42
  159. expect_run t_arrrecfld.mod 42
  160. expect_run t_arrrecbig.mod 42
  161. expect_run t_stmtsfx.mod 42
  162. expect_run t_retrec.mod 42
  163. expect_run t_retmeth.mod 42
  164. expect_run t_chain.mod 42
  165. expect_run t_goto.mod 42
  166. expect_fail t_gotobad.mod "undeclared identifier"
  167. expect_run t_under.mod 42
  168. expect_run t_f32.mod 42
  169. expect_run t_f32proc.mod 42
  170. expect_run t_f32field.mod 42
  171. expect_run t_f32conv.mod 42
  172. expect_run t_f32const.mod 42
  173. expect_run t_extern_alias.mod 42
  174. expect_run t_with.mod 114
  175. expect_run t_set.mod 131
  176. expect_run t_setchar.mod 77
  177. expect_run t_setrange.mod 55
  178. expect_run t_classmethod.mod 7
  179. expect_run t_classinherit.mod 7
  180. expect_run t_virtual.mod 3
  181. expect_run t_valconv.mod 15
  182. expect_run t_conv.mod 42
  183. expect_run t_convconst.mod 42
  184. expect_run t_classsibling.mod 7
  185. expect_run t_classinit.mod 42
  186. expect_run t_class.mod 0
  187. expect_run t_longline.mod 0
  188. expect_fail t_bad_parent.mod "undeclared identifier"
  189. expect_run showcase3.mod 183
  190. expect_run showcase4.mod 44
  191. expect_fail showcase5.mod "not supported yet"
  192. expect_run showcase6.mod 34
  193. expect_run showcase7.mod 219
  194. expect_run showcase8.mod 170
  195. expect_run showcase9.mod 140
  196. expect_run showcase10.mod 86
  197. expect_run t_pointer.mod 42
  198. expect_run t_ptrarray.mod 15
  199. expect_run t_ptrrec.mod 15
  200. expect_run t_ptrnest.mod 10
  201. expect_fail t_opaqueptr.mod ""
  202. expect_run t_enumdecl.mod 0
  203. expect_run t_enum.mod 15
  204. expect_run t_strcat.mod 63
  205. expect_run t_charcat.mod 15
  206. expect_run t_variant.mod 31
  207. expect_run t_ustrassign.mod 63
  208. expect_run t_ustrformal.mod 3
  209. expect_run t_ustrcat.mod 63
  210. expect_run t_proc.mod 0
  211. expect_run t_forward.mod 0
  212. expect_run t_call.mod 125
  213. expect_run t_varpar.mod 40
  214. expect_run t_mutual.mod 11
  215. expect_run t_withfield.mod 13
  216. expect_run t_valarray.mod 6
  217. expect_run t_openarr.mod 7
  218. expect_run t_nestedproc.mod 20
  219. expect_run t_nestdeep.mod 211
  220. expect_run t_nestrec.mod 15
  221. expect_fail t_bad_undecl.mod "undeclared identifier"
  222. expect_fail t_bad_dup.mod "duplicate identifier"
  223. expect_fail t_bad_mismatch.mod "module name mismatch"
  224. expect_fail t_bad_opaque.mod "opaque type outside definition"
  225. expect_fail t_bad_while.mod "BOOLEAN condition required"
  226. expect_fail t_bad_exit.mod "not supported yet"
  227. expect_fail t_bad_return.mod "bad RETURN"
  228. expect_fail t_bad_for.mod "FOR needs integer variable and bounds"
  229. expect_fail t_bad_mixed.mod "incompatible assignment"
  230. expect_fail t_bad_fwd.mod "incompatible assignment"
  231. expect_fail t_bad_nestfwd.mod "undeclared identifier"
  232. expect_fail t_fwdtype.mod "undeclared identifier"
  233. expect_fail t_fwdset.mod "undeclared identifier"
  234. expect_fail t_manyproc.mod "not supported yet"
  235. expect_fail t_bad_overlong.mod "invalid UTF-8"
  236. expect_fail t_bad_surrogate.mod "invalid UTF-8"
  237. expect_fail t_bad_utf8big.mod "invalid UTF-8"
  238. expect_fail t_bad_truncutf.mod "invalid UTF-8"
  239. expect_fail t_bad_arity.mod "invalid call"
  240. expect_fail t_bad_actual.mod "invalid call"
  241. expect_fail t_bad_funstmt.mod "invalid call"
  242. expect_fail t_bad_deref.mod "not a POINTER type"
  243. expect_fail t_bad_new.mod "not a POINTER type"
  244. expect_fail t_bad_field.mod "unknown field"
  245. expect_fail t_bad_with.mod "not a RECORD type"
  246. expect_fail t_bad_recassign.mod "incompatible assignment"
  247. expect_fail t_bad_setelem.mod "set operand mismatch"
  248. expect_run t_bad_setbase.mod 42
  249. expect_fail t_bad_setconst.mod "not supported yet"
  250. expect_fail t_bad_bigconst.mod "not supported yet"
  251. expect_fail t_bad_in.mod "set operand mismatch"
  252. expect_fail t_bad_index.mod "array index must be integer"
  253. expect_fail t_bad_bounds.mod "not supported yet"
  254. expect_fail t_bad_varbound.mod "not supported yet"
  255. expect_fail t_bad_manydims.mod "not supported yet"
  256. expect_run t_openformal.mod 0
  257. expect_run t_valopen.mod 15
  258. expect_fail t_bad_open.mod "not supported yet"
  259. expect_trap() {
  260. # $1 = test file — must parse, assemble, link, then abort (rc=134)
  261. name="$1"; mod=$(modof "$name")
  262. rm -f "gen_ssa/$mod.ssa" "gen_ssa/$mod.s" "gen_ssa/$mod"
  263. if ./M2 "tests/$name" 2>&1 | grep -q "Parsed correctly"; then :; else
  264. fail=$((fail+1)); echo "FAIL(trap): $name rejected"; return
  265. fi
  266. if ! qbe -o "gen_ssa/$mod.s" "gen_ssa/$mod.ssa" 2> "gen_ssa/$mod.qbeerr"; then
  267. fail=$((fail+1)); echo "FAIL(trap): $name qbe"; return
  268. fi
  269. if ! cc "gen_ssa/$mod.s" "$SHIM" -o "gen_ssa/$mod" 2> "gen_ssa/$mod.ccerr"; then
  270. fail=$((fail+1)); echo "FAIL(trap): $name cc"; return
  271. fi
  272. timeout 10 "gen_ssa/$mod" > /dev/null 2>&1; got=$?
  273. if [ "$got" = "134" ]; then
  274. pass=$((pass+1)); echo "PASS(trap): $name -> abort"
  275. else
  276. fail=$((fail+1)); echo "FAIL(trap): $name rc=$got want 134"
  277. fi
  278. }
  279. expect_trap t_trap_index.mod
  280. expect_trap t_trap_range.mod
  281. expect_trap t_trap_range_arg.mod
  282. expect_trap t_trap_range_ret.mod
  283. expect_run t_strtrunc.mod 42
  284. expect_trap t_trap_setspan.mod
  285. expect_run t_strempty.mod 42
  286. expect_trap t_trap_chr8.mod
  287. expect_trap t_except_unhandled.mod
  288. expect_trap t_trap_funcret.mod
  289. expect_fail t_defunit.mod ""
  290. expect_fail t_implunit.mod ""
  291. expect_run t_nested.mod 42
  292. # --- separate compilation (step 4.3): $1 prog module, $2 exit code,
  293. # then the session's source files (program last by convention) ---
  294. # Build a session image; echoes 0 on success, non-zero on failure.
  295. build_session() {
  296. prog="$1"; shift
  297. files=""
  298. for f in "$@"; do
  299. case "$f" in */*) files="$files $f";; *) files="$files tests/$f";; esac
  300. done
  301. rm -f "gen_ssa/$prog.ssa" "gen_ssa/$prog.s" "gen_ssa/$prog"
  302. if ./M2 $files 2>&1 | grep -q "Parsed correctly"; then :; else
  303. echo "rejected"; return 1
  304. fi
  305. [ -f "gen_ssa/$prog.ssa" ] || { echo "no image"; return 1; }
  306. qbe -o "gen_ssa/$prog.s" "gen_ssa/$prog.ssa" 2> "gen_ssa/$prog.qbeerr" \
  307. || { echo "qbe"; cat "gen_ssa/$prog.qbeerr"; return 1; }
  308. cc "gen_ssa/$prog.s" "$SHIM" -o "gen_ssa/$prog" -lm 2> "gen_ssa/$prog.ccerr" \
  309. || { echo "cc"; cat "gen_ssa/$prog.ccerr"; return 1; }
  310. return 0
  311. }
  312. expect_run_files() {
  313. prog="$1"; want="$2"; shift 2
  314. if ! build_session "$prog" "$@"; then
  315. fail=$((fail+1)); echo "FAIL(session): $prog $? ($(build_session "$prog" "$@" 2>&1))"; return
  316. fi
  317. timeout 10 "gen_ssa/$prog" > /dev/null 2>&1; got=$?
  318. if [ "$got" = "$want" ]; then
  319. pass=$((pass+1)); echo "PASS(session): $prog -> $got"
  320. else
  321. fail=$((fail+1)); echo "FAIL(session): $prog got $got want $want"
  322. fi
  323. }
  324. expect_run_files_out() {
  325. # $1 prog, $2 exit code, $3 expected first output line, then files
  326. prog="$1"; want="$2"; wantline="$3"; shift 3
  327. if ! build_session "$prog" "$@"; then
  328. fail=$((fail+1)); echo "FAIL(session-out): $prog build failed"; return
  329. fi
  330. out=$(timeout 10 "gen_ssa/$prog" 2>/dev/null); got=$?
  331. first=$(printf '%s\n' "$out" | head -n 1)
  332. if [ "$got" = "$want" ] && [ "$first" = "$wantline" ]; then
  333. pass=$((pass+1)); echo "PASS(session-out): $prog -> $got [$first]"
  334. else
  335. fail=$((fail+1)); echo "FAIL(session-out): $prog rc=$got line=[$first] want=[$wantline]"
  336. fi
  337. }
  338. expect_run_files DBasicProg 49 d_basic.def d_basic.mod d_basic_prog.mod
  339. expect_run_files CForeignProg 42 c_foreign.def c_foreign.mod c_foreign_prog.mod
  340. expect_run_files TCStringProg 42 t_cstring.def t_cstring_prog.mod
  341. expect_run_files TCStringQualProg 42 t_cstring.def t_cstring_qual_prog.mod
  342. expect_run_files CStrProg 42 ../runtime/syslib/CStr.def ../runtime/syslib/CStr.mod tests/cstr_test.def tests/cstr_prog.mod
  343. expect_run_files LinkNameProg 42 linkname.def linkname_prog.mod
  344. expect_run_files CAbiScalarsProg 42 cabi_scalars.def cabi_scalars_prog.mod
  345. expect_run_files EEnumProg 42 e_enum.def e_enum_re.def e_enum_prog.mod
  346. expect_run_files TClassDefProg 8 t_classdef.def t_classdef_prog.mod
  347. expect_run_files DQualProg 46 d_basic.def d_basic.mod d_qual_prog.mod
  348. expect_run_files DTypesProg 36 d_types.def d_types.mod d_types_prog.mod
  349. expect_run_files DOpaqueProg 55 d_opaque.def d_opaque.mod d_opaque_prog.mod
  350. expect_run_files TString 42 d_string.def d_string.mod t_string.mod
  351. expect_run_files FioProg 42 ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod ../runtime/syslib/FileIO.def ../runtime/syslib/FileIO.mod fio_prog.mod
  352. expect_run_files StorageProg 42 ../lib/common/storage.def ../lib/common/storage.mod storage_prog.mod
  353. expect_run_files TSysClock 42 ../lib/iso/sysclock.def ../lib/iso/sysclock.mod t_sysclock.mod
  354. expect_run_files TExceptLib 42 \
  355. ../runtime/syslib/SysExceptions.def \
  356. ../runtime/syslib/SysExceptions.mod \
  357. ../lib/iso/m2exception.def ../lib/iso/m2exception.mod \
  358. ../lib/iso/exceptions.def ../lib/iso/exceptions.mod \
  359. t_except_lib.mod
  360. expect_run_files TExceptTrap 42 \
  361. ../runtime/syslib/SysExceptions.def \
  362. ../runtime/syslib/SysExceptions.mod \
  363. ../lib/iso/m2exception.def ../lib/iso/m2exception.mod \
  364. t_except_trap.mod
  365. expect_run_files TExceptCase 42 \
  366. ../runtime/syslib/SysExceptions.def \
  367. ../runtime/syslib/SysExceptions.mod \
  368. ../lib/iso/m2exception.def ../lib/iso/m2exception.mod \
  369. t_except_case.mod
  370. expect_run_files TExceptFuncret 42 \
  371. ../runtime/syslib/SysExceptions.def \
  372. ../runtime/syslib/SysExceptions.mod \
  373. ../lib/iso/m2exception.def ../lib/iso/m2exception.mod \
  374. t_except_funcret.mod
  375. expect_run_files_out FinallyOrder 0 "P!B!A!" \
  376. f_order_a.def f_order_a.mod f_order_b.def f_order_b.mod \
  377. finally_order.mod
  378. expect_run_files TAst 42 \
  379. ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
  380. ../runtime/syslib/FileIO.def ../runtime/syslib/FileIO.mod \
  381. src/AST.def src/AST.mod \
  382. t_ast.mod
  383. expect_run_files GenericProg 42 \
  384. g_ident.def g_ident.mod g_intid.def g_intid.mod g_prog.mod
  385. expect_run_files PairProg 73 \
  386. g_pair.def g_pair.mod g_intchar.def g_intchar.mod g_pair_prog.mod
  387. expect_run_files BufProg 42 \
  388. g_buf.def g_buf.mod g_buf10.def g_buf10.mod g_bufprog.mod
  389. expect_run_files SortProg 3 \
  390. g_cmp.def g_cmp.mod g_sort.def g_sort.mod g_isort.def g_isort.mod g_sortprog.mod
  391. expect_run_files OrdProg 42 \
  392. g_ordbox.def g_ordbox.mod g_intbox.def g_intbox.mod g_ordprog.mod
  393. expect_run_files GWrapProg 42 \
  394. g_ordbox.def g_ordbox.mod g_intbox.def g_intbox.mod \
  395. g_wrap.def g_wrap.mod g_wrapb.def g_wrapb.mod g_wrapprog.mod
  396. expect_run_files GCBoxProg 42 \
  397. g_gcbox.def g_gcbox.mod g_gcint.def g_gcint.mod g_gcprog.mod
  398. expect_run_files GStkProg 42 \
  399. g_gstk.def g_gstk.mod g_gstki.def g_gstki.mod g_gstkp.mod
  400. expect_run_files GTwiceProg 42 \
  401. g_twice.def g_twice.mod g_twice_i.def g_twice_i.mod \
  402. g_twice_c.def g_twice_c.mod g_twice_p.mod
  403. expect_run_files TByteBuf 62 t_bytebuf.mod
  404. expect_run_files TStreamFile 42 \
  405. ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
  406. ../runtime/syslib/FileIO.def ../runtime/syslib/FileIO.mod \
  407. ../lib/iso/iochan.def ../lib/iso/iochan.mod \
  408. ../lib/iso/chanconsts.def ../lib/iso/chanconsts.mod \
  409. ../lib/iso/streamfile.def ../lib/iso/streamfile.mod \
  410. t_streamfile.mod
  411. expect_run_files TPimIO 42 \
  412. ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
  413. ../lib/pim/inout.def ../lib/pim/inout.mod \
  414. ../lib/pim/strio.def ../lib/pim/strio.mod \
  415. ../lib/pim/numberio.def ../lib/pim/numberio.mod \
  416. ../lib/iso/realio.def ../lib/iso/realio.mod \
  417. ../lib/pim/realinout.def ../lib/pim/realinout.mod \
  418. ../lib/pim/fpuio.def ../lib/pim/fpuio.mod \
  419. t_pimio.mod
  420. expect_run_files WrapProg 42 \
  421. ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
  422. ../lib/iso/iochan.def ../lib/iso/iochan.mod \
  423. ../lib/iso/stdchans.def ../lib/iso/stdchans.mod \
  424. ../lib/gm2/timestring.def ../lib/gm2/timestring.mod \
  425. ../lib/gm2/wrapclock.def ../lib/gm2/wrapclock.mod \
  426. ../lib/gm2/wraptime.def ../lib/gm2/wraptime.mod \
  427. ../lib/gm2/wrapc.def ../lib/gm2/wrapc.mod \
  428. wrapprog.mod
  429. expect_run_files_out Showcase23 35 "list: 5 10 20" \
  430. ../lib/common/sysio.def ../lib/common/sysio.mod \
  431. showcase23lib.def showcase23lib.mod \
  432. showcase23int.def showcase23int.mod \
  433. showcase23vis.def showcase23vis.mod showcase23.mod
  434. expect_run_files_out Showcase24 42 "showcase24 total=42" \
  435. ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
  436. ../lib/iso/textio.def ../lib/iso/textio.mod \
  437. ../lib/iso/conversions.def ../lib/iso/conversions.mod \
  438. ../lib/common/strings.def ../lib/common/strings.mod \
  439. ../lib/common/math.def ../lib/common/math.mod \
  440. showcase24stack.def showcase24stack.mod \
  441. showcase24int.def showcase24int.mod \
  442. showcase24pair.def showcase24pair.mod \
  443. showcase24pic.def showcase24pic.mod \
  444. showcase24util.def showcase24util.mod \
  445. showcase24.mod
  446. expect_run_files_out Showcase25 42 "showcase25 sets=42 addr=ok" \
  447. ../lib/common/sysio.def ../lib/common/sysio.mod showcase25.mod
  448. expect_run_files TImportProc 7 pvi.def pvi.mod t_importproc.mod
  449. expect_run_files_out Showcase22 42 "showcase22 total=42" \
  450. ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
  451. ../lib/iso/iochan.def ../lib/iso/iochan.mod \
  452. ../lib/iso/stdchans.def ../lib/iso/stdchans.mod \
  453. ../lib/gm2/timestring.def ../lib/gm2/timestring.mod \
  454. ../lib/gm2/wrapclock.def ../lib/gm2/wrapclock.mod \
  455. ../lib/gm2/wraptime.def ../lib/gm2/wraptime.mod \
  456. ../lib/gm2/wrapc.def ../lib/gm2/wrapc.mod \
  457. showcase22.mod
  458. expect_run_files Library1 42 \
  459. ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
  460. ../lib/iso/convtypes.def ../lib/iso/convtypes.mod \
  461. ../lib/iso/ioconsts.def ../lib/iso/ioconsts.mod \
  462. ../lib/iso/conversions.def ../lib/iso/conversions.mod \
  463. ../lib/common/math.def ../lib/common/math.mod \
  464. ../lib/iso/sioresult.def ../lib/iso/sioresult.mod \
  465. ../lib/iso/TERMINATION.def ../lib/iso/TERMINATION.mod \
  466. ../lib/iso/wholestr.def ../lib/iso/wholestr.mod \
  467. ../lib/iso/realstr.def ../lib/iso/realstr.mod \
  468. ../lib/iso/longstr.def ../lib/iso/longstr.mod \
  469. ../lib/iso/longmath.def ../lib/iso/longmath.mod \
  470. ../lib/iso/iochan.def ../lib/iso/iochan.mod \
  471. ../lib/iso/longio.def ../lib/iso/longio.mod \
  472. ../lib/pim/strio.def ../lib/pim/strio.mod \
  473. ../lib/pim/inout.def ../lib/pim/inout.mod \
  474. ../lib/gm2/stdio.def ../lib/gm2/stdio.mod \
  475. ../lib/iso/stextio.def ../lib/iso/stextio.mod \
  476. ../lib/iso/swholeio.def ../lib/iso/swholeio.mod \
  477. ../lib/iso/srealio.def ../lib/iso/srealio.mod \
  478. library1.mod
  479. expect_run_files TDynStr 42 \
  480. ../lib/gm2/dynamicstrings.def ../lib/gm2/dynamicstrings.mod \
  481. ../lib/gm2/sysstorage.def ../lib/gm2/sysstorage.mod \
  482. t_dynstr.mod
  483. expect_run_files ClashProg 60 d_clash_a.def d_clash_a.mod d_clash_b.def d_clash_b.mod d_clash_prog.mod
  484. expect_run_files_out Hello 0 "Hello, Modula-2!" ../lib/common/sysio.def ../lib/common/sysio.mod hello.mod
  485. expect_run_files_out StringsProg 0 "Hello World" ../lib/common/sysio.def ../lib/common/sysio.mod ../lib/common/strings.def ../lib/common/strings.mod strings_prog.mod
  486. expect_run_files StringsSliceProg 255 ../lib/common/strings.def ../lib/common/strings.mod strings_slice_prog.mod
  487. expect_run_files_out Stdlib2Prog 42 "stdlib2 n=42" ../lib/common/sysio.def ../lib/common/sysio.mod ../lib/common/math.def ../lib/common/math.mod ../lib/common/strings.def ../lib/common/strings.mod ../lib/common/charclass.def ../lib/common/charclass.mod stdlib2_prog.mod
  488. expect_run_files MathProg 12 ../lib/common/sysio.def ../lib/common/sysio.mod ../lib/common/math.def ../lib/common/math.mod math_prog.mod
  489. expect_run_files Math2Prog 31 ../lib/common/math.def ../lib/common/math.mod math2_prog.mod
  490. expect_run_files SysClockProg 3 ../lib/iso/sysclock.def ../lib/iso/sysclock.mod sysclock_prog.mod
  491. expect_run_files Utf8Prog 127 ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod utf8_prog.mod
  492. expect_run_files ConvProg 127 ../lib/iso/conversions.def ../lib/iso/conversions.mod conv_prog.mod
  493. expect_run_files ConvResultsProg 127 ../lib/iso/conversions.def ../lib/iso/conversions.mod convresults_prog.mod
  494. expect_run_files TStrEq 15 t_streq.mod
  495. expect_run_files ProgArgsProg 7 ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod ../lib/iso/programargs.def ../lib/iso/programargs.mod progargs_prog.mod
  496. expect_run_files_out UTextProg 42 "héllo" ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod ../lib/iso/textio.def ../lib/iso/textio.mod utext_prog.mod
  497. expect_run_files_in() {
  498. # $1 prog, $2 exit code, $3 expected first line, $4 stdin, then files
  499. prog="$1"; want="$2"; wantline="$3"; input="$4"; shift 4
  500. if ! build_session "$prog" "$@"; then
  501. fail=$((fail+1)); echo "FAIL(session-in): $prog build failed"; return
  502. fi
  503. out=$(printf '%s\n' "$input" | timeout 10 "gen_ssa/$prog" 2>/dev/null); got=$?
  504. first=$(printf '%s\n' "$out" | head -n 1)
  505. if [ "$got" = "$want" ] && [ "$first" = "$wantline" ]; then
  506. pass=$((pass+1)); echo "PASS(session-in): $prog -> $got [$first]"
  507. else
  508. fail=$((fail+1)); echo "FAIL(session-in): $prog rc=$got line=[$first] want=[$wantline]"
  509. fi
  510. }
  511. expect_run_files_in ReadProg 0 "42" "20 22" ../lib/common/sysio.def ../lib/common/sysio.mod read_prog.mod
  512. expect_run_files_in WholeIOProg 0 "42" "6 7" ../lib/common/sysio.def ../lib/common/sysio.mod ../lib/iso/wholeio.def ../lib/iso/wholeio.mod wholeio_prog.mod
  513. expect_run_files_in RealProg 42 "3.500000E+00" "1.25" ../lib/iso/realio.def ../lib/iso/realio.mod ../lib/common/sysio.def ../lib/common/sysio.mod realio_prog.mod
  514. expect_run_files_in IOChanProg 0 "hello 42" "Z" ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod ../lib/iso/iochan.def ../lib/iso/iochan.mod iochan_prog.mod
  515. rm -f gen_ssa/_iochan_tmp.txt
  516. expect_run_files IOChanFileProg 3 ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod ../lib/common/strings.def ../lib/common/strings.mod ../lib/iso/iochan.def ../lib/iso/iochan.mod iochanfile_prog.mod
  517. rm -f gen_ssa/_iochan_tmp.txt
  518. rm -f gen_ssa/_iochanseek.txt
  519. expect_run_files IOChanSeekProg 15 ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod ../lib/common/strings.def ../lib/common/strings.mod ../lib/iso/iochan.def ../lib/iso/iochan.mod iochanseek_prog.mod
  520. rm -f gen_ssa/_iochanseek.txt
  521. expect_run_files FilesProg 42 ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod ../lib/iso/iochan.def ../lib/iso/iochan.mod ../lib/iso/files.def ../lib/iso/files.mod files_prog.mod
  522. expect_run_files TBadFile 42 ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod ../lib/iso/iochan.def ../lib/iso/iochan.mod ../lib/iso/files.def ../lib/iso/files.mod t_badfile.mod
  523. rm -f gen_ssa/_files_tmp.txt
  524. expect_run_files_in Showcase11 80 "Modula-2" "42" \
  525. ../lib/common/sysio.def ../lib/common/sysio.mod \
  526. ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
  527. ../lib/iso/textio.def ../lib/iso/textio.mod \
  528. ../lib/iso/wholeio.def ../lib/iso/wholeio.mod \
  529. ../lib/common/strings.def ../lib/common/strings.mod \
  530. ../lib/common/math.def ../lib/common/math.mod \
  531. ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod ../lib/iso/iochan.def ../lib/iso/iochan.mod ../lib/iso/files.def ../lib/iso/files.mod \
  532. showcase11.mod
  533. rm -f gen_ssa/_showcase11.txt
  534. # step 8.2/8.3: const folding, forward types, trailing ';', empty
  535. # statements, 1-char strings, qualified type names.
  536. expect_run_files Showcase12 42 showcase12lib.def showcase12lib.mod showcase12.mod
  537. expect_run_files_out Showcase13 42 "Even(8)=T Odd(7)=T total=42" ../lib/common/sysio.def ../lib/common/sysio.mod showcase13.mod
  538. expect_run_files_out Showcase19 42 "showcase19 total=42" \
  539. ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
  540. ../lib/iso/textio.def ../lib/iso/textio.mod \
  541. ../lib/iso/conversions.def ../lib/iso/conversions.mod \
  542. showcase19.mod
  543. expect_run_files_out Showcase20 42 "showcase20 total=42" \
  544. ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
  545. ../lib/iso/textio.def ../lib/iso/textio.mod \
  546. ../lib/iso/conversions.def ../lib/iso/conversions.mod \
  547. showcase20.mod
  548. expect_run_files_out Showcase21 42 "showcase21 total=42" \
  549. ../lib/iso/convtypes.def ../lib/iso/convtypes.mod \
  550. ../lib/iso/conversions.def ../lib/iso/conversions.mod \
  551. ../lib/common/math.def ../lib/common/math.mod \
  552. ../lib/iso/wholestr.def ../lib/iso/wholestr.mod \
  553. ../lib/iso/realstr.def ../lib/iso/realstr.mod \
  554. ../lib/iso/longmath.def ../lib/iso/longmath.mod \
  555. ../lib/gm2/dynamicstrings.def ../lib/gm2/dynamicstrings.mod \
  556. ../lib/pim/strio.def ../lib/pim/strio.mod \
  557. showcase21.mod
  558. expect_run_files_out Showcase18 42 "showcase18 areas sum=139" \
  559. ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
  560. ../lib/iso/textio.def ../lib/iso/textio.mod \
  561. ../lib/iso/conversions.def ../lib/iso/conversions.mod \
  562. showcase18.mod
  563. expect_run_files_out Showcase17 42 "showcase17 total=42" \
  564. ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
  565. ../lib/iso/textio.def ../lib/iso/textio.mod \
  566. ../lib/iso/conversions.def ../lib/iso/conversions.mod \
  567. showcase17.mod
  568. rm -f gen_ssa/_showcase16.txt
  569. expect_run_files_out Showcase16 42 "showcase16: id=3 total=42" \
  570. ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
  571. ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
  572. ../lib/iso/iochan.def ../lib/iso/iochan.mod \
  573. ../lib/iso/files.def ../lib/iso/files.mod \
  574. ../lib/iso/textio.def ../lib/iso/textio.mod \
  575. ../lib/common/strings.def ../lib/common/strings.mod \
  576. ../lib/iso/conversions.def ../lib/iso/conversions.mod \
  577. showcase16.mod
  578. rm -f gen_ssa/_showcase16.txt
  579. rm -f gen_ssa/_showcase15.txt
  580. expect_run_files_out Showcase15 42 "read back: point 42" \
  581. ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
  582. ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
  583. ../lib/iso/iochan.def ../lib/iso/iochan.mod \
  584. ../lib/iso/textio.def ../lib/iso/textio.mod \
  585. ../lib/common/strings.def ../lib/common/strings.mod \
  586. ../lib/iso/conversions.def ../lib/iso/conversions.mod \
  587. showcase15lib.def showcase15lib.mod showcase15.mod
  588. rm -f gen_ssa/_showcase15.txt
  589. expect_run_files_out Showcase14 42 "showcase14 n=42" \
  590. ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod \
  591. ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod \
  592. ../lib/common/sysio.def ../lib/common/sysio.mod \
  593. ../lib/iso/textio.def ../lib/iso/textio.mod \
  594. ../lib/iso/conversions.def ../lib/iso/conversions.mod \
  595. ../lib/iso/realio.def ../lib/iso/realio.mod \
  596. ../lib/iso/programargs.def ../lib/iso/programargs.mod \
  597. ../lib/iso/iochan.def ../lib/iso/iochan.mod \
  598. showcase14.mod
  599. expect_run_files_out MixProg 0 "7" ../runtime/syslib/Utf8.def ../runtime/syslib/Utf8.mod ../lib/iso/textio.def ../lib/iso/textio.mod ../lib/common/sysio.def ../lib/common/sysio.mod ../runtime/syslib/SysShim.def ../runtime/syslib/SysShim.mod ../lib/iso/iochan.def ../lib/iso/iochan.mod ../lib/iso/files.def ../lib/iso/files.mod d_mix_prog.mod
  600. rm -f gen_ssa/_mix.txt
  601. expect_fail_files() {
  602. # $1 = listing basename, $2 = message (may be empty), then files
  603. lst="$1"; want="$2"; shift 2
  604. files=""
  605. for f in "$@"; do files="$files tests/$f"; done
  606. if ./M2 $files 2>&1 | grep -q "Incorrect source"; then :; else
  607. fail=$((fail+1)); echo "FAIL(session-rej): $lst accepted"; return
  608. fi
  609. if [ -z "$want" ]; then
  610. pass=$((pass+1)); echo "PASS(session-rej): $lst"
  611. elif grep -q "$want" "tests/$lst.LST" 2>/dev/null; then
  612. pass=$((pass+1)); echo "PASS(session-rej): $lst [$want]"
  613. else
  614. fail=$((fail+1)); echo "FAIL(session-rej): [$want] not in tests/$lst.LST"
  615. fi
  616. }
  617. expect_fail_files d_badimp_prog "undeclared identifier" d_basic.def d_basic.mod d_badimp_prog.mod
  618. expect_fail_files sig "implementation does not match definition" sig.def sig.mod sig_prog.mod
  619. expect_fail_files g_badbuf "invalid call" g_buf.def g_buf.mod g_badbuf.def
  620. expect_fail_files g_realbox "invalid call" g_ordbox.def g_ordbox.mod g_realbox.def
  621. # --- two-phase parse gate. Deferral is now the DEFAULT (procedure
  622. # bodies are parsed after the unit's declarations); -notwophase
  623. # restores the old inline parse for debugging. Forward-free code
  624. # must be byte-identical either way; forward-reference code must
  625. # still work. ---
  626. twophase_same() {
  627. # $1 = test file (no dir): default (deferral) vs -notwophase inline
  628. name="$1"; mod=$(modof "$name")
  629. rm -f "gen_ssa/$mod.ssa" "gen_ssa/$mod.off.ssa"
  630. ./M2 -notwophase "tests/$name" >/dev/null 2>&1
  631. cp "gen_ssa/$mod.ssa" "gen_ssa/$mod.off.ssa"
  632. if ./M2 "tests/$name" 2>&1 | grep -q "twophase .*mismatch"; then
  633. fail=$((fail+1)); echo "FAIL(twophase): $name probe mismatch"; return
  634. fi
  635. if cmp -s "gen_ssa/$mod.off.ssa" "gen_ssa/$mod.ssa"; then
  636. pass=$((pass+1)); echo "PASS(twophase): $name identical"
  637. else
  638. fail=$((fail+1)); echo "FAIL(twophase): $name .ssa differs"
  639. fi
  640. rm -f "gen_ssa/$mod.off.ssa"
  641. }
  642. twophase_same t_nestedproc.mod
  643. twophase_same t_classmethod.mod
  644. # Forward references compile *differently* with deferral than with the
  645. # legacy FwdVar path (the deferral makes them ordinary, so the codegen is
  646. # the normal one) — that is the point. Gate them functionally: same exit
  647. # code, and the forward diagnostic still fires.
  648. twophase_run() {
  649. # $1 = test file, $2 = expected exit code
  650. name="$1"; want="$2"; mod=$(modof "$name")
  651. rm -f "gen_ssa/$mod.ssa" "gen_ssa/$mod.s" "gen_ssa/$mod"
  652. if ./M2 "tests/$name" 2>&1 | grep -q "Parsed correctly"; then :; else
  653. fail=$((fail+1)); echo "FAIL(twophase-run): $name rejected"; return
  654. fi
  655. qbe -o "gen_ssa/$mod.s" "gen_ssa/$mod.ssa" 2>/dev/null || { fail=$((fail+1)); echo "FAIL(twophase-run): $name qbe"; return; }
  656. cc "gen_ssa/$mod.s" "$SHIM" -o "gen_ssa/$mod" 2>/dev/null || { fail=$((fail+1)); echo "FAIL(twophase-run): $name cc"; return; }
  657. timeout 10 "gen_ssa/$mod" >/dev/null 2>&1; got=$?
  658. if [ "$got" = "$want" ]; then pass=$((pass+1)); echo "PASS(twophase-run): $name -> $got"
  659. else fail=$((fail+1)); echo "FAIL(twophase-run): $name got $got want $want"; fi
  660. }
  661. twophase_fail() {
  662. # $1 = test file, $2 = message expected in the .LST
  663. name="$1"; want="$2"
  664. if ./M2 "tests/$name" 2>&1 | grep -q "Incorrect source"; then :; else
  665. fail=$((fail+1)); echo "FAIL(twophase-fail): $name accepted"; return
  666. fi
  667. if grep -q "$want" "tests/$(basename "$name" .mod).LST" 2>/dev/null; then
  668. pass=$((pass+1)); echo "PASS(twophase-fail): $name [$want]"
  669. else fail=$((fail+1)); echo "FAIL(twophase-fail): [$want] not found"; fi
  670. }
  671. twophase_fail t_fwdvar.mod "undeclared identifier"
  672. twophase_fail t_fwdsel.mod "undeclared identifier"
  673. twophase_fail t_fwdprop.mod "undeclared identifier"
  674. twophase_fail t_bad_fwd.mod "undeclared identifier"
  675. # --- separate compilation: compile one unit against .def interfaces,
  676. # link objects with cc; library objects must not define main. ---
  677. sep_compile() {
  678. # $1 = module name, $2 = target source, rest = interface files
  679. mod="$1"; target="$2"; shift 2
  680. rm -f "gen_ssa/$mod.ssa" "gen_ssa/$mod.s" "gen_ssa/$mod.o"
  681. if ! ./M2 -c "$@" "$target" 2>&1 | grep -q "Parsed correctly"; then
  682. return 1
  683. fi
  684. [ -f "gen_ssa/$mod.ssa" ] || return 1
  685. qbe -o "gen_ssa/$mod.s" "gen_ssa/$mod.ssa" 2> "gen_ssa/$mod.qbeerr" || return 1
  686. cc -c "gen_ssa/$mod.s" -o "gen_ssa/$mod.o" 2> "gen_ssa/$mod.ccerr" || return 1
  687. return 0
  688. }
  689. expect_separate() {
  690. # $1 = program module, $2 = expected exit code, $3 = library module,
  691. # $4 = library def, $5 = library mod, $6 = program source
  692. prog="$1"; want="$2"; lib="$3"; ldef="$4"; lmod="$5"; psrc="$6"
  693. if ! sep_compile "$lib" "tests/$lmod" "tests/$ldef"; then
  694. fail=$((fail+1)); echo "FAIL(separate): $lib compile"; return
  695. fi
  696. if grep -q '\$main' "gen_ssa/$lib.ssa"; then
  697. fail=$((fail+1)); echo "FAIL(separate): $lib defines main"; return
  698. fi
  699. if ! sep_compile "$prog" "tests/$psrc" "tests/$ldef"; then
  700. fail=$((fail+1)); echo "FAIL(separate): $prog compile"; return
  701. fi
  702. if ! grep -q '\$main' "gen_ssa/$prog.ssa"; then
  703. fail=$((fail+1)); echo "FAIL(separate): $prog has no main"; return
  704. fi
  705. if ! cc "gen_ssa/$prog.o" "gen_ssa/$lib.o" "$SHIM" -o "gen_ssa/$prog" -lm 2> "gen_ssa/$prog.ccerr"; then
  706. fail=$((fail+1)); echo "FAIL(separate): $prog link"; cat "gen_ssa/$prog.ccerr"; return
  707. fi
  708. timeout 10 "gen_ssa/$prog" >/dev/null 2>&1; got=$?
  709. if [ "$got" = "$want" ]; then
  710. pass=$((pass+1)); echo "PASS(separate): $prog -> $got"
  711. else
  712. fail=$((fail+1)); echo "FAIL(separate): $prog got $got want $want"
  713. fi
  714. }
  715. expect_separate SepProg 42 SepLib sep_lib.def sep_lib.mod sep_prog.mod
  716. expect_separate SepEmptyProg 42 SepEmpty sep_empty.def sep_empty.mod sep_empty_prog.mod
  717. # M2 -c -I: resolve the target's own .def and imports from the include path.
  718. sep_compile_auto() {
  719. # $1 = module, $2 = source
  720. mod="$1"; target="$2"
  721. rm -f "gen_ssa/$mod.ssa" "gen_ssa/$mod.s" "gen_ssa/$mod.o"
  722. ./M2 -c -I tests "tests/$target" 2>&1 | grep -q "Parsed correctly" || return 1
  723. [ -f "gen_ssa/$mod.ssa" ] || return 1
  724. qbe -o "gen_ssa/$mod.s" "gen_ssa/$mod.ssa" 2>/dev/null || return 1
  725. cc -c "gen_ssa/$mod.s" -o "gen_ssa/$mod.o" 2>/dev/null || return 1
  726. }
  727. expect_separate_auto() {
  728. # $1 = program module, $2 = expected exit code, $3 = library module,
  729. # $4 = library source, $5 = program source
  730. prog="$1"; want="$2"; lib="$3"; lsrc="$4"; psrc="$5"
  731. if ! sep_compile_auto "$lib" "$lsrc"; then
  732. fail=$((fail+1)); echo "FAIL(separate-I): $lib compile"; return
  733. fi
  734. if ! sep_compile_auto "$prog" "$psrc"; then
  735. fail=$((fail+1)); echo "FAIL(separate-I): $prog compile"; return
  736. fi
  737. if ! cc "gen_ssa/$prog.o" "gen_ssa/$lib.o" "$SHIM" -o "gen_ssa/$prog" -lm 2> "gen_ssa/$prog.ccerr"; then
  738. fail=$((fail+1)); echo "FAIL(separate-I): $prog link"; cat "gen_ssa/$prog.ccerr"; return
  739. fi
  740. timeout 10 "gen_ssa/$prog" >/dev/null 2>&1; got=$?
  741. if [ "$got" = "$want" ]; then
  742. pass=$((pass+1)); echo "PASS(separate-I): $prog -> $got"
  743. else
  744. fail=$((fail+1)); echo "FAIL(separate-I): $prog got $got want $want"
  745. fi
  746. }
  747. expect_separate_auto SepResProg 42 SepRes sepres.mod sepres_prog.mod
  748. expect_separate_auto CDefProg 8 CDef cdef.def cdef_prog.mod
  749. # --- M2 process exit codes: 0 = ok, 1 = compile errors, 2 = usage/IO ---
  750. check_exit() {
  751. # $1 = description, $2 = expected rc, rest = args
  752. desc="$1"; want="$2"; shift 2
  753. ./M2 "$@" >/dev/null 2>&1; got=$?
  754. if [ "$got" = "$want" ]; then pass=$((pass+1)); echo "PASS(exit): $desc -> $got"
  755. else fail=$((fail+1)); echo "FAIL(exit): $desc got $got want $want"; fi
  756. }
  757. check_exit "ok" 0 tests/t_minimal.mod
  758. check_exit "errors" 1 tests/t_bad_undecl.mod
  759. check_exit "no input" 2
  760. check_exit "missing file" 2 /tmp/opencode/_m2_no_such_file_.mod
  761. # --- step 7 gate: compiler sources free of gm2-only imports.
  762. # FileIO is the last module to port (see docs/summary_step7.md);
  763. # it is excluded here so the gate guards everything else. ---
  764. if grep -qE "(IMPORT|FROM)[[:space:]]+.*\b(Environment|FileSysOp|TextIO|RawIO|WholeIO|IOChan|ProgramArgs)\b" \
  765. src/SymTab.def src/SymTab.mod src/QbeGen.def src/QbeGen.mod \
  766. src/M2S.mod src/M2P.mod src/M2.mod src/*.frm 2>/dev/null; then
  767. fail=$((fail+1)); echo "FAIL(gate): gm2-only imports present"
  768. else
  769. pass=$((pass+1)); echo "PASS(gate): no gm2-only imports (FileIO port pending)"
  770. fi
  771. echo "--- $pass passed, $fail failed ---"
  772. [ "$fail" -eq 0 ]