From 598e5faba931834e72e0b4cc32a65c2f5822eec5 Mon Sep 17 00:00:00 2001
From: Boyan <boyan@confest.im>
Date: Sun, 17 Nov 2024 18:03:40 +0100
Subject: [PATCH] Added dependency check + haskell support

---
 ucompile | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/ucompile b/ucompile
index 970f174..bf73293 100755
--- a/ucompile
+++ b/ucompile
@@ -3,6 +3,17 @@ import argparse
 import os
 from glob import glob
 import subprocess
+from colorama import Fore, Style
+
+
+def check_dependencies() -> None:
+    # Necessary commands list
+    commands = ["astyle", "gcc", "ghc", "java", "javac", "mvn", "python3"]
+    
+    for command in commands:
+        if os.system(f"which {command} > /dev/null") != 0:
+            print(f"{Fore.RED}Error: {command} not found{Style.RESET_ALL}")
+    return
 
 def run_input_cases(program, verbose, output=False, tests_dir="."):
     input_files = glob(os.path.join(tests_dir, "*.in"))
@@ -46,12 +57,13 @@ def run_input_cases(program, verbose, output=False, tests_dir="."):
                     print("✅")
                 else:
                     print("❌")
-                    print("Expected output:")
-                    print(expected_output.strip())
-                    print("Program output:")
+                    # green expected output and red program output
+                    print(f"{Fore.GREEN}Expected output:{Style.RESET_ALL}")
+                    print(expected_output)
+                    print(f"{Fore.RED}Program output:{Style.RESET_ALL}")
                     print(program_output.strip())
             else:
-                print("Expected output file not found; cannot compare outputs.")
+                print(f"{Fore.YELLOW}Expected output file not found; cannot compare outputs.{Style.RESET_ALL}")
                 if not verbose:
                     print("Program output:")
                     print(program_output.strip())
@@ -75,6 +87,11 @@ def java_compile(file_name, maven=False, verbose=False, tests_dir="."):
     run_input_cases("java " + file_name[:file_name.rfind(".")], verbose, tests_dir=tests_dir)
     return
 
+def haskell_compile(file_name, verbose=False, tests_dir="."):
+    os.system("ghc -O2 " + file_name + " -o program")
+    run_input_cases("./program", verbose, tests_dir=tests_dir)
+    return
+
 def c_compile(file_name, verbose=False, output=False, tests_dir="."):
     # Style the code in Meijster's way
     os.system("astyle -A2s2cxgk3W3xbj " + file_name)
@@ -83,7 +100,7 @@ def c_compile(file_name, verbose=False, output=False, tests_dir="."):
     return
 
 def main():
-    SUPPORTED_LANGS = [".c", ".py", ".java"]
+    SUPPORTED_LANGS = [".c", ".py", ".java", ".hs"]
     parser = argparse.ArgumentParser(
         prog='UCompiler',
         description='Compiles based on language',
@@ -110,8 +127,10 @@ def main():
         python_compile(file_name, args.verbose, tests_dir=tests_dir)
     elif file_ext == ".java":
         java_compile(file_name, args.alternative, args.verbose, tests_dir=tests_dir)
-
+    elif file_ext == ".hs":
+        haskell_compile(file_name, args.verbose, tests_dir=tests_dir)
     return
 
 if __name__ == "__main__":
+    check_dependencies()
     main()