#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" if [[ $# -lt 1 || $# -gt 5 ]]; then echo "usage: $0 input.sy [output_dir] [--run] [--timing-out file]" >&2 exit 1 fi input=$1 out_dir="$REPO_ROOT/test/test_result/asm" run_exec=false input_dir=$(dirname "$input") timing_out="" _compile_ns=0 _run_ns=0 now_ns() { date +%s%N; } shift while [[ $# -gt 0 ]]; do case "$1" in --run) run_exec=true ;; --timing-out) timing_out="$2" shift ;; *) out_dir="$1" ;; esac shift done if [[ ! -f "$input" ]]; then echo "input file not found: $input" >&2 exit 1 fi compiler="" for candidate in "$REPO_ROOT/build_lab3/bin/compiler" "$REPO_ROOT/build_lab2/bin/compiler" "$REPO_ROOT/build/bin/compiler"; do if [[ -x "$candidate" ]]; then compiler="$candidate" break fi done if [[ -z "$compiler" ]]; then echo "compiler not found; try: cmake -S . -B build_lab3 && cmake --build build_lab3 -j" >&2 exit 1 fi if ! command -v aarch64-linux-gnu-gcc >/dev/null 2>&1; then echo "aarch64-linux-gnu-gcc not found" >&2 exit 1 fi mkdir -p "$out_dir" base=$(basename "$input") stem=${base%.sy} asm_file="$out_dir/$stem.s" exe="$out_dir/$stem" stdin_file="$input_dir/$stem.in" expected_file="$input_dir/$stem.out" _compile_start_ns=$(now_ns) "$compiler" --emit-asm "$input" > "$asm_file" echo "asm generated: $asm_file" aarch64-linux-gnu-gcc "$asm_file" "$REPO_ROOT/sylib/sylib.c" -O2 -o "$exe" echo "executable generated: $exe" _compile_ns=$(($(now_ns) - _compile_start_ns)) if [[ "$run_exec" == true ]]; then if ! command -v qemu-aarch64 >/dev/null 2>&1; then echo "qemu-aarch64 not found" >&2 exit 1 fi stdout_file="$out_dir/$stem.stdout" actual_file="$out_dir/$stem.actual.out" timeout_sec="${RUN_TIMEOUT_SEC:-60}" if [[ "$input" == *"/performance/"* || "$input" == *"/h_performance/"* ]]; then timeout_sec="${PERF_TIMEOUT_SEC:-300}" fi set +e _run_start_ns=$(now_ns) if command -v timeout >/dev/null 2>&1; then if [[ -f "$stdin_file" ]]; then timeout "$timeout_sec" qemu-aarch64 -L /usr/aarch64-linux-gnu "$exe" < "$stdin_file" > "$stdout_file" else timeout "$timeout_sec" qemu-aarch64 -L /usr/aarch64-linux-gnu "$exe" > "$stdout_file" fi else if [[ -f "$stdin_file" ]]; then qemu-aarch64 -L /usr/aarch64-linux-gnu "$exe" < "$stdin_file" > "$stdout_file" else qemu-aarch64 -L /usr/aarch64-linux-gnu "$exe" > "$stdout_file" fi fi status=$? _run_ns=$(($(now_ns) - _run_start_ns)) set -e if [[ $status -eq 124 ]]; then echo "timeout after ${timeout_sec}s: $exe" >&2 fi cat "$stdout_file" if [[ -s "$stdout_file" ]] && (( $(tail -c 1 "$stdout_file" | wc -l) == 0 )); then printf '\n' fi echo "exit code: $status" { cat "$stdout_file" if [[ -s "$stdout_file" ]] && (( $(tail -c 1 "$stdout_file" | wc -l) == 0 )); then printf '\n' fi printf '%s\n' "$status" } > "$actual_file" if [[ -f "$expected_file" ]]; then if diff -u <(awk '{ sub(/\r$/, ""); print }' "$expected_file") <(awk '{ sub(/\r$/, ""); print }' "$actual_file"); then echo "matched: $expected_file" else echo "mismatch: $expected_file" >&2 echo "actual saved to: $actual_file" >&2 exit 1 fi else echo "expected output not found, skipped diff: $expected_file" fi fi if [[ -n "$timing_out" ]]; then printf 'compile_ns=%s\nrun_ns=%s\n' "$_compile_ns" "$_run_ns" > "$timing_out" fi