|
|
#!/usr/bin/env bash
|
|
|
# 测试 Lab2 IR 生成 - 人员 1 的任务
|
|
|
# 测试内容:
|
|
|
# - 任务 1.1: 支持更多二元运算符(Sub, Mul, Div, Mod)
|
|
|
# - 任务 1.2: 支持一元运算符(正负号)
|
|
|
# - 任务 1.3: 支持赋值表达式
|
|
|
# - 任务 1.4: 支持逗号分隔的多个变量声明
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
|
COMPILER="$PROJECT_ROOT/build/bin/compiler"
|
|
|
TEST_DIR="$PROJECT_ROOT/test/test_case/irgen_lab1_4"
|
|
|
RESULT_DIR="$PROJECT_ROOT/test/test_result/lab2_ir1"
|
|
|
|
|
|
# 颜色输出
|
|
|
RED='\033[0;31m'
|
|
|
GREEN='\033[0;32m'
|
|
|
YELLOW='\033[1;33m'
|
|
|
NC='\033[0m' # No Color
|
|
|
|
|
|
echo "========================================="
|
|
|
echo "Lab2 IR 生成测试 - 部分任务验证"
|
|
|
echo "========================================="
|
|
|
echo ""
|
|
|
|
|
|
# 检查编译器是否存在
|
|
|
if [[ ! -x "$COMPILER" ]]; then
|
|
|
echo -e "${RED}错误:编译器不存在或不可执行:$COMPILER${NC}"
|
|
|
echo "请先运行:cmake --build build"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
# 检查测试目录是否存在
|
|
|
if [[ ! -d "$TEST_DIR" ]]; then
|
|
|
echo -e "${RED}错误:测试目录不存在:$TEST_DIR${NC}"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
# 创建结果目录
|
|
|
mkdir -p "$RESULT_DIR"
|
|
|
|
|
|
# 统计
|
|
|
total=0
|
|
|
passed=0
|
|
|
failed=0
|
|
|
|
|
|
# 测试函数
|
|
|
run_test() {
|
|
|
local input=$1
|
|
|
local basename=$(basename "$input" .sy)
|
|
|
local expected_out="$TEST_DIR/$basename.out"
|
|
|
local actual_out="$RESULT_DIR/$basename.actual.out"
|
|
|
local ll_file="$RESULT_DIR/$basename.ll"
|
|
|
|
|
|
((total++)) || true
|
|
|
|
|
|
echo -n "测试 $basename ... "
|
|
|
|
|
|
# 生成 IR
|
|
|
if ! "$COMPILER" --emit-ir "$input" > "$ll_file" 2>&1; then
|
|
|
echo -e "${RED}IR 生成失败${NC}"
|
|
|
((failed++)) || true
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
# 如果需要运行并比对输出
|
|
|
if [[ -f "$expected_out" ]]; then
|
|
|
# 编译并运行
|
|
|
local exe_file="$RESULT_DIR/$basename"
|
|
|
if ! llc -O0 -filetype=obj "$ll_file" -o "$RESULT_DIR/$basename.o" 2>/dev/null; then
|
|
|
echo -e "${YELLOW}LLVM 编译失败 (llc)${NC}"
|
|
|
cat "$ll_file"
|
|
|
((failed++)) || true
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
if ! clang "$RESULT_DIR/$basename.o" -o "$exe_file" 2>/dev/null; then
|
|
|
echo -e "${YELLOW}链接失败 (clang)${NC}"
|
|
|
((failed++)) || true
|
|
|
return 1
|
|
|
fi
|
|
|
|
|
|
# 运行程序,捕获返回值(低 8 位)
|
|
|
local exit_code=0
|
|
|
"$exe_file" > "$actual_out" 2>&1 || exit_code=$?
|
|
|
|
|
|
# 处理返回值(LLVM/AArch64 返回的是 8 位无符号整数)
|
|
|
if [[ $exit_code -gt 127 ]]; then
|
|
|
# 转换为有符号整数
|
|
|
exit_code=$((exit_code - 256))
|
|
|
fi
|
|
|
echo "$exit_code" > "$actual_out"
|
|
|
|
|
|
# 比对输出
|
|
|
if diff -q "$expected_out" "$actual_out" > /dev/null 2>&1; then
|
|
|
echo -e "${GREEN}✓ 通过${NC}"
|
|
|
((passed++)) || true
|
|
|
return 0
|
|
|
else
|
|
|
echo -e "${RED}✗ 输出不匹配${NC}"
|
|
|
echo " 期望:$(cat "$expected_out")"
|
|
|
echo " 实际:$(cat "$actual_out")"
|
|
|
((failed++)) || true
|
|
|
return 1
|
|
|
fi
|
|
|
else
|
|
|
# 没有期望输出,只检查 IR 生成
|
|
|
echo -e "${GREEN}✓ IR 生成成功${NC}"
|
|
|
((passed++)) || true
|
|
|
return 0
|
|
|
fi
|
|
|
}
|
|
|
|
|
|
# 查找所有测试用例
|
|
|
test_files=()
|
|
|
while IFS= read -r -d '' file; do
|
|
|
test_files+=("$file")
|
|
|
done < <(find "$TEST_DIR" -name "*.sy" -type f -print0 | sort -z)
|
|
|
|
|
|
if [[ ${#test_files[@]} -eq 0 ]]; then
|
|
|
echo -e "${RED}未找到测试用例:$TEST_DIR${NC}"
|
|
|
exit 1
|
|
|
fi
|
|
|
|
|
|
echo "找到 ${#test_files[@]} 个测试用例"
|
|
|
echo ""
|
|
|
|
|
|
# 运行所有测试
|
|
|
for test_file in "${test_files[@]}"; do
|
|
|
run_test "$test_file" || true
|
|
|
done
|
|
|
|
|
|
# 输出统计
|
|
|
echo ""
|
|
|
echo "========================================="
|
|
|
echo "测试结果统计"
|
|
|
echo "========================================="
|
|
|
echo -e "总数:$total"
|
|
|
echo -e "通过:${GREEN}$passed${NC}"
|
|
|
echo -e "失败:${RED}$failed${NC}"
|
|
|
echo ""
|
|
|
|
|
|
if [[ $failed -eq 0 ]]; then
|
|
|
echo -e "${GREEN}✓ 所有测试通过!${NC}"
|
|
|
echo ""
|
|
|
echo "测试覆盖:"
|
|
|
echo " ✓ 任务 1.1: 二元运算符(Sub, Mul, Div, Mod)"
|
|
|
echo " ✓ 任务 1.2: 一元运算符(正负号)"
|
|
|
echo " ✓ 任务 1.3: 赋值表达式"
|
|
|
echo " ✓ 任务 1.4: 逗号分隔的多变量声明"
|
|
|
exit 0
|
|
|
else
|
|
|
echo -e "${RED}✗ 有 $failed 个测试失败${NC}"
|
|
|
exit 1
|
|
|
fi
|