[backend]将testdata/下的测例替换为了赛方测试用例,更新了测试脚本

This commit is contained in:
Lixuanwang
2025-07-19 01:44:37 +08:00
parent 6335abe806
commit 69d27f058d
331 changed files with 45011 additions and 2365 deletions

2
.gitignore vendored
View File

@ -36,7 +36,7 @@
doxygen
!/testdata/functional/*.out
!/testdata/performance/*.out
!/testdata/h_functional/*.out
build/
.antlr
.vscode/

View File

@ -20,7 +20,12 @@ TESTDATA_DIR="${SCRIPT_DIR}/testdata"
# 定义编译器 (这里假设 gcc 在 VM 内部是可用的)
GCC_NATIVE="gcc" # VM 内部的 gcc
# 不再需要 QEMU_RISCV64因为直接执行
# --- 新增功能: 初始化变量 ---
TIMEOUT_SECONDS=5 # 默认运行时超时时间为 5 秒
COMPILE_TIMEOUT_SECONDS=10 # 默认编译超时时间为 10 秒
TOTAL_CASES=0
PASSED_CASES=0
# 显示帮助信息的函数
show_help() {
@ -29,31 +34,32 @@ show_help() {
echo "假设当前运行环境已经是 RISC-V 64 位架构,可以直接执行编译后的程序。"
echo ""
echo "选项:"
echo " -c, --clean 清理 'tmp' 目录下的所有生成文件。"
echo " -h, --help 显示此帮助信息并退出。"
echo " -c, --clean 清理 'tmp' 目录下的所有生成文件。"
echo " -t, --timeout N 设置每个测试用例的运行时超时为 N 秒 (默认: 5)。"
echo " -ct, --compile-timeout M 设置 gcc 编译的超时时间为 M 秒 (默认: 10)。"
echo " -h, --help 显示此帮助信息并退出。"
echo ""
echo "执行步骤:"
echo "1. 遍历 'tmp/' 目录下的所有 .s 汇编文件。"
echo "2. 使用 VM 内部的 gcc 将 .s 文件汇编并链接为可执行文件 (链接 -L./lib -lsysy_riscv -static)。"
echo "3. 直接运行编译后的可执行文件。"
echo "4. 根据对应的 testdata/*.out 文件内容(最后一行是否为整数)决定是进行返回值比较、标准输出比较,或两者都进行。"
echo "5. 如果没有对应的 .in/.out 文件,则打印可执行文件的返回值。"
echo "6. 输出比较时会忽略行尾多余的换行符。"
echo "2. 在指定的超时时间内使用 VM 内部的 gcc 将 .s 文件汇编并链接为可执行文件。"
echo "3. 在指定的超时时间内运行编译后的可执行文件。"
echo "4. 根据对应的 .out 文件内容进行返回值和/或标准输出比较。"
echo "5. 输出比较时会忽略行尾多余的换行符。"
echo "6. 所有测试结束后,报告总通过率。"
}
# 清理临时文件的函数
clean_tmp() {
echo "正在清理临时目录: ${TMP_DIR}"
# 清理所有由本脚本和 runit.sh 生成的文件
rm -rf "${TMP_DIR}"/*.s \
"${TMP_DIR}"/*_sysyc_riscv64 \
"${TMP_DIR}"/*_sysyc_riscv64.actual_out \
"${TMP_DIR}"/*_sysyc_riscv64.expected_stdout \
"${TMP_DIR}"/*_sysyc_riscv64.o # 以防生成了 .o 文件
"${TMP_DIR}"/*_sysyc_riscv64.o
echo "清理完成。"
}
# 如果临时目录不存在,则创建它 (尽管 runit.sh 应该已经创建了)
# 如果临时目录不存在,则创建它
mkdir -p "${TMP_DIR}"
# 解析命令行参数
@ -63,6 +69,24 @@ while [[ "$#" -gt 0 ]]; do
clean_tmp
exit 0
;;
-t|--timeout)
if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then
TIMEOUT_SECONDS="$2"
shift # 移过参数值
else
echo "错误: --timeout 需要一个正整数参数。" >&2
exit 1
fi
;;
-ct|--compile-timeout)
if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then
COMPILE_TIMEOUT_SECONDS="$2"
shift # 移过参数值
else
echo "错误: --compile-timeout 需要一个正整数参数。" >&2
exit 1
fi
;;
-h|--help)
show_help
exit 0
@ -73,30 +97,33 @@ while [[ "$#" -gt 0 ]]; do
exit 1
;;
esac
shift # 移过参数名
done
echo "SysY VM 内部测试运行器启动..."
echo "编译超时设置为: ${COMPILE_TIMEOUT_SECONDS}"
echo "运行时超时设置为: ${TIMEOUT_SECONDS}"
echo "汇编文件目录: ${TMP_DIR}"
echo "库文件目录: ${LIB_DIR}"
echo "测试数据目录: ${TESTDATA_DIR}"
echo ""
# 查找 tmp 目录下的所有 .s 汇编文件
s_files=$(find "${TMP_DIR}" -maxdepth 1 -name "*.s")
TOTAL_CASES=$(echo "$s_files" | wc -w)
# 遍历找到的每个 .s 文件
find "${TMP_DIR}" -maxdepth 1 -name "*.s" | while read s_file; do
echo "$s_files" | while read s_file; do
# --- 新增功能: 初始化用例通过状态 ---
is_passed=1 # 1 表示通过, 0 表示失败
# 从 .s 文件名中提取原始的测试用例名称部分
# 例如:从 functional_21_if_test2_sysyc_riscv64.s 提取 functional_21_if_test2
base_name_from_s_file=$(basename "$s_file" .s)
# 这一步得到的是 'functional_21_if_test2' 或 'performance_2024-2D0-22'
original_test_name_underscored=$(echo "$base_name_from_s_file" | sed 's/_sysyc_riscv64$//')
# 将 `original_test_name_underscored` 分割成类别和文件名
# 例如:'functional_21_if_test2' 分割为 'functional' 和 '21_if_test2'
category=$(echo "$original_test_name_underscored" | cut -d'_' -f1)
# cut -d'_' -f2- 会从第二个下划线开始获取所有剩余部分
test_file_base=$(echo "$original_test_name_underscored" | cut -d'_' -f2-)
# 构建原始的相对路径,例如:'functional/21_if_test2'
original_relative_path="${category}/${test_file_base}"
# 定义可执行文件、输入文件、参考输出文件和实际输出文件的路径
@ -109,109 +136,112 @@ find "${TMP_DIR}" -maxdepth 1 -name "*.s" | while read s_file; do
echo " 对应的测试用例路径: ${original_relative_path}"
# 步骤 1: 使用 VM 内部的 gcc 编译 .s 到可执行文件
# 注意:这里假设 gcc 在 VM 环境中可用,且 ./lib 是相对于当前脚本运行目录
echo " 使用 gcc 汇编并链接: ${GCC_NATIVE} \"${s_file}\" -o \"${executable_file}\" -L\"${LIB_DIR}\" -lsysy_riscv -static -g"
"${GCC_NATIVE}" "${s_file}" -o "${executable_file}" -L"${LIB_DIR}" -lsysy_riscv -static -g
if [ $? -ne 0 ]; then
echo -e "\e[31m错误: GCC 汇编/链接 ${s_file} 失败\e[0m"
continue
fi
echo " 生成的可执行文件: ${executable_file}"
echo " 使用 gcc 汇编并链接 (超时 ${COMPILE_TIMEOUT_SECONDS}s)..."
# --- 修改点: 为 gcc 增加 timeout ---
timeout ${COMPILE_TIMEOUT_SECONDS} "${GCC_NATIVE}" "${s_file}" -o "${executable_file}" -L"${LIB_DIR}" -lsysy_riscv -static -g
GCC_STATUS=$?
if [ $GCC_STATUS -eq 124 ]; then
echo -e "\e[31m错误: GCC 编译/链接 ${s_file} 超时 (超过 ${COMPILE_TIMEOUT_SECONDS} 秒)\e[0m"
is_passed=0
elif [ $GCC_STATUS -ne 0 ]; then
echo -e "\e[31m错误: GCC 汇编/链接 ${s_file} 失败,退出码: ${GCC_STATUS}\e[0m"
is_passed=0
else
echo " 生成的可执行文件: ${executable_file}"
echo " 正在执行 (超时 ${TIMEOUT_SECONDS}s): \"${executable_file}\""
# 步骤 2: 执行编译后的文件并比较/报告结果
# 直接执行可执行文件,不再通过 qemu-riscv64
echo " 正在执行: \"${executable_file}\"" # 修改点:移除多余的 ./
# 检查是否存在 .out 文件
if [ -f "${output_reference_file}" ]; then
# 尝试从 .out 文件中提取期望的返回码和期望的标准输出
# 获取 .out 文件的最后一行,去除空白字符
LAST_LINE_TRIMMED=$(tail -n 1 "${output_reference_file}" | tr -d '[:space:]')
# 检查最后一行是否为纯整数 (允许正负号)
if [[ "$LAST_LINE_TRIMMED" =~ ^[-+]?[0-9]+$ ]]; then
# 假设最后一行是期望的返回码
EXPECTED_RETURN_CODE="$LAST_LINE_TRIMMED"
# 步骤 2: 执行编译后的文件并比较/报告结果
if [ -f "${output_reference_file}" ]; then
LAST_LINE_TRIMMED=$(tail -n 1 "${output_reference_file}" | tr -d '[:space:]')
# 创建一个只包含期望标准输出的临时文件 (所有行除了最后一行)
EXPECTED_STDOUT_FILE="${TMP_DIR}/${base_name_from_s_file}.expected_stdout"
# 使用 head -n -1 来获取除了最后一行之外的所有行。如果文件只有一行,则生成一个空文件。
head -n -1 "${output_reference_file}" > "${EXPECTED_STDOUT_FILE}"
if [[ "$LAST_LINE_TRIMMED" =~ ^[-+]?[0-9]+$ ]]; then
EXPECTED_RETURN_CODE="$LAST_LINE_TRIMMED"
EXPECTED_STDOUT_FILE="${TMP_DIR}/${base_name_from_s_file}.expected_stdout"
head -n -1 "${output_reference_file}" > "${EXPECTED_STDOUT_FILE}"
echo " 检测到 .out 文件同时包含标准输出和期望的返回码。"
echo " 期望返回码: ${EXPECTED_RETURN_CODE}"
echo " 检测到 .out 文件同时包含标准输出和期望的返回码。"
echo " 期望返回码: ${EXPECTED_RETURN_CODE}"
if [ -s "${EXPECTED_STDOUT_FILE}" ]; then # -s 检查文件是否非空
echo " 期望标准输出文件: ${EXPECTED_STDOUT_FILE}"
else
echo " 期望标准输出为空。"
fi
if [ -f "${input_file}" ]; then
timeout ${TIMEOUT_SECONDS} "${executable_file}" < "${input_file}" > "${output_actual_file}"
else
timeout ${TIMEOUT_SECONDS} "${executable_file}" > "${output_actual_file}"
fi
ACTUAL_RETURN_CODE=$?
# 执行程序,捕获实际返回码和实际标准输出
if [ -f "${input_file}" ]; then
echo " 使用输入文件: ${input_file}"
"${executable_file}" < "${input_file}" > "${output_actual_file}" # 修改点:移除多余的 ./
else
"${executable_file}" > "${output_actual_file}" # 修改点:移除多余的 ./
fi
ACTUAL_RETURN_CODE=$? # 捕获执行状态
if [ "$ACTUAL_RETURN_CODE" -eq 124 ]; then
echo -e "\e[31m 执行超时: ${original_relative_path}.sy 运行超过 ${TIMEOUT_SECONDS} 秒\e[0m"
is_passed=0
else
if [ "$ACTUAL_RETURN_CODE" -eq "$EXPECTED_RETURN_CODE" ]; then
echo -e "\e[32m 返回码测试成功: (${ACTUAL_RETURN_CODE}) 与期望值 (${EXPECTED_RETURN_CODE}) 匹配\e[0m"
else
echo -e "\e[31m 返回码测试失败: 期望: ${EXPECTED_RETURN_CODE}, 实际: ${ACTUAL_RETURN_CODE}\e[0m"
is_passed=0
fi
# 比较实际返回码与期望返回码
if [ "$ACTUAL_RETURN_CODE" -eq "$EXPECTED_RETURN_CODE" ]; then
echo -e "\e[32m 返回码测试成功: ${original_relative_path}.sy 的返回码 (${ACTUAL_RETURN_CODE}) 与期望值 (${EXPECTED_RETURN_CODE}) 匹配\e[0m"
if diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then
echo -e "\e[32m 标准输出测试成功\e[0m"
else
echo -e "\e[31m 标准输出测试失败\e[0m"
echo " 差异:"
diff "${output_actual_file}" "${EXPECTED_STDOUT_FILE}"
is_passed=0
fi
fi
else
echo -e "\e[31m 返回码测试失败: ${original_relative_path}.sy 的返回码不匹配。期望: ${EXPECTED_RETURN_CODE}, 实际: ${ACTUAL_RETURN_CODE}\e[0m"
fi
echo " 检测到 .out 文件为纯标准输出参考。"
if [ -f "${input_file}" ]; then
timeout ${TIMEOUT_SECONDS} "${executable_file}" < "${input_file}" > "${output_actual_file}"
else
timeout ${TIMEOUT_SECONDS} "${executable_file}" > "${output_actual_file}"
fi
EXEC_STATUS=$?
# 比较实际标准输出与期望标准输出,忽略文件末尾的换行符差异
if diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then
echo -e "\e[32m 标准输出测试成功: 输出与 ${original_relative_path}.sy 的参考输出匹配 (忽略行尾换行符差异)\e[0m"
else
echo -e "\e[31m 标准输出测试失败: ${original_relative_path}.sy 的输出不匹配\e[0m"
echo " 差异 (可能包含行尾换行符差异):"
diff "${output_actual_file}" "${EXPECTED_STDOUT_FILE}" # 显示原始差异以便调试
if [ $EXEC_STATUS -eq 124 ]; then
echo -e "\e[31m 执行超时: ${original_relative_path}.sy 运行超过 ${TIMEOUT_SECONDS} 秒\e[0m"
is_passed=0
else
if [ $EXEC_STATUS -ne 0 ]; then
echo -e "\e[33m警告: 程序以非零状态 ${EXEC_STATUS} 退出 (纯输出比较模式)。\e[0m"
fi
if diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${output_reference_file}") >/dev/null 2>&1; then
echo -e "\e[32m 成功: 输出与参考输出匹配\e[0m"
else
echo -e "\e[31m 失败: 输出不匹配\e[0m"
echo " 差异:"
diff "${output_actual_file}" "${output_reference_file}"
is_passed=0
fi
fi
fi
else
# 最后一行不是纯整数,将整个 .out 文件视为纯标准输出
echo " 检测到 .out 文件为纯标准输出参考。正在与输出文件比较: ${output_reference_file}"
# 执行程序,并将输出重定向到临时文件
if [ -f "${input_file}" ]; then
echo " 使用输入文件: ${input_file}"
"${executable_file}" < "${input_file}" > "${output_actual_file}" # 修改点:移除多余的 ./
echo " 未找到 .out 文件。正在运行并报告返回码。"
timeout ${TIMEOUT_SECONDS} "${executable_file}"
EXEC_STATUS=$?
if [ $EXEC_STATUS -eq 124 ]; then
echo -e "\e[31m 执行超时: ${original_relative_path}.sy 运行超过 ${TIMEOUT_SECONDS} 秒\e[0m"
is_passed=0
else
"${executable_file}" > "${output_actual_file}" # 修改点:移除多余的 ./
fi
EXEC_STATUS=$? # 捕获执行状态
if [ $EXEC_STATUS -ne 0 ]; then
echo -e "\e[33m警告: 可执行文件 ${original_relative_path}.sy 以非零状态 ${EXEC_STATUS} 退出 (纯输出比较模式)。请检查程序逻辑或其是否应返回此状态。\e[0m"
fi
# 比较实际输出与参考输出,忽略文件末尾的换行符差异
if diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${output_reference_file}") >/dev/null 2>&1; then
echo -e "\e[32m 成功: 输出与 ${original_relative_path}.sy 的参考输出匹配 (忽略行尾换行符差异)\e[0m"
else
echo -e "\e[31m 失败: ${original_relative_path}.sy 的输出不匹配\e[0m"
echo " 差异 (可能包含行尾换行符差异):"
diff "${output_actual_file}" "${output_reference_file}" # 显示原始差异以便调试
echo " ${original_relative_path}.sy 的返回码: ${EXEC_STATUS}"
fi
fi
elif [ -f "${input_file}" ]; then
# 只有 .in 文件存在,使用输入运行并报告退出码(无参考输出)
echo " 使用输入文件: ${input_file}"
echo " 没有 .out 文件进行比较。正在运行并报告返回码。"
"${executable_file}" < "${input_file}" # 修改点:移除多余的 ./
EXEC_STATUS=$?
echo " ${original_relative_path}.sy 的返回码: ${EXEC_STATUS}"
else
# .in 和 .out 文件都不存在,只运行并报告退出码
echo " 未找到 .in 或 .out 文件。正在运行并报告返回码。"
"${executable_file}" # 修改点:移除多余的 ./
EXEC_STATUS=$?
echo " ${original_relative_path}.sy 的返回码: ${EXEC_STATUS}"
fi
echo "" # 为测试用例之间添加一个空行,以提高可读性
# --- 新增功能: 更新通过用例计数 ---
if [ "$is_passed" -eq 1 ]; then
((PASSED_CASES++))
fi
echo "" # 为测试用例之间添加一个空行
done
echo "脚本完成。"
# --- 新增功能: 打印最终总结 ---
echo "========================================"
echo "测试完成"
echo "测试通过率: [${PASSED_CASES}/${TOTAL_CASES}]"
echo "========================================"
if [ "$PASSED_CASES" -eq "$TOTAL_CASES" ]; then
exit 0
else
exit 1
fi

View File

@ -16,38 +16,32 @@ SYSYC="${BUILD_BIN_DIR}/sysyc"
GCC_RISCV64="riscv64-linux-gnu-gcc"
QEMU_RISCV64="qemu-riscv64"
# 标志,用于确定是否应该生成和运行可执行文件
# --- 新增功能: 初始化变量 ---
EXECUTE_MODE=false
SYSYC_TIMEOUT=10 # sysyc 编译超时 (秒)
GCC_TIMEOUT=10 # gcc 编译超时 (秒)
EXEC_TIMEOUT=5 # qemu 执行超时 (秒)
TOTAL_CASES=0
PASSED_CASES=0
# 显示帮助信息的函数
show_help() {
echo "用法: $0 [选项]"
echo "此脚本用于编译 .sy 文件,并可选择性地运行它们进行测试。"
echo "此脚本用于按文件名前缀数字升序编译和测试 .sy 文件。"
echo ""
echo "选项:"
echo " -e, --executable 编译为可执行文件运行可执行文件,并比较输出(如果存在 .in/.out 文件)。"
echo " 如果 .out 文件的最后一行是整数,则将其视为期望的返回值进行比较,其余内容视为期望的标准输出。"
echo " 如果 .out 文件的最后一行不是整数,则将整个 .out 文件视为期望的标准输出进行比较。"
echo " 输出比较时会忽略行尾多余的换行符。"
echo " 如果不存在 .in/.out 文件,则打印返回码。"
echo " -c, --clean 清理 'tmp' 目录下的所有生成文件。"
echo " -h, --help 显示此帮助信息并退出。"
echo ""
echo "编译步骤:"
echo "1. 调用 sysyc 将 .sy 编译为 .s (RISC-V 汇编)。"
echo "2. 调用 riscv64-linux-gnu-gcc 将 .s 编译为可执行文件,并链接 -L../lib/ -lsysy_riscv -static。"
echo "3. 调用 qemu-riscv64 执行编译后的文件。"
echo "4. 根据 .out 文件内容(最后一行是否为整数)决定是进行返回值比较、标准输出比较,或两者都进行。"
echo "5. 如果没有 .in/.out 文件,则打印可执行文件的返回值。"
echo " -e, --executable 编译为可执行文件运行测试。"
echo " -c, --clean 清理 'tmp' 目录下的所有生成文件。"
echo " -sct N 设置 sysyc 编译超时为 N 秒 (默认: 10)。"
echo " -gct N 设置 gcc 交叉编译超时为 N 秒 (默认: 10)。"
echo " -et N 设置 qemu 执行超时为 N 秒 (默认: 5)。"
echo " -h, --help 显示此帮助信息并退出。"
}
# 清理临时文件的函数
clean_tmp() {
echo "正在清理临时目录: ${TMP_DIR}"
rm -rf "${TMP_DIR}"/*
# 如果需要,也可以根据 clean.sh 示例清理其他特定文件
# rm -rf "${SCRIPT_DIR}"/*.s "${SCRIPT_DIR}"/*.ll "${SCRIPT_DIR}"/*clang "${SCRIPT_DIR}"/*sysyc
# rm -rf "${SCRIPT_DIR}"/*_riscv64
}
# 如果临时目录不存在,则创建它
@ -58,12 +52,20 @@ while [[ "$#" -gt 0 ]]; do
case "$1" in
-e|--executable)
EXECUTE_MODE=true
shift
;;
-c|--clean)
clean_tmp
exit 0
;;
-sct)
if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then SYSYC_TIMEOUT="$2"; shift; else echo "错误: -sct 需要一个正整数参数。" >&2; exit 1; fi
;;
-gct)
if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then GCC_TIMEOUT="$2"; shift; else echo "错误: -gct 需要一个正整数参数。" >&2; exit 1; fi
;;
-et)
if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then EXEC_TIMEOUT="$2"; shift; else echo "错误: -et 需要一个正整数参数。" >&2; exit 1; fi
;;
-h|--help)
show_help
exit 0
@ -74,150 +76,159 @@ while [[ "$#" -gt 0 ]]; do
exit 1
;;
esac
shift
done
echo "SysY 测试运行器启动..."
echo "输入目录: ${TESTDATA_DIR}"
echo "临时目录: ${TMP_DIR}"
echo "执行模式已启用: ${EXECUTE_MODE}"
echo "执行模式: ${EXECUTE_MODE}"
if ${EXECUTE_MODE}; then
echo "超时设置: sysyc=${SYSYC_TIMEOUT}s, gcc=${GCC_TIMEOUT}s, qemu=${EXEC_TIMEOUT}s"
fi
echo ""
# 查找 testdata 目录及其子目录中的所有 .sy 文件
# 遍历找到的每个 .sy 文件
find "${TESTDATA_DIR}" -name "*.sy" | while read sy_file; do
# 获取 .sy 文件的基本名称例如21_if_test2
# 这也处理了文件位于子目录中的情况例如functional/21_if_test2.sy
# --- 修改点: 查找所有 .sy 文件并按文件名前缀数字排序 ---
sy_files=$(find "${TESTDATA_DIR}" -name "*.sy" | sort -V)
TOTAL_CASES=$(echo "$sy_files" | wc -w)
# --- 本次修复: 使用 here-string (<<<) 代替管道 (|) 来避免子 shell 问题 ---
# 这样可以确保循环内的 PASSED_CASES 变量修改在循环结束后依然有效
while IFS= read -r sy_file; do
is_passed=1 # 1 表示通过, 0 表示失败
relative_path_no_ext=$(realpath --relative-to="${TESTDATA_DIR}" "${sy_file%.*}")
# 将斜杠替换为下划线,用于输出文件名,以避免冲突并保持结构
output_base_name=$(echo "${relative_path_no_ext}" | tr '/' '_')
# 定义汇编文件、可执行文件、输入文件和输出文件的路径
assembly_file="${TMP_DIR}/${output_base_name}_sysyc_riscv64.s"
executable_file="${TMP_DIR}/${output_base_name}_sysyc_riscv64"
input_file="${sy_file%.*}.in"
output_reference_file="${sy_file%.*}.out"
output_actual_file="${TMP_DIR}/${output_base_name}_sysyc_riscv64.actual_out"
echo "正在处理: $(basename "$sy_file")"
echo " SY 文件: ${sy_file}"
echo "正在处理: $(basename "$sy_file") (路径: ${relative_path_no_ext}.sy)"
# 步骤 1: 使用 sysyc 编译 .sy 到 .s
echo " 使用 sysyc 编译: ${SYSYC} -S \"${sy_file}\" -o \"${assembly_file}\""
"${SYSYC}" -S "${sy_file}" -o "${assembly_file}"
if [ $? -ne 0 ]; then
echo -e "\e[31m错误: SysY 编译 ${sy_file} 失败\e[0m"
echo " 使用 sysyc 编译 (超时 ${SYSYC_TIMEOUT}s)..."
timeout ${SYSYC_TIMEOUT} "${SYSYC}" -S "${sy_file}" -o "${assembly_file}"
SYSYC_STATUS=$?
if [ $SYSYC_STATUS -eq 124 ]; then
echo -e "\e[31m错误: SysY 编译 ${sy_file} 超时\e[0m"
is_passed=0
elif [ $SYSYC_STATUS -ne 0 ]; then
echo -e "\e[31m错误: SysY 编译 ${sy_file} 失败,退出码: ${SYSYC_STATUS}\e[0m"
is_passed=0
fi
# 只有当 EXECUTE_MODE 为 true 且上一步成功时才继续
if ${EXECUTE_MODE} && [ "$is_passed" -eq 1 ]; then
# 步骤 2: 使用 riscv64-linux-gnu-gcc 编译 .s 到可执行文件
echo " 使用 gcc 编译 (超时 ${GCC_TIMEOUT}s)..."
timeout ${GCC_TIMEOUT} "${GCC_RISCV64}" "${assembly_file}" -o "${executable_file}" -L"${LIB_DIR}" -lsysy_riscv -static
GCC_STATUS=$?
if [ $GCC_STATUS -eq 124 ]; then
echo -e "\e[31m错误: GCC 编译 ${assembly_file} 超时\e[0m"
is_passed=0
elif [ $GCC_STATUS -ne 0 ]; then
echo -e "\e[31m错误: GCC 编译 ${assembly_file} 失败,退出码: ${GCC_STATUS}\e[0m"
is_passed=0
fi
elif ! ${EXECUTE_MODE}; then
echo " 跳过执行模式。仅生成汇编文件。"
# 如果只编译不执行,只要编译成功就算通过
if [ "$is_passed" -eq 1 ]; then
((PASSED_CASES++))
fi
echo ""
continue
fi
echo " 生成的汇编文件: ${assembly_file}"
# 只有当 EXECUTE_MODE 为 true 时才继续生成和执行可执行文件
if ${EXECUTE_MODE}; then
# 步骤 2: 使用 riscv64-linux-gnu-gcc 编译 .s 到可执行文件
echo " 使用 gcc 编译: ${GCC_RISCV64} \"${assembly_file}\" -o \"${executable_file}\" -L\"${LIB_DIR}\" -lsysy_riscv -static"
"${GCC_RISCV64}" "${assembly_file}" -o "${executable_file}" -L"${LIB_DIR}" -lsysy_riscv -static
if [ $? -ne 0 ]; then
echo -e "\e[31m错误: GCC 编译 ${assembly_file} 失败\e[0m"
continue
# 步骤 3, 4, 5: 只有当编译都成功时才执行
if [ "$is_passed" -eq 1 ]; then
echo " 正在执行 (超时 ${EXEC_TIMEOUT}s)..."
# 准备执行命令
exec_cmd="${QEMU_RISCV64} \"${executable_file}\""
if [ -f "${input_file}" ]; then
exec_cmd+=" < \"${input_file}\""
fi
echo " 生成的可执行文件: ${executable_file}"
exec_cmd+=" > \"${output_actual_file}\""
# 步骤 3, 4, 5: 执行编译后的文件并比较/报告结果
echo " 正在执行: ${QEMU_RISCV664} \"${executable_file}\""
# 执行并捕获返回码
eval "timeout ${EXEC_TIMEOUT} ${exec_cmd}"
ACTUAL_RETURN_CODE=$?
# 检查是否存在 .out 文件
if [ -f "${output_reference_file}" ]; then
# 尝试从 .out 文件中提取期望的返回码和期望的标准输出
# 获取 .out 文件的最后一行,去除空白字符
LAST_LINE_TRIMMED=$(tail -n 1 "${output_reference_file}" | tr -d '[:space:]')
# 检查最后一行是否为纯整数 (允许正负号)
if [[ "$LAST_LINE_TRIMMED" =~ ^[-+]?[0-9]+$ ]]; then
# 假设最后一行是期望的返回码
EXPECTED_RETURN_CODE="$LAST_LINE_TRIMMED"
# 创建一个只包含期望标准输出的临时文件 (所有行除了最后一行)
EXPECTED_STDOUT_FILE="${TMP_DIR}/${output_base_name}_sysyc_riscv64.expected_stdout"
# 使用 head -n -1 来获取除了最后一行之外的所有行。如果文件只有一行,则生成一个空文件。
head -n -1 "${output_reference_file}" > "${EXPECTED_STDOUT_FILE}"
echo " 检测到 .out 文件同时包含标准输出和期望的返回码。"
echo " 期望返回码: ${EXPECTED_RETURN_CODE}"
if [ -s "${EXPECTED_STDOUT_FILE}" ]; then # -s 检查文件是否非空
echo " 期望标准输出文件: ${EXPECTED_STDOUT_FILE}"
else
echo " 期望标准输出为空。"
fi
# 执行程序,捕获实际返回码和实际标准输出
if [ -f "${input_file}" ]; then
echo " 使用输入文件: ${input_file}"
"${QEMU_RISCV64}" "${executable_file}" < "${input_file}" > "${output_actual_file}"
else
"${QEMU_RISCV64}" "${executable_file}" > "${output_actual_file}"
fi
ACTUAL_RETURN_CODE=$? # 捕获执行状态
# 比较实际返回码与期望返回码
if [ "$ACTUAL_RETURN_CODE" -eq "$EXPECTED_RETURN_CODE" ]; then
echo -e "\e[32m 返回码测试成功: ${sy_file} 的返回码 (${ACTUAL_RETURN_CODE}) 与期望值 (${EXPECTED_RETURN_CODE}) 匹配\e[0m"
else
echo -e "\e[31m 返回码测试失败: ${sy_file} 的返回码不匹配。期望: ${EXPECTED_RETURN_CODE}, 实际: ${ACTUAL_RETURN_CODE}\e[0m"
fi
# 比较实际标准输出与期望标准输出,忽略文件末尾的换行符差异
# 使用 sed 命令去除文件末尾的所有换行符,再通过 diff 进行比较
if diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then
echo -e "\e[32m 标准输出测试成功: 输出与 ${sy_file} 的参考输出匹配 (忽略行尾换行符差异)\e[0m"
else
echo -e "\e[31m 标准输出测试失败: ${sy_file} 的输出不匹配\e[0m"
echo " 差异 (可能包含行尾换行符差异):"
diff "${output_actual_file}" "${EXPECTED_STDOUT_FILE}" # 显示原始差异以便调试
fi
else
# 最后一行不是纯整数,将整个 .out 文件视为纯标准输出
echo " 检测到 .out 文件为纯标准输出参考。正在与输出文件比较: ${output_reference_file}"
# 使用输入文件(如果存在)运行可执行文件,并将输出重定向到临时文件
if [ -f "${input_file}" ]; then
echo " 使用输入文件: ${input_file}"
"${QEMU_RISCV64}" "${executable_file}" < "${input_file}" > "${output_actual_file}"
else
"${QEMU_RISCV64}" "${executable_file}" > "${output_actual_file}"
fi
EXEC_STATUS=$? # 捕获执行状态
if [ $EXEC_STATUS -ne 0 ]; then
echo -e "\e[33m警告: 可执行文件 ${sy_file} 以非零状态 ${EXEC_STATUS} 退出 (纯输出比较模式)。请检查程序逻辑或其是否应返回此状态。\e[0m"
fi
# 比较实际输出与参考输出,忽略文件末尾的换行符差异
if diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${output_reference_file}") >/dev/null 2>&1; then
echo -e "\e[32m 成功: 输出与 ${sy_file} 的参考输出匹配 (忽略行尾换行符差异)\e[0m"
else
echo -e "\e[31m 失败: ${sy_file} 的输出不匹配\e[0m"
echo " 差异 (可能包含行尾换行符差异):"
diff "${output_actual_file}" "${output_reference_file}" # 显示原始差异以便调试
fi
fi
elif [ -f "${input_file}" ]; then
# 只有 .in 文件存在,使用输入运行并报告退出码(无参考输出)
echo " 使用输入文件: ${input_file}"
echo " 没有 .out 文件进行比较。正在运行并报告返回码。"
"${QEMU_RISCV64}" "${executable_file}" < "${input_file}"
EXEC_STATUS=$?
echo " ${sy_file} 的返回码: ${EXEC_STATUS}"
if [ "$ACTUAL_RETURN_CODE" -eq 124 ]; then
echo -e "\e[31m 执行超时: ${sy_file} 运行超过 ${EXEC_TIMEOUT} 秒\e[0m"
is_passed=0
else
# .in 和 .out 文件都不存在,只运行并报告退出码
echo " 未找到 .in 或 .out 文件。正在运行并报告返回码。"
"${QEMU_RISCV64}" "${executable_file}"
EXEC_STATUS=$?
echo " ${sy_file} 的返回码: ${EXEC_STATUS}"
fi
else
echo " 跳过执行模式。仅生成汇编文件。"
fi
echo "" # 为测试用例之间添加一个空行,以提高可读性
done
# 检查是否存在 .out 文件以进行比较
if [ -f "${output_reference_file}" ]; then
LAST_LINE_TRIMMED=$(tail -n 1 "${output_reference_file}" | tr -d '[:space:]')
if [[ "$LAST_LINE_TRIMMED" =~ ^[-+]?[0-9]+$ ]]; then
EXPECTED_RETURN_CODE="$LAST_LINE_TRIMMED"
EXPECTED_STDOUT_FILE="${TMP_DIR}/${output_base_name}_sysyc_riscv64.expected_stdout"
head -n -1 "${output_reference_file}" > "${EXPECTED_STDOUT_FILE}"
echo "脚本完成。"
# 比较返回码
if [ "$ACTUAL_RETURN_CODE" -eq "$EXPECTED_RETURN_CODE" ]; then
echo -e "\e[32m 返回码测试成功: (${ACTUAL_RETURN_CODE}) 与期望值 (${EXPECTED_RETURN_CODE}) 匹配\e[0m"
else
echo -e "\e[31m 返回码测试失败: 期望: ${EXPECTED_RETURN_CODE}, 实际: ${ACTUAL_RETURN_CODE}\e[0m"
is_passed=0
fi
# 比较标准输出
if diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${EXPECTED_STDOUT_FILE}") >/dev/null 2>&1; then
echo -e "\e[32m 标准输出测试成功\e[0m"
else
echo -e "\e[31m 标准输出测试失败\e[0m"
is_passed=0
echo -e " \e[36m---------- 期望输出 ----------\e[0m"
cat "${EXPECTED_STDOUT_FILE}"
echo -e " \e[36m---------- 实际输出 ----------\e[0m"
cat "${output_actual_file}"
echo -e " \e[36m------------------------------\e[0m"
fi
else
# 纯标准输出比较
if [ $ACTUAL_RETURN_CODE -ne 0 ]; then
echo -e "\e[33m警告: 程序以非零状态 ${ACTUAL_RETURN_CODE} 退出 (纯输出比较模式)。\e[0m"
fi
if diff -q <(sed ':a;N;$!ba;s/\n*$//' "${output_actual_file}") <(sed ':a;N;$!ba;s/\n*$//' "${output_reference_file}") >/dev/null 2>&1; then
echo -e "\e[32m 成功: 输出与参考输出匹配\e[0m"
else
echo -e "\e[31m 失败: 输出不匹配\e[0m"
is_passed=0
echo -e " \e[36m---------- 期望输出 ----------\e[0m"
cat "${output_reference_file}"
echo -e " \e[36m---------- 实际输出 ----------\e[0m"
cat "${output_actual_file}"
echo -e " \e[36m------------------------------\e[0m"
fi
fi
else
# 没有 .out 文件,只报告返回码
echo " 无参考输出文件。程序返回码: ${ACTUAL_RETURN_CODE}"
fi
fi
fi
# 更新通过用例计数
if [ "$is_passed" -eq 1 ]; then
((PASSED_CASES++))
fi
echo "" # 添加空行以提高可读性
done <<< "$sy_files"
# --- 新增功能: 打印最终总结 ---
echo "========================================"
echo "测试完成"
echo "测试通过率: [${PASSED_CASES}/${TOTAL_CASES}]"
echo "========================================"
if [ "$PASSED_CASES" -eq "$TOTAL_CASES" ]; then
exit 0
else
exit 1
fi

1
testdata/functional/00_main.out vendored Normal file
View File

@ -0,0 +1 @@
3

3
testdata/functional/00_main.sy vendored Normal file
View File

@ -0,0 +1,3 @@
int main(){
return 3;
}

View File

@ -1,2 +1 @@
10
0

8
testdata/functional/01_var_defn2.sy vendored Normal file
View File

@ -0,0 +1,8 @@
//test domain of global var define and local define
int a = 3;
int b = 5;
int main(){
int a = 5;
return a + b;
}

1
testdata/functional/02_var_defn3.out vendored Normal file
View File

@ -0,0 +1 @@
5

8
testdata/functional/02_var_defn3.sy vendored Normal file
View File

@ -0,0 +1,8 @@
//test local var define
int main(){
int a, b0, _c;
a = 1;
b0 = 2;
_c = 3;
return b0 + _c;
}

1
testdata/functional/03_arr_defn2.out vendored Normal file
View File

@ -0,0 +1 @@
0

4
testdata/functional/03_arr_defn2.sy vendored Normal file
View File

@ -0,0 +1,4 @@
int a[10][10];
int main(){
return 0;
}

1
testdata/functional/04_arr_defn3.out vendored Normal file
View File

@ -0,0 +1 @@
14

9
testdata/functional/04_arr_defn3.sy vendored Normal file
View File

@ -0,0 +1,9 @@
//test array define
int main(){
int a[4][2] = {};
int b[4][2] = {1, 2, 3, 4, 5, 6, 7, 8};
int c[4][2] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
int d[4][2] = {1, 2, {3}, {5}, 7 , 8};
int e[4][2] = {{d[2][1], c[2][1]}, {3, 4}, {5, 6}, {7, 8}};
return e[3][1] + e[0][0] + e[0][1] + a[2][0];
}

1
testdata/functional/05_arr_defn4.out vendored Normal file
View File

@ -0,0 +1 @@
21

9
testdata/functional/05_arr_defn4.sy vendored Normal file
View File

@ -0,0 +1,9 @@
int main(){
const int a[4][2] = {{1, 2}, {3, 4}, {}, 7};
int b[4][2] = {};
int c[4][2] = {1, 2, 3, 4, 5, 6, 7, 8};
int d[3 + 1][2] = {1, 2, {3}, {5}, a[3][0], 8};
int e[4][2][1] = {{d[2][1], {c[2][1]}}, {3, 4}, {5, 6}, {7, 8}};
return e[3][1][0] + e[0][0][0] + e[0][1][0] + d[3][0];
}

View File

@ -0,0 +1 @@
5

View File

@ -0,0 +1,6 @@
//test const gloal var define
const int a = 10, b = 5;
int main(){
return b;
}

View File

@ -0,0 +1 @@
5

View File

@ -0,0 +1,5 @@
//test const local var define
int main(){
const int a = 10, b = 5;
return b;
}

View File

@ -0,0 +1 @@
4

View File

@ -0,0 +1,5 @@
const int a[5]={0,1,2,3,4};
int main(){
return a[4];
}

1
testdata/functional/09_func_defn.out vendored Normal file
View File

@ -0,0 +1 @@
9

11
testdata/functional/09_func_defn.sy vendored Normal file
View File

@ -0,0 +1,11 @@
int a;
int func(int p){
p = p - 1;
return p;
}
int main(){
int b;
a = 10;
b = func(a);
return b;
}

View File

@ -0,0 +1 @@
4

View File

@ -0,0 +1,8 @@
int defn(){
return 4;
}
int main(){
int a=defn();
return a;
}

1
testdata/functional/11_add2.out vendored Normal file
View File

@ -0,0 +1 @@
9

7
testdata/functional/11_add2.sy vendored Normal file
View File

@ -0,0 +1,7 @@
//test add
int main(){
int a, b;
a = 10;
b = -1;
return a + b;
}

1
testdata/functional/12_addc.out vendored Normal file
View File

@ -0,0 +1 @@
15

5
testdata/functional/12_addc.sy vendored Normal file
View File

@ -0,0 +1,5 @@
//test addc
const int a = 10;
int main(){
return a + 5;
}

1
testdata/functional/13_sub2.out vendored Normal file
View File

@ -0,0 +1 @@
248

7
testdata/functional/13_sub2.sy vendored Normal file
View File

@ -0,0 +1,7 @@
//test sub
const int a = 10;
int main(){
int b;
b = 2;
return b - a;
}

1
testdata/functional/14_subc.out vendored Normal file
View File

@ -0,0 +1 @@
8

6
testdata/functional/14_subc.sy vendored Normal file
View File

@ -0,0 +1,6 @@
//test subc
int main(){
int a;
a = 10;
return a - 2;
}

1
testdata/functional/15_mul.out vendored Normal file
View File

@ -0,0 +1 @@
50

7
testdata/functional/15_mul.sy vendored Normal file
View File

@ -0,0 +1,7 @@
//test mul
int main(){
int a, b;
a = 10;
b = 5;
return a * b;
}

1
testdata/functional/16_mulc.out vendored Normal file
View File

@ -0,0 +1 @@
25

5
testdata/functional/16_mulc.sy vendored Normal file
View File

@ -0,0 +1,5 @@
//test mulc
const int a = 5;
int main(){
return a * 5;
}

1
testdata/functional/17_div.out vendored Normal file
View File

@ -0,0 +1 @@
2

7
testdata/functional/17_div.sy vendored Normal file
View File

@ -0,0 +1,7 @@
//test div
int main(){
int a, b;
a = 10;
b = 5;
return a / b;
}

1
testdata/functional/18_divc.out vendored Normal file
View File

@ -0,0 +1 @@
2

5
testdata/functional/18_divc.sy vendored Normal file
View File

@ -0,0 +1,5 @@
//test divc
const int a = 10;
int main(){
return a / 5;
}

1
testdata/functional/19_mod.out vendored Normal file
View File

@ -0,0 +1 @@
3

6
testdata/functional/19_mod.sy vendored Normal file
View File

@ -0,0 +1,6 @@
//test mod
int main(){
int a;
a = 10;
return a / 3;
}

1
testdata/functional/20_rem.out vendored Normal file
View File

@ -0,0 +1 @@
1

6
testdata/functional/20_rem.sy vendored Normal file
View File

@ -0,0 +1,6 @@
//test rem
int main(){
int a;
a = 10;
return a % 3;
}

0
testdata/functional/21_if_test2.out vendored Executable file → Normal file
View File

0
testdata/functional/21_if_test2.sy vendored Executable file → Normal file
View File

1
testdata/functional/22_if_test3.out vendored Normal file
View File

@ -0,0 +1 @@
25

18
testdata/functional/22_if_test3.sy vendored Normal file
View File

@ -0,0 +1,18 @@
// test if-if-else
int ififElse() {
int a;
a = 5;
int b;
b = 10;
if(a == 5)
if (b == 10)
a = 25;
else
a = a + 15;
return (a);
}
int main(){
return (ififElse());
}

1
testdata/functional/23_if_test4.out vendored Normal file
View File

@ -0,0 +1 @@
25

18
testdata/functional/23_if_test4.sy vendored Normal file
View File

@ -0,0 +1,18 @@
// test if-{if-else}
int if_ifElse_() {
int a;
a = 5;
int b;
b = 10;
if(a == 5){
if (b == 10)
a = 25;
else
a = a + 15;
}
return (a);
}
int main(){
return (if_ifElse_());
}

1
testdata/functional/24_if_test5.out vendored Normal file
View File

@ -0,0 +1 @@
25

18
testdata/functional/24_if_test5.sy vendored Normal file
View File

@ -0,0 +1,18 @@
// test if-{if}-else
int if_if_Else() {
int a;
a = 5;
int b;
b = 10;
if(a == 5){
if (b == 10)
a = 25;
}
else
a = a + 15;
return (a);
}
int main(){
return (if_if_Else());
}

2
testdata/functional/25_while_if.out vendored Normal file
View File

@ -0,0 +1,2 @@
88
0

31
testdata/functional/25_while_if.sy vendored Normal file
View File

@ -0,0 +1,31 @@
int get_one(int a) {
return 1;
}
int deepWhileBr(int a, int b) {
int c;
c = a + b;
while (c < 75) {
int d;
d = 42;
if (c < 100) {
c = c + d;
if (c > 99) {
int e;
e = d * 2;
if (get_one(0) == 1) {
c = e * 2;
}
}
}
}
return (c);
}
int main() {
int p;
p = 2;
p = deepWhileBr(p, p);
putint(p);
return 0;
}

0
testdata/functional/26_while_test1.out vendored Executable file → Normal file
View File

0
testdata/functional/26_while_test1.sy vendored Executable file → Normal file
View File

View File

@ -0,0 +1 @@
54

31
testdata/functional/27_while_test2.sy vendored Normal file
View File

@ -0,0 +1,31 @@
int FourWhile() {
int a;
a = 5;
int b;
int c;
b = 6;
c = 7;
int d;
d = 10;
while (a < 20) {
a = a + 3;
while(b < 10){
b = b + 1;
while(c == 7){
c = c - 1;
while(d < 20){
d = d + 3;
}
d = d - 1;
}
c = c + 1;
}
b = b - 2;
}
return (a + (b + d) + c);
}
int main() {
return FourWhile();
}

View File

@ -0,0 +1 @@
23

55
testdata/functional/28_while_test3.sy vendored Normal file
View File

@ -0,0 +1,55 @@
int g;
int h;
int f;
int e;
int EightWhile() {
int a;
a = 5;
int b;
int c;
b = 6;
c = 7;
int d;
d = 10;
while (a < 20) {
a = a + 3;
while(b < 10){
b = b + 1;
while(c == 7){
c = c - 1;
while(d < 20){
d = d + 3;
while(e > 1){
e = e-1;
while(f > 2){
f = f -2;
while(g < 3){
g = g +10;
while(h < 10){
h = h + 8;
}
h = h-1;
}
g = g- 8;
}
f = f + 1;
}
e = e + 1;
}
d = d - 1;
}
c = c + 1;
}
b = b - 2;
}
return (a + (b + d) + c)-(e + d - g + h);
}
int main() {
g = 1;
h = 2;
e = 4;
f = 6;
return EightWhile();
}

1
testdata/functional/29_break.out vendored Normal file
View File

@ -0,0 +1 @@
201

15
testdata/functional/29_break.sy vendored Normal file
View File

@ -0,0 +1,15 @@
//test break
int main(){
int i;
i = 0;
int sum;
sum = 0;
while(i < 100){
if(i == 50){
break;
}
sum = sum + i;
i = i + 1;
}
return sum;
}

1
testdata/functional/30_continue.out vendored Normal file
View File

@ -0,0 +1 @@
36

16
testdata/functional/30_continue.sy vendored Normal file
View File

@ -0,0 +1,16 @@
//test continue
int main(){
int i;
i = 0;
int sum;
sum = 0;
while(i < 100){
if(i == 50){
i = i + 1;
continue;
}
sum = sum + i;
i = i + 1;
}
return sum;
}

View File

@ -0,0 +1 @@
198

View File

@ -0,0 +1,25 @@
// test while-if
int whileIf() {
int a;
a = 0;
int b;
b = 0;
while (a < 100) {
if (a == 5) {
b = 25;
}
else if (a == 10) {
b = 42;
}
else {
b = a * 2;
}
a = a + 1;
}
return (b);
}
int main(){
return (whileIf());
}

View File

@ -0,0 +1 @@
96

View File

@ -0,0 +1,23 @@
int ifWhile() {
int a;
a = 0;
int b;
b = 3;
if (a == 5) {
while(b == 2){
b = b + 2;
}
b = b + 25;
}
else
while (a < 5) {
b = b * 2;
a = a + 1;
}
return (b);
}
int main(){
return (ifWhile());
}

View File

@ -0,0 +1 @@
88

View File

@ -0,0 +1,25 @@
int deepWhileBr(int a, int b) {
int c;
c = a + b;
while (c < 75) {
int d;
d = 42;
if (c < 100) {
c = c + d;
if (c > 99) {
int e;
e = d * 2;
if (1 == 1) {
c = e * 2;
}
}
}
}
return (c);
}
int main() {
int p;
p = 2;
return deepWhileBr(p, p);
}

View File

@ -0,0 +1 @@
51

11
testdata/functional/34_arr_expr_len.sy vendored Normal file
View File

@ -0,0 +1,11 @@
//const int N = -1;
int arr[-1 + 2 * 4 - 99 / 99] = {1, 2, 33, 4, 5, 6};
int main() {
int i = 0, sum = 0;
while (i < 6) {
sum = sum + arr[i];
i = i + 1;
}
return sum;
}

0
testdata/functional/35_op_priority1.out vendored Executable file → Normal file
View File

0
testdata/functional/35_op_priority1.sy vendored Executable file → Normal file
View File

View File

@ -0,0 +1 @@
24

View File

@ -0,0 +1,9 @@
//test the priority of add and mul
int main(){
int a, b, c, d;
a = 10;
b = 4;
c = 2;
d = 2;
return (c + a) * (b - d);
}

View File

@ -0,0 +1 @@
40

View File

@ -0,0 +1,7 @@
//test the priority of unary operator and binary operator
int main(){
int a, b;
a = 10;
b = 30;
return a - -5 + b + -5;
}

View File

@ -0,0 +1 @@
0 1 1 1 1

View File

@ -0,0 +1 @@
1

19
testdata/functional/38_op_priority4.sy vendored Normal file
View File

@ -0,0 +1,19 @@
int a;
int b;
int c;
int d;
int e;
int main()
{
a=getint();
b=getint();
c=getint();
d=getint();
e=getint();
int flag=0;
if(a-b*c!=d-a/c||a*b/c==e+d||a+b+c==d+e)
{
flag=1;
}
return flag;
}

View File

@ -0,0 +1,2 @@
1
1

15
testdata/functional/39_op_priority5.sy vendored Normal file
View File

@ -0,0 +1,15 @@
int a = 1;
int b = 0;
int c = 1;
int d = 2;
int e = 4;
int main()
{
int flag=0;
if(a * b / c == e + d && a * (a + b) + c <= d + e || a - (b * c) == d - a / c)
{
flag=1;
}
putint(flag);
return flag;
}

0
testdata/functional/40_unary_op.out vendored Executable file → Normal file
View File

0
testdata/functional/40_unary_op.sy vendored Executable file → Normal file
View File

2
testdata/functional/41_unary_op2.out vendored Normal file
View File

@ -0,0 +1,2 @@
4
0

14
testdata/functional/41_unary_op2.sy vendored Normal file
View File

@ -0,0 +1,14 @@
int main() {
int a, b;
a = 070;
b = 0x4;
a = a - - 4 + + b;
if (+-!!!a) {
a = - - -1;
}
else {
a = 0 + + b;
}
putint(a);
return 0;
}

1
testdata/functional/42_empty_stmt.out vendored Normal file
View File

@ -0,0 +1 @@
21

5
testdata/functional/42_empty_stmt.sy vendored Normal file
View File

@ -0,0 +1,5 @@
int main() {
int a = 10;
;
return a * 2 + 1;
}

1
testdata/functional/43_logi_assign.in vendored Normal file
View File

@ -0,0 +1 @@
4 4

View File

@ -0,0 +1 @@
1

15
testdata/functional/43_logi_assign.sy vendored Normal file
View File

@ -0,0 +1,15 @@
int a;
int b;
int main()
{
a=getint();
b=getint();
int c;
if (a==b&&a!=3) {
c = 1;
}
else {
c = 0;
}
return c;
}

0
testdata/functional/44_stmt_expr.out vendored Executable file → Normal file
View File

0
testdata/functional/44_stmt_expr.sy vendored Executable file → Normal file
View File

1
testdata/functional/45_comment1.out vendored Normal file
View File

@ -0,0 +1 @@
5

12
testdata/functional/45_comment1.sy vendored Normal file
View File

@ -0,0 +1,12 @@
//test comment
int main(){
int a;
a = 5;
//int b = 4;
//a = b + a;
/*/*
b = 1;
// b = 2
*/
return a;
}

1
testdata/functional/46_hex_defn.out vendored Normal file
View File

@ -0,0 +1 @@
15

6
testdata/functional/46_hex_defn.sy vendored Normal file
View File

@ -0,0 +1,6 @@
// test hexadecimal define
int main(){
int a;
a = 0xf;
return a;
}

View File

@ -0,0 +1 @@
88

Some files were not shown because too many files have changed in this diff Show More