#!/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