You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.2 KiB

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
COMPILER="$ROOT_DIR/build/bin/compiler"
TMP_DIR="$ROOT_DIR/build/test_compiler"
TEST_DIRS=("$ROOT_DIR/test/test_case/functional" "$ROOT_DIR/test/test_case/performance")
if [[ ! -x "$COMPILER" ]]; then
echo "未找到编译器: $COMPILER"
echo "请先构建编译器,例如: mkdir -p build && cd build && cmake .. && make -j"
exit 1
fi
mkdir -p "$TMP_DIR"
ir_total=0
ir_pass=0
result_total=0
result_pass=0
ir_failures=()
result_failures=()
function normalize_file() {
sed 's/\r$//' "$1"
}
for test_dir in "${TEST_DIRS[@]}"; do
if [[ ! -d "$test_dir" ]]; then
echo "跳过不存在的测试目录: $test_dir"
continue
fi
shopt -s nullglob
for input in "$test_dir"/*.sy; do
ir_total=$((ir_total+1))
base=$(basename "$input")
stem=${base%.sy}
out_dir="$TMP_DIR/$(basename "$test_dir")"
mkdir -p "$out_dir"
ll_file="$out_dir/$stem.ll"
stdout_file="$out_dir/$stem.stdout"
expected_file="$test_dir/$stem.out"
stdin_file="$test_dir/$stem.in"
echo "[TEST] $input"
compiler_status=0
compiler_output=
compiler_output=$("$COMPILER" --emit-ir "$input" 2>&1) || compiler_status=$?
printf '%s\n' "$compiler_output" | sed '/^\[DEBUG/d' > "$ll_file"
if [[ $compiler_status -ne 0 ]]; then
echo " [IR] 编译失败: 返回码 $compiler_status"
ir_failures+=("$input: compiler failed ($compiler_status)")
continue
fi
if ! grep -qE '^define ' "$ll_file"; then
echo " [IR] 失败: 未生成有效函数定义"
ir_failures+=("$input: invalid IR output")
continue
fi
ir_pass=$((ir_pass+1))
echo " [IR] 生成成功"
if [[ -f "$expected_file" ]]; then
result_total=$((result_total+1))
expected=$(normalize_file "$expected_file")
run_status=0
if [[ -f "$stdin_file" ]]; then
lli "$ll_file" < "$stdin_file" > "$stdout_file" 2>&1 || run_status=$?
else
lli "$ll_file" > "$stdout_file" 2>&1 || run_status=$?
fi
if [[ ! -s "$stdout_file" && "$expected" =~ ^-?[0-9]+$ ]]; then
if [[ "$run_status" -eq "$expected" ]]; then
result_pass=$((result_pass+1))
echo " [RUN] 返回码匹配"
else
echo " [RUN] 返回码不匹配: got $run_status"
result_failures+=("$input: exit code mismatch (got $run_status)")
fi
else
if diff -u <(printf '%s\n' "$expected") <(normalize_file "$stdout_file") > "$out_dir/$stem.diff"; then
result_pass=$((result_pass+1))
echo " [RUN] 输出匹配"
else
echo " [RUN] 输出不匹配"
result_failures+=("$input: output mismatch")
fi
fi
else
echo " [RUN] 未找到预期输出 $expected_file,跳过结果验证"
fi
done
shopt -u nullglob
done
cat <<EOF
测试完成。
IR 生成: $ir_pass / $ir_total
结果匹配: $result_pass / $result_total
EOF
if [[ ${#ir_failures[@]} -gt 0 ]]; then
echo "\nIR 失败列表:"
for item in "${ir_failures[@]}"; do
echo " $item"
done
fi
if [[ ${#result_failures[@]} -gt 0 ]]; then
echo "\n结果失败列表:"
for item in "${result_failures[@]}"; do
echo " $item"
done
fi