#!/bin/sh # Step-1 regression: M2 -> gen_ssa/*.ssa -> qbe -> cc -> exit code. # Usage: ./run_tests.sh (from the compiler directory) pass=0; fail=0 modof() { sed -n 's/^MODULE \([A-Za-z][A-Za-z0-9]*\).*/\1/p' "tests/$1" | head -n 1 } expect_run() { # $1 = test file (no dir), $2 = expected exit code name="$1"; want="$2"; mod=$(modof "$name") rm -f "gen_ssa/$mod.ssa" "gen_ssa/$mod.s" "gen_ssa/$mod" if ./M2 "tests/$name" 2>&1 | grep -q "Parsed correctly"; then :; else fail=$((fail+1)); echo "FAIL(run): $name rejected"; return fi if [ ! -f "gen_ssa/$mod.ssa" ]; then fail=$((fail+1)); echo "FAIL(run): $name no gen_ssa/$mod.ssa"; return fi if ! qbe -o "gen_ssa/$mod.s" "gen_ssa/$mod.ssa" 2> "gen_ssa/$mod.qbeerr"; then fail=$((fail+1)); echo "FAIL(run): $name qbe:"; cat "gen_ssa/$mod.qbeerr"; return fi if ! cc "gen_ssa/$mod.s" -o "gen_ssa/$mod" 2> "gen_ssa/$mod.ccerr"; then fail=$((fail+1)); echo "FAIL(run): $name cc:"; cat "gen_ssa/$mod.ccerr"; return fi timeout 10 "gen_ssa/$mod" > /dev/null 2>&1; got=$? if [ "$got" = "$want" ]; then pass=$((pass+1)); echo "PASS(run): $name -> $got" else fail=$((fail+1)); echo "FAIL(run): $name got $got want $want" fi } expect_fail() { # $1 = test file, $2 = message text expected in the .LST name="$1"; want="$2" if ./M2 "tests/$name" 2>&1 | grep -q "Incorrect source"; then :; else fail=$((fail+1)); echo "FAIL(fail): $name accepted"; return fi lst="tests/$(basename "$name" .mod).LST" if grep -q "$want" "$lst" 2>/dev/null; then pass=$((pass+1)); echo "PASS(fail): $name [$want]" else fail=$((fail+1)); echo "FAIL(fail): [$want] not found in $lst" fi } mkdir -p gen_ssa expect_run t_minimal.mod 0 expect_run t_exit.mod 7 expect_run t_arith.mod 25 expect_run showcase1.mod 50 expect_run t_types.mod 8 expect_run showcase2.mod 71 expect_run t_if.mod 25 expect_run t_while.mod 55 expect_run t_repeat.mod 55 expect_run t_loop.mod 55 expect_run t_for.mod 85 expect_run t_case.mod 103 expect_run t_bool.mod 42 expect_run t_real.mod 31 expect_run t_array.mod 108 expect_run t_charbounds.mod 3 expect_run t_record.mod 160 expect_run t_with.mod 114 expect_run t_set.mod 131 expect_run t_setchar.mod 77 expect_run t_setrange.mod 55 expect_fail t_classdef.mod "not supported yet" expect_fail t_class.mod "not supported yet" expect_fail t_bad_parent.mod "undeclared identifier" expect_run showcase3.mod 183 expect_run showcase4.mod 44 expect_fail showcase5.mod "not supported yet" expect_run showcase6.mod 34 expect_run showcase7.mod 219 expect_run showcase8.mod 170 expect_run t_pointer.mod 42 expect_run t_ptrarray.mod 15 expect_run t_ptrrec.mod 15 expect_run t_ptrnest.mod 10 expect_fail t_opaqueptr.mod "not supported yet" expect_fail t_enumdecl.mod "not supported yet" expect_fail t_proc.mod "not supported yet" expect_fail t_forward.mod "not supported yet" expect_fail t_bad_undecl.mod "undeclared identifier" expect_fail t_bad_dup.mod "duplicate identifier" expect_fail t_bad_mismatch.mod "module name mismatch" expect_fail t_bad_opaque.mod "opaque type outside definition" expect_fail t_bad_while.mod "BOOLEAN condition required" expect_fail t_bad_exit.mod "not supported yet" expect_fail t_bad_return.mod "bad RETURN" expect_fail t_bad_for.mod "FOR needs integer variable and bounds" expect_fail t_bad_mixed.mod "incompatible assignment" expect_fail t_bad_deref.mod "not a POINTER type" expect_fail t_bad_new.mod "not a POINTER type" expect_fail t_bad_field.mod "unknown field" expect_fail t_bad_with.mod "not a RECORD type" expect_fail t_bad_recassign.mod "incompatible assignment" expect_fail t_bad_setelem.mod "set operand mismatch" expect_fail t_bad_setbase.mod "not supported yet" expect_fail t_bad_in.mod "set operand mismatch" expect_fail t_bad_index.mod "array index must be integer" expect_fail t_bad_bounds.mod "not supported yet" expect_fail t_bad_varbound.mod "not supported yet" expect_fail t_bad_manydims.mod "not supported yet" expect_fail t_openformal.mod "not supported yet" expect_fail t_bad_open.mod "not supported yet" expect_trap() { # $1 = test file — must parse, assemble, link, then abort (rc=134) name="$1"; mod=$(modof "$name") rm -f "gen_ssa/$mod.ssa" "gen_ssa/$mod.s" "gen_ssa/$mod" if ./M2 "tests/$name" 2>&1 | grep -q "Parsed correctly"; then :; else fail=$((fail+1)); echo "FAIL(trap): $name rejected"; return fi if ! qbe -o "gen_ssa/$mod.s" "gen_ssa/$mod.ssa" 2> "gen_ssa/$mod.qbeerr"; then fail=$((fail+1)); echo "FAIL(trap): $name qbe"; return fi if ! cc "gen_ssa/$mod.s" -o "gen_ssa/$mod" 2> "gen_ssa/$mod.ccerr"; then fail=$((fail+1)); echo "FAIL(trap): $name cc"; return fi timeout 10 "gen_ssa/$mod" > /dev/null 2>&1; got=$? if [ "$got" = "134" ]; then pass=$((pass+1)); echo "PASS(trap): $name -> abort" else fail=$((fail+1)); echo "FAIL(trap): $name rc=$got want 134" fi } expect_trap t_trap_index.mod expect_trap t_trap_count.mod expect_trap t_trap_setspan.mod expect_trap t_trap_emptystr.mod expect_fail t_defunit.mod "not supported yet" expect_fail t_implunit.mod "not supported yet" expect_fail t_nested.mod "not supported yet" echo "--- $pass passed, $fail failed ---" [ "$fail" -eq 0 ]