-- ---------------------------------------------------------------------- -- | This module is the main interface to the QuipperASCIIParser -- library. It provides functions for parsing circuits in the ASCII -- format written by 'print_generic' and similar functions. module Quipper.Libraries.QuipperASCIIParser where import qualified Quipper.Libraries.QuipperASCIIParser.CircInfo as CI import qualified Quipper.Libraries.QuipperASCIIParser.ASCIICirc as AC import Quipper import Quipper.Internal.Monad import Quipper.Utils.PortableSignals import System.IO import Data.List -- | Parse a string containing a circuit in the format output by -- Quipper's ASCII format. Return a circuit producing function of the -- parsed circuit, along with a specimen \"shape\" for the input of -- the parsed circuit. parse_circuit :: String -> ([Endpoint],[Endpoint] -> Circ [Endpoint]) parse_circuit all_lines = AC.run mins gates subs circ_info where split_lines = lines' all_lines (mins, ci) = CI.run_ascii_lines split_lines (gates,subs,circ_info) = CI.run ci -- | Like 'lines', except that the last line is omitted if it doesn't -- end with a newline character lines' :: String -> [String] lines' [] = [] lines' s = case elemIndex '\n' s of Nothing -> [] Just n -> (take (n) s):lines' (drop (n+1) s) -- | Like 'parse_circuit', but read the circuit from the standard -- input stream, rather than from a string. This can be used to build -- stand-alone tools that process circuits in a pipeline. parse_from_stdin :: IO ([Endpoint], [Endpoint] -> Circ [Endpoint]) parse_from_stdin = do all_lines <- hGetContents stdin return $ parse_circuit all_lines -- | Like 'parse_from_stdin', but as a special convenience, this -- function also installs a signal handler that will intercept the first -- kill signal (e.g., Ctrl-C) and close the standard input stream. -- This means that whichever part of the circuit was generated before the -- first Ctrl-C can still be processed as a partial circuit. Note that the -- second kill signal will still kill the program. Note that this is only -- defined for Non-Windows OS environments. parse_from_stdin_with_handler :: IO ([Endpoint], [Endpoint] -> Circ [Endpoint]) parse_from_stdin_with_handler = do installHandler Interrupt (CatchOnce (hClose stdin)) all_lines <- hGetContents stdin return $ parse_circuit all_lines