|
|
#!/bin/bash
|
|
|
|
|
|
# 测试脚本(支持动态输出目录)
|
|
|
# 用法: ./run_tests.sh [--verbose] [--mode <模式>] [<单个测试文件>]
|
|
|
# 模式: parse-tree, ir, asm, run (默认 run)
|
|
|
|
|
|
COMPILER="./build/bin/compiler"
|
|
|
TEST_SCRIPT="./scripts/verify_asm.sh"
|
|
|
TEST_DIR="test/test_case"
|
|
|
RESULT_FILE="result.txt"
|
|
|
VERBOSE=0
|
|
|
MODE="run" # 默认模式为完整测试
|
|
|
|
|
|
# 解析参数
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
case "$1" in
|
|
|
--verbose|-v)
|
|
|
VERBOSE=1
|
|
|
shift
|
|
|
;;
|
|
|
--mode)
|
|
|
MODE="$2"
|
|
|
shift 2
|
|
|
;;
|
|
|
--emit-parse-tree)
|
|
|
MODE="parse-tree"
|
|
|
shift
|
|
|
;;
|
|
|
--emit-ir)
|
|
|
MODE="ir"
|
|
|
shift
|
|
|
;;
|
|
|
--emit-asm)
|
|
|
MODE="asm"
|
|
|
shift
|
|
|
;;
|
|
|
--run)
|
|
|
MODE="run"
|
|
|
shift
|
|
|
;;
|
|
|
-*)
|
|
|
echo "未知选项: $1"
|
|
|
exit 1
|
|
|
;;
|
|
|
*)
|
|
|
# 非选项参数视为测试文件
|
|
|
SINGLE_FILE="$1"
|
|
|
shift
|
|
|
;;
|
|
|
esac
|
|
|
done
|
|
|
|
|
|
# 检查编译器是否存在
|
|
|
if [ ! -f "$COMPILER" ]; then
|
|
|
echo "错误: 编译器未找到于 $COMPILER"
|
|
|
echo "请先完成项目构建 (cmake 和 make)"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
# 如果是 run 模式,检查测试脚本是否存在
|
|
|
if [ "$MODE" = "run" ] && [ ! -f "$TEST_SCRIPT" ]; then
|
|
|
echo "错误: 测试脚本未找到于 $TEST_SCRIPT"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
# 如果指定了单个文件,检查文件是否存在
|
|
|
if [ -n "$SINGLE_FILE" ] && [ ! -f "$SINGLE_FILE" ]; then
|
|
|
echo "错误: 文件 $SINGLE_FILE 不存在"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
# 清空(或创建)结果文件
|
|
|
> "$RESULT_FILE"
|
|
|
|
|
|
# 计数器
|
|
|
total=0
|
|
|
passed=0
|
|
|
failed=0
|
|
|
|
|
|
echo "开始测试 (模式: $MODE)..."
|
|
|
echo "输出将保存到 $RESULT_FILE"
|
|
|
echo "------------------------"
|
|
|
|
|
|
# 确定测试文件列表
|
|
|
if [ -n "$SINGLE_FILE" ]; then
|
|
|
TEST_FILES=("$SINGLE_FILE")
|
|
|
else
|
|
|
mapfile -t TEST_FILES < <(find "$TEST_DIR" -type f -name "*.sy" | sort)
|
|
|
fi
|
|
|
|
|
|
# 根据模式执行测试
|
|
|
for file in "${TEST_FILES[@]}"; do
|
|
|
((total++))
|
|
|
if [ $VERBOSE -eq 1 ]; then
|
|
|
echo "测试文件: $file"
|
|
|
else
|
|
|
echo -n "测试 $file ... "
|
|
|
fi
|
|
|
|
|
|
echo "========== $file ==========" >> "$RESULT_FILE"
|
|
|
|
|
|
# 根据模式构建命令
|
|
|
case "$MODE" in
|
|
|
parse-tree)
|
|
|
cmd="$COMPILER --emit-parse-tree \"$file\""
|
|
|
;;
|
|
|
ir)
|
|
|
cmd="$COMPILER --emit-ir \"$file\""
|
|
|
;;
|
|
|
asm)
|
|
|
cmd="$COMPILER --emit-asm \"$file\""
|
|
|
;;
|
|
|
run)
|
|
|
# 根据输入文件所在子目录确定输出目录
|
|
|
# 提取 test/test_case/ 之后的子目录名(functional 或 performance)
|
|
|
rel_path="${file#$TEST_DIR/}"
|
|
|
subdir=$(echo "$rel_path" | cut -d'/' -f1)
|
|
|
if [[ "$subdir" != "functional" && "$subdir" != "performance" ]]; then
|
|
|
echo "警告: 未知子目录 $subdir,使用默认输出目录" >> "$RESULT_FILE"
|
|
|
out_dir="test/test_result/asm"
|
|
|
else
|
|
|
out_dir="test/test_result/$subdir/asm"
|
|
|
fi
|
|
|
cmd="$TEST_SCRIPT \"$file\" \"$out_dir\" --run"
|
|
|
;;
|
|
|
*)
|
|
|
echo "未知模式: $MODE" >&2
|
|
|
exit 1
|
|
|
;;
|
|
|
esac
|
|
|
|
|
|
if [ $VERBOSE -eq 1 ]; then
|
|
|
eval "$cmd" 2>&1 | tee -a "$RESULT_FILE"
|
|
|
result=${PIPESTATUS[0]}
|
|
|
else
|
|
|
eval "$cmd" >> "$RESULT_FILE" 2>&1
|
|
|
result=$?
|
|
|
fi
|
|
|
|
|
|
echo "" >> "$RESULT_FILE"
|
|
|
|
|
|
if [ $result -eq 0 ]; then
|
|
|
if [ $VERBOSE -eq 0 ]; then
|
|
|
echo "通过"
|
|
|
fi
|
|
|
((passed++))
|
|
|
else
|
|
|
if [ $VERBOSE -eq 0 ]; then
|
|
|
echo "失败"
|
|
|
else
|
|
|
echo ">>> 测试失败: $file"
|
|
|
fi
|
|
|
((failed++))
|
|
|
fi
|
|
|
done
|
|
|
|
|
|
echo "------------------------"
|
|
|
echo "总计: $total"
|
|
|
echo "通过: $passed"
|
|
|
echo "失败: $failed"
|
|
|
echo "详细输出已保存至 $RESULT_FILE"
|
|
|
|
|
|
if [ $failed -gt 0 ]; then
|
|
|
exit 1
|
|
|
else
|
|
|
exit 0
|
|
|
fi |