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.
nudt-compiler-cpp/scripts/test_lab2_ir1.sh

158 lines
4.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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