module Main where

import IO
import System

import Pappy
import ReadGrammar
import ReduceGrammar
import SimplifyGrammar
import MemoAnalysis
import WriteParser
import RawFiles
import Options

parseImports gram _ [] = return gram
parseImports gram ds (x:xs) | x `elem` ds = parseImports gram ds xs
parseImports gram ds (x:xs) = do
    ngram <- pappyParseFile x
    let pgram = gram { grammarNonterminals = grammarNonterminals gram ++ grammarNonterminals ngram }
    parseImports pgram (x:ds) (xs ++ grammarImports ngram)


processFile flags inname outname = do
    gram@Grammar { grammarImports = is }  <- pappyParseFile inname
    gram@Grammar { grammarNonterminals = g } <- parseImports gram [inname] is
    putStrLn ("Original grammar: " ++ show (length g) ++ " size " ++ show (sizeofNonterminals g))
    --putStrLn (showNonterminals g)
    let gram'@Grammar { grammarNonterminals = g' } = reduceGrammar gram
    putStrLn ("Reduced grammar: " ++ show (length g') ++ " size " ++ show (sizeofNonterminals g'))
    --putStrLn (showNonterminals g')
    let gram''@Grammar { grammarNonterminals = g'' }  = simplifyGrammar gram'
    putStrLn ("Simplified grammar: " ++ show (length g'') ++ " size " ++ show (sizeofNonterminals g''))
    --putStrLn (showNonterminals g'')

    gram'' <- return gram'' { grammarOptions = flags }

    let m'' = memoAnalysis g''
    putStrLn ("Memoized: " ++ show (length m''))

    parser <- writeParser m'' gram''
    sa <- isStandalone
    writeFile outname (if sa then parser ++ standalone_code else parser)

standalone_code = f pappypos_hs ++ f pappyparse_hs where
    f xs = unlines . dropWhile (/= "-- BEGIN CODE") $ lines xs

main = do
    (fs ,inname, outname) <- processArgs
    putVerboseLn $ "Input " ++ inname ++ "\nOutput: " ++ outname
    processFile fs inname outname


