{-# LANGUAGE FlexibleContexts, RecordWildCards #-}
-- | Word-level parsers.
module Language.Bash.Parse.Word
    ( skipSpace
    , arith
    , word
    , heredocWord
    , name
    , functionName
    , subscript
    , assign
    , operator
    ) where

import Prelude hiding (Word)

import           Control.Applicative
import           Control.Monad
import           Data.Char
import           Data.List
import           Data.Maybe
import           Text.Parsec                 hiding ((<|>), optional, many)

import           Language.Bash.Parse.Builder ((<+>))
import qualified Language.Bash.Parse.Builder as B
import           Language.Bash.Pretty
import           Language.Bash.Syntax
import           Language.Bash.Word

-- | @surroundBy p sep@ parses zero or more occurences of @p@, beginning,
-- ending, and separated by @sep@.
surroundBy
    :: Stream s m t
    => ParsecT s u m a
    -> ParsecT s u m sep
    -> ParsecT s u m [a]
surroundBy :: forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
surroundBy ParsecT s u m a
p ParsecT s u m sep
sep = ParsecT s u m sep
sep ParsecT s u m sep -> ParsecT s u m [a] -> ParsecT s u m [a]
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
endBy ParsecT s u m a
p ParsecT s u m sep
sep

-- | @upTo n p@ parses zero to @n@ occurences of @p@.
upTo :: Alternative f => Int -> f a -> f [a]
upTo :: forall (f :: * -> *) a. Alternative f => Int -> f a -> f [a]
upTo Int
m f a
p = Int -> f [a]
forall {t}. (Ord t, Num t) => t -> f [a]
go Int
m
  where
    go :: t -> f [a]
go t
n | t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< t
0     = f [a]
forall a. f a
forall (f :: * -> *) a. Alternative f => f a
empty
         | t
n t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
0    = [a] -> f [a]
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
         | Bool
otherwise = (:) (a -> [a] -> [a]) -> f a -> f ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
p f ([a] -> [a]) -> f [a] -> f [a]
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> t -> f [a]
go (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1) f [a] -> f [a] -> f [a]
forall a. f a -> f a -> f a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [a] -> f [a]
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []

-- | @upTo1 n p@ parses one to @n@ occurences of @p@.
upTo1 :: Alternative f => Int -> f a -> f [a]
upTo1 :: forall (f :: * -> *) a. Alternative f => Int -> f a -> f [a]
upTo1 Int
n f a
p = (:) (a -> [a] -> [a]) -> f a -> f ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
p f ([a] -> [a]) -> f [a] -> f [a]
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> f a -> f [a]
forall (f :: * -> *) a. Alternative f => Int -> f a -> f [a]
upTo (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) f a
p

-- | Parse a span until a delimiter.
spans
    :: Stream s m Char
    => [Char]              -- ^ Delimiters
    -> Bool                -- ^ Remove escaped newlines
    -> ParsecT s u m Span  -- ^ Inner spans
    -> ParsecT s u m Word
spans :: forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
spans [Char]
delims Bool
removeEscapedNewline ParsecT s u m Span
innerSpan = [Maybe Span] -> Word
forall a. [Maybe a] -> [a]
catMaybes ([Maybe Span] -> Word)
-> ParsecT s u m [Maybe Span] -> ParsecT s u m Word
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m (Maybe Span) -> ParsecT s u m [Maybe Span]
forall a. ParsecT s u m a -> ParsecT s u m [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many ParsecT s u m (Maybe Span)
inner
  where
    inner :: ParsecT s u m (Maybe Span)
inner = Maybe Span
forall a. Maybe a
Nothing     Maybe Span -> ParsecT s u m [Char] -> ParsecT s u m (Maybe Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$  ParsecT s u m [Char]
forall {u}. ParsecT s u m [Char]
escapedNewline
        ParsecT s u m (Maybe Span)
-> ParsecT s u m (Maybe Span) -> ParsecT s u m (Maybe Span)
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Span -> Maybe Span
forall a. a -> Maybe a
Just        (Span -> Maybe Span)
-> ParsecT s u m Span -> ParsecT s u m (Maybe Span)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Span
innerSpan
        ParsecT s u m (Maybe Span)
-> ParsecT s u m (Maybe Span) -> ParsecT s u m (Maybe Span)
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Span -> Maybe Span
forall a. a -> Maybe a
Just (Span -> Maybe Span) -> (Char -> Span) -> Char -> Maybe Span
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Span
Char (Char -> Maybe Span)
-> ParsecT s u m Char -> ParsecT s u m (Maybe Span)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
noneOf [Char]
delims

    escapedNewline :: ParsecT s u m [Char]
escapedNewline = if Bool
removeEscapedNewline
                     then ParsecT s u m [Char] -> ParsecT s u m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([Char] -> ParsecT s u m [Char]
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m [Char]
string [Char]
"\\\n")
                     else ParsecT s u m [Char]
forall a. ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a
empty

-- | Parse a matched pair.
matchedPair
    :: Stream s m Char
    => Char                -- ^ Start character
    -> Char                -- ^ End character
    -> Bool                -- ^ Remove escaped newlines
    -> ParsecT s u m Span  -- ^ Inner spans
    -> ParsecT s u m Word
matchedPair :: forall s (m :: * -> *) u.
Stream s m Char =>
Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
matchedPair Char
begin Char
end Bool
removeEscapedNewline ParsecT s u m Span
innerSpan =
    Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
begin ParsecT s u m Char -> ParsecT s u m Word -> ParsecT s u m Word
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Char] -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
spans [Char
end] Bool
removeEscapedNewline ParsecT s u m Span
innerSpan ParsecT s u m Word -> ParsecT s u m Char -> ParsecT s u m Word
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
end

-- | Skip spaces, tabs, and comments.
skipSpace :: Stream s m Char => ParsecT s u m ()
skipSpace :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
skipSpace = ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT s u m ()
forall {u}. ParsecT s u m ()
spaceChar ParsecT s u m ()
-> ParsecT s u m (Maybe [Char]) -> ParsecT s u m ()
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT s u m [Char] -> ParsecT s u m (Maybe [Char])
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT s u m [Char]
forall {u}. ParsecT s u m [Char]
comment ParsecT s u m () -> [Char] -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"whitespace"
  where
    spaceChar :: ParsecT s u m ()
spaceChar = () () -> ParsecT s u m [Char] -> ParsecT s u m ()
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT s u m [Char] -> ParsecT s u m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([Char] -> ParsecT s u m [Char]
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m [Char]
string [Char]
"\\\n")
            ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> () () -> ParsecT s u m Char -> ParsecT s u m ()
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ [Char] -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
" \t"

    comment :: ParsecT s u m [Char]
comment = Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'#' ParsecT s u m Char -> ParsecT s u m [Char] -> ParsecT s u m [Char]
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT s u m Char -> ParsecT s u m [Char]
forall a. ParsecT s u m a -> ParsecT s u m [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many ((Char -> Bool) -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\n'))

-- | Parse a single-quoted string.
singleQuote :: Stream s m Char => ParsecT s u m Span
singleQuote :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
singleQuote = Word -> Span
Single (Word -> Span) -> ParsecT s u m Word -> ParsecT s u m Span
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
matchedPair Char
'\'' Char
'\'' Bool
False ParsecT s u m Span
forall a. ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a
empty

-- | Parse a double-quoted string.
doubleQuote :: Stream s m Char => ParsecT s u m Span
doubleQuote :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
doubleQuote = Word -> Span
Double (Word -> Span) -> ParsecT s u m Word -> ParsecT s u m Span
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
matchedPair Char
'"' Char
'"' Bool
True ParsecT s u m Span
forall {u}. ParsecT s u m Span
inner
  where
    inner :: ParsecT s u m Span
inner = ParsecT s u m Span -> ParsecT s u m Span
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> Span
Escape (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m (Char -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\' ParsecT s u m (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Char] -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"$\\`\"")
        ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
backquote
        ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
dollar

-- | Parse an ANSI C string.
ansiQuote :: Stream s m Char => ParsecT s u m Span
ansiQuote :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
ansiQuote = Word -> Span
ANSIC (Word -> Span)
-> ParsecT s u m Char -> ParsecT s u m (Word -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$' ParsecT s u m (Word -> Span)
-> ParsecT s u m Word -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
matchedPair Char
'\'' Char
'\'' Bool
True ParsecT s u m Span
forall {u}. ParsecT s u m Span
escape
  where
    escape :: ParsecT s u m Span
escape = ParsecT s u m Span -> ParsecT s u m Span
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> Span
fromChar (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m (Char -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\' ParsecT s u m (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m Char
forall {u}. ParsecT s u m Char
escapeCode)

    fromChar :: Char -> Span
fromChar Char
c | Char
c Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char]
"\\\'" = Char -> Span
Escape Char
c
               | Bool
otherwise       = Char -> Span
Char Char
c

    escapeCode :: ParsecT s u m Char
escapeCode = ParsecT s u m Char
forall {u}. ParsecT s u m Char
charCodes
             ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'x' ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> ParsecT s u m Char
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
Int -> ParsecT s u m Char
hex Int
2
             ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'u' ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> ParsecT s u m Char
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
Int -> ParsecT s u m Char
hex Int
4
             ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'U' ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> ParsecT s u m Char
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
Int -> ParsecT s u m Char
hex Int
8
             ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Int -> ParsecT s u m Char
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
Int -> ParsecT s u m Char
oct Int
3
             ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'c' ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT s u m Char
forall {u}. ParsecT s u m Char
ctrlCodes

    charCodes :: ParsecT s u m Char
charCodes = [Char] -> [Char] -> ParsecT s u m Char
forall {s} {m :: * -> *} {a} {u}.
Stream s m Char =>
[Char] -> [a] -> ParsecT s u m a
codes [Char]
"abeEfnrtv\\\'\"" [Char]
"\a\b\ESC\ESC\f\n\r\t\v\\\'\""

    ctrlCodes :: ParsecT s u m Char
ctrlCodes = Char
'\FS' Char -> ParsecT s u m [Char] -> ParsecT s u m Char
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT s u m [Char] -> ParsecT s u m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([Char] -> ParsecT s u m [Char]
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m [Char]
string [Char]
"\\\\")
            ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Char] -> [Char] -> ParsecT s u m Char
forall {s} {m :: * -> *} {a} {u}.
Stream s m Char =>
[Char] -> [a] -> ParsecT s u m a
codes [Char]
"@ABCDEFGHIJKLMOPQRSTUVWXYZ[]^_?"
                      ([Char]
"\NUL\SOH\STX\ETX\EOT\ENQ\ACK\BEL\BS\HT\LF\VT\FF" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                       [Char]
"\CR\SO\SI\DLE\DC1\DC2\DC3\DC4\NAK\SYN\ETB\CAN\EM" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
                       [Char]
"\SUB\ESC\GS\RS\US\DEL")

    codes :: [Char] -> [a] -> ParsecT s u m a
codes [Char]
chars [a]
replacements = ParsecT s u m a -> ParsecT s u m a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m a -> ParsecT s u m a)
-> ParsecT s u m a -> ParsecT s u m a
forall a b. (a -> b) -> a -> b
$ do
        Char
c <- ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
        case Char -> [(Char, a)] -> Maybe a
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Char
c [(Char, a)]
table of
            Maybe a
Nothing -> [Char] -> ParsecT s u m a
forall s (m :: * -> *) t u a.
Stream s m t =>
[Char] -> ParsecT s u m a
unexpected [Char
c]
            Just a
c' -> a -> ParsecT s u m a
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
c'
      where
        table :: [(Char, a)]
table = [Char] -> [a] -> [(Char, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Char]
chars [a]
replacements

    oct :: Int -> ParsecT s u m Char
oct Int
n = Int -> Int -> ParsecT s u m Char -> ParsecT s u m Char
forall {m :: * -> *}.
(Monad m, Alternative m) =>
Int -> Int -> m Char -> m Char
number Int
n Int
8 ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
octDigit
    hex :: Int -> ParsecT s u m Char
hex Int
n = Int -> Int -> ParsecT s u m Char -> ParsecT s u m Char
forall {m :: * -> *}.
(Monad m, Alternative m) =>
Int -> Int -> m Char -> m Char
number Int
n Int
16 ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
hexDigit

    number :: Int -> Int -> m Char -> m Char
number Int
maxDigits Int
base m Char
baseDigit = do
        [Int]
digits <- (Char -> Int) -> [Char] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Int
digitToInt ([Char] -> [Int]) -> m [Char] -> m [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> m Char -> m [Char]
forall (f :: * -> *) a. Alternative f => Int -> f a -> f [a]
upTo1 Int
maxDigits m Char
baseDigit
        let n :: Int
n = (Int -> Int -> Int) -> Int -> [Int] -> Int
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Int
x Int
d -> Int
baseInt -> Int -> Int
forall a. Num a => a -> a -> a
*Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
d) Int
0 [Int]
digits
        Char -> m Char
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Char -> m Char) -> Char -> m Char
forall a b. (a -> b) -> a -> b
$ if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Char -> Int
ord Char
forall a. Bounded a => a
maxBound then Char
'\0' else Int -> Char
chr Int
n  -- arbitrary

-- | Parse a locale string.
localeQuote :: Stream s m Char => ParsecT s u m Span
localeQuote :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
localeQuote = Word -> Span
Locale (Word -> Span)
-> ParsecT s u m Char -> ParsecT s u m (Word -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$' ParsecT s u m (Word -> Span)
-> ParsecT s u m Word -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
matchedPair Char
'"' Char
'"' Bool
True ParsecT s u m Span
forall {u}. ParsecT s u m Span
inner
  where
    inner :: ParsecT s u m Span
inner = ParsecT s u m Span -> ParsecT s u m Span
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> Span
Escape (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m (Char -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\' ParsecT s u m (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Char] -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"$\\`\"")
        ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
backquote
        ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
dollar

-- | Parse a backquoted string.
backquote :: Stream s m Char => ParsecT s u m Span
backquote :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
backquote = Word -> Span
Backquote (Word -> Span) -> ParsecT s u m Word -> ParsecT s u m Span
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
matchedPair Char
'`' Char
'`' Bool
False ParsecT s u m Span
forall {u}. ParsecT s u m Span
escape
  where
    escape :: ParsecT s u m Span
escape = ParsecT s u m Span -> ParsecT s u m Span
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> Span
Escape (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m (Char -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\' ParsecT s u m (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Char] -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"$\\`")

-- | Parse an arithmetic expression.
arith :: Stream s m Char => ParsecT s u m String
arith :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
arith = Builder -> [Char]
B.toString (Builder -> [Char])
-> ParsecT s u m Builder -> ParsecT s u m [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Builder
forall {u}. ParsecT s u m Builder
arithPart ParsecT s u m [Char] -> [Char] -> ParsecT s u m [Char]
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"arithmetic expression"
  where
    arithPart :: ParsecT s u m Builder
arithPart = ParsecT s u m Builder -> ParsecT s u m Builder
forall a s u (m :: * -> *).
Monoid a =>
ParsecT s u m a -> ParsecT s u m a
B.many ParsecT s u m Builder
inner
    inner :: ParsecT s u m Builder
inner     = [Char] -> ParsecT s u m Builder
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Builder
B.noneOf [Char]
"()" ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT s u m Builder
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Builder
B.char Char
'(' ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall (f :: * -> *) a.
(Applicative f, Monoid a) =>
f a -> f a -> f a
<+> ParsecT s u m Builder
arithPart ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall (f :: * -> *) a.
(Applicative f, Monoid a) =>
f a -> f a -> f a
<+> Char -> ParsecT s u m Builder
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Builder
B.char Char
')'

-- | Parse a parenthesized substitution.
subst :: Stream s m Char => ParsecT s u m String
subst :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
subst = Builder -> [Char]
B.toString (Builder -> [Char])
-> ParsecT s u m Char -> ParsecT s u m (Builder -> [Char])
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'(' ParsecT s u m (Builder -> [Char])
-> ParsecT s u m Builder -> ParsecT s u m [Char]
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m Builder -> ParsecT s u m Builder
forall a s u (m :: * -> *).
Monoid a =>
ParsecT s u m a -> ParsecT s u m a
B.many ParsecT s u m Builder
forall {u}. ParsecT s u m Builder
parens ParsecT s u m [Char] -> ParsecT s u m Char -> ParsecT s u m [Char]
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
  where
    parens :: ParsecT s u m Builder
parens = Char -> ParsecT s u m Builder
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Builder
B.char Char
'(' ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall (f :: * -> *) a.
(Applicative f, Monoid a) =>
f a -> f a -> f a
<+> ParsecT s u m Builder -> ParsecT s u m Builder
forall a s u (m :: * -> *).
Monoid a =>
ParsecT s u m a -> ParsecT s u m a
B.many ParsecT s u m Builder
parens ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall (f :: * -> *) a.
(Applicative f, Monoid a) =>
f a -> f a -> f a
<+> Char -> ParsecT s u m Builder
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Builder
B.char Char
')'
         ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT s u m Builder
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Builder
B.char Char
'#' ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall (f :: * -> *) a.
(Applicative f, Monoid a) =>
f a -> f a -> f a
<+> ParsecT s u m Builder -> ParsecT s u m Builder
forall a s u (m :: * -> *).
Monoid a =>
ParsecT s u m a -> ParsecT s u m a
B.many ((Char -> Bool) -> ParsecT s u m Builder
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Builder
B.satisfy (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\n')) ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall (f :: * -> *) a.
(Applicative f, Monoid a) =>
f a -> f a -> f a
<+> Char -> ParsecT s u m Builder
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Builder
B.char Char
'\n'
         ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT s u m Builder
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Builder
B.char Char
'\\' ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall (f :: * -> *) a.
(Applicative f, Monoid a) =>
f a -> f a -> f a
<+> ParsecT s u m Builder
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Builder
B.anyChar
         ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Span -> Builder
fromSpan (Span -> Builder) -> ParsecT s u m Span -> ParsecT s u m Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
singleQuote
         ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Span -> Builder
fromSpan (Span -> Builder) -> ParsecT s u m Span -> ParsecT s u m Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
doubleQuote
         ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Span -> Builder
fromSpan (Span -> Builder) -> ParsecT s u m Span -> ParsecT s u m Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
backquote
         ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Span -> Builder
fromSpan (Span -> Builder) -> ParsecT s u m Span -> ParsecT s u m Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
dollar
         ParsecT s u m Builder
-> ParsecT s u m Builder -> ParsecT s u m Builder
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Char -> Bool) -> ParsecT s u m Builder
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Builder
B.satisfy (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
')')

    fromSpan :: Span -> Builder
fromSpan = [Char] -> Builder
B.fromString ([Char] -> Builder) -> (Span -> [Char]) -> Span -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Span -> [Char]
forall a. Pretty a => a -> [Char]
prettyText

-- | Parse a dollar substitution.
dollar :: Stream s m Char => ParsecT s u m Span
dollar :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
dollar = Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$' ParsecT s u m Char -> ParsecT s u m Span -> ParsecT s u m Span
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT s u m Span
forall {u}. ParsecT s u m Span
rest
  where
    rest :: ParsecT s u m Span
rest = ParsecT s u m Span
forall {u}. ParsecT s u m Span
arithSubst
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall {u}. ParsecT s u m Span
commandSubst
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall {u}. ParsecT s u m Span
braceSubst
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall {u}. ParsecT s u m Span
bareSubst
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Span -> ParsecT s u m Span
forall a. a -> ParsecT s u m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Char -> Span
Char Char
'$')

    arithSubst :: ParsecT s u m Span
arithSubst   = [Char] -> Span
ArithSubst   ([Char] -> Span)
-> ParsecT s u m [Char] -> ParsecT s u m ([Char] -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$  ParsecT s u m [Char] -> ParsecT s u m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([Char] -> ParsecT s u m [Char]
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m [Char]
string [Char]
"((") ParsecT s u m ([Char] -> Span)
-> ParsecT s u m [Char] -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m [Char]
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
arith ParsecT s u m Span -> ParsecT s u m [Char] -> ParsecT s u m Span
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* [Char] -> ParsecT s u m [Char]
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m [Char]
string [Char]
"))"
    commandSubst :: ParsecT s u m Span
commandSubst = [Char] -> Span
CommandSubst ([Char] -> Span) -> ParsecT s u m [Char] -> ParsecT s u m Span
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m [Char]
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
subst
    braceSubst :: ParsecT s u m Span
braceSubst   = ParamSubst -> Span
ParamSubst   (ParamSubst -> Span)
-> ParsecT s u m Char -> ParsecT s u m (ParamSubst -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$  Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'{' ParsecT s u m (ParamSubst -> Span)
-> ParsecT s u m ParamSubst -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m ParamSubst
forall s (m :: * -> *) u.
Stream s m Char =>
ParsecT s u m ParamSubst
paramSubst ParsecT s u m Span -> ParsecT s u m Char -> ParsecT s u m Span
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'

    bareSubst :: ParsecT s u m Span
bareSubst = ParamSubst -> Span
ParamSubst (ParamSubst -> Span)
-> (Parameter -> ParamSubst) -> Parameter -> Span
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parameter -> ParamSubst
Bare (Parameter -> Span)
-> ParsecT s u m Parameter -> ParsecT s u m Span
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Parameter
forall {u}. ParsecT s u m Parameter
bareParam
      where
        bareParam :: ParsecT s u m Parameter
bareParam = [Char] -> Maybe Word -> Parameter
Parameter ([Char] -> Maybe Word -> Parameter)
-> ParsecT s u m [Char] -> ParsecT s u m (Maybe Word -> Parameter)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m [Char]
forall {u}. ParsecT s u m [Char]
bareParamName ParsecT s u m (Maybe Word -> Parameter)
-> ParsecT s u m (Maybe Word) -> ParsecT s u m Parameter
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe Word -> ParsecT s u m (Maybe Word)
forall a. a -> ParsecT s u m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Word
forall a. Maybe a
Nothing

        bareParamName :: ParsecT s u m [Char]
bareParamName = ParsecT s u m [Char]
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
name
                    ParsecT s u m [Char]
-> ParsecT s u m [Char] -> ParsecT s u m [Char]
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m [Char]
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
specialName
                    ParsecT s u m [Char]
-> ParsecT s u m [Char] -> ParsecT s u m [Char]
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[]) (Char -> [Char]) -> ParsecT s u m Char -> ParsecT s u m [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit

-- | Parse a parameter substitution.
paramSubst :: Stream s m Char => ParsecT s u m ParamSubst
paramSubst :: forall s (m :: * -> *) u.
Stream s m Char =>
ParsecT s u m ParamSubst
paramSubst = ParsecT s u m ParamSubst -> ParsecT s u m ParamSubst
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m ParamSubst
forall {u}. ParsecT s u m ParamSubst
prefixSubst
         ParsecT s u m ParamSubst
-> ParsecT s u m ParamSubst -> ParsecT s u m ParamSubst
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m ParamSubst -> ParsecT s u m ParamSubst
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m ParamSubst
forall {u}. ParsecT s u m ParamSubst
indicesSubst
         ParsecT s u m ParamSubst
-> ParsecT s u m ParamSubst -> ParsecT s u m ParamSubst
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m ParamSubst -> ParsecT s u m ParamSubst
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m ParamSubst
forall {u}. ParsecT s u m ParamSubst
lengthSubst
         ParsecT s u m ParamSubst
-> ParsecT s u m ParamSubst -> ParsecT s u m ParamSubst
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m ParamSubst
forall {u}. ParsecT s u m ParamSubst
normalSubst
  where
    param :: ParsecT s u m Parameter
param = [Char] -> Maybe Word -> Parameter
Parameter ([Char] -> Maybe Word -> Parameter)
-> ParsecT s u m [Char] -> ParsecT s u m (Maybe Word -> Parameter)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m [Char]
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
name        ParsecT s u m (Maybe Word -> Parameter)
-> ParsecT s u m (Maybe Word) -> ParsecT s u m Parameter
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m Word -> ParsecT s u m (Maybe Word)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT s u m Word
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Word
subscript
        ParsecT s u m Parameter
-> ParsecT s u m Parameter -> ParsecT s u m Parameter
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Char] -> Maybe Word -> Parameter
Parameter ([Char] -> Maybe Word -> Parameter)
-> ParsecT s u m [Char] -> ParsecT s u m (Maybe Word -> Parameter)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Char -> ParsecT s u m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit ParsecT s u m (Maybe Word -> Parameter)
-> ParsecT s u m (Maybe Word) -> ParsecT s u m Parameter
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe Word -> ParsecT s u m (Maybe Word)
forall a. a -> ParsecT s u m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Word
forall a. Maybe a
Nothing
        ParsecT s u m Parameter
-> ParsecT s u m Parameter -> ParsecT s u m Parameter
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Char] -> Maybe Word -> Parameter
Parameter ([Char] -> Maybe Word -> Parameter)
-> ParsecT s u m [Char] -> ParsecT s u m (Maybe Word -> Parameter)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m [Char]
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
specialName ParsecT s u m (Maybe Word -> Parameter)
-> ParsecT s u m (Maybe Word) -> ParsecT s u m Parameter
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe Word -> ParsecT s u m (Maybe Word)
forall a. a -> ParsecT s u m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Word
forall a. Maybe a
Nothing

    switch :: Char -> ParsecT s u m Bool
switch Char
c = Maybe Char -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Char -> Bool)
-> ParsecT s u m (Maybe Char) -> ParsecT s u m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Char -> ParsecT s u m (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c)

    doubled :: ParsecT s u m a -> ParsecT s u m (a, Bool)
doubled ParsecT s u m a
p = do
        a
a <- ParsecT s u m a
p
        Bool
d <- (Maybe () -> Bool)
-> ParsecT s u m (Maybe ()) -> ParsecT s u m Bool
forall a b. (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe () -> Bool
forall a. Maybe a -> Bool
isJust (ParsecT s u m (Maybe ()) -> ParsecT s u m Bool)
-> (ParsecT s u m () -> ParsecT s u m (Maybe ()))
-> ParsecT s u m ()
-> ParsecT s u m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT s u m () -> ParsecT s u m (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT s u m () -> ParsecT s u m (Maybe ()))
-> (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m ()
-> ParsecT s u m (Maybe ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m () -> ParsecT s u m Bool)
-> ParsecT s u m () -> ParsecT s u m Bool
forall a b. (a -> b) -> a -> b
$ do
            a
b <- ParsecT s u m a
p
            Bool -> ParsecT s u m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
b)
        (a, Bool) -> ParsecT s u m (a, Bool)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, Bool
d)

    direction :: ParsecT s u m Direction
direction = Direction
Front Direction -> ParsecT s u m Char -> ParsecT s u m Direction
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'#'
            ParsecT s u m Direction
-> ParsecT s u m Direction -> ParsecT s u m Direction
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Direction
Back  Direction -> ParsecT s u m Char -> ParsecT s u m Direction
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'%'

    substWord :: [Char] -> ParsecT s u m Word
substWord [Char]
delims = [Char] -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
spans [Char]
delims Bool
True ParsecT s u m Span
forall {u}. ParsecT s u m Span
inner
      where
        inner :: ParsecT s u m Span
inner = Char -> Span
Escape (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m (Char -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\' ParsecT s u m (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
            ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
singleQuote
            ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
doubleQuote
            ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
backquote
            ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
dollar

    prefixSubst :: ParsecT s u m ParamSubst
prefixSubst = do
        Char
_        <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'!'
        [Char]
prefix   <- ParsecT s u m [Char]
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
name
        Char
modifier <- [Char] -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"*@"
        ParamSubst -> ParsecT s u m ParamSubst
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Prefix{Char
[Char]
prefix :: [Char]
modifier :: Char
prefix :: [Char]
modifier :: Char
..}

    indicesSubst :: ParsecT s u m ParamSubst
indicesSubst = do
        Char
_   <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'!'
        [Char]
n   <- ParsecT s u m [Char]
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
name
        Char
_   <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
        Char
sub <- [Char] -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"*@"
        Char
_   <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
']'
        let parameter :: Parameter
parameter = [Char] -> Maybe Word -> Parameter
Parameter [Char]
n (Word -> Maybe Word
forall a. a -> Maybe a
Just [Char -> Span
Char Char
sub])
        ParamSubst -> ParsecT s u m ParamSubst
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Indices{Parameter
parameter :: Parameter
parameter :: Parameter
..}

    lengthSubst :: ParsecT s u m ParamSubst
lengthSubst = do
        Char
_         <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'#'
        Parameter
parameter <- ParsecT s u m Parameter
forall {u}. ParsecT s u m Parameter
param
        ParamSubst -> ParsecT s u m ParamSubst
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Length {Parameter
parameter :: Parameter
parameter :: Parameter
..}

    normalSubst :: ParsecT s u m ParamSubst
normalSubst = do
        Bool
indirect <- Char -> ParsecT s u m Bool
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
Char -> ParsecT s u m Bool
switch Char
'!'
        Parameter
parameter <- ParsecT s u m Parameter
forall {u}. ParsecT s u m Parameter
param
        [ParsecT s u m ParamSubst] -> ParsecT s u m ParamSubst
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice ([ParsecT s u m ParamSubst] -> ParsecT s u m ParamSubst)
-> ([ParsecT s u m ParamSubst] -> [ParsecT s u m ParamSubst])
-> [ParsecT s u m ParamSubst]
-> ParsecT s u m ParamSubst
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ParsecT s u m ParamSubst -> ParsecT s u m ParamSubst)
-> [ParsecT s u m ParamSubst] -> [ParsecT s u m ParamSubst]
forall a b. (a -> b) -> [a] -> [b]
map ParsecT s u m ParamSubst -> ParsecT s u m ParamSubst
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([ParsecT s u m ParamSubst] -> ParsecT s u m ParamSubst)
-> [ParsecT s u m ParamSubst] -> ParsecT s u m ParamSubst
forall a b. (a -> b) -> a -> b
$
            [ do Bool
testNull <- Char -> ParsecT s u m Bool
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
Char -> ParsecT s u m Bool
switch Char
':'
                 AltOp
altOp <- AltOp
AltDefault AltOp -> ParsecT s u m Char -> ParsecT s u m AltOp
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-'
                      ParsecT s u m AltOp -> ParsecT s u m AltOp -> ParsecT s u m AltOp
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> AltOp
AltAssign  AltOp -> ParsecT s u m Char -> ParsecT s u m AltOp
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'='
                      ParsecT s u m AltOp -> ParsecT s u m AltOp -> ParsecT s u m AltOp
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> AltOp
AltError   AltOp -> ParsecT s u m Char -> ParsecT s u m AltOp
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'?'
                      ParsecT s u m AltOp -> ParsecT s u m AltOp -> ParsecT s u m AltOp
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> AltOp
AltReplace AltOp -> ParsecT s u m Char -> ParsecT s u m AltOp
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'+'
                 Word
altWord <- [Char] -> ParsecT s u m Word
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
[Char] -> ParsecT s u m Word
substWord [Char]
"}"
                 ParamSubst -> ParsecT s u m ParamSubst
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Alt{Bool
Word
AltOp
Parameter
parameter :: Parameter
indirect :: Bool
parameter :: Parameter
testNull :: Bool
altOp :: AltOp
altWord :: Word
indirect :: Bool
testNull :: Bool
altOp :: AltOp
altWord :: Word
..}
            , do Word
subOffset <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
':' ParsecT s u m Char -> ParsecT s u m Word -> ParsecT s u m Word
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Char] -> ParsecT s u m Word
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
[Char] -> ParsecT s u m Word
substWord [Char]
":}"
                 Word
subLength <- Word -> ParsecT s u m Word -> ParsecT s u m Word
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
':' ParsecT s u m Char -> ParsecT s u m Word -> ParsecT s u m Word
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Char] -> ParsecT s u m Word
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
[Char] -> ParsecT s u m Word
substWord [Char]
"}")
                 ParamSubst -> ParsecT s u m ParamSubst
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Substring{Bool
Word
Parameter
parameter :: Parameter
indirect :: Bool
parameter :: Parameter
indirect :: Bool
subOffset :: Word
subLength :: Word
subOffset :: Word
subLength :: Word
..}
            , do (Direction
deleteDirection, Bool
longest) <- ParsecT s u m Direction -> ParsecT s u m (Direction, Bool)
forall {a} {s} {u} {m :: * -> *}.
Eq a =>
ParsecT s u m a -> ParsecT s u m (a, Bool)
doubled ParsecT s u m Direction
forall {u}. ParsecT s u m Direction
direction
                 Word
pattern <- [Char] -> ParsecT s u m Word
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
[Char] -> ParsecT s u m Word
substWord [Char]
"}"
                 ParamSubst -> ParsecT s u m ParamSubst
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Delete{Bool
Word
Direction
Parameter
parameter :: Parameter
indirect :: Bool
parameter :: Parameter
indirect :: Bool
deleteDirection :: Direction
longest :: Bool
pattern :: Word
longest :: Bool
deleteDirection :: Direction
pattern :: Word
..}
            , do Char
_ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'/'
                 Bool
replaceAll <- Char -> ParsecT s u m Bool
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
Char -> ParsecT s u m Bool
switch Char
'/'
                 Maybe Direction
replaceDirection <- ParsecT s u m Direction -> ParsecT s u m (Maybe Direction)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT s u m Direction
forall {u}. ParsecT s u m Direction
direction
                 Word
pattern <- [Char] -> ParsecT s u m Word
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
[Char] -> ParsecT s u m Word
substWord [Char]
"/}"
                 Word
replacement <- Word -> ParsecT s u m Word -> ParsecT s u m Word
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'/' ParsecT s u m Char -> ParsecT s u m Word -> ParsecT s u m Word
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Char] -> ParsecT s u m Word
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
[Char] -> ParsecT s u m Word
substWord [Char]
"}")
                 ParamSubst -> ParsecT s u m ParamSubst
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Replace{Bool
Word
Maybe Direction
Parameter
parameter :: Parameter
indirect :: Bool
parameter :: Parameter
indirect :: Bool
pattern :: Word
replaceAll :: Bool
replaceDirection :: Maybe Direction
pattern :: Word
replacement :: Word
replaceAll :: Bool
replaceDirection :: Maybe Direction
replacement :: Word
..}
            , do (LetterCaseOp
letterCaseOp, Bool
convertAll) <- ParsecT s u m LetterCaseOp -> ParsecT s u m (LetterCaseOp, Bool)
forall {a} {s} {u} {m :: * -> *}.
Eq a =>
ParsecT s u m a -> ParsecT s u m (a, Bool)
doubled (ParsecT s u m LetterCaseOp -> ParsecT s u m (LetterCaseOp, Bool))
-> ParsecT s u m LetterCaseOp -> ParsecT s u m (LetterCaseOp, Bool)
forall a b. (a -> b) -> a -> b
$
                        LetterCaseOp
ToLower LetterCaseOp -> ParsecT s u m Char -> ParsecT s u m LetterCaseOp
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
','
                    ParsecT s u m LetterCaseOp
-> ParsecT s u m LetterCaseOp -> ParsecT s u m LetterCaseOp
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> LetterCaseOp
ToUpper LetterCaseOp -> ParsecT s u m Char -> ParsecT s u m LetterCaseOp
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'^'
                 Word
pattern <- [Char] -> ParsecT s u m Word
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
[Char] -> ParsecT s u m Word
substWord [Char]
"}"
                 ParamSubst -> ParsecT s u m ParamSubst
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return LetterCase{Bool
Word
LetterCaseOp
Parameter
parameter :: Parameter
indirect :: Bool
parameter :: Parameter
indirect :: Bool
pattern :: Word
letterCaseOp :: LetterCaseOp
convertAll :: Bool
pattern :: Word
letterCaseOp :: LetterCaseOp
convertAll :: Bool
..}
            , ParamSubst -> ParsecT s u m ParamSubst
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Brace {Bool
Parameter
parameter :: Parameter
indirect :: Bool
parameter :: Parameter
indirect :: Bool
..}
            ]

-- | Parse a process substitution.
processSubst :: Stream s m Char => ParsecT s u m Span
processSubst :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
processSubst = ProcessSubstOp -> [Char] -> Span
ProcessSubst (ProcessSubstOp -> [Char] -> Span)
-> ParsecT s u m ProcessSubstOp -> ParsecT s u m ([Char] -> Span)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m ProcessSubstOp
forall {u}. ParsecT s u m ProcessSubstOp
processSubstOp ParsecT s u m ([Char] -> Span)
-> ParsecT s u m [Char] -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m [Char]
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
subst
  where
    processSubstOp :: ParsecT s u m ProcessSubstOp
processSubstOp = ProcessSubstOp
ProcessIn  ProcessSubstOp
-> ParsecT s u m Char -> ParsecT s u m ProcessSubstOp
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'<'
                 ParsecT s u m ProcessSubstOp
-> ParsecT s u m ProcessSubstOp -> ParsecT s u m ProcessSubstOp
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ProcessSubstOp
ProcessOut ProcessSubstOp
-> ParsecT s u m Char -> ParsecT s u m ProcessSubstOp
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'>'

-- | Parse any span that may occur in a word.
wordSpan :: Stream s m Char => ParsecT s u m Span
wordSpan :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
wordSpan = ParsecT s u m Span -> ParsecT s u m Span
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> Span
Escape (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m (Char -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\' ParsecT s u m (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar)
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
singleQuote
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
doubleQuote
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span -> ParsecT s u m Span
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
ansiQuote
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span -> ParsecT s u m Span
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
localeQuote
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
backquote
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
dollar
       ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span -> ParsecT s u m Span
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
processSubst

-- | Parse a word.
word :: Stream s m Char => ParsecT s u m Word
word :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Word
word = [Char] -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
spans [Char]
" \t\r\n&|;()<>" Bool
True ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
wordSpan

-- | Parse a here document as a word. This parses substitutions, but not
-- most quoting.
heredocWord :: Stream s m Char => ParsecT s u m Word
heredocWord :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Word
heredocWord = [Char] -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
spans [] Bool
True ParsecT s u m Span
forall {u}. ParsecT s u m Span
inner
  where
    inner :: ParsecT s u m Span
inner = ParsecT s u m Span -> ParsecT s u m Span
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> Span
Escape (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m (Char -> Span)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\' ParsecT s u m (Char -> Span)
-> ParsecT s u m Char -> ParsecT s u m Span
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Char] -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"$\\`")
        ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
backquote
        ParsecT s u m Span -> ParsecT s u m Span -> ParsecT s u m Span
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
dollar

-- | Parse a parameter name.
name :: Stream s m Char => ParsecT s u m String
name :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
name = (:) (Char -> [Char] -> [Char])
-> ParsecT s u m Char -> ParsecT s u m ([Char] -> [Char])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Char
forall {u}. ParsecT s u m Char
nameStart ParsecT s u m ([Char] -> [Char])
-> ParsecT s u m [Char] -> ParsecT s u m [Char]
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m Char -> ParsecT s u m [Char]
forall a. ParsecT s u m a -> ParsecT s u m [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many ParsecT s u m Char
forall {u}. ParsecT s u m Char
nameLetter
  where
    nameStart :: ParsecT s u m Char
nameStart  = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter   ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'_'
    nameLetter :: ParsecT s u m Char
nameLetter = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
alphaNum ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'_'

-- | Parse a function name.
functionName :: Stream s m Char => ParsecT s u m String
functionName :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
functionName = (:) (Char -> [Char] -> [Char])
-> ParsecT s u m Char -> ParsecT s u m ([Char] -> [Char])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Char
forall {u}. ParsecT s u m Char
nameStart ParsecT s u m ([Char] -> [Char])
-> ParsecT s u m [Char] -> ParsecT s u m [Char]
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m Char -> ParsecT s u m [Char]
forall a. ParsecT s u m a -> ParsecT s u m [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many ParsecT s u m Char
forall {u}. ParsecT s u m Char
nameLetter
  where
    nameStart :: ParsecT s u m Char
nameStart  = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter   ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Char
forall {u}. ParsecT s u m Char
specialChar
    nameLetter :: ParsecT s u m Char
nameLetter = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
alphaNum ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT s u m Char
forall {u}. ParsecT s u m Char
specialChar
    specialChar :: ParsecT s u m Char
specialChar = [Char] -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"_-.+!"

-- | Parse a special parameter name.
specialName :: Stream s m Char => ParsecT s u m String
specialName :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
specialName = (Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[]) (Char -> [Char]) -> ParsecT s u m Char -> ParsecT s u m [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"*@#?-$!_"

-- | Parse a subscript.
subscript :: Stream s m Char => ParsecT s u m Word
subscript :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Word
subscript = Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> Char -> Bool -> ParsecT s u m Span -> ParsecT s u m Word
matchedPair Char
'[' Char
']' Bool
True ParsecT s u m Span
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Span
wordSpan

-- | Parse an assignment.
assign :: Stream s m Char => ParsecT s u m Assign
assign :: forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Assign
assign = Parameter -> AssignOp -> RValue -> Assign
Assign (Parameter -> AssignOp -> RValue -> Assign)
-> ParsecT s u m Parameter
-> ParsecT s u m (AssignOp -> RValue -> Assign)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Parameter
forall {u}. ParsecT s u m Parameter
lvalue ParsecT s u m (AssignOp -> RValue -> Assign)
-> ParsecT s u m AssignOp -> ParsecT s u m (RValue -> Assign)
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m AssignOp
forall {u}. ParsecT s u m AssignOp
assignOp ParsecT s u m (RValue -> Assign)
-> ParsecT s u m RValue -> ParsecT s u m Assign
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m RValue
forall {u}. ParsecT s u m RValue
rvalue ParsecT s u m Assign -> [Char] -> ParsecT s u m Assign
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"assignment"
  where
    lvalue :: ParsecT s u m Parameter
lvalue = [Char] -> Maybe Word -> Parameter
Parameter ([Char] -> Maybe Word -> Parameter)
-> ParsecT s u m [Char] -> ParsecT s u m (Maybe Word -> Parameter)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m [Char]
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m [Char]
name ParsecT s u m (Maybe Word -> Parameter)
-> ParsecT s u m (Maybe Word) -> ParsecT s u m Parameter
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m Word -> ParsecT s u m (Maybe Word)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT s u m Word
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Word
subscript

    assignOp :: ParsecT s u m AssignOp
assignOp = AssignOp
Equals     AssignOp -> ParsecT s u m [Char] -> ParsecT s u m AssignOp
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ [Char] -> ParsecT s u m [Char]
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m [Char]
string [Char]
"="
           ParsecT s u m AssignOp
-> ParsecT s u m AssignOp -> ParsecT s u m AssignOp
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> AssignOp
PlusEquals AssignOp -> ParsecT s u m [Char] -> ParsecT s u m AssignOp
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ [Char] -> ParsecT s u m [Char]
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m [Char]
string [Char]
"+="

    rvalue :: ParsecT s u m RValue
rvalue = [(Maybe Word, Word)] -> RValue
RArray ([(Maybe Word, Word)] -> RValue)
-> ParsecT s u m Char
-> ParsecT s u m ([(Maybe Word, Word)] -> RValue)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$  Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'(' ParsecT s u m ([(Maybe Word, Word)] -> RValue)
-> ParsecT s u m [(Maybe Word, Word)] -> ParsecT s u m RValue
forall a b.
ParsecT s u m (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT s u m [(Maybe Word, Word)]
forall {u}. ParsecT s u m [(Maybe Word, Word)]
arrayElems ParsecT s u m RValue -> ParsecT s u m Char -> ParsecT s u m RValue
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
         ParsecT s u m RValue
-> ParsecT s u m RValue -> ParsecT s u m RValue
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Word -> RValue
RValue (Word -> RValue) -> ParsecT s u m Word -> ParsecT s u m RValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Word
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Word
word

    arrayElems :: ParsecT s u m [(Maybe Word, Word)]
arrayElems = ParsecT s u m (Maybe Word, Word)
forall {u}. ParsecT s u m (Maybe Word, Word)
arrayElem ParsecT s u m (Maybe Word, Word)
-> ParsecT s u m [Char] -> ParsecT s u m [(Maybe Word, Word)]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`surroundBy` ParsecT s u m [Char]
forall {u}. ParsecT s u m [Char]
skipArraySpace

    arrayElem :: ParsecT s u m (Maybe Word, Word)
arrayElem = do
        Maybe Word
s <- ParsecT s u m Word -> ParsecT s u m (Maybe Word)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT s u m Word
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Word
subscript ParsecT s u m Word -> ParsecT s u m Char -> ParsecT s u m Word
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'=')
        Word
w <- ParsecT s u m Word
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Word
word
        case (Maybe Word
s, Word
w) of
            (Maybe Word
Nothing, []) -> ParsecT s u m (Maybe Word, Word)
forall a. ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a
empty
            (Maybe Word, Word)
_             -> (Maybe Word, Word) -> ParsecT s u m (Maybe Word, Word)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Word
s, Word
w)

    skipArraySpace :: ParsecT s u m [Char]
skipArraySpace = Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\n' ParsecT s u m Char -> ParsecT s u m () -> ParsecT s u m [Char]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
`surroundBy` ParsecT s u m ()
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
skipSpace

-- | Parse the longest available operator from a list.
operator :: Stream s m Char => [String] -> ParsecT s u m String
operator :: forall s (m :: * -> *) u.
Stream s m Char =>
[[Char]] -> ParsecT s u m [Char]
operator [[Char]]
ops = [[Char]] -> ParsecT s u m [Char]
forall s (m :: * -> *) u.
Stream s m Char =>
[[Char]] -> ParsecT s u m [Char]
go [[Char]]
ops ParsecT s u m [Char] -> [Char] -> ParsecT s u m [Char]
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"operator"
  where
    go :: [[Char]] -> ParsecT s u m [Char]
go [[Char]]
xs
        | [[Char]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Char]]
xs      = ParsecT s u m [Char]
forall a. ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a
empty
        | [Char]
"" [Char] -> [[Char]] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Char]]
xs = ParsecT s u m [Char] -> ParsecT s u m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([[Char]] -> ParsecT s u m [Char]
continue [[Char]]
xs) ParsecT s u m [Char]
-> ParsecT s u m [Char] -> ParsecT s u m [Char]
forall a. ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Char] -> ParsecT s u m [Char]
forall a. a -> ParsecT s u m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
""
        | Bool
otherwise    = [[Char]] -> ParsecT s u m [Char]
continue [[Char]]
xs

    continue :: [[Char]] -> ParsecT s u m [Char]
continue [[Char]]
xs = do
        Char
c <- ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
        (Char
c Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:) ([Char] -> [Char]) -> ParsecT s u m [Char] -> ParsecT s u m [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [[Char]] -> ParsecT s u m [Char]
go (([Char] -> Maybe [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ([Char] -> [Char] -> Maybe [Char]
forall a. Eq a => [a] -> [a] -> Maybe [a]
stripPrefix [Char
c]) [[Char]]
xs)