#!/usr/bin/env python3 """ AVM Dataset Panel — Cross-Language Dispatcher Runs each language's existing AVM test harness and reports pass/fail. Uses language-specific test runners. """ import subprocess import sys import os import re from typing import Dict, Optional, Tuple, Callable ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) # ── Helper ────────────────────────────────────────────────────────── def _run(cmd: list, cwd: str = ROOT, timeout: int = 60) -> dict: try: result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True, timeout=timeout) return {"rc": result.returncode, "out": result.stdout, "err": result.stderr} except FileNotFoundError: return {"rc": -1, "out": "", "err": "not_found"} except subprocess.TimeoutExpired: return {"rc": -1, "out": "", "err": "timeout"} except Exception as e: return {"rc": -1, "out": "", "err": str(e)} # ── Per-language test runners ───────────────────────────────────── # Each returns (passes: int, fails: int, note: str) def run_python() -> Tuple[int, int, str]: test = os.path.join(ROOT, "tests", "test_avm_python.py") if not os.path.exists(test): return 0, 0, "test file missing" r = _run([sys.executable, test]) # Count "✅ ..." lines = passes passes = r["out"].count("✅") errors = r["out"].count("❌") return passes, errors, f"rc={r['rc']}" def run_julia() -> Tuple[int, int, str]: test = os.path.join(ROOT, "julia", "AVMIsa", "test_avm.jl") if not os.path.exists(test): return 0, 0, "test file missing" r = _run(["julia", test]) # Julia TestSummary format: "| Pass Total Time" / "| 12 12 0.8s" # Look for the numeric line after "Test Summary:" for line in r["out"].splitlines(): if "|" in line: parts = [p.strip() for p in line.split("|")] for part in parts: nums = part.strip().split() if len(nums) >= 2 and nums[0].isdigit() and nums[1].isdigit(): return int(nums[0]), int(nums[1]) - int(nums[0]), "" return 0, 0, f"rc={r['rc']}" def run_r() -> Tuple[int, int, str]: test = os.path.join(ROOT, "r", "AVMIsa", "test_avm.r") if not os.path.exists(test): return 0, 0, "test file missing" r = _run(["Rscript", test]) passes = r["out"].count("PASS:") errors = r["out"].count("FAIL:") return passes, errors, f"rc={r['rc']}" def run_rust() -> Tuple[int, int, str]: r = _run(["cargo", "test"], cwd=os.path.join(ROOT, "rust"), timeout=120) # Parse "test result: X passed; Y failed" m = re.search(r'test result:\s+(\w+)\.\s+(\d+)\s+passed;\s+(\d+)\s+failed', r["out"] + r["err"]) if m: return int(m.group(2)), int(m.group(3)), "" # Fallback: count "ok" + "FAILED" p = (r["out"] + r["err"]).count("ok") f = (r["out"] + r["err"]).count("FAILED") return p, f, f"rc={r['rc']}" def _count_pf(out: str) -> Tuple[int, int]: p = out.count("PASS:") + out.count("✅") + out.count("✓") f = out.count("FAIL:") + out.count("❌") + out.count("✗") return p, f def run_c() -> Tuple[int, int, str]: r = _run(["sh", "-c", "cd /home/allaun/SilverSight/c && gcc -o /tmp/avm_c_test test_avm.c -lm && /tmp/avm_c_test"], timeout=30) p, f = _count_pf(r["out"]) return p, f, f"rc={r['rc']}" def run_cpp() -> Tuple[int, int, str]: r = _run(["sh", "-c", "cd /home/allaun/SilverSight/cpp && g++ -o /tmp/avm_cpp_test test_avm.cpp && /tmp/avm_cpp_test"], timeout=30) p, f = _count_pf(r["out"]) return p, f, f"rc={r['rc']}" def run_go() -> Tuple[int, int, str]: r = _run(["go", "test", "-v"], cwd=os.path.join(ROOT, "go"), timeout=60) p, f = _count_pf(r["out"] + r["err"]) return p, f, f"rc={r['rc']}" def run_fortran() -> Tuple[int, int, str]: r = _run(["which", "gfortran"]) if r["rc"] != 0: return 0, 0, "gfortran not found" r = _run(["sh", "-c", "cd /home/allaun/SilverSight/fortran && gfortran -c avm.f90 -o /tmp/avm_f90.o && gfortran -o /tmp/avm_f90_test test_avm.f90 /tmp/avm_f90.o && /tmp/avm_f90_test"], timeout=30) p, f = _count_pf(r["out"]) return p, f, f"rc={r['rc']}" def run_scala() -> Tuple[int, int, str]: r = _run(["which", "scala-cli"]) if r["rc"] != 0: return 0, 0, "scala-cli not found" r = _run(["scala-cli", "--power", "run", "--server=false", os.path.join(ROOT, "scala", "avm.scala"), os.path.join(ROOT, "scala", "TestAVM.scala")], timeout=60) p, f = _count_pf(r["out"]) return p, f, f"rc={r['rc']}" def run_octave() -> Tuple[int, int, str]: r = _run(["octave", "--no-gui", "-q", "test_avm.m"], cwd=os.path.join(ROOT, "octave"), timeout=30) p, f = _count_pf(r["out"]) return p, f, f"rc={r['rc']}" # ── Language registry ────────────────────────────────────────────── LANGUAGES: Dict[str, Callable] = { "Python": run_python, "Julia": run_julia, "R": run_r, "Rust": run_rust, "C": run_c, "C++": run_cpp, "Go": run_go, "Fortran": run_fortran, "Scala": run_scala, "Octave": run_octave, } # ── Main ─────────────────────────────────────────────────────────── def build_panel(): print("=" * 90) print("AVM Dataset Panel — Cross-Language Dispatcher") print("=" * 90) print() print("Running all language test harnesses...") print() results = {} for lang_name, runner in LANGUAGES.items(): print(f" [{lang_name:10s}] ", end="", flush=True) passes, fails, note = runner() results[lang_name] = (passes, fails, note) if fails == 0 and passes > 0: print(f"✅ {passes} passed") elif fails > 0: print(f"❌ {passes} passed, {fails} failed ({note})") else: print(f"⚪ {passes} passed, {fails} failed ({note})") # Summary print() print("-" * 90) print(f"{'Language':12s} {'Status':8s} {'Passed':8s} {'Failed':8s} Notes") print("-" * 90) total_p, total_f = 0, 0 all_pass = True for lang_name, (passes, fails, note) in results.items(): total_p += passes total_f += fails if passes > 0 and fails == 0: status = "✅" elif fails > 0: status = "❌" all_pass = False elif passes == 0: status = "⚪" all_pass = False else: status = "?" print(f"{lang_name:12s} {status:8s} {passes:8d} {fails:8d} {note}") print("-" * 90) verdict = "ALL CONSISTENT" if all_pass else "NOT all consistent (missing/partial coverage)" print(f"\nTotal: {total_p} passed, {total_f} failed across {len(LANGUAGES)} languages") print(f"Verdict: {verdict}") print() print("=" * 90) if __name__ == "__main__": build_panel()