<commit_before>-- | L0 Compiler Driver
module Main (main) where

import Control.Applicative
import Control.Monad
import Control.Monad.Identity (Identity)
import System.Environment (getArgs)

import L0.AbSyn
import L0.Parser (parseL0)
import L0.TypeChecker
import L0.Renamer
import L0.Interpreter
-- import L0.CCodeGen

-- To parse and prettyprint an input program located at ../DATA/filename.l0, run
--  
--  $ l0c -p ../DATA/filename.l0
-- To interpret an input program located at ../DATA/filename.l0, run
--  
--  $ l0c -I ../DATA/filename.l0
-- 
--  To compile the same program with optimizations enabled, run
-- 
--  $ l0c -o ../DATA/filename.l0
-- 
--  To compile the same program without optimizations enabled, run
-- 
--  $ l0c -c ../DATA/filename.l0
-- 
--  or simply,
-- 
--  $ l0c ../DATA/filename.l0
-- 
-- Little of the above is implemented.  Your mileage will vary.
--

main :: IO ()
main = do args <- getArgs
          case args of
            ["-p", file] -> prettyprint file
            ["-t", file] -> typecheck (const $ return ()) file
            ["-tp", file] -> typecheck (putStrLn . prettyPrint) file
            ["-r", file] -> rename file
            ["-i", file] -> interpret file
--            ["-c", file] -> compile file
            _ -> error "Usage: <-p|-t|-tp|-r|-i|-c> <file>"

prettyprint :: FilePath -> IO ()
prettyprint file = putStrLn =<< prettyPrint <$> parse file

typecheck :: (Prog Identity -> IO ()) -> FilePath -> IO ()
typecheck next file = do
  prog <- parse file
  case checkProg prog of
    Left e -> error $ show e
    Right prog'  ->
      case checkProg prog' of
        Left e  -> error $ "Error during second type checking phase. This implies a bug in the type checker.\n" ++ show e
        Right _ -> next prog'

rename :: FilePath -> IO ()
rename file = do prog <- renameProg <$> parse file
                 putStrLn $ prettyPrint prog
                 case checkProg prog of
                   Left e -> error $ "Type error after renaming:\n" ++ show e
                   _      -> return ()

interpret :: FilePath -> IO ()
interpret file = do
  prog <- parse file
  case checkProg prog of
    Left err    -> error $ "Typechecking error:\n" ++ show err
    Right prog' -> do
      res <- runProgIO prog'
      case res of Left err -> error $ "Interpreter error:\n" ++ show err
                  Right v  -> putStrLn $ ppValue v -- ++ (prettyPrint prog')<commit_msg>option for testing copy propagation<commit_after>-- | L0 Compiler Driver
module Main (main) where

import Control.Applicative
import Control.Monad
import Control.Monad.Identity (Identity)
import System.Environment (getArgs)

import L0.AbSyn
import L0.Parser (parseL0)
import L0.TypeChecker
import L0.Renamer
import L0.Interpreter
import L0.EnablingOpt

import Debug.Trace

-- import L0.CCodeGen

-- To parse and prettyprint an input program located at ../DATA/filename.l0, run
--  
--  $ l0c -p ../DATA/filename.l0
-- To interpret an input program located at ../DATA/filename.l0, run
--  
--  $ l0c -I ../DATA/filename.l0
-- 
--  To compile the same program with optimizations enabled, run
-- 
--  $ l0c -o ../DATA/filename.l0
-- 
--  To compile the same program without optimizations enabled, run
-- 
--  $ l0c -c ../DATA/filename.l0
-- 
--  or simply,
-- 
--  $ l0c ../DATA/filename.l0
-- 
-- Little of the above is implemented.  Your mileage will vary.
--

main :: IO ()
main = do args <- getArgs
          case args of
            ["-p", file] -> prettyprint file
            ["-t", file] -> typecheck (const $ return ()) file
            ["-tp", file] -> typecheck (putStrLn . prettyPrint) file
            ["-r", file] -> rename file
            ["-i", file] -> interpret file
            ["-cos", file] -> testCosmin file
--            ["-c", file] -> compile file
            _ -> error "Usage: <-p|-t|-tp|-r|-i|-c> <file>"

prettyprint :: FilePath -> IO ()
prettyprint file = putStrLn =<< prettyPrint <$> parse file

typecheck :: (Prog Identity -> IO ()) -> FilePath -> IO ()
typecheck next file = do
  prog <- parse file
  case checkProg prog of
    Left e -> error $ show e
    Right prog'  ->
      case checkProg prog' of
        Left e  -> error $ "Error during second type checking phase. This implies a bug in the type checker.\n" ++ show e
        Right _ -> next prog'

rename :: FilePath -> IO ()
rename file = do prog <- renameProg <$> parse file
                 putStrLn $ prettyPrint prog
                 case checkProg prog of
                   Left e -> error $ "Type error after renaming:\n" ++ show e
                   _      -> return ()

interpret :: FilePath -> IO ()
interpret file = do
  prog <- parse file
  case checkProg prog of
    Left err    -> error $ "Typechecking error:\n" ++ show err
    Right prog' -> do
      res <- runProgIO prog'
      case res of Left err -> error $ "Interpreter error:\n" ++ show err
                  Right v  -> putStrLn $ ppValue v -- ++ (prettyPrint prog')


testCosmin :: FilePath -> IO ()
testCosmin file = do
  prog <- parse file
  case checkProg prog of
    Left err    -> error $ "Typechecking error:\n" ++ show err
    Right prog' -> 
      case enablingOpts prog' of
        Left  err -> error $ "Enabling Optimization Error:\n" ++ show err
        Right prog2 -> do
          _   <- trace ("Opt Program: "++prettyPrint prog2++"\nResult:") (putStrLn "")
          res <- runProgIO prog2
          case res of Left err -> error $ "Interpreter error:\n" ++ show err
                      Right v  -> putStrLn $ ppValue v -- ++ (prettyPrint prog')

{'fraction_non_alphanumeric': 0.13183047790802524, 'fraction_numerical': 0.00793507664562669, 'mean_word_length': 2.064088397790055, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5745693', 'n_tokens_mistral': 1777, 'n_tokens_neox': 1691, 'n_words': 604}