{-
    Copyright 2012-2022 Vidar Holen

    This file is part of ShellCheck.
    https://www.shellcheck.net

    ShellCheck is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    ShellCheck is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiWayIf #-}
module ShellCheck.Parser (parseScript, runTests) where

import ShellCheck.AST
import ShellCheck.ASTLib hiding (runTests)
import ShellCheck.Data
import ShellCheck.Interface
import ShellCheck.Prelude

import Control.Applicative ((<*), (*>))
import Control.Monad
import Control.Monad.Identity
import Control.Monad.Trans
import Data.Char
import Data.Functor
import Data.List (isPrefixOf, isInfixOf, isSuffixOf, partition, sortBy, intercalate, nub, find)
import Data.Maybe
import Data.Monoid
import GHC.Exts (sortWith)
import Prelude hiding (readList)
import System.IO
import Text.Parsec hiding (runParser, (<?>))
import Text.Parsec.Error
import Text.Parsec.Pos
import qualified Control.Monad.Reader as Mr
import qualified Control.Monad.State as Ms
import qualified Data.List.NonEmpty as NE
import qualified Data.Map.Strict as Map
import Debug.Trace

import Test.QuickCheck.All (quickCheckAll)

type SCBase m = Mr.ReaderT (Environment m) (Ms.StateT SystemState m)
type SCParser m v = ParsecT String UserState (SCBase m) v

backslash :: Monad m => SCParser m Char
backslash :: forall (m :: * -> *). Monad m => SCParser m Char
backslash = Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\'
linefeed :: Monad m => SCParser m Char
linefeed :: forall (m :: * -> *). Monad m => SCParser m Char
linefeed = do
    SCParser m Char -> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional SCParser m Char
forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
carriageReturn
    Char
c <- Char -> SCParser m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\n'
    ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readPendingHereDocs
    Char -> SCParser m Char
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
c
singleQuote :: ParsecT s u m Char
singleQuote = Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\''
doubleQuote :: ParsecT s u m Char
doubleQuote = Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'"'
variableStart :: ParsecT s u m Char
variableStart = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
upper ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
lower ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"_"
variableChars :: ParsecT s u m Char
variableChars = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
upper ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
lower ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"_"
-- Chars to allow function names to start with
functionStartChars :: ParsecT s u m Char
functionStartChars = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableChars ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
":+?-./^@,"
-- Chars to allow inside function names
functionChars :: ParsecT s u m Char
functionChars = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableChars ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"#:+?-./^@,"
-- Chars to allow function names to start with, using the 'function' keyword
extendedFunctionStartChars :: ParsecT s u m Char
extendedFunctionStartChars = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
functionStartChars ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"[]*=!"
-- Chars to allow in functions using the 'function' keyword
extendedFunctionChars :: ParsecT s u m Char
extendedFunctionChars = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
extendedFunctionStartChars ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"[]*=!"
specialVariable :: ParsecT s u m Char
specialVariable = String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf ([String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
specialVariables)
paramSubSpecialChars :: ParsecT s u m Char
paramSubSpecialChars = String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"/:+-=%"
quotableChars :: String
quotableChars = String
"|&;<>()\\ '\t\n\r\xA0" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
doubleQuotableChars
quotable :: ParsecT s UserState m Char
quotable = ParsecT s UserState m Char
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m,
 Stream s m Char) =>
ParsecT s UserState m Char
almostSpace ParsecT s UserState m Char
-> ParsecT s UserState m Char -> ParsecT s UserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
quotableChars
bracedQuotable :: ParsecT s u m Char
bracedQuotable = String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"}\"$`'"
doubleQuotableChars :: String
doubleQuotableChars = String
"\\\"$`"
doubleQuotable :: ParsecT s u m Char
doubleQuotable = String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
doubleQuotableChars
whitespace :: ParsecT String UserState (SCBase m) Char
whitespace = String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
" \t" ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
carriageReturn ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m,
 Stream s m Char) =>
ParsecT s UserState m Char
almostSpace ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
linefeed
linewhitespace :: ParsecT s UserState m Char
linewhitespace = String -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
" \t" ParsecT s UserState m Char
-> ParsecT s UserState m Char -> ParsecT s UserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s UserState m Char
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m,
 Stream s m Char) =>
ParsecT s UserState m Char
almostSpace

suspectCharAfterQuotes :: ParsecT s u m Char
suspectCharAfterQuotes = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableChars ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'%'

extglobStartChars :: String
extglobStartChars = String
"?*@!+"
extglobStart :: ParsecT s u m Char
extglobStart = String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
extglobStartChars

unicodeDoubleQuotes :: String
unicodeDoubleQuotes = String
"\x201C\x201D\x2033\x2036"
unicodeSingleQuotes :: String
unicodeSingleQuotes = String
"\x2018\x2019"

prop_spacing1 :: Bool
prop_spacing1 = ParsecT String UserState (SCBase Identity) String -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing String
"  \\\n # Comment"
prop_spacing2 :: Bool
prop_spacing2 = ParsecT String UserState (SCBase Identity) String -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing String
"# We can continue lines with \\"
prop_spacing3 :: Bool
prop_spacing3 = ParsecT String UserState (SCBase Identity) String -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing String
"   \\\n #  --verbose=true \\"
spacing :: ParsecT s UserState m String
spacing = do
    [String]
x <- ParsecT s UserState m String -> ParsecT s UserState m [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT s UserState m Char -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT s UserState m Char
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Char
linewhitespace ParsecT s UserState m String
-> ParsecT s UserState m String -> ParsecT s UserState m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s UserState m String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
continuation)
    ParsecT s UserState m String -> ParsecT s UserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT s UserState m String
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
readComment
    String -> ParsecT s UserState m String
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT s UserState m String)
-> String -> ParsecT s UserState m String
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
x
  where
    continuation :: ParsecT s UserState m String
continuation = do
        ParsecT s UserState m String -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT s UserState m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"\\\n")
        -- The line was continued. Warn if this next line is a comment with a trailing \
        String
whitespace <- ParsecT s UserState m Char -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT s UserState m Char
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Char
linewhitespace
        ParsecT s UserState m () -> ParsecT s UserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT s UserState m () -> ParsecT s UserState m ())
-> ParsecT s UserState m () -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ do
            String
x <- ParsecT s UserState m String
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
readComment
            Bool -> ParsecT s UserState m () -> ParsecT s UserState m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
"\\" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
x) (ParsecT s UserState m () -> ParsecT s UserState m ())
-> ParsecT s UserState m () -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$
                Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1143 String
"This backslash is part of a comment and does not continue the line."
        String -> ParsecT s UserState m String
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return String
whitespace

spacing1 :: ParsecT s UserState m String
spacing1 = do
    String
spacing <- ParsecT s UserState m String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Bool -> ParsecT s UserState m () -> ParsecT s UserState m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
spacing) (ParsecT s UserState m () -> ParsecT s UserState m ())
-> ParsecT s UserState m () -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s UserState m ()
forall a. String -> ParsecT s UserState m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected whitespace"
    String -> ParsecT s UserState m String
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return String
spacing

prop_allspacing :: Bool
prop_allspacing = ParsecT String UserState (SCBase Identity) String -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing String
"#foo"
prop_allspacing2 :: Bool
prop_allspacing2 = ParsecT String UserState (SCBase Identity) String -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing String
" #foo\n # bar\n#baz\n"
prop_allspacing3 :: Bool
prop_allspacing3 = ParsecT String UserState (SCBase Identity) String -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing String
"#foo\n#bar\n#baz\n"
allspacing :: ParsecT String UserState (SCBase m) String
allspacing = do
    String
s <- ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Bool
more <- Bool
-> ParsecT String UserState (SCBase m) Bool
-> ParsecT String UserState (SCBase m) Bool
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
False (SCParser m Char
forall (m :: * -> *). Monad m => SCParser m Char
linefeed SCParser m Char
-> ParsecT String UserState (SCBase m) Bool
-> ParsecT String UserState (SCBase m) Bool
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> ParsecT String UserState (SCBase m) Bool
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
    if Bool
more then do
        String
rest <- ParsecT String UserState (SCBase m) String
allspacing
        String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT String UserState (SCBase m) String)
-> String -> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
rest
      else
        String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
s

allspacingOrFail :: ParsecT String UserState (SCBase m) String
allspacingOrFail = do
    String
s <- ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
s) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) ()
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected whitespace"
    String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
s

readUnicodeQuote :: ParsecT String UserState (SCBase m) Token
readUnicodeQuote = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Char
c <- String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf (String
unicodeSingleQuotes String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
unicodeDoubleQuotes)
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Id -> Severity -> Integer -> String -> SCParser m ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
WarningC Integer
1110 String
"This is a unicode quote. Delete and retype it (or quote to make literal)."
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id [Char
c]

carriageReturn :: ParsecT s u m Char
carriageReturn = do
    SourcePos
pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\r'
    SourcePos -> Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1017 String
"Literal carriage return. Run script through tr -d '\\r' ."
    Char -> ParsecT s u m Char
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\r'

almostSpace :: ParsecT s UserState m Char
almostSpace = do
        Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s UserState m ()
parseNote Severity
ErrorC Integer
1018 (String -> ParsecT s UserState m ())
-> String -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ String
"This is a unicode space. Delete and retype it."
        String -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"\xA0\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2009\x200B\x202F"
        Char -> ParsecT s UserState m Char
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
' '

--------- Message/position annotation on top of user state
data ParseNote = ParseNote SourcePos SourcePos Severity Code String deriving (Line -> ParseNote -> String -> String
[ParseNote] -> String -> String
ParseNote -> String
(Line -> ParseNote -> String -> String)
-> (ParseNote -> String)
-> ([ParseNote] -> String -> String)
-> Show ParseNote
forall a.
(Line -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Line -> ParseNote -> String -> String
showsPrec :: Line -> ParseNote -> String -> String
$cshow :: ParseNote -> String
show :: ParseNote -> String
$cshowList :: [ParseNote] -> String -> String
showList :: [ParseNote] -> String -> String
Show, ParseNote -> ParseNote -> Bool
(ParseNote -> ParseNote -> Bool)
-> (ParseNote -> ParseNote -> Bool) -> Eq ParseNote
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ParseNote -> ParseNote -> Bool
== :: ParseNote -> ParseNote -> Bool
$c/= :: ParseNote -> ParseNote -> Bool
/= :: ParseNote -> ParseNote -> Bool
Eq)
data Context =
        ContextName SourcePos String
        | ContextAnnotation [Annotation]
        | ContextSource String
    deriving (Line -> Context -> String -> String
[Context] -> String -> String
Context -> String
(Line -> Context -> String -> String)
-> (Context -> String)
-> ([Context] -> String -> String)
-> Show Context
forall a.
(Line -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Line -> Context -> String -> String
showsPrec :: Line -> Context -> String -> String
$cshow :: Context -> String
show :: Context -> String
$cshowList :: [Context] -> String -> String
showList :: [Context] -> String -> String
Show)

data HereDocContext =
        HereDocPending Id Dashed Quoted String [Context] -- on linefeed, read this T_HereDoc
    deriving (Line -> HereDocContext -> String -> String
[HereDocContext] -> String -> String
HereDocContext -> String
(Line -> HereDocContext -> String -> String)
-> (HereDocContext -> String)
-> ([HereDocContext] -> String -> String)
-> Show HereDocContext
forall a.
(Line -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Line -> HereDocContext -> String -> String
showsPrec :: Line -> HereDocContext -> String -> String
$cshow :: HereDocContext -> String
show :: HereDocContext -> String
$cshowList :: [HereDocContext] -> String -> String
showList :: [HereDocContext] -> String -> String
Show)

data UserState = UserState {
    UserState -> Id
lastId :: Id,
    UserState -> Map Id (SourcePos, SourcePos)
positionMap :: Map.Map Id (SourcePos, SourcePos),
    UserState -> [ParseNote]
parseNotes :: [ParseNote],
    UserState -> Map Id [Token]
hereDocMap :: Map.Map Id [Token],
    UserState -> [HereDocContext]
pendingHereDocs :: [HereDocContext]
}
initialUserState :: UserState
initialUserState = UserState {
    lastId :: Id
lastId = Line -> Id
Id (Line -> Id) -> Line -> Id
forall a b. (a -> b) -> a -> b
$ -Line
1,
    positionMap :: Map Id (SourcePos, SourcePos)
positionMap = Map Id (SourcePos, SourcePos)
forall k a. Map k a
Map.empty,
    parseNotes :: [ParseNote]
parseNotes = [],
    hereDocMap :: Map Id [Token]
hereDocMap = Map Id [Token]
forall k a. Map k a
Map.empty,
    pendingHereDocs :: [HereDocContext]
pendingHereDocs = []
}

codeForParseNote :: ParseNote -> Integer
codeForParseNote (ParseNote SourcePos
_ SourcePos
_ Severity
_ Integer
code String
_) = Integer
code

getLastId :: ParsecT s UserState m Id
getLastId = UserState -> Id
lastId (UserState -> Id)
-> ParsecT s UserState m UserState -> ParsecT s UserState m Id
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s UserState m UserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState

getNextIdBetween :: SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
startPos SourcePos
endPos = do
    UserState
state <- ParsecT s UserState m UserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    let newId :: Id
newId = Id -> Id
incId (UserState -> Id
lastId UserState
state)
    let newMap :: Map Id (SourcePos, SourcePos)
newMap = Id
-> (SourcePos, SourcePos)
-> Map Id (SourcePos, SourcePos)
-> Map Id (SourcePos, SourcePos)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Id
newId (SourcePos
startPos, SourcePos
endPos) (UserState -> Map Id (SourcePos, SourcePos)
positionMap UserState
state)
    UserState -> ParsecT s UserState m ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState (UserState -> ParsecT s UserState m ())
-> UserState -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ UserState
state {
        lastId = newId,
        positionMap = newMap
    }
    Id -> ParsecT s UserState m Id
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Id
newId
  where incId :: Id -> Id
incId (Id Line
n) = Line -> Id
Id (Line -> Id) -> Line -> Id
forall a b. (a -> b) -> a -> b
$ Line
nLine -> Line -> Line
forall a. Num a => a -> a -> a
+Line
1

getNextIdSpanningTokens :: Token -> Token -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokens Token
startTok Token
endTok = do
    (SourcePos
start, SourcePos
_) <- Id -> SCParser m (SourcePos, SourcePos)
forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId (Token -> Id
getId Token
startTok)
    (SourcePos
_, SourcePos
end)   <- Id -> SCParser m (SourcePos, SourcePos)
forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId (Token -> Id
getId Token
endTok)
    SourcePos -> SourcePos -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
end

-- Get an ID starting from the first token of the list, and ending after the last
getNextIdSpanningTokenList :: [Token] -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokenList [Token]
list =
    case [Token]
list of
    [] -> do
        SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        SourcePos -> SourcePos -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
pos SourcePos
pos
    (Token
h:[Token]
_) ->
        Token -> Token -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *}.
Monad m =>
Token -> Token -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokens Token
h ([Token] -> Token
forall a. HasCallStack => [a] -> a
last [Token]
list)

-- Get the span covered by an id
getSpanForId :: Monad m => Id -> SCParser m (SourcePos, SourcePos)
getSpanForId :: forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId Id
id =
    (SourcePos, SourcePos)
-> Id -> Map Id (SourcePos, SourcePos) -> (SourcePos, SourcePos)
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault (String -> (SourcePos, SourcePos)
forall a. HasCallStack => String -> a
error (String -> (SourcePos, SourcePos))
-> String -> (SourcePos, SourcePos)
forall a b. (a -> b) -> a -> b
$ String -> String
pleaseReport String
"no parser span for id") Id
id (Map Id (SourcePos, SourcePos) -> (SourcePos, SourcePos))
-> ParsecT
     String UserState (SCBase m) (Map Id (SourcePos, SourcePos))
-> ParsecT String UserState (SCBase m) (SourcePos, SourcePos)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        ParsecT String UserState (SCBase m) (Map Id (SourcePos, SourcePos))
forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m (Map Id (SourcePos, SourcePos))
getMap

-- Create a new id with the same span as an existing one
getNewIdFor :: Monad m => Id -> SCParser m Id
getNewIdFor :: forall (m :: * -> *). Monad m => Id -> SCParser m Id
getNewIdFor Id
id = Id -> SCParser m (SourcePos, SourcePos)
forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId Id
id SCParser m (SourcePos, SourcePos)
-> ((SourcePos, SourcePos)
    -> ParsecT String UserState (SCBase m) Id)
-> ParsecT String UserState (SCBase m) Id
forall a b.
ParsecT String UserState (SCBase m) a
-> (a -> ParsecT String UserState (SCBase m) b)
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (SourcePos -> SourcePos -> ParsecT String UserState (SCBase m) Id)
-> (SourcePos, SourcePos) -> ParsecT String UserState (SCBase m) Id
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry SourcePos -> SourcePos -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween

data IncompleteInterval = IncompleteInterval SourcePos

startSpan :: ParsecT s u m IncompleteInterval
startSpan = SourcePos -> IncompleteInterval
IncompleteInterval (SourcePos -> IncompleteInterval)
-> ParsecT s u m SourcePos -> ParsecT s u m IncompleteInterval
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition

endSpan :: IncompleteInterval -> ParsecT s UserState m Id
endSpan (IncompleteInterval SourcePos
start) = do
    SourcePos
endPos <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    SourcePos -> SourcePos -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
endPos

getSpanPositionsFor :: ParsecT s u m a -> ParsecT s u m (SourcePos, SourcePos)
getSpanPositionsFor ParsecT s u m a
m = do
    SourcePos
start <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT s u m a
m
    SourcePos
end <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    (SourcePos, SourcePos) -> ParsecT s u m (SourcePos, SourcePos)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SourcePos
start, SourcePos
end)

addToHereDocMap :: Id -> [Token] -> ParsecT s UserState m ()
addToHereDocMap Id
id [Token]
list = do
    UserState
state <- ParsecT s UserState m UserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    let map :: Map Id [Token]
map = UserState -> Map Id [Token]
hereDocMap UserState
state
    UserState -> ParsecT s UserState m ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState (UserState -> ParsecT s UserState m ())
-> UserState -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ UserState
state {
        hereDocMap = Map.insert id list map
    }

addPendingHereDoc :: Id -> Dashed -> Quoted -> String -> ParsecT s UserState m ()
addPendingHereDoc Id
id Dashed
d Quoted
q String
str = do
    UserState
state <- ParsecT s UserState m UserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    [Context]
context <- ParsecT s UserState m [Context]
forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    let docs :: [HereDocContext]
docs = UserState -> [HereDocContext]
pendingHereDocs UserState
state
    UserState -> ParsecT s UserState m ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState (UserState -> ParsecT s UserState m ())
-> UserState -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ UserState
state {
        pendingHereDocs = HereDocPending id d q str context : docs
    }

popPendingHereDocs :: ParsecT s UserState m [HereDocContext]
popPendingHereDocs = do
    UserState
state <- ParsecT s UserState m UserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
    let pending :: [HereDocContext]
pending = UserState -> [HereDocContext]
pendingHereDocs UserState
state
    UserState -> ParsecT s UserState m ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState (UserState -> ParsecT s UserState m ())
-> UserState -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ UserState
state {
        pendingHereDocs = []
    }
    [HereDocContext] -> ParsecT s UserState m [HereDocContext]
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([HereDocContext] -> ParsecT s UserState m [HereDocContext])
-> ([HereDocContext] -> [HereDocContext])
-> [HereDocContext]
-> ParsecT s UserState m [HereDocContext]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [HereDocContext] -> [HereDocContext]
forall a. [a] -> [a]
reverse ([HereDocContext] -> ParsecT s UserState m [HereDocContext])
-> [HereDocContext] -> ParsecT s UserState m [HereDocContext]
forall a b. (a -> b) -> a -> b
$ UserState -> [HereDocContext]
pendingHereDocs UserState
state

getMap :: ParsecT s UserState m (Map Id (SourcePos, SourcePos))
getMap = UserState -> Map Id (SourcePos, SourcePos)
positionMap (UserState -> Map Id (SourcePos, SourcePos))
-> ParsecT s UserState m UserState
-> ParsecT s UserState m (Map Id (SourcePos, SourcePos))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s UserState m UserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
getParseNotes :: ParsecT s UserState m [ParseNote]
getParseNotes = UserState -> [ParseNote]
parseNotes (UserState -> [ParseNote])
-> ParsecT s UserState m UserState
-> ParsecT s UserState m [ParseNote]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s UserState m UserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState

addParseNote :: ParseNote -> ParsecT s UserState m ()
addParseNote ParseNote
n = do
    Bool
irrelevant <- Integer -> ParsecT s UserState m Bool
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> m Bool
shouldIgnoreCode (ParseNote -> Integer
codeForParseNote ParseNote
n)
    Bool -> ParsecT s UserState m () -> ParsecT s UserState m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
irrelevant (ParsecT s UserState m () -> ParsecT s UserState m ())
-> ParsecT s UserState m () -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ do
        UserState
state <- ParsecT s UserState m UserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
        UserState -> ParsecT s UserState m ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState (UserState -> ParsecT s UserState m ())
-> UserState -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ UserState
state {
            parseNotes = n : parseNotes state
        }

ignoreProblemsOf :: t (t m) b -> t (t m) b
ignoreProblemsOf t (t m) b
p = do
    a
systemState <- t m a -> t (t m) a
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (t m a -> t (t m) a) -> (m a -> t m a) -> m a -> t (t m) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> t m a
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> t (t m) a) -> m a -> t (t m) a
forall a b. (a -> b) -> a -> b
$ m a
forall s (m :: * -> *). MonadState s m => m s
Ms.get
    t (t m) b
p t (t m) b -> t (t m) () -> t (t m) b
forall a b. t (t m) a -> t (t m) b -> t (t m) a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (t m () -> t (t m) ()
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (t m () -> t (t m) ()) -> (a -> t m ()) -> a -> t (t m) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m () -> t m ()
forall (m :: * -> *) a. Monad m => m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> t m ()) -> (a -> m ()) -> a -> t m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
Ms.put (a -> t (t m) ()) -> a -> t (t m) ()
forall a b. (a -> b) -> a -> b
$ a
systemState)

shouldIgnoreCode :: Integer -> m Bool
shouldIgnoreCode Integer
code = do
    [Context]
context <- m [Context]
forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    Bool
checkSourced <- (Environment m -> Bool) -> m Bool
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Mr.asks Environment m -> Bool
forall (m :: * -> *). Environment m -> Bool
checkSourced
    Bool -> m Bool
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ (Context -> Bool) -> [Context] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Bool -> Integer -> Context -> Bool
contextItemDisablesCode Bool
checkSourced Integer
code) [Context]
context

-- Does this item on the context stack disable warnings for 'code'?
contextItemDisablesCode :: Bool -> Integer -> Context -> Bool
contextItemDisablesCode :: Bool -> Integer -> Context -> Bool
contextItemDisablesCode Bool
alsoCheckSourced Integer
code = Bool -> Context -> Bool
disabling Bool
alsoCheckSourced
  where
    disabling :: Bool -> Context -> Bool
disabling Bool
checkSourced Context
item =
        case Context
item of
            ContextAnnotation [Annotation]
list -> (Annotation -> Bool) -> [Annotation] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Annotation -> Bool
disabling' [Annotation]
list
            ContextSource String
_ -> Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Bool
checkSourced
            Context
_ -> Bool
False
    disabling' :: Annotation -> Bool
disabling' (DisableComment Integer
n Integer
m) = Integer
code Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
n Bool -> Bool -> Bool
&& Integer
code Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
m
    disabling' Annotation
_ = Bool
False



getCurrentAnnotations :: Bool -> f [Annotation]
getCurrentAnnotations Bool
includeSource =
    (Context -> [Annotation]) -> [Context] -> [Annotation]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Context -> [Annotation]
get ([Context] -> [Annotation])
-> ([Context] -> [Context]) -> [Context] -> [Annotation]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Context -> Bool) -> [Context] -> [Context]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not (Bool -> Bool) -> (Context -> Bool) -> Context -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Context -> Bool
isBoundary) ([Context] -> [Annotation]) -> f [Context] -> f [Annotation]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f [Context]
forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
  where
    get :: Context -> [Annotation]
get (ContextAnnotation [Annotation]
list) = [Annotation]
list
    get Context
_ = []
    isBoundary :: Context -> Bool
isBoundary (ContextSource String
_) = Bool -> Bool
not Bool
includeSource
    isBoundary Context
_ = Bool
False


shouldFollow :: String -> ParsecT s u m Bool
shouldFollow String
file = do
    [Context]
context <- ParsecT s u m [Context]
forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    if (Context -> Bool) -> [Context] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Context -> Bool
isThisFile [Context]
context
      then Bool -> ParsecT s u m Bool
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
      else
        if [Context] -> Line
forall a. [a] -> Line
forall (t :: * -> *) a. Foldable t => t a -> Line
length ((Context -> Bool) -> [Context] -> [Context]
forall a. (a -> Bool) -> [a] -> [a]
filter Context -> Bool
isSource [Context]
context) Line -> Line -> Bool
forall a. Ord a => a -> a -> Bool
>= Line
100
          then do
            Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1092 String
"Stopping at 100 'source' frames :O"
            Bool -> ParsecT s u m Bool
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
          else
            Bool -> ParsecT s u m Bool
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
  where
    isSource :: Context -> Bool
isSource (ContextSource String
_) = Bool
True
    isSource Context
_ = Bool
False
    isThisFile :: Context -> Bool
isThisFile (ContextSource String
name) | String
name String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
file = Bool
True
    isThisFile Context
_= Bool
False

getSourceOverride :: m (Maybe String)
getSourceOverride = do
    [Context]
context <- m [Context]
forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    Maybe String -> m (Maybe String)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe String -> m (Maybe String))
-> ([Context] -> Maybe String) -> [Context] -> m (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe String] -> Maybe String
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum ([Maybe String] -> Maybe String)
-> ([Context] -> [Maybe String]) -> [Context] -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Context -> Maybe String) -> [Context] -> [Maybe String]
forall a b. (a -> b) -> [a] -> [b]
map Context -> Maybe String
findFile ([Context] -> m (Maybe String)) -> [Context] -> m (Maybe String)
forall a b. (a -> b) -> a -> b
$ (Context -> Bool) -> [Context] -> [Context]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile Context -> Bool
isSameFile [Context]
context
  where
    isSameFile :: Context -> Bool
isSameFile (ContextSource String
_) = Bool
False
    isSameFile Context
_ = Bool
True

    findFile :: Context -> Maybe String
findFile (ContextAnnotation [Annotation]
list) = [Maybe String] -> Maybe String
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum ([Maybe String] -> Maybe String) -> [Maybe String] -> Maybe String
forall a b. (a -> b) -> a -> b
$ (Annotation -> Maybe String) -> [Annotation] -> [Maybe String]
forall a b. (a -> b) -> [a] -> [b]
map Annotation -> Maybe String
getFile [Annotation]
list
    findFile Context
_ = Maybe String
forall a. Maybe a
Nothing
    getFile :: Annotation -> Maybe String
getFile (SourceOverride String
str) = String -> Maybe String
forall a. a -> Maybe a
Just String
str
    getFile Annotation
_ = Maybe String
forall a. Maybe a
Nothing

-- Store potential parse problems outside of parsec

data SystemState = SystemState {
    SystemState -> [Context]
contextStack :: [Context],
    SystemState -> [ParseNote]
parseProblems :: [ParseNote]
}
initialSystemState :: SystemState
initialSystemState = SystemState {
    contextStack :: [Context]
contextStack = [],
    parseProblems :: [ParseNote]
parseProblems = []
}

data Environment m = Environment {
    forall (m :: * -> *). Environment m -> SystemInterface m
systemInterface :: SystemInterface m,
    forall (m :: * -> *). Environment m -> Bool
checkSourced :: Bool,
    forall (m :: * -> *). Environment m -> Bool
ignoreRC :: Bool,
    forall (m :: * -> *). Environment m -> String
currentFilename :: String,
    forall (m :: * -> *). Environment m -> Maybe Shell
shellTypeOverride :: Maybe Shell
}

parseProblem :: Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
level Integer
code String
msg = do
    SourcePos
pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    SourcePos -> Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
level Integer
code String
msg

setCurrentContexts :: [Context] -> m ()
setCurrentContexts [Context]
c = (SystemState -> SystemState) -> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
Ms.modify (\SystemState
state -> SystemState
state { contextStack = c })
getCurrentContexts :: m [Context]
getCurrentContexts = (SystemState -> [Context]) -> m [Context]
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
Ms.gets SystemState -> [Context]
contextStack

popContext :: m (Maybe Context)
popContext = do
    [Context]
v <- m [Context]
forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    case [Context]
v of
        (Context
a:[Context]
r) -> do
            [Context] -> m ()
forall {m :: * -> *}. MonadState SystemState m => [Context] -> m ()
setCurrentContexts [Context]
r
            Maybe Context -> m (Maybe Context)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Context -> m (Maybe Context))
-> Maybe Context -> m (Maybe Context)
forall a b. (a -> b) -> a -> b
$ Context -> Maybe Context
forall a. a -> Maybe a
Just Context
a
        [] ->
            Maybe Context -> m (Maybe Context)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Context
forall a. Maybe a
Nothing

pushContext :: Context -> m ()
pushContext Context
c = do
    [Context]
v <- m [Context]
forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts
    [Context] -> m ()
forall {m :: * -> *}. MonadState SystemState m => [Context] -> m ()
setCurrentContexts (Context
cContext -> [Context] -> [Context]
forall a. a -> [a] -> [a]
:[Context]
v)

parseProblemAtWithEnd :: SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
start SourcePos
end Severity
level Integer
code String
msg = do
    Bool
irrelevant <- Integer -> m Bool
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> m Bool
shouldIgnoreCode Integer
code
    Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
irrelevant (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
        ParseNote -> m ()
forall {m :: * -> *}. MonadState SystemState m => ParseNote -> m ()
addParseProblem ParseNote
note
  where
    note :: ParseNote
note = SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
start SourcePos
end Severity
level Integer
code String
msg

addParseProblem :: ParseNote -> m ()
addParseProblem ParseNote
note =
    (SystemState -> SystemState) -> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
Ms.modify (\SystemState
state -> SystemState
state {
        parseProblems = note:parseProblems state
    })

parseProblemAt :: SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos = SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
pos SourcePos
pos

parseProblemAtId :: Monad m => Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId :: forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
level Integer
code String
msg = do
    (SourcePos
start, SourcePos
end) <- Id -> SCParser m (SourcePos, SourcePos)
forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId Id
id
    SourcePos
-> SourcePos -> Severity -> Integer -> String -> SCParser m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
start SourcePos
end Severity
level Integer
code String
msg

-- Store non-parse problems inside

parseNote :: Severity -> Integer -> String -> ParsecT s UserState m ()
parseNote Severity
c Integer
l String
a = do
    SourcePos
pos <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
c Integer
l String
a

parseNoteAt :: SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
c Integer
l String
a = ParseNote -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
ParseNote -> ParsecT s UserState m ()
addParseNote (ParseNote -> ParsecT s UserState m ())
-> ParseNote -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
pos SourcePos
pos Severity
c Integer
l String
a
parseNoteAtId :: Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
parseNoteAtId Id
id Severity
c Integer
l String
a = do
    (SourcePos
start, SourcePos
end) <- Id -> SCParser m (SourcePos, SourcePos)
forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId Id
id
    ParseNote -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
ParseNote -> ParsecT s UserState m ()
addParseNote (ParseNote -> ParsecT String UserState (SCBase m) ())
-> ParseNote -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
start SourcePos
end Severity
c Integer
l String
a

parseNoteAtWithEnd :: SourcePos
-> SourcePos
-> Severity
-> Integer
-> String
-> ParsecT s UserState m ()
parseNoteAtWithEnd SourcePos
start SourcePos
end Severity
c Integer
l String
a = ParseNote -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
ParseNote -> ParsecT s UserState m ()
addParseNote (ParseNote -> ParsecT s UserState m ())
-> ParseNote -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ SourcePos
-> SourcePos -> Severity -> Integer -> String -> ParseNote
ParseNote SourcePos
start SourcePos
end Severity
c Integer
l String
a

--------- Convenient combinators
thenSkip :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
thenSkip ParsecT s u m a
main ParsecT s u m a
follow = ParsecT s u m a
main ParsecT s u m a -> ParsecT s u m () -> ParsecT s u m a
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 a -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT s u m a
follow

unexpecting :: String -> ParsecT s u m a -> ParsecT s u m ()
unexpecting String
s ParsecT s u m a
p = 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 ())
-> ParsecT s u m () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$
    (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
p ParsecT s u m a -> ParsecT s u m () -> ParsecT s u m ()
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> ParsecT s u m ()
forall a. String -> ParsecT s u m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Unexpected " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s)) ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> () -> ParsecT s u m ()
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

notFollowedBy2 :: ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 = String -> ParsecT s u m a -> ParsecT s u m ()
forall {s} {u} {m :: * -> *} {a}.
String -> ParsecT s u m a -> ParsecT s u m ()
unexpecting String
""

isFollowedBy :: ParsecT s u m a -> ParsecT s u m Bool
isFollowedBy ParsecT s u m a
p = (ParsecT s u m Bool -> ParsecT s u m Bool
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s u m Bool -> ParsecT s u m Bool)
-> (ParsecT s u m Bool -> ParsecT s u m Bool)
-> ParsecT s u m Bool
-> ParsecT s u m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT s u m Bool -> ParsecT s u m Bool
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m Bool -> ParsecT s u m Bool)
-> ParsecT s u m Bool -> ParsecT s u m Bool
forall a b. (a -> b) -> a -> b
$ ParsecT s u m a
p ParsecT s u m a -> Bool -> ParsecT s u m Bool
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
True) ParsecT s u m Bool -> ParsecT s u m Bool -> ParsecT s u m Bool
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Bool -> ParsecT s u m Bool
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

reluctantlyTill :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
reluctantlyTill ParsecT s u m a
p ParsecT s u m a
end =
    (ParsecT s u m () -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s u m a -> ParsecT s u m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (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
end) ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof) ParsecT s u m () -> 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 (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [a] -> ParsecT s u m [a]
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return []) ParsecT s u m [a] -> 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 -> ParsecT s u m a
<|> do
        a
x <- ParsecT s u m a
p
        [a]
more <- ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
reluctantlyTill ParsecT s u m a
p ParsecT s u m a
end
        [a] -> ParsecT s u m [a]
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> ParsecT s u m [a]) -> [a] -> ParsecT s u m [a]
forall a b. (a -> b) -> a -> b
$ a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
more
      ParsecT s u m [a] -> 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 -> ParsecT s u m a
<|> [a] -> ParsecT s u m [a]
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return []

reluctantlyTill1 :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
reluctantlyTill1 ParsecT s u m a
p ParsecT s u m a
end = do
    ParsecT s u m a -> ParsecT s u m ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 ParsecT s u m a
end
    a
x <- ParsecT s u m a
p
    [a]
more <- ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
reluctantlyTill ParsecT s u m a
p ParsecT s u m a
end
    [a] -> ParsecT s u m [a]
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> ParsecT s u m [a]) -> [a] -> ParsecT s u m [a]
forall a b. (a -> b) -> a -> b
$ a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
more

attempting :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
attempting ParsecT s u m a
rest ParsecT s u m a
branch =
    (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
branch ParsecT s u m a -> 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 (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT s u m a
rest) ParsecT s u m a -> 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 -> ParsecT s u m a
<|> ParsecT s u m a
rest

orFail :: ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
orFail ParsecT s u m a
parser ParsecT s u m String
errorAction =
    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
parser ParsecT s u m a -> 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 -> ParsecT s u m a
<|> (ParsecT s u m String
errorAction ParsecT s u m String
-> (String -> ParsecT s u m a) -> ParsecT s u m a
forall a b.
ParsecT s u m a -> (a -> ParsecT s u m b) -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> ParsecT s u m a
forall a. String -> ParsecT s u m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail)

-- Construct a node with a parser, e.g. T_Literal `withParser` (readGenericLiteral ",")
withParser :: (Id -> t -> b)
-> ParsecT s UserState m t -> ParsecT s UserState m b
withParser Id -> t -> b
node ParsecT s UserState m t
parser = do
    IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    t
contents <- ParsecT s UserState m t
parser
    Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    b -> ParsecT s UserState m b
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> ParsecT s UserState m b) -> b -> ParsecT s UserState m b
forall a b. (a -> b) -> a -> b
$ Id -> t -> b
node Id
id t
contents

wasIncluded :: ParsecT s u m a -> ParsecT s u m Bool
wasIncluded ParsecT s u m a
p = Bool -> ParsecT s u m Bool -> ParsecT s u m Bool
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
False (ParsecT s u m a
p ParsecT s u m a -> ParsecT s u m Bool -> ParsecT s u m Bool
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> ParsecT s u m Bool
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)

acceptButWarn :: ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn ParsecT s u m a
parser Severity
level Integer
code String
note =
    ParsecT s u m () -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do
        SourcePos
pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        ParsecT s u m a
parser
        SourcePos -> Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
level Integer
code String
note
      )

parsecBracket :: ParsecT s u m t
-> (t -> ParsecT s u m a)
-> (t -> ParsecT s u m b)
-> ParsecT s u m b
parsecBracket ParsecT s u m t
before t -> ParsecT s u m a
after t -> ParsecT s u m b
op = do
    t
val <- ParsecT s u m t
before
    t -> ParsecT s u m b
op t
val ParsecT s u m b -> ParsecT s u m a -> ParsecT s u m b
forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` t -> ParsecT s u m a
after t
val ParsecT s u m b -> ParsecT s u m b -> ParsecT s u m b
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (t -> ParsecT s u m a
after t
val ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
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
*> String -> ParsecT s u m b
forall a. String -> ParsecT s u m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"")

swapContext :: [Context] -> ParsecT s u m b -> ParsecT s u m b
swapContext [Context]
contexts ParsecT s u m b
p =
    ParsecT s u m [Context]
-> ([Context] -> ParsecT s u m ())
-> ([Context] -> ParsecT s u m b)
-> ParsecT s u m b
forall {s} {m :: * -> *} {t} {u} {t} {a} {b}.
Stream s m t =>
ParsecT s u m t
-> (t -> ParsecT s u m a)
-> (t -> ParsecT s u m b)
-> ParsecT s u m b
parsecBracket (ParsecT s u m [Context]
forall {m :: * -> *}. MonadState SystemState m => m [Context]
getCurrentContexts ParsecT s u m [Context]
-> ParsecT s u m () -> ParsecT s u m [Context]
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
<* [Context] -> ParsecT s u m ()
forall {m :: * -> *}. MonadState SystemState m => [Context] -> m ()
setCurrentContexts [Context]
contexts)
                  [Context] -> ParsecT s u m ()
forall {m :: * -> *}. MonadState SystemState m => [Context] -> m ()
setCurrentContexts
                  (ParsecT s u m b -> [Context] -> ParsecT s u m b
forall a b. a -> b -> a
const ParsecT s u m b
p)

withContext :: Context -> ParsecT s u m b -> ParsecT s u m b
withContext Context
entry ParsecT s u m b
p = ParsecT s u m ()
-> (() -> ParsecT s u m (Maybe Context))
-> (() -> ParsecT s u m b)
-> ParsecT s u m b
forall {s} {m :: * -> *} {t} {u} {t} {a} {b}.
Stream s m t =>
ParsecT s u m t
-> (t -> ParsecT s u m a)
-> (t -> ParsecT s u m b)
-> ParsecT s u m b
parsecBracket (Context -> ParsecT s u m ()
forall {m :: * -> *}. MonadState SystemState m => Context -> m ()
pushContext Context
entry) (ParsecT s u m (Maybe Context)
-> () -> ParsecT s u m (Maybe Context)
forall a b. a -> b -> a
const ParsecT s u m (Maybe Context)
forall {m :: * -> *}. MonadState SystemState m => m (Maybe Context)
popContext) (ParsecT s u m b -> () -> ParsecT s u m b
forall a b. a -> b -> a
const ParsecT s u m b
p)

called :: String -> ParsecT s u m b -> ParsecT s u m b
called String
s ParsecT s u m b
p = do
    SourcePos
pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Context -> ParsecT s u m b -> ParsecT s u m b
forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
Context -> ParsecT s u m b -> ParsecT s u m b
withContext (SourcePos -> String -> Context
ContextName SourcePos
pos String
s) ParsecT s u m b
p

withAnnotations :: [Annotation] -> ParsecT s u m b -> ParsecT s u m b
withAnnotations [Annotation]
anns ParsecT s u m b
p =
    if [Annotation] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Annotation]
anns then ParsecT s u m b
p else Context -> ParsecT s u m b -> ParsecT s u m b
forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
Context -> ParsecT s u m b -> ParsecT s u m b
withContext ([Annotation] -> Context
ContextAnnotation [Annotation]
anns) ParsecT s u m b
p

readConditionContents :: Bool -> ParsecT String UserState (SCBase m) Token
readConditionContents Bool
single =
    ParsecT String UserState (SCBase m) Token
readCondContents ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) Token
forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (do
                                SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                                String
s <- ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
                                ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing1
                                Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
s String -> [String] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
commonCommands) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
                                    SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1014 String
"Use 'if cmd; then ..' to check exit code, or 'if [[ $(cmd) == .. ]]' to check output.")

  where
    spacingOrLf :: ParsecT String UserState (SCBase m) String
spacingOrLf = Bool -> ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
True
    condSpacing :: Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
required = do
        SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
space <- ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
required Bool -> Bool -> Bool
&& String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
space) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
            SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1035 String
"You are missing a required space here."
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
single Bool -> Bool -> Bool
&& Char
'\n' Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
space) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
            SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1080 String
"When breaking lines in [ ], you need \\ before the linefeed."
        String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
space

    typ :: ConditionType
typ = if Bool
single then ConditionType
SingleBracket else ConditionType
DoubleBracket
    readCondBinaryOp :: ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondBinaryOp = ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) (Token -> Token -> Token)
 -> ParsecT String UserState (SCBase m) (Token -> Token -> Token))
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall a b. (a -> b) -> a -> b
$ do
        ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
guardArithmetic
        Token -> Token -> Token
op <- ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *} {s} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m (Token -> Token -> Token)
getOp
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacingOrLf
        (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token -> Token -> Token
op
      where
        flaglessOps :: [String]
flaglessOps = [ String
"==", String
"!=", String
"<=", String
">=", String
"=~", String
">", String
"<", String
"=" ]

        getOp :: ParsecT s UserState m (Token -> Token -> Token)
getOp = do
            IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            String
op <- ParsecT s UserState m String -> ParsecT s UserState m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String -> ParsecT s u m String
readRegularOrEscaped ParsecT s UserState m String
forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m String
anyOp
            Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            (Token -> Token -> Token)
-> ParsecT s UserState m (Token -> Token -> Token)
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Token -> Token -> Token)
 -> ParsecT s UserState m (Token -> Token -> Token))
-> (Token -> Token -> Token)
-> ParsecT s UserState m (Token -> Token -> Token)
forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> String -> Token -> Token -> Token
TC_Binary Id
id ConditionType
typ String
op

        anyOp :: ParsecT s u m String
anyOp = ParsecT s u m String
forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m String
flagOp ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
flaglessOp ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT s u m String
forall a. String -> ParsecT s u m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail
                    String
"Expected comparison operator (don't wrap commands in []/[[]])"
        flagOp :: ParsecT s u m String
flagOp = ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ do
            String
s <- ParsecT s u m String
forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m String
readOp
            Bool -> ParsecT s u m () -> ParsecT s u m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
s String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"-a" Bool -> Bool -> Bool
|| String
s String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"-o") (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s u m ()
forall a. String -> ParsecT s u m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unexpected operator"
            String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return String
s
        flaglessOp :: ParsecT s u m String
flaglessOp =
            [ParsecT s u m String] -> ParsecT s u m String
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 String] -> ParsecT s u m String)
-> [ParsecT s u m String] -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ (String -> ParsecT s u m String)
-> [String] -> [ParsecT s u m String]
forall a b. (a -> b) -> [a] -> [b]
map (ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m String -> ParsecT s u m String)
-> (String -> ParsecT s u m String)
-> String
-> ParsecT s u m String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string) [String]
flaglessOps

        -- hacks to read quoted operators without having to read a shell word
    readEscaped :: ParsecT s u m String -> ParsecT s u m String
readEscaped ParsecT s u m String
p = ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ ParsecT s u m String
withEscape ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m String
withQuotes
      where
        withEscape :: ParsecT s u m String
withEscape = do
            Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\'
            String -> String
escaped (String -> String) -> ParsecT s u m String -> ParsecT s u m String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m String
p
        withQuotes :: ParsecT s u m String
withQuotes = do
            Char
c <- String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"'\""
            String
s <- ParsecT s u m String
p
            Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c
            String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT s u m String) -> String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ String -> String
escaped String
s
        escaped :: String -> String
escaped String
s = if (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
s) String
"<>()" then Char
'\\'Char -> String -> String
forall a. a -> [a] -> [a]
:String
s else String
s

    readRegularOrEscaped :: ParsecT s u m String -> ParsecT s u m String
readRegularOrEscaped ParsecT s u m String
p = ParsecT s u m String -> ParsecT s u m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String -> ParsecT s u m String
readEscaped ParsecT s u m String
p ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m String
p


    guardArithmetic :: ParsecT s u m ()
guardArithmetic = do
        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 ())
-> (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m ()
-> ParsecT s u m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT s u m () -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ ParsecT s u m Char -> ParsecT s u m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"+*/%") ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m String -> ParsecT s u m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"- ")
        Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1076 (String -> ParsecT s u m ()) -> String -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$
            if Bool
single
            then String
"Trying to do math? Use e.g. [ $((i/2+7)) -ge 18 ]."
            else String
"Trying to do math? Use e.g. [[ $((i/2+7)) -ge 18 ]]."

    readCondUnaryExp :: ParsecT String UserState (SCBase m) Token
readCondUnaryExp = do
      Token -> Token
op <- ParsecT String UserState (SCBase m) (Token -> Token)
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token)
readCondUnaryOp
      SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
      (Token -> Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Token -> Token
op ParsecT String UserState (SCBase m) Token
readCondWord ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) Token
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
`orFail` do
          SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1019 String
"Expected this to be an argument to the unary condition."
          String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"Expected an argument for the unary operator"

    readCondUnaryOp :: ParsecT String UserState (SCBase m) (Token -> Token)
readCondUnaryOp = ParsecT String UserState (SCBase m) (Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) (Token -> Token)
 -> ParsecT String UserState (SCBase m) (Token -> Token))
-> ParsecT String UserState (SCBase m) (Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token)
forall a b. (a -> b) -> a -> b
$ do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
s <- ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m String
readOp
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacingOrLf
        (Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token)
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Token -> Token)
 -> ParsecT String UserState (SCBase m) (Token -> Token))
-> (Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token)
forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> String -> Token -> Token
TC_Unary Id
id ConditionType
typ String
s

    readOp :: ParsecT s u m String
readOp = ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ do
        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 s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m Char
forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
weirdDash
        String
s <- ParsecT s u m Char -> ParsecT s u m String
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
letter ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT s u m String
forall a. String -> ParsecT s u m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected a test operator"
        String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Char
'-'Char -> String -> String
forall a. a -> [a] -> [a]
:String
s)

    weirdDash :: ParsecT s u m Char
weirdDash = do
        SourcePos
pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"\x058A\x05BE\x2010\x2011\x2012\x2013\x2014\x2015\xFE63\xFF0D"
        SourcePos -> Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1100
            String
"This is a unicode dash. Delete and retype as ASCII minus."
        Char -> ParsecT s u m Char
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'-'

    readCondWord :: ParsecT String UserState (SCBase m) Token
readCondWord = do
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"]"))
        Token
x <- ParsecT String UserState (SCBase m) Token
readNormalWord
        SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Token -> Bool
notArrayIndex Token
x Bool -> Bool -> Bool
&& String -> Token -> Bool
endedWith String
"]" Token
x Bool -> Bool -> Bool
&& Bool -> Bool
not (Token
x Token -> String -> Bool
`containsLiteral` String
"[")) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
            SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1020 (String -> ParsecT String UserState (SCBase m) ())
-> String -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
                String
"You need a space before the " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (if Bool
single then String
"]" else String
"]]") String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"."
            String -> ParsecT String UserState (SCBase m) ()
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Missing space before ]"
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
single Bool -> Bool -> Bool
&& String -> Token -> Bool
endedWith String
")" Token
x) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
            SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1021
                String
"You need a space before the \\)"
            String -> ParsecT String UserState (SCBase m) ()
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Missing space before )"
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
x
      where endedWith :: String -> Token -> Bool
endedWith String
str (T_NormalWord Id
id s :: [Token]
s@(Token
_:[Token]
_)) =
                case [Token] -> Token
forall a. HasCallStack => [a] -> a
last [Token]
s of T_Literal Id
id String
s -> String
str String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
s
                               Token
_ -> Bool
False
            endedWith String
_ Token
_ = Bool
False
            notArrayIndex :: Token -> Bool
notArrayIndex (T_NormalWord Id
id s :: [Token]
s@(Token
_:T_Literal Id
_ String
t:[Token]
_)) = String
t String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"["
            notArrayIndex Token
_ = Bool
True
            containsLiteral :: Token -> String -> Bool
containsLiteral Token
x String
s = String
s String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` Token -> String
onlyLiteralString Token
x

    readCondAndOp :: ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondAndOp = (Id -> ConditionType -> String -> Token -> Token -> Token)
-> String
-> Bool
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *} {b}.
Monad m =>
(Id -> ConditionType -> String -> b)
-> String -> Bool -> ParsecT String UserState (SCBase m) b
readAndOrOp Id -> ConditionType -> String -> Token -> Token -> Token
TC_And String
"&&" Bool
False ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Id -> ConditionType -> String -> Token -> Token -> Token)
-> String
-> Bool
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *} {b}.
Monad m =>
(Id -> ConditionType -> String -> b)
-> String -> Bool -> ParsecT String UserState (SCBase m) b
readAndOrOp Id -> ConditionType -> String -> Token -> Token -> Token
TC_And String
"-a" Bool
True

    readCondOrOp :: ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondOrOp = do
        ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
guardArithmetic
        (Id -> ConditionType -> String -> Token -> Token -> Token)
-> String
-> Bool
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *} {b}.
Monad m =>
(Id -> ConditionType -> String -> b)
-> String -> Bool -> ParsecT String UserState (SCBase m) b
readAndOrOp Id -> ConditionType -> String -> Token -> Token -> Token
TC_Or String
"||" Bool
False ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Id -> ConditionType -> String -> Token -> Token -> Token)
-> String
-> Bool
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *} {b}.
Monad m =>
(Id -> ConditionType -> String -> b)
-> String -> Bool -> ParsecT String UserState (SCBase m) b
readAndOrOp Id -> ConditionType -> String -> Token -> Token -> Token
TC_Or String
"-o" Bool
True

    readAndOrOp :: (Id -> ConditionType -> String -> b)
-> String -> Bool -> ParsecT String UserState (SCBase m) b
readAndOrOp Id -> ConditionType -> String -> b
node String
op Bool
requiresSpacing = do
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT String UserState (SCBase m) Char
forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
weirdDash
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
x <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
op
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Bool -> ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
requiresSpacing
        b -> ParsecT String UserState (SCBase m) b
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> ParsecT String UserState (SCBase m) b)
-> b -> ParsecT String UserState (SCBase m) b
forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> String -> b
node Id
id ConditionType
typ String
x

    readCondNullaryOrBinary :: ParsecT String UserState (SCBase m) Token
readCondNullaryOrBinary = do
      IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
      Token
x <- ParsecT String UserState (SCBase m) Token
readCondWord ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) Token
forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` (do
              SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
              ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'[')
              SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1026 (String -> ParsecT String UserState (SCBase m) ())
-> String -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ if Bool
single
                  then String
"If grouping expressions inside [..], use \\( ..\\)."
                  else String
"If grouping expressions inside [[..]], use ( .. )."
            )
      Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
      (do
            SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            Bool
isRegex <- ParsecT String UserState (SCBase m) Bool
forall {s} {m :: * -> *} {u}. Stream s m Char => ParsecT s u m Bool
regexOperatorAhead
            Token -> Token -> Token
op <- ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondBinaryOp
            Token
y <- if Bool
isRegex
                    then ParsecT String UserState (SCBase m) Token
readRegex
                    else  ParsecT String UserState (SCBase m) Token
readCondWord ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1027 String
"Expected another argument for this operator." ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase m) Token
forall a. ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadPlus m => m a
mzero)
            Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token
x Token -> Token -> Token
`op` Token
y)
          ) ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ( do
            Token -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
Token -> ParsecT String UserState (SCBase m) ()
checkTrailingOp Token
x
            Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> Token -> Token
TC_Nullary Id
id ConditionType
typ Token
x
          )

    checkTrailingOp :: Token -> ParsecT String UserState (SCBase m) ()
checkTrailingOp Token
x = Maybe (ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ (Maybe (ParsecT String UserState (SCBase m) ())
 -> ParsecT String UserState (SCBase m) ())
-> Maybe (ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        (T_Literal Id
id String
str) <- Token -> Maybe Token
getTrailingUnquotedLiteral Token
x
        String
trailingOp <- (String -> Bool) -> [String] -> Maybe String
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
str) [String]
binaryTestOps
        ParsecT String UserState (SCBase m) ()
-> Maybe (ParsecT String UserState (SCBase m) ())
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (ParsecT String UserState (SCBase m) ()
 -> Maybe (ParsecT String UserState (SCBase m) ()))
-> ParsecT String UserState (SCBase m) ()
-> Maybe (ParsecT String UserState (SCBase m) ())
forall a b. (a -> b) -> a -> b
$ Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
ErrorC Integer
1108 (String -> ParsecT String UserState (SCBase m) ())
-> String -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
            String
"You need a space before and after the " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
trailingOp String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ."

    readCondGroup :: ParsecT String UserState (SCBase m) Token
readCondGroup = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
lparen <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String -> ParsecT s u m String
readRegularOrEscaped (String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"(")
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
single Bool -> Bool -> Bool
&& String
lparen String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"(") (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
            SourcePos -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> m ()
singleWarning SourcePos
pos
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
single Bool -> Bool -> Bool
&& String
lparen String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"\\(") (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
            SourcePos -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> m ()
doubleWarning SourcePos
pos
        Bool -> ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
single
        Token
x <- ParsecT String UserState (SCBase m) Token
readCondContents
        SourcePos
cpos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
rparen <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String -> ParsecT s u m String
readRegularOrEscaped (String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
")")
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Bool -> ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
single
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
single Bool -> Bool -> Bool
&& String
rparen String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
")") (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
            SourcePos -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> m ()
singleWarning SourcePos
cpos
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
single Bool -> Bool -> Bool
&& String
rparen String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"\\)") (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
            SourcePos -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> m ()
doubleWarning SourcePos
cpos
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> Token -> Token
TC_Group Id
id ConditionType
typ Token
x

      where
        singleWarning :: SourcePos -> m ()
singleWarning SourcePos
pos =
            SourcePos -> Severity -> Integer -> String -> m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1028 String
"In [..] you have to escape \\( \\) or preferably combine [..] expressions."
        doubleWarning :: SourcePos -> m ()
doubleWarning SourcePos
pos =
            SourcePos -> Severity -> Integer -> String -> m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1029 String
"In [[..]] you shouldn't escape ( or )."


    -- Currently a bit of a hack since parsing rules are obscure
    regexOperatorAhead :: ParsecT s u m Bool
regexOperatorAhead = ParsecT s u m Bool -> ParsecT s u m Bool
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (do
        ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"=~") ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"~=")
        Bool -> ParsecT s u m Bool
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
          ParsecT s u m Bool -> ParsecT s u m Bool -> ParsecT s u m Bool
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Bool -> ParsecT s u m Bool
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
    readRegex :: ParsecT String UserState (SCBase m) Token
readRegex = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"regex" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        [Token]
parts <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) Token
readPart
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id [Token]
parts
      where
        readPart :: ParsecT String UserState (SCBase m) Token
readPart = [ParsecT String UserState (SCBase m) Token]
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
            ParsecT String UserState (SCBase m) Token
readGroup,
            ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted,
            ParsecT String UserState (SCBase m) Token
readDoubleQuoted,
            ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression,
            ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {s} {a}.
(MonadState s m, Stream s m Char) =>
ParsecT s UserState m a -> ParsecT s UserState m Token
readLiteralForParser (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) Token
readNormalLiteral String
"( ",
            String -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
String -> ParsecT s UserState m Token
readLiteralString String
"|",
            ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
readGlobLiteral
            ]
        readGlobLiteral :: ParsecT s UserState m Token
readGlobLiteral = do
            IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            Char
s <- ParsecT s UserState m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
extglobStart ParsecT s UserState m Char
-> ParsecT s UserState m Char -> ParsecT s UserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"{}[]$"
            Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id [Char
s]
        readGroup :: ParsecT String UserState (SCBase m) Token
readGroup = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"regex grouping" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
            IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            Token
p1 <- String -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
String -> ParsecT s UserState m Token
readLiteralString String
"("
            [Token]
parts <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String UserState (SCBase m) Token
readPart ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readRegexLiteral)
            Token
p2 <- String -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
String -> ParsecT s UserState m Token
readLiteralString String
")"
            Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id (Token
p1Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
:([Token]
parts [Token] -> [Token] -> [Token]
forall a. [a] -> [a] -> [a]
++ [Token
p2]))
        readRegexLiteral :: ParsecT String UserState (SCBase m) Token
readRegexLiteral = do
            IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            String
str <- ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {a}.
Monad m =>
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) String
readGenericLiteral1 (ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
singleQuote ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuotable ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"()")
            Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str
        readLiteralString :: String -> ParsecT s UserState m Token
readLiteralString String
s = do
            IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            String
str <- String -> ParsecT s UserState m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
s
            Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str

    readCondTerm :: ParsecT String UserState (SCBase m) Token
readCondTerm = do
        Token
term <- ParsecT String UserState (SCBase m) Token
readCondNot ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readCondExpr
        Bool -> ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) String
condSpacing Bool
False
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
term

    readCondNot :: ParsecT String UserState (SCBase m) Token
readCondNot = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'!'
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacingOrLf
        Token
expr <- ParsecT String UserState (SCBase m) Token
readCondExpr
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> String -> Token -> Token
TC_Unary Id
id ConditionType
typ String
"!" Token
expr

    readCondExpr :: ParsecT String UserState (SCBase m) Token
readCondExpr =
      ParsecT String UserState (SCBase m) Token
readCondGroup ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readCondUnaryExp ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readCondNullaryOrBinary

    readCondOr :: ParsecT String UserState (SCBase m) Token
readCondOr = ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainl1 ParsecT String UserState (SCBase m) Token
readCondAnd ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondAndOp
    readCondAnd :: ParsecT String UserState (SCBase m) Token
readCondAnd = ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainl1 ParsecT String UserState (SCBase m) Token
readCondTerm ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readCondOrOp
    readCondContents :: ParsecT String UserState (SCBase m) Token
readCondContents = ParsecT String UserState (SCBase m) Token
readCondOr


prop_a1 :: Bool
prop_a1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
" n++ + ++c"
prop_a2 :: Bool
prop_a2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"$N*4-(3,2)"
prop_a3 :: Bool
prop_a3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"n|=2<<1"
prop_a4 :: Bool
prop_a4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"n &= 2 **3"
prop_a5 :: Bool
prop_a5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"1 |= 4 && n >>= 4"
prop_a6 :: Bool
prop_a6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
" 1 | 2 ||3|4"
prop_a7 :: Bool
prop_a7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"3*2**10"
prop_a8 :: Bool
prop_a8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"3"
prop_a9 :: Bool
prop_a9 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"a^!-b"
prop_a10 :: Bool
prop_a10 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"! $?"
prop_a11 :: Bool
prop_a11 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"10#08 * 16#f"
prop_a12 :: Bool
prop_a12 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"\"$((3+2))\" + '37'"
prop_a13 :: Bool
prop_a13 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"foo[9*y+x]++"
prop_a14 :: Bool
prop_a14 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"1+`echo 2`"
prop_a15 :: Bool
prop_a15 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"foo[`echo foo | sed s/foo/4/g` * 3] + 4"
prop_a16 :: Bool
prop_a16 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"$foo$bar"
prop_a17 :: Bool
prop_a17 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"i<(0+(1+1))"
prop_a18 :: Bool
prop_a18 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"a?b:c"
prop_a19 :: Bool
prop_a19 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"\\\n3 +\\\n  2"
prop_a20 :: Bool
prop_a20 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"a ? b ? c : d : e"
prop_a21 :: Bool
prop_a21 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"a ? b : c ? d : e"
prop_a22 :: Bool
prop_a22 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"!!a"
prop_a23 :: Bool
prop_a23 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents String
"~0"
readArithmeticContents :: Monad m => SCParser m Token
readArithmeticContents :: forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents =
    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSequence
  where
    spacing :: ParsecT String UserState (SCBase m) String
spacing =
        let lf :: ParsecT s u m Char
lf = ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"\\\n") ParsecT s u m String -> 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 (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT s u m Char
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'\n'
        in ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
whitespace ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
lf)

    splitBy :: ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
splitBy ParsecT String UserState (SCBase m) Token
x [String]
ops = ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainl1 ParsecT String UserState (SCBase m) Token
x ([String]
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *}.
Monad m =>
[String]
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readBinary [String]
ops)
    readBinary :: [String]
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readBinary [String]
ops = [String]
-> (Id -> String -> Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *} {b}.
Monad m =>
[String]
-> (Id -> String -> b) -> ParsecT String UserState (SCBase m) b
readComboOp [String]
ops Id -> String -> Token -> Token -> Token
TA_Binary
    readComboOp :: [String]
-> (Id -> String -> b) -> ParsecT String UserState (SCBase m) b
readComboOp [String]
op Id -> String -> b
token = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
op <- [ParsecT String UserState (SCBase m) String]
-> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice ((String -> ParsecT String UserState (SCBase m) String)
-> [String] -> [ParsecT String UserState (SCBase m) String]
forall a b. (a -> b) -> [a] -> [b]
map (\String
x -> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ do
                                        String
s <- String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
x
                                        ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {u}. Stream s m Char => ParsecT s u m ()
failIfIncompleteOp
                                        String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
s
                            ) [String]
op)
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        b -> ParsecT String UserState (SCBase m) b
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> ParsecT String UserState (SCBase m) b)
-> b -> ParsecT String UserState (SCBase m) b
forall a b. (a -> b) -> a -> b
$ Id -> String -> b
token Id
id String
op

    failIfIncompleteOp :: ParsecT s u m ()
failIfIncompleteOp = ParsecT s u m Char -> ParsecT s u m ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (ParsecT s u m Char -> ParsecT s u m ())
-> ParsecT s u m Char -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"&|<>="

    -- Read binary minus, but also check for -lt, -gt and friends:
    readMinusOp :: ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readMinusOp = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
            Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-'
            ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {u}. Stream s m Char => ParsecT s u m ()
failIfIncompleteOp
        ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
            (String
str, String
alt) <- ParsecT String UserState (SCBase m) (String, String)
-> ParsecT String UserState (SCBase m) (String, String)
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) (String, String)
 -> ParsecT String UserState (SCBase m) (String, String))
-> ([ParsecT String UserState (SCBase m) (String, String)]
    -> ParsecT String UserState (SCBase m) (String, String))
-> [ParsecT String UserState (SCBase m) (String, String)]
-> ParsecT String UserState (SCBase m) (String, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ParsecT String UserState (SCBase m) (String, String)]
-> ParsecT String UserState (SCBase m) (String, String)
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice ([ParsecT String UserState (SCBase m) (String, String)]
 -> ParsecT String UserState (SCBase m) (String, String))
-> [ParsecT String UserState (SCBase m) (String, String)]
-> ParsecT String UserState (SCBase m) (String, String)
forall a b. (a -> b) -> a -> b
$ ((String, String)
 -> ParsecT String UserState (SCBase m) (String, String))
-> [(String, String)]
-> [ParsecT String UserState (SCBase m) (String, String)]
forall a b. (a -> b) -> [a] -> [b]
map (String, String)
-> ParsecT String UserState (SCBase m) (String, String)
forall {s} {m :: * -> *} {m :: * -> *} {b}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
(String, b) -> ParsecT s UserState m (String, b)
tryOp [
                (String
"lt", String
"<"),
                (String
"gt", String
">"),
                (String
"le", String
"<="),
                (String
"ge", String
">="),
                (String
"eq", String
"=="),
                (String
"ne", String
"!=")
              ]
            SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1106 (String -> ParsecT String UserState (SCBase m) ())
-> String -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ String
"In arithmetic contexts, use " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
alt String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" instead of -" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Token -> Token -> Token)
 -> ParsecT String UserState (SCBase m) (Token -> Token -> Token))
-> (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token -> Token
TA_Binary Id
id String
"-"
      where
        tryOp :: (String, b) -> ParsecT s UserState m (String, b)
tryOp (String
str, b
alt) = ParsecT s UserState m (String, b)
-> ParsecT s UserState m (String, b)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s UserState m (String, b)
 -> ParsecT s UserState m (String, b))
-> ParsecT s UserState m (String, b)
-> ParsecT s UserState m (String, b)
forall a b. (a -> b) -> a -> b
$ do
            String -> ParsecT s UserState m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
str
            ParsecT s UserState m String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing1
            (String, b) -> ParsecT s UserState m (String, b)
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (String
str, b
alt)

    readArrayIndex :: ParsecT String UserState (SCBase m) Token
readArrayIndex = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
        SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
middle <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {s} {u} {a}.
(MonadState s m, Stream s m Char) =>
ParsecT s u m a -> ParsecT s u m String
readStringForParser ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
']'
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> SourcePos -> String -> Token
T_UnparsedIndex Id
id SourcePos
pos String
middle

    literal :: String -> ParsecT s UserState m Token
literal String
s = do
        IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String -> ParsecT s UserState m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
s
        Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
s

    readVariable :: ParsecT String UserState (SCBase m) Token
readVariable = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
name <- ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
        [Token]
indices <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArrayIndex
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> Token
TA_Variable Id
id String
name [Token]
indices

    readExpansion :: ParsecT String UserState (SCBase m) Token
readExpansion = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        [Token]
pieces <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) [Token])
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall a b. (a -> b) -> a -> b
$ [ParsecT String UserState (SCBase m) Token]
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
            ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted,
            ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted,
            ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalDollar,
            ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced,
            ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readUnquotedBackTicked,
            String -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
String -> ParsecT s UserState m Token
literal String
"#",
            String -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) Token
readNormalLiteral String
"+-*/=%^,]?:"
            ]
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
TA_Expansion Id
id [Token]
pieces

    readGroup :: ParsecT String UserState (SCBase m) Token
readGroup = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
        Token
s <- ParsecT String UserState (SCBase m) Token
readSequence
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token
TA_Parenthesis Id
id Token
s

    readArithTerm :: ParsecT String UserState (SCBase m) Token
readArithTerm = ParsecT String UserState (SCBase m) Token
readGroup ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readVariable ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExpansion

    readSequence :: ParsecT String UserState (SCBase m) Token
readSequence = do
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        [Token]
l <- ParsecT String UserState (SCBase m) Token
readAssignment ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) [Token]
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]
`sepBy` (Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
',' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing)
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
TA_Sequence Id
id [Token]
l

    readAssignment :: ParsecT String UserState (SCBase m) Token
readAssignment = ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainr1 ParsecT String UserState (SCBase m) Token
readTrinary ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readAssignmentOp
    readAssignmentOp :: ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readAssignmentOp = [String]
-> (Id -> String -> Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *} {b}.
Monad m =>
[String]
-> (Id -> String -> b) -> ParsecT String UserState (SCBase m) b
readComboOp [String
"=", String
"*=", String
"/=", String
"%=", String
"+=", String
"-=", String
"<<=", String
">>=", String
"&=", String
"^=", String
"|="] Id -> String -> Token -> Token -> Token
TA_Assignment

    readTrinary :: ParsecT String UserState (SCBase m) Token
readTrinary = do
        Token
x <- ParsecT String UserState (SCBase m) Token
readLogicalOr
        do
            IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"?"
            ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
            Token
y <- ParsecT String UserState (SCBase m) Token
readTrinary
            String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
":"
            ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
            Token
z <- ParsecT String UserState (SCBase m) Token
readTrinary
            Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token -> Token -> Token
TA_Trinary Id
id Token
x Token
y Token
z
         ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
          Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
x

    readLogicalOr :: ParsecT String UserState (SCBase m) Token
readLogicalOr  = ParsecT String UserState (SCBase m) Token
readLogicalAnd ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"||"]
    readLogicalAnd :: ParsecT String UserState (SCBase m) Token
readLogicalAnd = ParsecT String UserState (SCBase m) Token
readBitOr ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"&&"]
    readBitOr :: ParsecT String UserState (SCBase m) Token
readBitOr  = ParsecT String UserState (SCBase m) Token
readBitXor ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"|"]
    readBitXor :: ParsecT String UserState (SCBase m) Token
readBitXor = ParsecT String UserState (SCBase m) Token
readBitAnd ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"^"]
    readBitAnd :: ParsecT String UserState (SCBase m) Token
readBitAnd = ParsecT String UserState (SCBase m) Token
readEquated ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"&"]
    readEquated :: ParsecT String UserState (SCBase m) Token
readEquated = ParsecT String UserState (SCBase m) Token
readCompared ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"==", String
"!="]
    readCompared :: ParsecT String UserState (SCBase m) Token
readCompared = ParsecT String UserState (SCBase m) Token
readShift ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"<=", String
">=", String
"<", String
">"]
    readShift :: ParsecT String UserState (SCBase m) Token
readShift = ParsecT String UserState (SCBase m) Token
readAddition ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"<<", String
">>"]
    readAddition :: ParsecT String UserState (SCBase m) Token
readAddition = ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainl1 ParsecT String UserState (SCBase m) Token
readMultiplication ([String]
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *}.
Monad m =>
[String]
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readBinary [String
"+"] ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Token -> Token -> Token)
readMinusOp)
    readMultiplication :: ParsecT String UserState (SCBase m) Token
readMultiplication = ParsecT String UserState (SCBase m) Token
readExponential ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"*", String
"/", String
"%"]
    readExponential :: ParsecT String UserState (SCBase m) Token
readExponential = ParsecT String UserState (SCBase m) Token
readAnyNegated ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
-> [String] -> ParsecT String UserState (SCBase m) Token
`splitBy` [String
"**"]

    readAnyNegated :: ParsecT String UserState (SCBase m) Token
readAnyNegated = ParsecT String UserState (SCBase m) Token
readNegated ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readAnySigned
    readNegated :: ParsecT String UserState (SCBase m) Token
readNegated = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Char
op <- String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"!~"
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        Token
x <- ParsecT String UserState (SCBase m) Token
readAnyNegated
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
TA_Unary Id
id [Char
op] Token
x

    readAnySigned :: ParsecT String UserState (SCBase m) Token
readAnySigned = ParsecT String UserState (SCBase m) Token
readSigned ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readAnycremented
    readSigned :: ParsecT String UserState (SCBase m) Token
readSigned = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Char
op <- [ParsecT String UserState (SCBase m) Char]
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice ((Char -> ParsecT String UserState (SCBase m) Char)
-> String -> [ParsecT String UserState (SCBase m) Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> ParsecT String UserState (SCBase m) Char
forall {m :: * -> *}.
Monad m =>
Char -> ParsecT String UserState (SCBase m) Char
readSignOp String
"+-")
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        Token
x <- ParsecT String UserState (SCBase m) Token
readAnycremented
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
TA_Unary Id
id [Char
op] Token
x
     where
        readSignOp :: Char -> ParsecT String UserState (SCBase m) Char
readSignOp Char
c = ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ do
            Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c
            ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c
            ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
            Char -> ParsecT String UserState (SCBase m) Char
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
c

    readAnycremented :: ParsecT String UserState (SCBase m) Token
readAnycremented = ParsecT String UserState (SCBase m) Token
readNormalOrPostfixIncremented ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readPrefixIncremented
    readPrefixIncremented :: ParsecT String UserState (SCBase m) Token
readPrefixIncremented = do
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
op <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"++" ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"--"
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        Token
x <- ParsecT String UserState (SCBase m) Token
readArithTerm
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
TA_Unary Id
id (String
op String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"|") Token
x

    readNormalOrPostfixIncremented :: ParsecT String UserState (SCBase m) Token
readNormalOrPostfixIncremented = do
        Token
x <- ParsecT String UserState (SCBase m) Token
readArithTerm
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
        do
            IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            String
op <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"++" ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"--"
            Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
spacing
            Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
TA_Unary Id
id (Char
'|'Char -> String -> String
forall a. a -> [a] -> [a]
:String
op) Token
x
         ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
            Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
x



prop_readCondition :: Bool
prop_readCondition   = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ \\( a = b \\) -a \\( c = d \\) ]"
prop_readCondition2 :: Bool
prop_readCondition2  = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ (a = b) || (c = d) ]]"
prop_readCondition3 :: Bool
prop_readCondition3  = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c = [[:alpha:].~-] ]]"
prop_readCondition4 :: Bool
prop_readCondition4  = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c =~ *foo* ]]"
prop_readCondition5 :: Bool
prop_readCondition5  = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c =~ f( ]] )* ]]"
prop_readCondition5a :: Bool
prop_readCondition5a = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c =~ a(b) ]]"
prop_readCondition5b :: Bool
prop_readCondition5b = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c =~ f( ($var ]]) )* ]]"
prop_readCondition6 :: Bool
prop_readCondition6  = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $c =~ ^[yY]$ ]]"
prop_readCondition7 :: Bool
prop_readCondition7  = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ ${line} =~ ^[[:space:]]*# ]]"
prop_readCondition8 :: Bool
prop_readCondition8  = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $l =~ ogg|flac ]]"
prop_readCondition9 :: Bool
prop_readCondition9  = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ foo -a -f bar ]"
prop_readCondition10 :: Bool
prop_readCondition10 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[\na == b\n||\nc == d ]]"
prop_readCondition10a :: Bool
prop_readCondition10a = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[\na == b  ||\nc == d ]]"
prop_readCondition10b :: Bool
prop_readCondition10b = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ a == b\n||\nc == d ]]"
prop_readCondition11 :: Bool
prop_readCondition11 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ a == b ||\n c == d ]]"
prop_readCondition12 :: Bool
prop_readCondition12 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ a == b \n -o c == d ]"
prop_readCondition13 :: Bool
prop_readCondition13 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ foo =~ ^fo{1,3}$ ]]"
prop_readCondition14 :: Bool
prop_readCondition14 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ foo '>' bar ]"
prop_readCondition15 :: Bool
prop_readCondition15 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ foo \">=\" bar ]"
prop_readCondition16 :: Bool
prop_readCondition16 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ foo \\< bar ]"
prop_readCondition17 :: Bool
prop_readCondition17 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ ${file::1} = [-.\\|/\\\\] ]]"
prop_readCondition18 :: Bool
prop_readCondition18 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ ]"
prop_readCondition19 :: Bool
prop_readCondition19 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[ '(' x \")\" ]"
prop_readCondition20 :: Bool
prop_readCondition20 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ echo_rc -eq 0 ]]"
prop_readCondition21 :: Bool
prop_readCondition21 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $1 =~ ^(a\\ b)$ ]]"
prop_readCondition22 :: Bool
prop_readCondition22 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ $1 =~ \\.a\\.(\\.b\\.)\\.c\\. ]]"
prop_readCondition23 :: Bool
prop_readCondition23 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ -v arr[$var] ]]"
prop_readCondition25 :: Bool
prop_readCondition25 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ lex.yy.c -ot program.l ]]"
prop_readCondition26 :: Bool
prop_readCondition26 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"[[ foo ]]\\\n && bar"
prop_readCondition27 :: Bool
prop_readCondition27 = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readConditionCommand String
"[[ x ]] foo"
prop_readCondition28 :: Bool
prop_readCondition28 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ x = [\"$1\"] ]]"
prop_readCondition29 :: Bool
prop_readCondition29 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCondition String
"[[ x = [*] ]]"

readCondition :: ParsecT String UserState (SCBase m) Token
readCondition = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"test expression" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    SourcePos
opos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
open <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"[[") ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"["
    let single :: Bool
single = String
open String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"["
    let typ :: ConditionType
typ = if Bool
single then ConditionType
SingleBracket else ConditionType
DoubleBracket

    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    String
space <- ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
space) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
        SourcePos
-> SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
opos SourcePos
pos Severity
ErrorC Integer
1035 (String -> ParsecT String UserState (SCBase m) ())
-> String -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ String
"You need a space after the " String -> String -> String
forall a. [a] -> [a] -> [a]
++
            if Bool
single
                then String
"[ and before the ]."
                else String
"[[ and before the ]]."
    Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
single Bool -> Bool -> Bool
&& Char
'\n' Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
space) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1080 String
"You need \\ before line feeds to break lines in [ ]."

    Token
condition <- Bool -> ParsecT String UserState (SCBase m) Token
readConditionContents Bool
single ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        Bool -> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParsecT String UserState (SCBase m) ())
-> (String -> Bool)
-> String
-> ParsecT String UserState (SCBase m) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not (Bool -> Bool) -> (String -> Bool) -> String -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (String -> ParsecT String UserState (SCBase m) ())
-> String -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ String
space
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"]"
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> Token
TC_Empty Id
id ConditionType
typ

    SourcePos
cpos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    String
close <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"]]") ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"]" ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) String
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected test to end here (don't wrap commands in []/[[]])"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
open String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"[[" Bool -> Bool -> Bool
&& String
close String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"]]") (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
cpos Severity
ErrorC Integer
1033 String
"Test expression was opened with double [[ but closed with single ]. Make sure they match."
    Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
open String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"[" Bool -> Bool -> Bool
&& String
close String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"]" ) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
opos Severity
ErrorC Integer
1034 String
"Test expression was opened with single [ but closed with double ]]. Make sure they match."
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> ConditionType -> Token -> Token
T_Condition Id
id ConditionType
typ Token
condition

readAnnotationPrefix :: ParsecT s UserState m String
readAnnotationPrefix = do
    Char -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'#'
    ParsecT s UserState m Char -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT s UserState m Char
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Char
linewhitespace
    String -> ParsecT s UserState m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"shellcheck"

prop_readAnnotation1 :: Bool
prop_readAnnotation1 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=1234,5678\n"
prop_readAnnotation2 :: Bool
prop_readAnnotation2 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=SC1234 disable=SC5678\n"
prop_readAnnotation3 :: Bool
prop_readAnnotation3 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=SC1234 source=/dev/null disable=SC5678\n"
prop_readAnnotation4 :: Bool
prop_readAnnotation4 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck cats=dogs disable=SC1234\n"
prop_readAnnotation5 :: Bool
prop_readAnnotation5 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=SC2002 # All cats are precious\n"
prop_readAnnotation6 :: Bool
prop_readAnnotation6 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=SC1234 # shellcheck foo=bar\n"
prop_readAnnotation7 :: Bool
prop_readAnnotation7 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=SC1000,SC2000-SC3000,SC1001\n"
prop_readAnnotation8 :: Bool
prop_readAnnotation8 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable=all\n"
prop_readAnnotation9 :: Bool
prop_readAnnotation9 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck source='foo bar' source-path=\"baz etc\"\n"
prop_readAnnotation10 :: Bool
prop_readAnnotation10 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation String
"# shellcheck disable='SC1234,SC2345' enable=\"foo\" shell='bash'\n"
prop_readAnnotation11 :: Bool
prop_readAnnotation11 = ParsecT String UserState (SCBase Identity) [Annotation]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk (Bool -> ParsecT String UserState (SCBase Identity) [Annotation]
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) [Annotation]
readAnnotationWithoutPrefix Bool
False) String
"external-sources='true'"

readAnnotation :: ParsecT String UserState (SCBase m) [Annotation]
readAnnotation = String
-> ParsecT String UserState (SCBase m) [Annotation]
-> ParsecT String UserState (SCBase m) [Annotation]
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"shellcheck directive" (ParsecT String UserState (SCBase m) [Annotation]
 -> ParsecT String UserState (SCBase m) [Annotation])
-> ParsecT String UserState (SCBase m) [Annotation]
-> ParsecT String UserState (SCBase m) [Annotation]
forall a b. (a -> b) -> a -> b
$ do
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
readAnnotationPrefix
    ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) Char
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Char
linewhitespace
    Bool -> ParsecT String UserState (SCBase m) [Annotation]
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) [Annotation]
readAnnotationWithoutPrefix Bool
True

readAnnotationWithoutPrefix :: Bool -> ParsecT String UserState (SCBase m) [Annotation]
readAnnotationWithoutPrefix Bool
sandboxed = do
    [[Annotation]]
values <- ParsecT String UserState (SCBase m) [Annotation]
-> ParsecT String UserState (SCBase m) [[Annotation]]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readKey
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readAnyComment
    ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
linefeed ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        Severity
-> Integer -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s UserState m ()
parseNote Severity
ErrorC Integer
1125 String
"Invalid key=value pair? Ignoring the rest of this directive starting here."
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\n")
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
linefeed ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
    ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Char
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Char
linewhitespace
    [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Annotation] -> ParsecT String UserState (SCBase m) [Annotation])
-> [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a b. (a -> b) -> a -> b
$ [[Annotation]] -> [Annotation]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Annotation]]
values
  where
    plainOrQuoted :: ParsecT String u m a -> ParsecT String u m a
plainOrQuoted ParsecT String u m a
p = ParsecT String u m a -> ParsecT String u m a
forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
quoted ParsecT String u m a
p ParsecT String u m a
-> ParsecT String u m a -> ParsecT String u m a
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String u m a
p
    quoted :: ParsecT String u m b -> ParsecT String u m b
quoted ParsecT String u m b
p = do
        Char
c <- String -> ParsecT String u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"'\""
        SourcePos
start <- ParsecT String u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
str <- ParsecT String u m Char -> ParsecT String u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String u m Char -> ParsecT String u m String)
-> ParsecT String u m Char -> ParsecT String u m String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf (Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
"\n")
        Char -> ParsecT String u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c ParsecT String u m Char
-> ParsecT String u m Char -> ParsecT String u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String u m Char
forall a. String -> ParsecT String u m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Missing terminating quote for directive."
        SourcePos -> ParsecT String u m b -> String -> ParsecT String u m b
forall {m :: * -> *} {s} {u} {b}.
Monad m =>
SourcePos -> ParsecT s u m b -> s -> ParsecT s u m b
subParse SourcePos
start ParsecT String u m b
p String
str
    readKey :: ParsecT String UserState (SCBase m) [Annotation]
readKey = do
        SourcePos
keyPos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
key <- ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-')
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'=' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected '=' after directive key"
        [Annotation]
annotations <- case String
key of
            String
"disable" -> ParsecT String UserState (SCBase m) [Annotation]
-> ParsecT String UserState (SCBase m) [Annotation]
forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
plainOrQuoted (ParsecT String UserState (SCBase m) [Annotation]
 -> ParsecT String UserState (SCBase m) [Annotation])
-> ParsecT String UserState (SCBase m) [Annotation]
-> ParsecT String UserState (SCBase m) [Annotation]
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Annotation
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m Annotation
readElement ParsecT String UserState (SCBase m) Annotation
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) [Annotation]
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]
`sepBy` Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
','
              where
                readElement :: ParsecT s u m Annotation
readElement = ParsecT s u m Annotation
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m Annotation
readRange ParsecT s u m Annotation
-> ParsecT s u m Annotation -> ParsecT s u m Annotation
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m Annotation
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m Annotation
readAll
                readAll :: ParsecT s u m Annotation
readAll = do
                    String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"all"
                    Annotation -> ParsecT s u m Annotation
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Annotation -> ParsecT s u m Annotation)
-> Annotation -> ParsecT s u m Annotation
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Annotation
DisableComment Integer
0 Integer
1000000
                readRange :: ParsecT s u m Annotation
readRange = do
                    Integer
from <- ParsecT s u m Integer
forall {s} {m :: * -> *} {b} {u}.
(Stream s m Char, Read b) =>
ParsecT s u m b
readCode
                    Integer
to <- [ParsecT s u m Integer] -> ParsecT s u m Integer
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ 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 Integer -> ParsecT s u m Integer
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 Integer
forall {s} {m :: * -> *} {b} {u}.
(Stream s m Char, Read b) =>
ParsecT s u m b
readCode, Integer -> ParsecT s u m Integer
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> ParsecT s u m Integer)
-> Integer -> ParsecT s u m Integer
forall a b. (a -> b) -> a -> b
$ Integer
fromInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1 ]
                    Annotation -> ParsecT s u m Annotation
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Annotation -> ParsecT s u m Annotation)
-> Annotation -> ParsecT s u m Annotation
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Annotation
DisableComment Integer
from Integer
to
                readCode :: ParsecT s u m b
readCode = do
                    ParsecT s u m String -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT s u m String -> ParsecT s u m ())
-> ParsecT s u m String -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"SC"
                    String
int <- ParsecT s u m Char -> ParsecT s u m String
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
                    b -> ParsecT s u m b
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> ParsecT s u m b) -> b -> ParsecT s u m b
forall a b. (a -> b) -> a -> b
$ String -> b
forall a. Read a => String -> a
read String
int

            String
"enable" -> ParsecT String UserState (SCBase m) [Annotation]
-> ParsecT String UserState (SCBase m) [Annotation]
forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
plainOrQuoted (ParsecT String UserState (SCBase m) [Annotation]
 -> ParsecT String UserState (SCBase m) [Annotation])
-> ParsecT String UserState (SCBase m) [Annotation]
-> ParsecT String UserState (SCBase m) [Annotation]
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Annotation
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m Annotation
readName ParsecT String UserState (SCBase m) Annotation
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) [Annotation]
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]
`sepBy` Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
','
              where
                readName :: ParsecT s u m Annotation
readName = String -> Annotation
EnableComment (String -> Annotation)
-> ParsecT s u m String -> ParsecT s u m Annotation
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Char -> ParsecT s u m String
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
letter ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-')

            String
"source" -> do
                String
filename <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
quoted (ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
" \n")
                [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [String -> Annotation
SourceOverride String
filename]

            String
"source-path" -> do
                String
dirname <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
quoted (ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
" \n")
                [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [String -> Annotation
SourcePath String
dirname]

            String
"shell" -> do
                SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                String
shell <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
quoted (ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
" \n")
                Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Maybe Shell -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe Shell -> Bool) -> Maybe Shell -> Bool
forall a b. (a -> b) -> a -> b
$ String -> Maybe Shell
shellForExecutable String
shell) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
                    SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1103
                        String
"This shell type is unknown. Use e.g. sh or bash."
                [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [String -> Annotation
ShellOverride String
shell]

            String
"extended-analysis" -> do
                SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                String
value <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
plainOrQuoted (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter
                case String
value of
                    String
"true" -> [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Bool -> Annotation
ExtendedAnalysis Bool
True]
                    String
"false" -> [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Bool -> Annotation
ExtendedAnalysis Bool
False]
                    String
_ -> do
                        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1146 String
"Unknown extended-analysis value. Expected true/false."
                        [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return []

            String
"external-sources" -> do
                SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                String
value <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {u} {b}.
Monad m =>
ParsecT String u m b -> ParsecT String u m b
plainOrQuoted (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter
                case String
value of
                    String
"true" ->
                        if Bool
sandboxed
                        then do
                            SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1144 String
"external-sources can only be enabled in .shellcheckrc, not in individual files."
                            [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return []
                        else [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Bool -> Annotation
ExternalSources Bool
True]
                    String
"false" -> [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Bool -> Annotation
ExternalSources Bool
False]
                    String
_ -> do
                        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1145 String
"Unknown external-sources value. Expected true/false."
                        [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return []

            String
_ -> do
                SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
keyPos Severity
WarningC Integer
1107 String
"This directive is unknown. It will be ignored."
                ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill` ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
whitespace
                [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return []

        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Char
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Char
linewhitespace
        [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Annotation]
annotations

readAnnotations :: ParsecT String UserState (SCBase m) [Annotation]
readAnnotations = do
    [[Annotation]]
annotations <- ParsecT String UserState (SCBase m) [Annotation]
-> ParsecT String UserState (SCBase m) [[Annotation]]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String UserState (SCBase m) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotation ParsecT String UserState (SCBase m) [Annotation]
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) [Annotation]
forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing)
    [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Annotation] -> ParsecT String UserState (SCBase m) [Annotation])
-> [Annotation] -> ParsecT String UserState (SCBase m) [Annotation]
forall a b. (a -> b) -> a -> b
$ [[Annotation]] -> [Annotation]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Annotation]]
annotations

readComment :: ParsecT s UserState m String
readComment = do
    String -> ParsecT s UserState m String -> ParsecT s UserState m ()
forall {s} {u} {m :: * -> *} {a}.
String -> ParsecT s u m a -> ParsecT s u m ()
unexpecting String
"shellcheck annotation" ParsecT s UserState m String
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
readAnnotationPrefix
    ParsecT s UserState m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readAnyComment

prop_readAnyComment :: Bool
prop_readAnyComment = ParsecT String UserState (SCBase Identity) String -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readAnyComment String
"# Comment"
readAnyComment :: ParsecT s u m String
readAnyComment = do
    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 String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT s u m Char -> ParsecT s u m String)
-> ParsecT s u m Char -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\r\n"

prop_readNormalWord :: Bool
prop_readNormalWord = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"'foo'\"bar\"{1..3}baz$(lol)"
prop_readNormalWord2 :: Bool
prop_readNormalWord2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"foo**(foo)!!!(@@(bar))"
prop_readNormalWord3 :: Bool
prop_readNormalWord3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"foo#"
prop_readNormalWord4 :: Bool
prop_readNormalWord4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"$\"foo\"$'foo\nbar'"
prop_readNormalWord5 :: Bool
prop_readNormalWord5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"${foo}}"
prop_readNormalWord6 :: Bool
prop_readNormalWord6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"foo/{}"
prop_readNormalWord7 :: Bool
prop_readNormalWord7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"foo\\\nbar"
prop_readNormalWord8 :: Bool
prop_readNormalWord8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSubshell String
"(foo\\ \nbar)"
prop_readNormalWord9 :: Bool
prop_readNormalWord9 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSubshell String
"(foo\\ ;\nbar)"
prop_readNormalWord10 :: Bool
prop_readNormalWord10 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\x201Chello\x201D"
prop_readNormalWord11 :: Bool
prop_readNormalWord11 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\x2018hello\x2019"
prop_readNormalWord12 :: Bool
prop_readNormalWord12 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"hello\x2018"
readNormalWord :: ParsecT String UserState (SCBase m) Token
readNormalWord = String -> [String] -> ParsecT String UserState (SCBase m) Token
readNormalishWord String
"" [String
"do", String
"done", String
"then", String
"fi", String
"esac"]

readPatternWord :: ParsecT String UserState (SCBase m) Token
readPatternWord = String -> [String] -> ParsecT String UserState (SCBase m) Token
readNormalishWord String
"" [String
"esac"]

readNormalishWord :: String -> [String] -> ParsecT String UserState (SCBase m) Token
readNormalishWord String
end [String]
terms = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    [Token]
x <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT String UserState (SCBase m) Token
readNormalWordPart String
end)
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    SourcePos
-> [Token] -> [String] -> ParsecT String UserState (SCBase m) ()
forall {f :: * -> *} {t :: * -> *} {m :: * -> *}.
(Foldable t, MonadState SystemState f,
 MonadReader (Environment m) f) =>
SourcePos -> [Token] -> t String -> f ()
checkPossibleTermination SourcePos
pos [Token]
x [String]
terms
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id [Token]
x

readIndexSpan :: ParsecT String UserState (SCBase m) Token
readIndexSpan = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [Token]
x <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (String -> ParsecT String UserState (SCBase m) Token
readNormalWordPart String
"]" ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
someSpace ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
otherLiteral)
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id [Token]
x
  where
    someSpace :: ParsecT s UserState m Token
someSpace = do
        IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
str <- ParsecT s UserState m String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing1
        Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str
    otherLiteral :: ParsecT s UserState m Token
otherLiteral = do
        IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
str <- ParsecT s UserState m Char -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT s UserState m Char -> ParsecT s UserState m String)
-> ParsecT s UserState m Char -> ParsecT s UserState m String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
quotableChars
        Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str

checkPossibleTermination :: SourcePos -> [Token] -> t String -> f ()
checkPossibleTermination SourcePos
pos [T_Literal Id
_ String
x] t String
terminators =
    Bool -> f () -> f ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
x String -> t String -> Bool
forall a. Eq a => a -> t a -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` t String
terminators) (f () -> f ()) -> f () -> f ()
forall a b. (a -> b) -> a -> b
$
        SourcePos -> Severity -> Integer -> String -> f ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1010 (String -> f ()) -> String -> f ()
forall a b. (a -> b) -> a -> b
$ String
"Use semicolon or linefeed before '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' (or quote to make it literal)."
checkPossibleTermination SourcePos
_ [Token]
_ t String
_ = () -> f ()
forall a. a -> f a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

readNormalWordPart :: String -> ParsecT String UserState (SCBase m) Token
readNormalWordPart String
end = do
    ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
end
    ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
checkForParenthesis
    [ParsecT String UserState (SCBase m) Token]
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
        ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted,
        ParsecT String UserState (SCBase m) Token
readDoubleQuoted,
        ParsecT String UserState (SCBase m) Token
readGlob,
        ParsecT String UserState (SCBase m) Token
readNormalDollar,
        ParsecT String UserState (SCBase m) Token
readBraced,
        ParsecT String UserState (SCBase m) Token
readUnquotedBackTicked,
        ParsecT String UserState (SCBase m) Token
readProcSub,
        ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readUnicodeQuote,
        String -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) Token
readNormalLiteral String
end,
        ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
readLiteralCurlyBraces
      ]
  where
    checkForParenthesis :: ParsecT s u m ()
checkForParenthesis =
        () -> ParsecT s u m ()
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return () ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` do
            SourcePos
pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            ParsecT s u m Char -> ParsecT s u m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s u m Char -> ParsecT s u m Char)
-> ParsecT s u m Char -> ParsecT s u m Char
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
            SourcePos -> Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1036 String
"'(' is invalid here. Did you forget to escape it?"

    readLiteralCurlyBraces :: ParsecT s UserState m Token
readLiteralCurlyBraces = do
        IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
str <- ParsecT s UserState m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
findParam ParsecT s UserState m String
-> ParsecT s UserState m String -> ParsecT s UserState m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s UserState m String
forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m String
literalBraces
        Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str

    findParam :: ParsecT s u m String
findParam = ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{}"
    literalBraces :: ParsecT s u m String
literalBraces = do
        SourcePos
pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Char
c <- String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"{}"
        SourcePos -> Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1083 (String -> ParsecT s u m ()) -> String -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$
            String
"This " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
c] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is literal. Check expression (missing ;/\\n?) or quote it."
        String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char
c]


readSpacePart :: ParsecT String UserState (SCBase m) Token
readSpacePart = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
x <- ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
whitespace
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
x

readDollarBracedWord :: ParsecT String UserState (SCBase m) Token
readDollarBracedWord = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [Token]
list <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
readDollarBracedPart
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id [Token]
list

readDollarBracedPart :: ParsecT String UserState (SCBase m) Token
readDollarBracedPart = ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDoubleQuoted ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                       ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
readParamSubSpecialChar ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readExtglob ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readNormalDollar ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                       ParsecT String UserState (SCBase m) Token
readUnquotedBackTicked ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBracedLiteral

readDollarBracedLiteral :: ParsecT String UserState (SCBase m) Token
readDollarBracedLiteral = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [String]
vars <- (ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readBraceEscaped ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ((\Char
x -> [Char
x]) (Char -> String)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar)) ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) [String]
forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill1` ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
bracedQuotable
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id (String -> Token) -> String -> Token
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
vars

readParamSubSpecialChar :: ParsecT s UserState m Token
readParamSubSpecialChar = do
    IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
x <- ParsecT s UserState m Char -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT s UserState m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
paramSubSpecialChars
    Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_ParamSubSpecialChar Id
id String
x

prop_readProcSub1 :: Bool
prop_readProcSub1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readProcSub String
"<(echo test | wc -l)"
prop_readProcSub2 :: Bool
prop_readProcSub2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readProcSub String
"<(  if true; then true; fi )"
prop_readProcSub3 :: Bool
prop_readProcSub3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readProcSub String
"<( # nothing here \n)"
readProcSub :: ParsecT String UserState (SCBase m) Token
readProcSub = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"process substitution" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
dir <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ do
                    Char
x <- String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"<>"
                    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
                    String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char
x]
    [Token]
list <- ParsecT String UserState (SCBase m) [Token]
readCompoundListOrEmpty
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> Token
T_ProcSub Id
id String
dir [Token]
list

prop_readSingleQuoted :: Bool
prop_readSingleQuoted = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted String
"'foo bar'"
prop_readSingleQuoted2 :: Bool
prop_readSingleQuoted2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted String
"'foo bar\\'"
prop_readSingleQuoted4 :: Bool
prop_readSingleQuoted4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"'it's"
prop_readSingleQuoted5 :: Bool
prop_readSingleQuoted5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"foo='bar\ncow 'arg"
prop_readSingleQuoted6 :: Bool
prop_readSingleQuoted6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"foo='bar cow 'arg"
prop_readSingleQuoted7 :: Bool
prop_readSingleQuoted7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted String
"'foo\x201C\&bar'"
prop_readSingleQuoted8 :: Bool
prop_readSingleQuoted8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted String
"'foo\x2018\&bar'"
readSingleQuoted :: ParsecT String UserState (SCBase m) Token
readSingleQuoted = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"single quoted string" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
startPos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
singleQuote
    [String]
s <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readSingleQuotedPart
    let string :: String
string = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
s
    SourcePos
endPos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
singleQuote ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected end of single quoted string"

    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        Char
c <- ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> (ParsecT String UserState (SCBase m) Char
    -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
suspectCharAfterQuotes ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"'"
        if Bool -> Bool
not (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
string) Bool -> Bool -> Bool
&& Char -> Bool
isAlpha Char
c Bool -> Bool -> Bool
&& Char -> Bool
isAlpha (String -> Char
forall a. HasCallStack => [a] -> a
last String
string)
          then
            SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
endPos Severity
WarningC Integer
1011
                String
"This apostrophe terminated the single quoted string!"
          else
            Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char
'\n' Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
string Bool -> Bool -> Bool
&& Bool -> Bool
not (String
"\n" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
string)) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
                SourcePos
-> SourcePos -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> String -> m ()
suggestForgotClosingQuote SourcePos
startPos SourcePos
endPos String
"single quoted string"

    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> String -> Token
T_SingleQuoted Id
id String
string)

readSingleQuotedLiteral :: ParsecT String UserState (SCBase m) String
readSingleQuotedLiteral = do
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
singleQuote
    [String]
strs <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readSingleQuotedPart
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
singleQuote
    String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT String UserState (SCBase m) String)
-> String -> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
strs

readSingleQuotedPart :: ParsecT String UserState (SCBase m) String
readSingleQuotedPart =
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readSingleEscaped
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf (String -> ParsecT String UserState (SCBase m) Char)
-> String -> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ String
"'\\" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
unicodeSingleQuotes)
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m String
readUnicodeQuote
   where
    readUnicodeQuote :: ParsecT s u m String
readUnicodeQuote = do
        SourcePos
pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Char
x <- String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
unicodeSingleQuotes
        SourcePos -> Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1112
            String
"This is a unicode quote. Delete and retype it (or ignore/doublequote for literal)."
        String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char
x]


prop_readBackTicked :: Bool
prop_readBackTicked = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk (Bool -> ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
False) String
"`ls *.mp3`"
prop_readBackTicked2 :: Bool
prop_readBackTicked2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk (Bool -> ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
False) String
"`grep \"\\\"\"`"
prop_readBackTicked3 :: Bool
prop_readBackTicked3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning (Bool -> ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
False) String
"´grep \"\\\"\"´"
prop_readBackTicked4 :: Bool
prop_readBackTicked4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"`echo foo\necho bar`"
prop_readBackTicked5 :: Bool
prop_readBackTicked5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo `foo`bar"
prop_readBackTicked6 :: Bool
prop_readBackTicked6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo `foo\necho `bar"
prop_readBackTicked7 :: Bool
prop_readBackTicked7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"`#inline comment`"
prop_readBackTicked8 :: Bool
prop_readBackTicked8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo `#comment` \\\nbar baz"
readQuotedBackTicked :: ParsecT String UserState (SCBase m) Token
readQuotedBackTicked = Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
True
readUnquotedBackTicked :: ParsecT String UserState (SCBase m) Token
readUnquotedBackTicked = Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
False
readBackTicked :: Bool -> ParsecT String UserState (SCBase m) Token
readBackTicked Bool
quoted = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"backtick expansion" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
startPos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
backtick
    SourcePos
subStart <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    String
subString <- String -> ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) String
readGenericLiteral String
"`´"
    SourcePos
endPos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
backtick
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start

    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        Char
c <- ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> (ParsecT String UserState (SCBase m) Char
    -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
suspectCharAfterQuotes
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char
'\n' Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
subString Bool -> Bool -> Bool
&& Bool -> Bool
not (String
"\n" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
subString)) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
            SourcePos
-> SourcePos -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> String -> m ()
suggestForgotClosingQuote SourcePos
startPos SourcePos
endPos String
"backtick expansion"

    -- Result positions may be off due to escapes
    [Token]
result <- SourcePos
-> ParsecT String UserState (SCBase m) [Token]
-> String
-> ParsecT String UserState (SCBase m) [Token]
forall {m :: * -> *} {s} {u} {b}.
Monad m =>
SourcePos -> ParsecT s u m b -> s -> ParsecT s u m b
subParse SourcePos
subStart (ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall (m :: * -> *) v. Monad m => SCParser m v -> SCParser m v
tryWithErrors ParsecT String UserState (SCBase m) [Token]
subParser ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return []) (String -> String
unEscape String
subString)
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_Backticked Id
id [Token]
result
  where
    unEscape :: String -> String
unEscape [] = []
    unEscape (Char
'\\':Char
'"':String
rest) | Bool
quoted = Char
'"' Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
unEscape String
rest
    unEscape (Char
'\\':Char
x:String
rest) | Char
x Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"$`\\" = Char
x Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
unEscape String
rest
    unEscape (Char
'\\':Char
'\n':String
rest) = String -> String
unEscape String
rest
    unEscape (Char
c:String
rest) = Char
c Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
unEscape String
rest
    subParser :: ParsecT String UserState (SCBase m) [Token]
subParser = do
        [Token]
cmds <- ParsecT String UserState (SCBase m) [Token]
readCompoundListOrEmpty
        ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
verifyEof
        [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
cmds
    backtick :: ParsecT s u m ()
backtick =
      ParsecT s u m Char -> ParsecT s u m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (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 () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
         SourcePos
pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
         Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'´'
         SourcePos -> Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1077
            String
"For command expansion, the tick should slant left (` vs ´). Use $(..) instead."

-- Run a parser on a new input, such as for `..` or here documents.
subParse :: SourcePos -> ParsecT s u m b -> s -> ParsecT s u m b
subParse SourcePos
pos ParsecT s u m b
parser s
input = do
    SourcePos
lastPosition <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    s
lastInput <- ParsecT s u m s
forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
    SourcePos -> ParsecT s u m ()
forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
pos
    s -> ParsecT s u m ()
forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput s
input
    b
result <- ParsecT s u m b
parser
    s -> ParsecT s u m ()
forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput s
lastInput
    SourcePos -> ParsecT s u m ()
forall (m :: * -> *) s u. Monad m => SourcePos -> ParsecT s u m ()
setPosition SourcePos
lastPosition
    b -> ParsecT s u m b
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return b
result

-- Parse something, but forget all parseProblems
inSeparateContext :: ParsecT s u m b -> ParsecT s u m b
inSeparateContext = Bool -> ParsecT s u m b -> ParsecT s u m b
forall {s} {m :: * -> *} {s} {u} {b}.
MonadState s m =>
Bool -> ParsecT s u m b -> ParsecT s u m b
parseForgettingContext Bool
True
-- Parse something, but forget all parseProblems on failure
forgetOnFailure :: ParsecT s u m b -> ParsecT s u m b
forgetOnFailure = Bool -> ParsecT s u m b -> ParsecT s u m b
forall {s} {m :: * -> *} {s} {u} {b}.
MonadState s m =>
Bool -> ParsecT s u m b -> ParsecT s u m b
parseForgettingContext Bool
False

parseForgettingContext :: Bool -> ParsecT s u m b -> ParsecT s u m b
parseForgettingContext Bool
alsoOnSuccess ParsecT s u m b
parser = do
    s
context <- ParsecT s u m s
forall s (m :: * -> *). MonadState s m => m s
Ms.get
    s -> ParsecT s u m b
success s
context ParsecT s u m b -> ParsecT s u m b -> ParsecT s u m b
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> s -> ParsecT s u m b
forall {m :: * -> *} {s} {b}.
(MonadState s m, MonadFail m) =>
s -> m b
failure s
context
  where
    success :: s -> ParsecT s u m b
success s
c = do
        b
res <- ParsecT s u m b -> ParsecT s u m b
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m b
parser
        Bool -> ParsecT s u m () -> ParsecT s u m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
alsoOnSuccess (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ s -> ParsecT s u m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
Ms.put s
c
        b -> ParsecT s u m b
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return b
res
    failure :: s -> m b
failure s
c = do
        s -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
Ms.put s
c
        String -> m b
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
""

prop_readDoubleQuoted :: Bool
prop_readDoubleQuoted = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted String
"\"Hello $FOO\""
prop_readDoubleQuoted2 :: Bool
prop_readDoubleQuoted2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted String
"\"$'\""
prop_readDoubleQuoted3 :: Bool
prop_readDoubleQuoted3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted String
"\"\x2018hello\x2019\""
prop_readDoubleQuoted4 :: Bool
prop_readDoubleQuoted4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"\"foo\nbar\"foo"
prop_readDoubleQuoted5 :: Bool
prop_readDoubleQuoted5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"lol \"foo\nbar\" etc"
prop_readDoubleQuoted6 :: Bool
prop_readDoubleQuoted6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo \"${ ls; }\""
prop_readDoubleQuoted7 :: Bool
prop_readDoubleQuoted7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo \"${ ls;}bar\""
prop_readDoubleQuoted8 :: Bool
prop_readDoubleQuoted8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted String
"\"\x201Chello\x201D\""
prop_readDoubleQuoted10 :: Bool
prop_readDoubleQuoted10 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleQuoted String
"\"foo\\\\n\""
readDoubleQuoted :: ParsecT String UserState (SCBase m) Token
readDoubleQuoted = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"double quoted string" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
startPos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuote
    [Token]
x <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
doubleQuotedPart
    SourcePos
endPos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuote ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected end of double quoted string"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> (ParsecT String UserState (SCBase m) Char
    -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
suspectCharAfterQuotes ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"$\""
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ((Token -> Bool) -> [Token] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Token -> Bool
hasLineFeed [Token]
x Bool -> Bool -> Bool
&& Bool -> Bool
not ([Token] -> Bool
startsWithLineFeed [Token]
x)) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
            SourcePos
-> SourcePos -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> String -> m ()
suggestForgotClosingQuote SourcePos
startPos SourcePos
endPos String
"double quoted string"
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_DoubleQuoted Id
id [Token]
x
  where
    startsWithLineFeed :: [Token] -> Bool
startsWithLineFeed (T_Literal Id
_ (Char
'\n':String
_):[Token]
_) = Bool
True
    startsWithLineFeed [Token]
_ = Bool
False
    hasLineFeed :: Token -> Bool
hasLineFeed (T_Literal Id
_ String
str) | Char
'\n' Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
str = Bool
True
    hasLineFeed Token
_ = Bool
False

suggestForgotClosingQuote :: SourcePos -> SourcePos -> String -> m ()
suggestForgotClosingQuote SourcePos
startPos SourcePos
endPos String
name = do
    SourcePos -> Severity -> Integer -> String -> m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
startPos Severity
WarningC Integer
1078 (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$
        String
"Did you forget to close this " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"?"
    SourcePos -> Severity -> Integer -> String -> m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
endPos Severity
InfoC Integer
1079
        String
"This is actually an end quote, but due to next char it looks suspect."

doubleQuotedPart :: ParsecT String UserState (SCBase m) Token
doubleQuotedPart = ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDoubleLiteral ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDoubleQuotedDollar ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readQuotedBackTicked ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
readUnicodeQuote
  where
    readUnicodeQuote :: ParsecT s UserState m Token
readUnicodeQuote = do
        SourcePos
pos <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        Char
c <- String -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
unicodeDoubleQuotes
        Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1111
            String
"This is a unicode quote. Delete and retype it (or ignore/singlequote for literal)."
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id [Char
c]

readDoubleLiteral :: ParsecT String UserState (SCBase m) Token
readDoubleLiteral = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [String]
s <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readDoubleLiteralPart
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id ([String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
s)

readDoubleLiteralPart :: ParsecT String UserState (SCBase m) String
readDoubleLiteralPart = do
    [String]
x <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readDoubleEscaped ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf (String
doubleQuotableChars String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
unicodeDoubleQuotes)))
    String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT String UserState (SCBase m) String)
-> String -> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
x

readNormalLiteral :: String -> ParsecT String UserState (SCBase m) Token
readNormalLiteral String
end = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [String]
s <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) String
readNormalLiteralPart String
end)
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id ([String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
s)

prop_readGlob1 :: Bool
prop_readGlob1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"*"
prop_readGlob2 :: Bool
prop_readGlob2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[^0-9]"
prop_readGlob3 :: Bool
prop_readGlob3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[a[:alpha:]]"
prop_readGlob4 :: Bool
prop_readGlob4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[[:alnum:]]"
prop_readGlob5 :: Bool
prop_readGlob5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[^[:alpha:]1-9]"
prop_readGlob6 :: Bool
prop_readGlob6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[\\|]"
prop_readGlob7 :: Bool
prop_readGlob7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[^[]"
prop_readGlob8 :: Bool
prop_readGlob8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[*?]"
prop_readGlob9 :: Bool
prop_readGlob9 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[!]^]"
prop_readGlob10 :: Bool
prop_readGlob10 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readGlob String
"[]]"
readGlob :: ParsecT String UserState (SCBase m) Token
readGlob = ParsecT String UserState (SCBase m) Token
readExtglob ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
readSimple ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readClass ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
readGlobbyLiteral
    where
        readSimple :: ParsecT s UserState m Token
readSimple = do
            IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            Char
c <- String -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"*?"
            Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Glob Id
id [Char
c]
        readClass :: ParsecT String UserState (SCBase m) Token
readClass = ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
            IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
            String
negation <- ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {f :: * -> *} {a}.
(Monad m, Functor f) =>
f a -> f (m a)
charToString (String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"!^") ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
""
            String
leadingBracket <- ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {f :: * -> *} {a}.
(Monad m, Functor f) =>
f a -> f (m a)
charToString (String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"]") ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
""
            [String]
s <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
predefined ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) String
readNormalLiteralPart String
"]" ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {m :: * -> *} {u}.
(Stream s m Char, Monad m) =>
ParsecT s u m (m Char)
globchars)
            Bool -> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParsecT String UserState (SCBase m) ())
-> Bool -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
leadingBracket) Bool -> Bool -> Bool
|| Bool -> Bool
not ([String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
s)
            Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
']'
            Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Glob Id
id (String -> Token) -> String -> Token
forall a b. (a -> b) -> a -> b
$ String
"[" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (String
negationString -> [String] -> [String]
forall a. a -> [a] -> [a]
:String
leadingBracketString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
s) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]"
          where
           globchars :: ParsecT s u m (m Char)
globchars = ParsecT s u m Char -> ParsecT s u m (m Char)
forall {m :: * -> *} {f :: * -> *} {a}.
(Monad m, Functor f) =>
f a -> f (m a)
charToString (ParsecT s u m Char -> ParsecT s u m (m Char))
-> ParsecT s u m Char -> ParsecT s u m (m Char)
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf (String -> ParsecT s u m Char) -> String -> ParsecT s u m Char
forall a b. (a -> b) -> a -> b
$ String
"![" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
extglobStartChars
           predefined :: ParsecT s u m String
predefined = do
              ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"[:"
              String
s <- ParsecT s u m Char -> ParsecT s u m String
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
letter
              String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
":]"
              String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT s u m String) -> String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ String
"[:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":]"

        charToString :: f a -> f (m a)
charToString = (a -> m a) -> f a -> f (m a)
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return
        readGlobbyLiteral :: ParsecT s UserState m Token
readGlobbyLiteral = do
            IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
            Char
c <- ParsecT s UserState m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
extglobStart ParsecT s UserState m Char
-> ParsecT s UserState m Char -> ParsecT s UserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
            Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
            Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id [Char
c]

readNormalLiteralPart :: String -> ParsecT String UserState (SCBase m) String
readNormalLiteralPart String
customEnd =
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readNormalEscaped ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf (String
customEnd String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
standardEnd))
  where
    standardEnd :: String
standardEnd = String
"[{}"
        String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
quotableChars
        String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
extglobStartChars
        String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
unicodeDoubleQuotes
        String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
unicodeSingleQuotes

readNormalEscaped :: ParsecT String UserState (SCBase m) String
readNormalEscaped = String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"escaped char" (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    SCParser m Char
forall (m :: * -> *). Monad m => SCParser m Char
backslash
    do
        Char
next <- SCParser m Char
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m,
 Stream s m Char) =>
ParsecT s UserState m Char
quotable SCParser m Char -> SCParser m Char -> SCParser m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> SCParser m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"?*@!+[]{}.,~#"
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char
next Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ SourcePos -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
SourcePos -> ParsecT String UserState (SCBase m) ()
checkTrailingSpaces SourcePos
pos ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> () -> ParsecT String UserState (SCBase m) ()
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
        -- Check if this line is followed by a commented line with a trailing backslash
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Char
next Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n') (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> (ParsecT String UserState (SCBase m) ()
    -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
        String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT String UserState (SCBase m) String)
-> String -> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ if Char
next Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' then String
"" else [Char
next]
      ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        do
            Char
next <- SCParser m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
            case Char -> Maybe String
escapedChar Char
next of
                Just String
name -> SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
WarningC Integer
1012 (String -> ParsecT String UserState (SCBase m) ())
-> String -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ String
"\\" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
next] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is just literal '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
next] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' here. For " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", use " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Char -> String
alternative Char
next String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" instead."
                Maybe String
Nothing -> SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
InfoC Integer
1001 (String -> ParsecT String UserState (SCBase m) ())
-> String -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ String
"This \\" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
next] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" will be a regular '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
next] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' in this context."
            String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char
next]
  where
    alternative :: Char -> String
alternative Char
'n' = String
"a quoted, literal line feed"
    alternative Char
t = String
"\"$(printf '\\" String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
t] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"')\""
    escapedChar :: Char -> Maybe String
escapedChar Char
'n' = String -> Maybe String
forall a. a -> Maybe a
Just String
"line feed"
    escapedChar Char
't' = String -> Maybe String
forall a. a -> Maybe a
Just String
"tab"
    escapedChar Char
'r' = String -> Maybe String
forall a. a -> Maybe a
Just String
"carriage return"
    escapedChar Char
_ = Maybe String
forall a. Maybe a
Nothing

    checkTrailingSpaces :: SourcePos -> ParsecT String UserState (SCBase m) ()
checkTrailingSpaces SourcePos
pos = ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> (ParsecT String UserState (SCBase m) ()
    -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Char
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Char
linewhitespace
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
linefeed ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1101 String
"Delete trailing spaces after \\ to break line (or use quotes for literal space)."


prop_readExtglob1 :: Bool
prop_readExtglob1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"!(*.mp3)"
prop_readExtglob2 :: Bool
prop_readExtglob2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"!(*.mp3|*.wmv)"
prop_readExtglob4 :: Bool
prop_readExtglob4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"+(foo \\) bar)"
prop_readExtglob5 :: Bool
prop_readExtglob5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"+(!(foo *(bar)))"
prop_readExtglob6 :: Bool
prop_readExtglob6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"*(((||))|())"
prop_readExtglob7 :: Bool
prop_readExtglob7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"*(<>)"
prop_readExtglob8 :: Bool
prop_readExtglob8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readExtglob String
"@(|*())"
readExtglob :: ParsecT String UserState (SCBase m) Token
readExtglob = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"extglob" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Char
c <- ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ do
            Char
f <- ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
extglobStart
            Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
            Char -> ParsecT String UserState (SCBase m) Char
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
f
    [Token]
contents <- ParsecT String UserState (SCBase m) Token
readExtglobPart ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) [Token]
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]
`sepBy` Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|'
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> Token
T_Extglob Id
id [Char
c] [Token]
contents

readExtglobPart :: ParsecT String UserState (SCBase m) Token
readExtglobPart = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    [Token]
x <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String UserState (SCBase m) Token
readExtglobGroup ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Token
readNormalWordPart String
"" ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSpacePart ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
readExtglobLiteral)
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id [Token]
x
  where
    readExtglobGroup :: ParsecT String UserState (SCBase m) Token
readExtglobGroup = do
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
        IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        [Token]
contents <- ParsecT String UserState (SCBase m) Token
readExtglobPart ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) [Token]
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]
`sepBy` Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|'
        Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> Token
T_Extglob Id
id String
"" [Token]
contents
    readExtglobLiteral :: ParsecT s UserState m Token
readExtglobLiteral = do
        IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
str <- ParsecT s UserState m Char -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"<>#;&")
        Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
str


readSingleEscaped :: ParsecT String UserState (SCBase m) String
readSingleEscaped = do
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Char
s <- SCParser m Char
forall (m :: * -> *). Monad m => SCParser m Char
backslash
    Char
x <- SCParser m Char -> SCParser m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead SCParser m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar

    case Char
x of
        Char
'\'' -> SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
InfoC Integer
1003 String
"Want to escape a single quote? echo 'This is how it'\\''s done'.";
        Char
_ -> () -> ParsecT String UserState (SCBase m) ()
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

    String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char
s]

readDoubleEscaped :: ParsecT String UserState (SCBase m) String
readDoubleEscaped = do
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Char
bs <- SCParser m Char
forall (m :: * -> *). Monad m => SCParser m Char
backslash
    (SCParser m Char
forall (m :: * -> *). Monad m => SCParser m Char
linefeed SCParser m Char
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"")
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Char -> String)
-> SCParser m Char -> ParsecT String UserState (SCBase m) String
forall a b.
(a -> b)
-> ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> String
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return SCParser m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuotable
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
            Char
c <- SCParser m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
            -- This is an invalid escape sequence where the \ is literal.
            -- Previously this caused a SC1117, which may be re-enabled as
            -- as a pedantic warning.
            String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Char
bs, Char
c]

readBraceEscaped :: ParsecT String UserState (SCBase m) String
readBraceEscaped = do
    Char
bs <- SCParser m Char
forall (m :: * -> *). Monad m => SCParser m Char
backslash
    (SCParser m Char
forall (m :: * -> *). Monad m => SCParser m Char
linefeed SCParser m Char
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"")
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Char -> String)
-> SCParser m Char -> ParsecT String UserState (SCBase m) String
forall a b.
(a -> b)
-> ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> String
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return SCParser m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
bracedQuotable
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Char -> String)
-> SCParser m Char -> ParsecT String UserState (SCBase m) String
forall a b.
(a -> b)
-> ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\ Char
x -> [Char
bs, Char
x]) SCParser m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar


readGenericLiteral :: String -> ParsecT String UserState (SCBase m) String
readGenericLiteral String
endChars = do
    [String]
strings <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) [String]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readGenericEscaped ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf (Char
'\\'Char -> String -> String
forall a. a -> [a] -> [a]
:String
endChars)))
    String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT String UserState (SCBase m) String)
-> String -> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
strings

readGenericLiteral1 :: ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) String
readGenericLiteral1 ParsecT String UserState (SCBase m) a
endExp = do
    [String]
strings <- (ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readGenericEscaped ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ((\Char
x -> [Char
x]) (Char -> String)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar)) ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) [String]
forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill1` ParsecT String UserState (SCBase m) a
endExp
    String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT String UserState (SCBase m) String)
-> String -> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
strings

readGenericEscaped :: ParsecT String UserState (SCBase m) String
readGenericEscaped = do
    SCParser m Char
forall (m :: * -> *). Monad m => SCParser m Char
backslash
    Char
x <- SCParser m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
    String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT String UserState (SCBase m) String)
-> String -> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ if Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' then [] else [Char
'\\', Char
x]

prop_readBraced :: Bool
prop_readBraced = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{1..4}"
prop_readBraced2 :: Bool
prop_readBraced2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{foo,bar,\"baz lol\"}"
prop_readBraced3 :: Bool
prop_readBraced3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{1,\\},2}"
prop_readBraced4 :: Bool
prop_readBraced4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{1,{2,3}}"
prop_readBraced5 :: Bool
prop_readBraced5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{JP{,E}G,jp{,e}g}"
prop_readBraced6 :: Bool
prop_readBraced6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{foo,bar,$((${var}))}"
prop_readBraced7 :: Bool
prop_readBraced7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{}"
prop_readBraced8 :: Bool
prop_readBraced8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraced String
"{foo}"
readBraced :: ParsecT String UserState (SCBase m) Token
readBraced = ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT String UserState (SCBase m) Token
braceExpansion
  where
    braceExpansion :: ParsecT String UserState (SCBase m) Token
braceExpansion =
        Id -> [Token] -> Token
T_BraceExpansion (Id -> [Token] -> Token)
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {t} {b} {s}.
Monad m =>
(Id -> t -> b)
-> ParsecT s UserState m t -> ParsecT s UserState m b
`withParser` do
            Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'{'
            [Token]
elements <- ParsecT String UserState (SCBase m) Token
bracedElement ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) [Token]
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]
`sepBy1` Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
','
            Bool -> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParsecT String UserState (SCBase m) ())
-> Bool -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
                case [Token]
elements of
                    (Token
_:Token
_:[Token]
_) -> Bool
True
                    [Token
t] -> String
".." String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` Token -> String
onlyLiteralString Token
t
                    [] -> Bool
False
            Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
            [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
elements
    bracedElement :: ParsecT String UserState (SCBase m) Token
bracedElement =
        Id -> [Token] -> Token
T_NormalWord (Id -> [Token] -> Token)
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {t} {b} {s}.
Monad m =>
(Id -> t -> b)
-> ParsecT s UserState m t -> ParsecT s UserState m b
`withParser` do
            ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) [Token])
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall a b. (a -> b) -> a -> b
$ [ParsecT String UserState (SCBase m) Token]
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
                ParsecT String UserState (SCBase m) Token
braceExpansion,
                ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression,
                ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSingleQuoted,
                ParsecT String UserState (SCBase m) Token
readDoubleQuoted,
                ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
braceLiteral
                ]
    braceLiteral :: ParsecT String UserState (SCBase m) Token
braceLiteral =
        Id -> String -> Token
T_Literal (Id -> String -> Token)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {t} {b} {s}.
Monad m =>
(Id -> t -> b)
-> ParsecT s UserState m t -> ParsecT s UserState m b
`withParser` ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {a}.
Monad m =>
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) String
readGenericLiteral1 (String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"{}\"$'," ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
whitespace)

ensureDollar :: ParsecT s u m Char
ensureDollar =
    -- The grammar should have been designed along the lines of readDollarExpr = char '$' >> stuff, but
    -- instead, each subunit parses its own $. This results in ~7 1-3 char lookaheads instead of one 1-char.
    -- Instead of optimizing the grammar, here's a green cut that decreases shellcheck runtime by 10%:
    ParsecT s u m Char -> ParsecT s u m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s u m Char -> ParsecT s u m Char)
-> ParsecT s u m Char -> ParsecT s u m Char
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$'

readNormalDollar :: ParsecT String UserState (SCBase m) Token
readNormalDollar = do
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
ensureDollar
    ParsecT String UserState (SCBase m) Token
readDollarExp ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDollarDoubleQuote ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarSingleQuote ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Bool -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readDollarLonely Bool
False
readDoubleQuotedDollar :: ParsecT String UserState (SCBase m) Token
readDoubleQuotedDollar = do
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
ensureDollar
    ParsecT String UserState (SCBase m) Token
readDollarExp ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Bool -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readDollarLonely Bool
True


prop_readDollarExpression1 :: Bool
prop_readDollarExpression1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression String
"$(((1) && 3))"
prop_readDollarExpression2 :: Bool
prop_readDollarExpression2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression String
"$(((1)) && 3)"
prop_readDollarExpression3 :: Bool
prop_readDollarExpression3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression String
"$((\"$@\" &); foo;)"
readDollarExpression :: Monad m => SCParser m Token
readDollarExpression :: forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpression = do
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
ensureDollar
    SCParser m Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExp

readDollarExp :: ParsecT String UserState (SCBase m) Token
readDollarExp = ParsecT String UserState (SCBase m) Token
arithmetic ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDollarExpansion ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBracket ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDollarBraceCommandExpansion ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readDollarBraced ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable
  where
    arithmetic :: ParsecT String UserState (SCBase m) Token
arithmetic = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> (SourcePos -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) Token
forall (m :: * -> *) p.
Monad m =>
String
-> SCParser m p
-> SCParser m p
-> (SourcePos -> SCParser m ())
-> SCParser m p
readAmbiguous String
"$((" ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarArithmetic ParsecT String UserState (SCBase m) Token
readDollarExpansion (\SourcePos
pos ->
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1102 String
"Shells disambiguate $(( differently or not at all. For $(command substitution), add space after $( . For $((arithmetics)), fix parsing errors.")

prop_readDollarSingleQuote :: Bool
prop_readDollarSingleQuote = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarSingleQuote String
"$'foo\\\'lol'"
readDollarSingleQuote :: ParsecT String UserState (SCBase m) Token
readDollarSingleQuote = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"$'..' expression" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"$'"
    String
str <- String -> ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) String
readGenericLiteral String
"'"
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\''
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_DollarSingleQuoted Id
id String
str

prop_readDollarDoubleQuote :: Bool
prop_readDollarDoubleQuote = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarDoubleQuote String
"$\"hello\""
readDollarDoubleQuote :: ParsecT String UserState (SCBase m) Token
readDollarDoubleQuote = do
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> (ParsecT String UserState (SCBase m) String
    -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"$\""
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$'
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuote
    [Token]
x <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) Token
doubleQuotedPart
    ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
doubleQuote ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected end of translated double quoted string"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_DollarDoubleQuoted Id
id [Token]
x

prop_readDollarArithmetic :: Bool
prop_readDollarArithmetic = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarArithmetic String
"$(( 3 * 4 +5))"
prop_readDollarArithmetic2 :: Bool
prop_readDollarArithmetic2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarArithmetic String
"$(((3*4)+(1*2+(3-1))))"
readDollarArithmetic :: ParsecT String UserState (SCBase m) Token
readDollarArithmetic = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"$((..)) expression" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"$((")
    Token
c <- ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')'
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected a double )) to end the $((..))"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Token -> Token
T_DollarArithmetic Id
id Token
c)

readDollarBracket :: ParsecT String UserState (SCBase m) Token
readDollarBracket = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"$[..] expression" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"$[")
    Token
c <- ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
    String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"]"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Token -> Token
T_DollarBracket Id
id Token
c)

prop_readArithmeticExpression :: Bool
prop_readArithmeticExpression = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticExpression String
"((a?b:c))"
readArithmeticExpression :: ParsecT String UserState (SCBase m) Token
readArithmeticExpression = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"((..)) command" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"((")
    Token
c <- ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
    String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"))"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Token -> Token
T_Arithmetic Id
id Token
c)

-- If the next characters match prefix, try two different parsers and warn if the alternate parser had to be used
readAmbiguous :: Monad m => String -> SCParser m p -> SCParser m p -> (SourcePos -> SCParser m ()) -> SCParser m p
readAmbiguous :: forall (m :: * -> *) p.
Monad m =>
String
-> SCParser m p
-> SCParser m p
-> (SourcePos -> SCParser m ())
-> SCParser m p
readAmbiguous String
prefix SCParser m p
expected SCParser m p
alternative SourcePos -> SCParser m ()
warner = do
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> (ParsecT String UserState (SCBase m) String
    -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
prefix
    -- If the expected parser fails, try the alt.
    -- If the alt fails, run the expected one again for the errors.
    SCParser m p -> SCParser m p
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try SCParser m p
expected SCParser m p -> SCParser m p -> SCParser m p
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> SCParser m p -> SCParser m p
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (SourcePos -> SCParser m p
withAlt SourcePos
pos) SCParser m p -> SCParser m p -> SCParser m p
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> SCParser m p
expected
  where
    withAlt :: SourcePos -> SCParser m p
withAlt SourcePos
pos = do
        p
t <- SCParser m p -> SCParser m p
forall {s} {m :: * -> *} {s} {u} {b}.
MonadState s m =>
ParsecT s u m b -> ParsecT s u m b
forgetOnFailure SCParser m p
alternative
        SourcePos -> SCParser m ()
warner SourcePos
pos
        p -> SCParser m p
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return p
t

prop_readDollarBraceCommandExpansion1 :: Bool
prop_readDollarBraceCommandExpansion1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraceCommandExpansion String
"${ ls; }"
prop_readDollarBraceCommandExpansion2 :: Bool
prop_readDollarBraceCommandExpansion2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraceCommandExpansion String
"${\nls\n}"
prop_readDollarBraceCommandExpansion3 :: Bool
prop_readDollarBraceCommandExpansion3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraceCommandExpansion String
"${|  REPLY=42; }"
readDollarBraceCommandExpansion :: ParsecT String UserState (SCBase m) Token
readDollarBraceCommandExpansion = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"ksh-style ${ ..; } command expansion" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Char
c <- ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ do
            String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"${"
            Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
whitespace
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    [Token]
term <- ParsecT String UserState (SCBase m) [Token]
readTerm
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected } to end the ksh-style ${ ..; } command expansion"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> Piped -> [Token] -> Token
T_DollarBraceCommandExpansion Id
id (if Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'|' then Piped
Piped else Piped
Unpiped) [Token]
term

prop_readDollarBraced1 :: Bool
prop_readDollarBraced1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraced String
"${foo//bar/baz}"
prop_readDollarBraced2 :: Bool
prop_readDollarBraced2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraced String
"${foo/'{cow}'}"
prop_readDollarBraced3 :: Bool
prop_readDollarBraced3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraced String
"${foo%%$(echo cow\\})}"
prop_readDollarBraced4 :: Bool
prop_readDollarBraced4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarBraced String
"${foo#\\}}"
readDollarBraced :: ParsecT String UserState (SCBase m) Token
readDollarBraced = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"parameter expansion" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"${")
    Token
word <- ParsecT String UserState (SCBase m) Token
readDollarBracedWord
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> Bool -> Token -> Token
T_DollarBraced Id
id Bool
True Token
word

prop_readDollarExpansion1 :: Bool
prop_readDollarExpansion1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpansion String
"$(echo foo; ls\n)"
prop_readDollarExpansion2 :: Bool
prop_readDollarExpansion2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpansion String
"$(  )"
prop_readDollarExpansion3 :: Bool
prop_readDollarExpansion3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarExpansion String
"$( command \n#comment \n)"
readDollarExpansion :: ParsecT String UserState (SCBase m) Token
readDollarExpansion = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"command expansion" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"$(")
    [Token]
cmds <- ParsecT String UserState (SCBase m) [Token]
readCompoundListOrEmpty
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected end of $(..) expression"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_DollarExpansion Id
id [Token]
cmds

prop_readDollarVariable :: Bool
prop_readDollarVariable = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable String
"$@"
prop_readDollarVariable2 :: Bool
prop_readDollarVariable2 = ParsecT String UserState (SCBase Identity) Char -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk (ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable ParsecT String UserState (SCBase Identity) Token
-> ParsecT String UserState (SCBase Identity) Char
-> ParsecT String UserState (SCBase Identity) Char
forall a b.
ParsecT String UserState (SCBase Identity) a
-> ParsecT String UserState (SCBase Identity) b
-> ParsecT String UserState (SCBase Identity) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase Identity) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) String
"$?!"
prop_readDollarVariable3 :: Bool
prop_readDollarVariable3 = ParsecT String UserState (SCBase Identity) Char -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning (ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable ParsecT String UserState (SCBase Identity) Token
-> ParsecT String UserState (SCBase Identity) Char
-> ParsecT String UserState (SCBase Identity) Char
forall a b.
ParsecT String UserState (SCBase Identity) a
-> ParsecT String UserState (SCBase Identity) b
-> ParsecT String UserState (SCBase Identity) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase Identity) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) String
"$10"
prop_readDollarVariable4 :: Bool
prop_readDollarVariable4 = ParsecT String UserState (SCBase Identity) String -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning (ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable ParsecT String UserState (SCBase Identity) Token
-> ParsecT String UserState (SCBase Identity) String
-> ParsecT String UserState (SCBase Identity) String
forall a b.
ParsecT String UserState (SCBase Identity) a
-> ParsecT String UserState (SCBase Identity) b
-> ParsecT String UserState (SCBase Identity) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> ParsecT String UserState (SCBase Identity) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"[@]") String
"$arr[@]"
prop_readDollarVariable5 :: Bool
prop_readDollarVariable5 = ParsecT String UserState (SCBase Identity) String -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning (ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable ParsecT String UserState (SCBase Identity) Token
-> ParsecT String UserState (SCBase Identity) String
-> ParsecT String UserState (SCBase Identity) String
forall a b.
ParsecT String UserState (SCBase Identity) a
-> ParsecT String UserState (SCBase Identity) b
-> ParsecT String UserState (SCBase Identity) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> ParsecT String UserState (SCBase Identity) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"[f") String
"$arr[f"

readDollarVariable :: Monad m => SCParser m Token
readDollarVariable :: forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readDollarVariable = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition

    let singleCharred :: ParsecT s UserState m Char -> ParsecT s UserState m Token
singleCharred ParsecT s UserState m Char
p = do
        Token
value <- ParsecT s UserState m String -> ParsecT s UserState m Token
forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m String -> ParsecT s UserState m Token
wrapString ((Char -> String -> String
forall a. a -> [a] -> [a]
:[]) (Char -> String)
-> ParsecT s UserState m Char -> ParsecT s UserState m String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s UserState m Char
p)
        Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ (Id -> Bool -> Token -> Token
T_DollarBraced Id
id Bool
False Token
value)

    let positional :: ParsecT s UserState m Token
positional = do
        Token
value <- ParsecT s UserState m Char -> ParsecT s UserState m Token
forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m Char -> ParsecT s UserState m Token
singleCharred ParsecT s UserState m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
value ParsecT s UserState m Token
-> ParsecT s UserState m () -> ParsecT s UserState m Token
forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` do
            ParsecT s UserState m Char -> ParsecT s UserState m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT s UserState m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
            SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1037 String
"Braces are required for positionals over 9, e.g. ${10}."

    let special :: ParsecT s UserState m Token
special = ParsecT s UserState m Char -> ParsecT s UserState m Token
forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m Char -> ParsecT s UserState m Token
singleCharred ParsecT s UserState m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
specialVariable

    let regular :: ParsecT s UserState m Token
regular = do
        Token
value <- ParsecT s UserState m String -> ParsecT s UserState m Token
forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m String -> ParsecT s UserState m Token
wrapString ParsecT s UserState m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
        Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Bool -> Token -> Token
T_DollarBraced Id
id Bool
False Token
value) ParsecT s UserState m Token
-> ParsecT s UserState m () -> ParsecT s UserState m Token
forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` do
            ParsecT s UserState m Char -> ParsecT s UserState m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s UserState m Char -> ParsecT s UserState m Char)
-> ParsecT s UserState m Char -> ParsecT s UserState m Char
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
            SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
parseNoteAt SourcePos
pos Severity
ErrorC Integer
1087 String
"Use braces when expanding arrays, e.g. ${array[idx]} (or ${var}[.. to quiet)."

    SCParser m Token -> SCParser m Token
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (SCParser m Token -> SCParser m Token)
-> SCParser m Token -> SCParser m Token
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$' ParsecT String UserState (SCBase m) Char
-> SCParser m Token -> SCParser m Token
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (SCParser m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
positional SCParser m Token -> SCParser m Token -> SCParser m Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> SCParser m Token
forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
special SCParser m Token -> SCParser m Token -> SCParser m Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> SCParser m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
regular)

  where
    wrapString :: ParsecT s UserState m String -> ParsecT s UserState m Token
wrapString ParsecT s UserState m String
p = do
        SourcePos
start <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
s <- ParsecT s UserState m String
p
        SourcePos
end <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Id
id1 <- SourcePos -> SourcePos -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
end
        Id
id2 <- SourcePos -> SourcePos -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
end
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_NormalWord Id
id1 [Id -> String -> Token
T_Literal Id
id2 String
s]

readVariableName :: ParsecT s u m String
readVariableName = do
    Char
f <- ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableStart
    String
rest <- ParsecT s u m Char -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableChars
    String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Char
fChar -> String -> String
forall a. a -> [a] -> [a]
:String
rest)


prop_readDollarLonely1 :: Bool
prop_readDollarLonely1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\"$\"var"
prop_readDollarLonely2 :: Bool
prop_readDollarLonely2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\"$\"\"var\""
prop_readDollarLonely3 :: Bool
prop_readDollarLonely3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\"$\"$var"
prop_readDollarLonely4 :: Bool
prop_readDollarLonely4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"\"$\"*"
prop_readDollarLonely5 :: Bool
prop_readDollarLonely5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readNormalWord String
"$\"str\""
readDollarLonely :: Bool -> ParsecT String UserState (SCBase m) Token
readDollarLonely Bool
quoted = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$'
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
quoted (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        Bool
isHack <- ParsecT String UserState (SCBase m) Bool
forall {s} {m :: * -> *} {u}. Stream s m Char => ParsecT s u m Bool
quoteForEscape
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
isHack (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
            Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
StyleC Integer
1135
                String
"Prefer escape over ending quote to make $ literal. Instead of \"It costs $\"5, use \"It costs \\$5\"."
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
"$"
  where
    quoteForEscape :: ParsecT s u m Bool
quoteForEscape = Bool -> ParsecT s u m Bool -> ParsecT s u m Bool
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
False (ParsecT s u m Bool -> ParsecT s u m Bool)
-> ParsecT s u m Bool -> ParsecT s u m Bool
forall a b. (a -> b) -> a -> b
$ ParsecT s u m Bool -> ParsecT s u m Bool
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m Bool -> ParsecT s u m Bool)
-> (ParsecT s u m Bool -> ParsecT s u m Bool)
-> ParsecT s u m Bool
-> ParsecT s u m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT s u m Bool -> ParsecT s u m Bool
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s u m Bool -> ParsecT s u m Bool)
-> ParsecT s u m Bool -> ParsecT s u m Bool
forall a b. (a -> b) -> a -> b
$ do
        Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'"'
        -- Check for "foo $""bar"
        ParsecT s u m Char -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT s u m Char -> ParsecT s u m ())
-> ParsecT s u m Char -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'"'
        Char
c <- ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyVar
        -- Don't trigger on [[ x == "$"* ]] or "$"$pattern
        Bool -> ParsecT s u m Bool
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> ParsecT s u m Bool) -> Bool -> ParsecT s u m Bool
forall a b. (a -> b) -> a -> b
$ Char
c Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` String
"*$"
    anyVar :: ParsecT s u m Char
anyVar = ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableStart ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit ParsecT s u m Char -> 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 -> ParsecT s u m a
<|> ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
specialVariable


prop_readHereDoc :: Bool
prop_readHereDoc = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\nlol\ncow\nfoo"
prop_readHereDoc2 :: Bool
prop_readHereDoc2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<- EOF\n  cow\n  EOF"
prop_readHereDoc3 :: Bool
prop_readHereDoc3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\n$\"\nfoo"
prop_readHereDoc4 :: Bool
prop_readHereDoc4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\n`\nfoo"
prop_readHereDoc5 :: Bool
prop_readHereDoc5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<- !foo\nbar\n!foo"
prop_readHereDoc6 :: Bool
prop_readHereDoc6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\\ bar\ncow\nfoo bar"
prop_readHereDoc7 :: Bool
prop_readHereDoc7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\n\\$(f ())\nfoo"
prop_readHereDoc8 :: Bool
prop_readHereDoc8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<foo>>bar\netc\nfoo"
prop_readHereDoc9 :: Bool
prop_readHereDoc9 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"if true; then cat << foo; fi\nbar\nfoo\n"
prop_readHereDoc10 :: Bool
prop_readHereDoc10 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"if true; then cat << foo << bar; fi\nfoo\nbar\n"
prop_readHereDoc11 :: Bool
prop_readHereDoc11 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo $(\nfoo\n)lol\nfoo\n"
prop_readHereDoc12 :: Bool
prop_readHereDoc12 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo|cat\nbar\nfoo"
prop_readHereDoc13 :: Bool
prop_readHereDoc13 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<'#!'\nHello World\n#!\necho Done"
prop_readHereDoc14 :: Bool
prop_readHereDoc14 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\nbar\nfoo \n"
prop_readHereDoc15 :: Bool
prop_readHereDoc15 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<foo\nbar\nfoo bar\nfoo"
prop_readHereDoc16 :: Bool
prop_readHereDoc16 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<- ' foo'\nbar\n foo\n"
prop_readHereDoc17 :: Bool
prop_readHereDoc17 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<- ' foo'\nbar\n  foo\n foo\n"
prop_readHereDoc18 :: Bool
prop_readHereDoc18 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat <<'\"foo'\nbar\n\"foo\n"
prop_readHereDoc20 :: Bool
prop_readHereDoc20 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\n  foo\n()\nfoo\n"
prop_readHereDoc21 :: Bool
prop_readHereDoc21 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"# shellcheck disable=SC1039\ncat << foo\n  foo\n()\nfoo\n"
prop_readHereDoc22 :: Bool
prop_readHereDoc22 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo\r\ncow\r\nfoo\r\n"
prop_readHereDoc23 :: Bool
prop_readHereDoc23 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"cat << foo \r\ncow\r\nfoo\r\n"
readHereDoc :: ParsecT String UserState (SCBase m) Token
readHereDoc = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"here document" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"<<"
    Dashed
dashed <- (Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Dashed
-> ParsecT String UserState (SCBase m) Dashed
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Dashed -> ParsecT String UserState (SCBase m) Dashed
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Dashed
Dashed) ParsecT String UserState (SCBase m) Dashed
-> ParsecT String UserState (SCBase m) Dashed
-> ParsecT String UserState (SCBase m) Dashed
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Dashed -> ParsecT String UserState (SCBase m) Dashed
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Dashed
Undashed
    String
sp <- ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> (ParsecT String UserState (SCBase m) Char
    -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
        let message :: String
message = String
"Shells are space sensitive. Use '< <(cmd)', not '<<" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
sp String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"(cmd)'."
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1038 String
message
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    (Quoted
quoted, String
endToken) <- ParsecT String UserState (SCBase m) (Quoted, String)
readToken
    Id
hid <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start

    -- add empty tokens for now, read the rest in readPendingHereDocs
    let doc :: Token
doc = Id -> Dashed -> Quoted -> String -> [Token] -> Token
T_HereDoc Id
hid Dashed
dashed Quoted
quoted String
endToken []
    Id
-> Dashed
-> Quoted
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {s}.
MonadState SystemState m =>
Id -> Dashed -> Quoted -> String -> ParsecT s UserState m ()
addPendingHereDoc Id
hid Dashed
dashed Quoted
quoted String
endToken
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
doc
  where
    unquote :: String -> (Quoted, String)
    unquote :: String -> (Quoted, String)
unquote String
"" = (Quoted
Unquoted, String
"")
    unquote [Char
c] = (Quoted
Unquoted, [Char
c])
    unquote s :: String
s@(Char
cl:String
tl) =
      case String -> String
forall a. [a] -> [a]
reverse String
tl of
        (Char
cr:String
tr) | Char
cr Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
cl Bool -> Bool -> Bool
&& Char
cl Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"\"'" -> (Quoted
Quoted, String -> String
forall a. [a] -> [a]
reverse String
tr)
        String
_ -> (if Char
'\\' Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
s then (Quoted
Quoted, (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
(/=) Char
'\\') String
s) else (Quoted
Unquoted, String
s))
    -- Fun fact: bash considers << foo"" quoted, but not << <("foo").
    readToken :: ParsecT String UserState (SCBase m) (Quoted, String)
readToken = do
        String
str <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {s} {u} {a}.
(MonadState s m, Stream s m Char) =>
ParsecT s u m a -> ParsecT s u m String
readStringForParser ParsecT String UserState (SCBase m) Token
readNormalWord
        -- A here doc actually works with \r\n because the \r becomes part of the token
        String
crstr <- (ParsecT String UserState (SCBase m) Char
forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
carriageReturn ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT String UserState (SCBase m) String)
-> String -> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String
str String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\r")) ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
str
        (Quoted, String)
-> ParsecT String UserState (SCBase m) (Quoted, String)
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Quoted, String)
 -> ParsecT String UserState (SCBase m) (Quoted, String))
-> (Quoted, String)
-> ParsecT String UserState (SCBase m) (Quoted, String)
forall a b. (a -> b) -> a -> b
$ String -> (Quoted, String)
unquote String
crstr

readPendingHereDocs :: ParsecT String UserState (SCBase m) ()
readPendingHereDocs = do
    [HereDocContext]
docs <- ParsecT String UserState (SCBase m) [HereDocContext]
forall {m :: * -> *} {s}.
Monad m =>
ParsecT s UserState m [HereDocContext]
popPendingHereDocs
    (HereDocContext -> ParsecT String UserState (SCBase m) ())
-> [HereDocContext] -> ParsecT String UserState (SCBase m) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ HereDocContext -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
HereDocContext -> ParsecT String UserState (SCBase m) ()
readDoc [HereDocContext]
docs
  where
    readDoc :: HereDocContext -> ParsecT String UserState (SCBase m) ()
readDoc (HereDocPending Id
id Dashed
dashed Quoted
quoted String
endToken [Context]
ctx) =
      [Context]
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
[Context] -> ParsecT s u m b -> ParsecT s u m b
swapContext [Context]
ctx (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
      do
        SourcePos
docStartPos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        (Bool
terminated, Bool
wasWarned, [String]
lines) <- Dashed -> String -> SCParser m (Bool, Bool, [String])
forall (m :: * -> *).
Monad m =>
Dashed -> String -> SCParser m (Bool, Bool, [String])
readDocLines Dashed
dashed String
endToken
        SourcePos
docEndPos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        let hereData :: String
hereData = [String] -> String
unlines [String]
lines
        Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
terminated (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
            Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
wasWarned (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
                Id -> String -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
Id -> String -> String -> ParsecT String UserState (SCBase m) ()
debugHereDoc Id
id String
endToken String
hereData
            String -> ParsecT String UserState (SCBase m) ()
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Here document was not correctly terminated"
        [Token]
list <- Quoted
-> (SourcePos, SourcePos)
-> String
-> ParsecT String UserState (SCBase m) [Token]
forall {m :: * -> *}.
Monad m =>
Quoted
-> (SourcePos, SourcePos)
-> String
-> ParsecT String UserState (SCBase m) [Token]
parseHereData Quoted
quoted (SourcePos
docStartPos, SourcePos
docEndPos) String
hereData
        Id -> [Token] -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {s}.
Monad m =>
Id -> [Token] -> ParsecT s UserState m ()
addToHereDocMap Id
id [Token]
list

    -- Read the lines making up the here doc. Returns (IsTerminated, Lines)
    readDocLines :: Monad m => Dashed -> String -> SCParser m (Bool, Bool, [String])
    readDocLines :: forall (m :: * -> *).
Monad m =>
Dashed -> String -> SCParser m (Bool, Bool, [String])
readDocLines Dashed
dashed String
endToken = do
        SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
str <- ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
rawLine
        Bool
isEof <- Bool
-> ParsecT String UserState (SCBase m) Bool
-> ParsecT String UserState (SCBase m) Bool
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Bool
False (ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) Bool
-> ParsecT String UserState (SCBase m) Bool
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> ParsecT String UserState (SCBase m) Bool
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
        (Bool
isEnd, Bool
wasWarned) <- SourcePos
-> ParsecT String UserState (SCBase m) (Bool, Bool)
-> String
-> ParsecT String UserState (SCBase m) (Bool, Bool)
forall {m :: * -> *} {s} {u} {b}.
Monad m =>
SourcePos -> ParsecT s u m b -> s -> ParsecT s u m b
subParse SourcePos
pos ParsecT String UserState (SCBase m) (Bool, Bool)
forall {m :: * -> *} {s} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m (Bool, Bool)
checkEnd String
str
        if
            | Bool
isEnd -> (Bool, Bool, [String]) -> SCParser m (Bool, Bool, [String])
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, Bool
wasWarned, [])
            | Bool
isEof -> (Bool, Bool, [String]) -> SCParser m (Bool, Bool, [String])
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, Bool
wasWarned, [String
str])
            | Bool
True -> do
                (Bool
ok, Bool
previousWarning, [String]
rest) <- Dashed -> String -> SCParser m (Bool, Bool, [String])
forall (m :: * -> *).
Monad m =>
Dashed -> String -> SCParser m (Bool, Bool, [String])
readDocLines Dashed
dashed String
endToken
                (Bool, Bool, [String]) -> SCParser m (Bool, Bool, [String])
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
ok, Bool
wasWarned Bool -> Bool -> Bool
|| Bool
previousWarning, String
strString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
rest)
      where
        -- Check if this is the actual end, or a plausible false end
        checkEnd :: ParsecT s UserState m (Bool, Bool)
checkEnd = (Bool, Bool)
-> ParsecT s UserState m (Bool, Bool)
-> ParsecT s UserState m (Bool, Bool)
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option (Bool
False, Bool
False) (ParsecT s UserState m (Bool, Bool)
 -> ParsecT s UserState m (Bool, Bool))
-> ParsecT s UserState m (Bool, Bool)
-> ParsecT s UserState m (Bool, Bool)
forall a b. (a -> b) -> a -> b
$ ParsecT s UserState m (Bool, Bool)
-> ParsecT s UserState m (Bool, Bool)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s UserState m (Bool, Bool)
 -> ParsecT s UserState m (Bool, Bool))
-> ParsecT s UserState m (Bool, Bool)
-> ParsecT s UserState m (Bool, Bool)
forall a b. (a -> b) -> a -> b
$ do
            -- Match what's basically '^( *)token( *)(.*)$'
            SourcePos
leadingSpacePos <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            String
leadingSpace <- ParsecT s UserState m Char
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Char
linewhitespace ParsecT s UserState m Char
-> ParsecT s UserState m String -> ParsecT s UserState m String
forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill` String -> ParsecT s UserState m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
endToken
            String -> ParsecT s UserState m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
endToken
            SourcePos
trailingSpacePos <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            String
trailingSpace <- ParsecT s UserState m Char -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT s UserState m Char
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Char
linewhitespace
            SourcePos
trailerPos <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            String
trailer <- ParsecT s UserState m Char -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT s UserState m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar

            let leadingSpacesAreTabs :: Bool
leadingSpacesAreTabs = (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\t') String
leadingSpace
            let thereIsNoTrailer :: Bool
thereIsNoTrailer = String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
trailingSpace Bool -> Bool -> Bool
&& String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
trailer
            let leaderIsOk :: Bool
leaderIsOk = String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
leadingSpace
                    Bool -> Bool -> Bool
|| Dashed
dashed Dashed -> Dashed -> Bool
forall a. Eq a => a -> a -> Bool
== Dashed
Dashed Bool -> Bool -> Bool
&& Bool
leadingSpacesAreTabs
            let trailerStart :: Char
trailerStart = case String
trailer of [] -> Char
'\0'; (Char
h:String
_) -> Char
h
            let hasTrailingSpace :: Bool
hasTrailingSpace = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
trailingSpace
            let hasTrailer :: Bool
hasTrailer = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
trailer
            let ppt :: Integer -> String -> m ()
ppt = SourcePos -> Severity -> Integer -> String -> m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
trailerPos Severity
ErrorC

            if Bool
leaderIsOk Bool -> Bool -> Bool
&& Bool
thereIsNoTrailer
              then (Bool, Bool) -> ParsecT s UserState m (Bool, Bool)
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, Bool
False)
              else do
                let foundCause :: m (Bool, Bool)
foundCause = (Bool, Bool) -> m (Bool, Bool)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, Bool
True)
                let skipLine :: m (Bool, Bool)
skipLine = (Bool, Bool) -> m (Bool, Bool)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, Bool
False)
                -- This may be intended as an end token. Debug why it isn't.
                if
                    | Char
trailerStart Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
')' -> do
                        Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> String -> m ()
ppt Integer
1119 (String -> ParsecT s UserState m ())
-> String -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ String
"Add a linefeed between end token and terminating ')'."
                        ParsecT s UserState m (Bool, Bool)
forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Char
trailerStart Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'#' -> do
                        Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> String -> m ()
ppt Integer
1120 String
"No comments allowed after here-doc token. Comment the next line instead."
                        ParsecT s UserState m (Bool, Bool)
forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Char
trailerStart Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
";>|&" -> do
                        Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> String -> m ()
ppt Integer
1121 String
"Add ;/& terminators (and other syntax) on the line with the <<, not here."
                        ParsecT s UserState m (Bool, Bool)
forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Bool
hasTrailingSpace Bool -> Bool -> Bool
&& Bool
hasTrailer -> do
                        Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Integer -> String -> m ()
ppt Integer
1122 String
"Nothing allowed after end token. To continue a command, put it on the line with the <<."
                        ParsecT s UserState m (Bool, Bool)
forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Bool
leaderIsOk Bool -> Bool -> Bool
&& Bool
hasTrailingSpace Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
hasTrailer -> do
                        SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
trailingSpacePos Severity
ErrorC Integer
1118 String
"Delete whitespace after the here-doc end token."
                        -- Parse as if it's the actual end token. Will koala_man regret this once again?
                        (Bool, Bool) -> ParsecT s UserState m (Bool, Bool)
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, Bool
True)
                    | Bool -> Bool
not Bool
hasTrailingSpace Bool -> Bool -> Bool
&& Bool
hasTrailer ->
                        -- The end token is just a prefix
                        ParsecT s UserState m (Bool, Bool)
forall {m :: * -> *}. Monad m => m (Bool, Bool)
skipLine
                    | Bool
hasTrailer ->
                        String -> ParsecT s UserState m (Bool, Bool)
forall a. HasCallStack => String -> a
error (String -> ParsecT s UserState m (Bool, Bool))
-> String -> ParsecT s UserState m (Bool, Bool)
forall a b. (a -> b) -> a -> b
$ String -> String
pleaseReport String
"unexpected heredoc trailer"

                    -- The following cases assume no trailing text:
                    | Dashed
dashed Dashed -> Dashed -> Bool
forall a. Eq a => a -> a -> Bool
== Dashed
Undashed Bool -> Bool -> Bool
&& (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
leadingSpace) -> do
                        SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
leadingSpacePos Severity
ErrorC Integer
1039 String
"Remove indentation before end token (or use <<- and indent with tabs)."
                        ParsecT s UserState m (Bool, Bool)
forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Dashed
dashed Dashed -> Dashed -> Bool
forall a. Eq a => a -> a -> Bool
== Dashed
Dashed Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
leadingSpacesAreTabs -> do
                        SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
leadingSpacePos Severity
ErrorC Integer
1040 String
"When using <<-, you can only indent with tabs."
                        ParsecT s UserState m (Bool, Bool)
forall {m :: * -> *}. Monad m => m (Bool, Bool)
foundCause
                    | Bool
True -> ParsecT s UserState m (Bool, Bool)
forall {m :: * -> *}. Monad m => m (Bool, Bool)
skipLine

    rawLine :: ParsecT s u m String
rawLine = do
        String
c <- ParsecT s u m Char -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT s u m Char -> ParsecT s u m String)
-> ParsecT s u m Char -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\n"
        ParsecT s u m Char -> ParsecT s u m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (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 () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
        String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return String
c

    parseHereData :: Quoted
-> (SourcePos, SourcePos)
-> String
-> ParsecT String UserState (SCBase m) [Token]
parseHereData Quoted
Quoted (SourcePos
start,SourcePos
end) String
hereData = do
        Id
id <- SourcePos -> SourcePos -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
end
        [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Id -> String -> Token
T_Literal Id
id String
hereData]

    parseHereData Quoted
Unquoted (SourcePos
startPos, SourcePos
_) String
hereData =
        SourcePos
-> ParsecT String UserState (SCBase m) [Token]
-> String
-> ParsecT String UserState (SCBase m) [Token]
forall {m :: * -> *} {s} {u} {b}.
Monad m =>
SourcePos -> ParsecT s u m b -> s -> ParsecT s u m b
subParse SourcePos
startPos ParsecT String UserState (SCBase m) [Token]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Token]
readHereData String
hereData

    readHereData :: ParsecT String UserState (SCBase m) [Token]
readHereData = ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) [Token])
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) [Token]
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
doubleQuotedPart ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s}.
Stream s m Char =>
ParsecT s UserState m Token
readHereLiteral

    readHereLiteral :: ParsecT s UserState m Token
readHereLiteral = do
        IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
        String
chars <- ParsecT s UserState m Char -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT s UserState m Char -> ParsecT s UserState m String)
-> ParsecT s UserState m Char -> ParsecT s UserState m String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"`$\\"
        Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
        Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Literal Id
id String
chars

    debugHereDoc :: Id -> String -> String -> ParsecT String UserState (SCBase m) ()
debugHereDoc Id
tokenId String
endToken String
doc
        | String
endToken String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` String
doc =
            let lookAt :: String -> ParsecT String UserState (SCBase m) ()
lookAt String
line = Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
endToken String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` String
line) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
                      Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
tokenId Severity
ErrorC Integer
1042 (String
"Close matches include '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String -> String
e4m String
line) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' (!= '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String -> String
e4m String
endToken) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"').")
            in do
                  Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
tokenId Severity
ErrorC Integer
1041 (String
"Found '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String -> String
e4m String
endToken) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' further down, but not on a separate line.")
                  (String -> ParsecT String UserState (SCBase m) ())
-> [String] -> ParsecT String UserState (SCBase m) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) ()
lookAt (String -> [String]
lines String
doc)
        | (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
endToken String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
doc =
            Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
tokenId Severity
ErrorC Integer
1043 (String
"Found " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String -> String
e4m String
endToken) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" further down, but with wrong casing.")
        | Bool
otherwise =
            Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
tokenId Severity
ErrorC Integer
1044 (String
"Couldn't find end token `" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String -> String
e4m String
endToken) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' in the here document.")


readFilename :: ParsecT String UserState (SCBase m) Token
readFilename = ParsecT String UserState (SCBase m) Token
readNormalWord
readIoFileOp :: ParsecT s UserState m Token
readIoFileOp = [ParsecT s UserState m Token] -> ParsecT s UserState m Token
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ParsecT s UserState m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_DGREAT, ParsecT s UserState m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_LESSGREAT, ParsecT s UserState m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_GREATAND, ParsecT s UserState m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_LESSAND, ParsecT s UserState m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_CLOBBER, Char -> (Id -> Token) -> ParsecT s UserState m Token
forall {m :: * -> *} {s} {a}.
Stream s m Char =>
Char -> (Id -> a) -> ParsecT s UserState m a
redirToken Char
'<' Id -> Token
T_Less, Char -> (Id -> Token) -> ParsecT s UserState m Token
forall {m :: * -> *} {s} {a}.
Stream s m Char =>
Char -> (Id -> a) -> ParsecT s UserState m a
redirToken Char
'>' Id -> Token
T_Greater ]

readIoDuplicate :: ParsecT s UserState m Token
readIoDuplicate = ParsecT s UserState m Token -> ParsecT s UserState m Token
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s UserState m Token -> ParsecT s UserState m Token)
-> ParsecT s UserState m Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Token
op <- ParsecT s UserState m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_GREATAND ParsecT s UserState m Token
-> ParsecT s UserState m Token -> ParsecT s UserState m Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s UserState m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_LESSAND
    String
target <- ParsecT s UserState m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readIoVariable ParsecT s UserState m String
-> ParsecT s UserState m String -> ParsecT s UserState m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s UserState m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
digitsAndOrDash
    Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> Token -> String -> Token
T_IoDuplicate Id
id Token
op String
target
  where
    -- either digits with optional dash, or a required dash
    digitsAndOrDash :: ParsecT s u m String
digitsAndOrDash = do
        String
str <- ParsecT s u m Char -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
        String
dash <- (if String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
str then ParsecT s u m String -> ParsecT s u m String
forall a. a -> a
id else String -> ParsecT s u m String -> ParsecT s u m String
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option String
"") (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"-"
        String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT s u m String) -> String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ String
str String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
dash


prop_readIoFile :: Bool
prop_readIoFile = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoFile String
">> \"$(date +%YYmmDD)\""
readIoFile :: ParsecT String UserState (SCBase m) Token
readIoFile = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"redirection" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Token
op <- ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
readIoFileOp
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Token
file <- ParsecT String UserState (SCBase m) Token
readFilename
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token -> Token
T_IoFile Id
id Token
op Token
file

readIoVariable :: ParsecT s u m String
readIoVariable = ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ do
    Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'{'
    String
x <- ParsecT s u m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
    Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
    String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ParsecT s u m String) -> String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ String
"{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"

readIoSource :: ParsecT s UserState m String
readIoSource = ParsecT s UserState m String -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s UserState m String -> ParsecT s UserState m String)
-> ParsecT s UserState m String -> ParsecT s UserState m String
forall a b. (a -> b) -> a -> b
$ do
    String
x <- String -> ParsecT s UserState m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"&" ParsecT s UserState m String
-> ParsecT s UserState m String -> ParsecT s UserState m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s UserState m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readIoVariable ParsecT s UserState m String
-> ParsecT s UserState m String -> ParsecT s UserState m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s UserState m Char -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT s UserState m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    ParsecT s UserState m () -> ParsecT s UserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s UserState m () -> ParsecT s UserState m ())
-> ParsecT s UserState m () -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ ParsecT s UserState m Token -> ParsecT s UserState m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT s UserState m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
readIoFileOp ParsecT s UserState m ()
-> ParsecT s UserState m () -> ParsecT s UserState m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s UserState m String -> ParsecT s UserState m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (String -> ParsecT s UserState m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"<<")
    String -> ParsecT s UserState m String
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return String
x

prop_readIoRedirect :: Bool
prop_readIoRedirect = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"3>&2"
prop_readIoRedirect2 :: Bool
prop_readIoRedirect2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"2> lol"
prop_readIoRedirect3 :: Bool
prop_readIoRedirect3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"4>&-"
prop_readIoRedirect4 :: Bool
prop_readIoRedirect4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"&> lol"
prop_readIoRedirect5 :: Bool
prop_readIoRedirect5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"{foo}>&2"
prop_readIoRedirect6 :: Bool
prop_readIoRedirect6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"{foo}<&-"
prop_readIoRedirect7 :: Bool
prop_readIoRedirect7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIoRedirect String
"{foo}>&1-"
readIoRedirect :: ParsecT String UserState (SCBase m) Token
readIoRedirect = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    String
n <- ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
readIoSource
    Token
redir <- ParsecT String UserState (SCBase m) Token
readHereString ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readHereDoc ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
readIoDuplicate ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
readIoFile
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m ()
skipAnnotationAndWarn
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
T_FdRedirect Id
id String
n Token
redir

prop_readHereString :: Bool
prop_readHereString = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readHereString String
"<<< \"Hello $world\""
readHereString :: ParsecT String UserState (SCBase m) Token
readHereString = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"here string" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"<<<"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Token
word <- ParsecT String UserState (SCBase m) Token
readNormalWord
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token
T_HereString Id
id Token
word

prop_readNewlineList1 :: Bool
prop_readNewlineList1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"&> /dev/null echo foo"
readNewlineList :: ParsecT String UserState (SCBase m) String
readNewlineList =
    ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ((ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
linefeed ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m Char
carriageReturn) ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) Char
forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing) ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) String
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {s} {m :: * -> *} {u}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m ()
checkBadBreak
  where
    checkBadBreak :: ParsecT s u m ()
checkBadBreak = ParsecT s u m () -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ do
                SourcePos
pos <- ParsecT s u m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                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 (ParsecT s u m Char -> ParsecT s u m Char)
-> ParsecT s u m Char -> ParsecT s u m Char
forall a b. (a -> b) -> a -> b
$ ParsecT s u m Char -> ParsecT s u m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"|&") --  See if the next thing could be |, || or &&
                ParsecT s u m String -> ParsecT s u m ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"&>") --  Except &> or &>> which is valid
                SourcePos -> Severity -> Integer -> String -> ParsecT s u m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1133
                    String
"Unexpected start of line. If breaking lines, |/||/&& should be at the end of the previous one."
readLineBreak :: ParsecT String UserState (SCBase m) ()
readLineBreak = ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readNewlineList

prop_readSeparator1 :: Bool
prop_readSeparator1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"a &; b"
prop_readSeparator2 :: Bool
prop_readSeparator2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"a & b"
prop_readSeparator3 :: Bool
prop_readSeparator3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"a &amp; b"
prop_readSeparator4 :: Bool
prop_readSeparator4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"a &gt; file; b"
prop_readSeparator5 :: Bool
prop_readSeparator5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readScript String
"curl https://example.com/?foo=moo&bar=cow"
readSeparatorOp :: ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
readSeparatorOp = do
    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_AND_IF ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) CaseType
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) CaseType
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) CaseType
readCaseSeparator)
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"&>")
    SourcePos
start <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    Char
f <- ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do
                    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'&'
                    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ [ParsecT String UserState (SCBase m) ()]
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
                        do
                            String
s <- ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ([String] -> ParsecT String UserState (SCBase m) String)
-> [String]
-> ParsecT String UserState (SCBase m) String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ParsecT String UserState (SCBase m) String]
-> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice ([ParsecT String UserState (SCBase m) String]
 -> ParsecT String UserState (SCBase m) String)
-> ([String] -> [ParsecT String UserState (SCBase m) String])
-> [String]
-> ParsecT String UserState (SCBase m) String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> ParsecT String UserState (SCBase m) String)
-> [String] -> [ParsecT String UserState (SCBase m) String]
forall a b. (a -> b) -> [a] -> [b]
map (ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> (String -> ParsecT String UserState (SCBase m) String)
-> String
-> ParsecT String UserState (SCBase m) String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string) ([String] -> ParsecT String UserState (SCBase m) String)
-> [String] -> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$
                                [String
"amp;", String
"gt;", String
"lt;"]
                            SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1109 String
"This is an unquoted HTML entity. Replace with corresponding character.",

                        do
                            ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> (ParsecT String UserState (SCBase m) Char
    -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableStart
                            SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
WarningC Integer
1132 String
"This & terminates the command. Escape it or add space after & to silence."
                      ]

                    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
                    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';'
                    -- In case statements we might have foo & ;;
                    ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';'
                    SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1045 String
"It's not 'foo &; bar', just 'foo & bar'."
                    Char -> ParsecT String UserState (SCBase m) Char
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Char
'&'
            ) ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'&'
    SourcePos
end <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    (Char, (SourcePos, SourcePos))
-> ParsecT
     String UserState (SCBase m) (Char, (SourcePos, SourcePos))
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Char
f, (SourcePos
start, SourcePos
end))

readSequentialSep :: ParsecT String UserState (SCBase m) ()
readSequentialSep = ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Semi ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak) ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readNewlineList
readSeparator :: ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
readSeparator =
    do
        (Char, (SourcePos, SourcePos))
separator <- ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
readSeparatorOp
        ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak
        (Char, (SourcePos, SourcePos))
-> ParsecT
     String UserState (SCBase m) (Char, (SourcePos, SourcePos))
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Char, (SourcePos, SourcePos))
separator
     ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
-> ParsecT
     String UserState (SCBase m) (Char, (SourcePos, SourcePos))
-> ParsecT
     String UserState (SCBase m) (Char, (SourcePos, SourcePos))
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
        do
            SourcePos
start <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
readNewlineList
            SourcePos
end <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            (Char, (SourcePos, SourcePos))
-> ParsecT
     String UserState (SCBase m) (Char, (SourcePos, SourcePos))
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Char
'\n', (SourcePos
start, SourcePos
end))

prop_readSimpleCommand :: Bool
prop_readSimpleCommand = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"echo test > file"
prop_readSimpleCommand2 :: Bool
prop_readSimpleCommand2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"cmd &> file"
prop_readSimpleCommand3 :: Bool
prop_readSimpleCommand3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"export foo=(bar baz)"
prop_readSimpleCommand4 :: Bool
prop_readSimpleCommand4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"typeset -a foo=(lol)"
prop_readSimpleCommand5 :: Bool
prop_readSimpleCommand5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"time if true; then echo foo; fi"
prop_readSimpleCommand6 :: Bool
prop_readSimpleCommand6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"time -p ( ls -l; )"
prop_readSimpleCommand7 :: Bool
prop_readSimpleCommand7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"\\ls"
prop_readSimpleCommand7b :: Bool
prop_readSimpleCommand7b = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"\\:"
prop_readSimpleCommand8 :: Bool
prop_readSimpleCommand8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"// Lol"
prop_readSimpleCommand9 :: Bool
prop_readSimpleCommand9 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"/* Lolbert */"
prop_readSimpleCommand10 :: Bool
prop_readSimpleCommand10 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"/**** Lolbert */"
prop_readSimpleCommand11 :: Bool
prop_readSimpleCommand11 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"/\\* foo"
prop_readSimpleCommand12 :: Bool
prop_readSimpleCommand12 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"elsif foo"
prop_readSimpleCommand13 :: Bool
prop_readSimpleCommand13 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"ElseIf foo"
prop_readSimpleCommand14 :: Bool
prop_readSimpleCommand14 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"elseif[$i==2]"
prop_readSimpleCommand15 :: Bool
prop_readSimpleCommand15 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSimpleCommand String
"trap 'foo\"bar' INT"
readSimpleCommand :: ParsecT String UserState (SCBase m) Token
readSimpleCommand = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"simple command" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    [Token]
prefix <- [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] ParsecT String UserState (SCBase m) [Token]
readCmdPrefix
    ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m ()
skipAnnotationAndWarn
    Maybe Token
cmd <- Maybe Token
-> ParsecT String UserState (SCBase m) (Maybe Token)
-> ParsecT String UserState (SCBase m) (Maybe Token)
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Maybe Token
forall a. Maybe a
Nothing (ParsecT String UserState (SCBase m) (Maybe Token)
 -> ParsecT String UserState (SCBase m) (Maybe Token))
-> ParsecT String UserState (SCBase m) (Maybe Token)
-> ParsecT String UserState (SCBase m) (Maybe Token)
forall a b. (a -> b) -> a -> b
$ Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Maybe Token)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String UserState (SCBase m) Token
readCmdName
    Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([Token] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Token]
prefix Bool -> Bool -> Bool
&& Maybe Token -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Token
cmd) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) ()
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected a command"

    case Maybe Token
cmd of
      Maybe Token
Nothing -> do
        Id
id1 <- [Token] -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *}.
Monad m =>
[Token] -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokenList [Token]
prefix
        Id
id2 <- Id -> ParsecT String UserState (SCBase m) Id
forall (m :: * -> *). Monad m => Id -> SCParser m Id
getNewIdFor Id
id1
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> Id -> [Token] -> [Token] -> [Token] -> Token
makeSimpleCommand Id
id1 Id
id2 [Token]
prefix [] []

      Just Token
cmd -> do
            Token -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
Token -> ParsecT String UserState (SCBase m) ()
validateCommand Token
cmd
            -- We have to ignore possible parsing problems from the lookAhead parser
            Maybe Token
firstArgument <- ParsecT String UserState (SCBase m) (Maybe Token)
-> ParsecT String UserState (SCBase m) (Maybe Token)
forall {t :: (* -> *) -> * -> *} {t :: (* -> *) -> * -> *}
       {m :: * -> *} {a} {b}.
(MonadTrans t, MonadTrans t, Monad (t (t m)), Monad (t m),
 MonadState a m) =>
t (t m) b -> t (t m) b
ignoreProblemsOf (ParsecT String UserState (SCBase m) (Maybe Token)
 -> ParsecT String UserState (SCBase m) (Maybe Token))
-> (ParsecT String UserState (SCBase m) Token
    -> ParsecT String UserState (SCBase m) (Maybe Token))
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Maybe Token)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Maybe Token)
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) (Maybe Token))
-> (ParsecT String UserState (SCBase m) Token
    -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Maybe Token)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> (ParsecT String UserState (SCBase m) Token
    -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) (Maybe Token))
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Maybe Token)
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Token
readCmdWord
            [Token]
suffix <- [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] (ParsecT String UserState (SCBase m) [Token]
 -> ParsecT String UserState (SCBase m) [Token])
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) [Token]
-> Token
-> [([String], ParsecT String UserState (SCBase m) [Token])]
-> ParsecT String UserState (SCBase m) [Token]
forall {t :: * -> *} {t}.
Foldable t =>
t -> Token -> [(t String, t)] -> t
getParser ParsecT String UserState (SCBase m) [Token]
readCmdSuffix
                    -- If `export` or other modifier commands are called with `builtin` we have to look at the first argument
                    (if [String] -> Token -> Bool
forall {t :: * -> *}. Foldable t => t String -> Token -> Bool
isCommand [String
"builtin"] Token
cmd then Token -> Maybe Token -> Token
forall a. a -> Maybe a -> a
fromMaybe Token
cmd Maybe Token
firstArgument else Token
cmd) [
                        ([String
"declare", String
"export", String
"local", String
"readonly", String
"typeset"], ParsecT String UserState (SCBase m) [Token]
readModifierSuffix),
                        ([String
"time"], ParsecT String UserState (SCBase m) [Token]
readTimeSuffix),
                        ([String
"let"], ParsecT String UserState (SCBase m) [Token]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Token]
readLetSuffix),
                        ([String
"eval"], ParsecT String UserState (SCBase m) [Token]
readEvalSuffix)
                    ]

            Id
id1 <- [Token] -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *}.
Monad m =>
[Token] -> ParsecT String UserState (SCBase m) Id
getNextIdSpanningTokenList ([Token]
prefix [Token] -> [Token] -> [Token]
forall a. [a] -> [a] -> [a]
++ (Token
cmdToken -> [Token] -> [Token]
forall a. a -> [a] -> [a]
:[Token]
suffix))
            Id
id2 <- Id -> ParsecT String UserState (SCBase m) Id
forall (m :: * -> *). Monad m => Id -> SCParser m Id
getNewIdFor Id
id1

            let result :: Token
result = Id -> Id -> [Token] -> [Token] -> [Token] -> Token
makeSimpleCommand Id
id1 Id
id2 [Token]
prefix [Token
cmd] [Token]
suffix
            case () of
                ()
_ | [String] -> Token -> Bool
forall {t :: * -> *}. Foldable t => t String -> Token -> Bool
isCommand [String
"source", String
"."] Token
cmd -> Token -> ParsecT String UserState (SCBase m) Token
forall (m :: * -> *). Monad m => Token -> SCParser m Token
readSource Token
result
                ()
_ | [String] -> Token -> Bool
forall {t :: * -> *}. Foldable t => t String -> Token -> Bool
isCommand [String
"trap"] Token
cmd -> do
                        Token -> ParsecT String UserState (SCBase m) ()
syntaxCheckTrap Token
result
                        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
result
                ()
_ -> Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
result
  where
    isCommand :: t String -> Token -> Bool
isCommand t String
strings (T_NormalWord Id
_ [T_Literal Id
_ String
s]) = String
s String -> t String -> Bool
forall a. Eq a => a -> t a -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` t String
strings
    isCommand t String
_ Token
_ = Bool
False
    getParser :: t -> Token -> [(t String, t)] -> t
getParser t
def Token
cmd [] = t
def
    getParser t
def Token
cmd ((t String
list, t
action):[(t String, t)]
rest) =
        if t String -> Token -> Bool
forall {t :: * -> *}. Foldable t => t String -> Token -> Bool
isCommand t String
list Token
cmd
        then t
action
        else t -> Token -> [(t String, t)] -> t
getParser t
def Token
cmd [(t String, t)]
rest

    validateCommand :: Token -> SCParser m ()
validateCommand Token
cmd =
        case Token
cmd of
            (T_NormalWord Id
_ [T_Literal Id
_ String
"//"]) -> Id -> SCParser m ()
forall {m :: * -> *}. Monad m => Id -> SCParser m ()
commentWarning (Token -> Id
getId Token
cmd)
            (T_NormalWord Id
_ (T_Literal Id
_ String
"/" : T_Glob Id
_ String
"*" :[Token]
_)) -> Id -> SCParser m ()
forall {m :: * -> *}. Monad m => Id -> SCParser m ()
commentWarning (Token -> Id
getId Token
cmd)
            (T_NormalWord Id
_ (T_Literal Id
_ String
str:[Token]
_)) -> do
                let cmdString :: String
cmdString = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
takeWhile Char -> Bool
isAlpha String
str
                Bool -> SCParser m () -> SCParser m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String
cmdString String -> [String] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"elsif", String
"elseif"]) (SCParser m () -> SCParser m ()) -> SCParser m () -> SCParser m ()
forall a b. (a -> b) -> a -> b
$
                    Id -> Severity -> Integer -> String -> SCParser m ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId (Token -> Id
getId Token
cmd) Severity
ErrorC Integer
1131 String
"Use 'elif' to start another branch."
            Token
_ -> () -> SCParser m ()
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

    syntaxCheckTrap :: Token -> ParsecT String UserState (SCBase m) ()
syntaxCheckTrap Token
cmd =
        case Token
cmd of
            (T_Redirecting Id
_ [Token]
_ (T_SimpleCommand Id
_ [Token]
_ (Token
cmd:Token
arg:[Token]
_))) -> Token -> Maybe String -> ParsecT String UserState (SCBase m) ()
checkArg Token
arg (Token -> Maybe String
getLiteralString Token
arg)
            Token
_ -> () -> ParsecT String UserState (SCBase m) ()
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      where
        checkArg :: Token -> Maybe String -> ParsecT String UserState (SCBase m) ()
checkArg Token
_ Maybe String
Nothing = () -> ParsecT String UserState (SCBase m) ()
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
        checkArg Token
arg (Just (Char
'-':String
_)) = () -> ParsecT String UserState (SCBase m) ()
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
        checkArg Token
arg (Just String
str) = do
            (SourcePos
start,SourcePos
end) <- Id -> SCParser m (SourcePos, SourcePos)
forall (m :: * -> *).
Monad m =>
Id -> SCParser m (SourcePos, SourcePos)
getSpanForId (Token -> Id
getId Token
arg)
            SourcePos
-> ParsecT String UserState (SCBase m) ()
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {s} {u} {b}.
Monad m =>
SourcePos -> ParsecT s u m b -> s -> ParsecT s u m b
subParse SourcePos
start (ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *) v. Monad m => SCParser m v -> SCParser m v
tryWithErrors (ParsecT String UserState (SCBase m) [Token]
readCompoundListOrEmpty ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
verifyEof) ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> () -> ParsecT String UserState (SCBase m) ()
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()) String
str

    commentWarning :: Id -> SCParser m ()
commentWarning Id
id =
        Id -> Severity -> Integer -> String -> SCParser m ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
id Severity
ErrorC Integer
1127 String
"Was this intended as a comment? Use # in sh."

    makeSimpleCommand :: Id -> Id -> [Token] -> [Token] -> [Token] -> Token
makeSimpleCommand Id
id1 Id
id2 [Token]
prefix [Token]
cmd [Token]
suffix =
        let
            ([Token]
preAssigned, [Token]
preRest) = (Token -> Bool) -> [Token] -> ([Token], [Token])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Token -> Bool
assignment [Token]
prefix
            ([Token]
preRedirected, [Token]
preRest2) = (Token -> Bool) -> [Token] -> ([Token], [Token])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Token -> Bool
redirection [Token]
preRest
            ([Token]
postRedirected, [Token]
postRest) = (Token -> Bool) -> [Token] -> ([Token], [Token])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Token -> Bool
redirection [Token]
suffix

            redirs :: [Token]
redirs = [Token]
preRedirected [Token] -> [Token] -> [Token]
forall a. [a] -> [a] -> [a]
++ [Token]
postRedirected
            assigns :: [Token]
assigns = [Token]
preAssigned
            args :: [Token]
args = [Token]
cmd [Token] -> [Token] -> [Token]
forall a. [a] -> [a] -> [a]
++ [Token]
preRest2 [Token] -> [Token] -> [Token]
forall a. [a] -> [a] -> [a]
++ [Token]
postRest
        in
            Id -> [Token] -> Token -> Token
T_Redirecting Id
id1 [Token]
redirs (Token -> Token) -> Token -> Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> [Token] -> Token
T_SimpleCommand Id
id2 [Token]
assigns [Token]
args
      where
        assignment :: Token -> Bool
assignment (T_Assignment {}) = Bool
True
        assignment Token
_ = Bool
False
        redirection :: Token -> Bool
redirection (T_FdRedirect {}) = Bool
True
        redirection Token
_ = Bool
False


readSource :: Monad m => Token -> SCParser m Token
readSource :: forall (m :: * -> *). Monad m => Token -> SCParser m Token
readSource t :: Token
t@(T_Redirecting Id
_ [Token]
_ (T_SimpleCommand Id
cmdId [Token]
_ (Token
cmd:[Token]
args'))) = do
    let file :: Maybe Token
file = [Token] -> Maybe Token
getFile [Token]
args'
    Maybe String
override <- ParsecT String UserState (SCBase m) (Maybe String)
forall {m :: * -> *}. MonadState SystemState m => m (Maybe String)
getSourceOverride
    let literalFile :: Maybe String
literalFile = do
        String
name <- Maybe String
override Maybe String -> Maybe String -> Maybe String
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` (Token -> Maybe String
getLiteralString (Token -> Maybe String) -> Maybe Token -> Maybe String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Token
file) Maybe String -> Maybe String -> Maybe String
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` (Token -> Maybe String
stripDynamicPrefix (Token -> Maybe String) -> Maybe Token -> Maybe String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Token
file)
        -- Hack to avoid 'source ~/foo' trying to read from literal tilde
        Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> (Bool -> Bool) -> Bool -> Maybe ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ String
"~/" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
name
        String -> Maybe String
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return String
name
    let fileId :: Id
fileId = Id -> Maybe Id -> Id
forall a. a -> Maybe a -> a
fromMaybe (Token -> Id
getId Token
cmd) (Token -> Id
getId (Token -> Id) -> Maybe Token -> Maybe Id
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Token
file)
    case Maybe String
literalFile of
        Maybe String
Nothing -> do
            Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseNoteAtId Id
fileId Severity
WarningC Integer
1090
                String
"ShellCheck can't follow non-constant source. Use a directive to specify location."
            Token -> SCParser m Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
t
        Just String
filename -> do
            Bool
proceed <- String -> ParsecT String UserState (SCBase m) Bool
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
String -> ParsecT s u m Bool
shouldFollow String
filename
            if Bool -> Bool
not Bool
proceed
              then do
                -- FIXME: This actually gets squashed without -a
                Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseNoteAtId Id
fileId Severity
InfoC Integer
1093
                    String
"This file appears to be recursively sourced. Ignoring."
                Token -> SCParser m Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
t
              else do
                SystemInterface m
sys <- (Environment m -> SystemInterface m)
-> ParsecT String UserState (SCBase m) (SystemInterface m)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Mr.asks Environment m -> SystemInterface m
forall (m :: * -> *). Environment m -> SystemInterface m
systemInterface
                (Either String String
input, String
resolvedFile) <-
                    if String
filename String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"/dev/null" -- always allow /dev/null
                    then (Either String String, String)
-> ParsecT
     String UserState (SCBase m) (Either String String, String)
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Either String String
forall a b. b -> Either a b
Right String
"", String
filename)
                    else do
                        [Annotation]
allAnnotations <- Bool -> ParsecT String UserState (SCBase m) [Annotation]
forall {f :: * -> *}.
MonadState SystemState f =>
Bool -> f [Annotation]
getCurrentAnnotations Bool
True
                        String
currentScript <- (Environment m -> String)
-> ParsecT String UserState (SCBase m) String
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
Mr.asks Environment m -> String
forall (m :: * -> *). Environment m -> String
currentFilename
                        let paths :: [String]
paths = (Annotation -> Maybe String) -> [Annotation] -> [String]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Annotation -> Maybe String
getSourcePath [Annotation]
allAnnotations
                        let externalSources :: Maybe Bool
externalSources = [Bool] -> Maybe Bool
forall a. [a] -> Maybe a
listToMaybe ([Bool] -> Maybe Bool) -> [Bool] -> Maybe Bool
forall a b. (a -> b) -> a -> b
$ (Annotation -> Maybe Bool) -> [Annotation] -> [Bool]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Annotation -> Maybe Bool
getExternalSources [Annotation]
allAnnotations
                        String
resolved <- m String -> ParsecT String UserState (SCBase m) String
forall {t :: (* -> *) -> * -> *} {t :: (* -> *) -> * -> *}
       {t :: (* -> *) -> * -> *} {m :: * -> *} {a}.
(MonadTrans t, MonadTrans t, MonadTrans t, Monad m,
 Monad (t (t m)), Monad (t m)) =>
m a -> t (t (t m)) a
system (m String -> ParsecT String UserState (SCBase m) String)
-> m String -> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ SystemInterface m
-> String -> Maybe Bool -> [String] -> String -> m String
forall (m :: * -> *).
SystemInterface m
-> String -> Maybe Bool -> [String] -> String -> m String
siFindSource SystemInterface m
sys String
currentScript Maybe Bool
externalSources [String]
paths String
filename
                        Either String String
contents <- m (Either String String)
-> ParsecT String UserState (SCBase m) (Either String String)
forall {t :: (* -> *) -> * -> *} {t :: (* -> *) -> * -> *}
       {t :: (* -> *) -> * -> *} {m :: * -> *} {a}.
(MonadTrans t, MonadTrans t, MonadTrans t, Monad m,
 Monad (t (t m)), Monad (t m)) =>
m a -> t (t (t m)) a
system (m (Either String String)
 -> ParsecT String UserState (SCBase m) (Either String String))
-> m (Either String String)
-> ParsecT String UserState (SCBase m) (Either String String)
forall a b. (a -> b) -> a -> b
$ SystemInterface m
-> Maybe Bool -> String -> m (Either String String)
forall (m :: * -> *).
SystemInterface m
-> Maybe Bool -> String -> m (Either String String)
siReadFile SystemInterface m
sys Maybe Bool
externalSources String
resolved
                        (Either String String, String)
-> ParsecT
     String UserState (SCBase m) (Either String String, String)
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String String
contents, String
resolved)
                case Either String String
input of
                    Left String
err -> do
                        Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseNoteAtId Id
fileId Severity
InfoC Integer
1091 (String -> ParsecT String UserState (SCBase m) ())
-> String -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
                            String
"Not following: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
err
                        Token -> SCParser m Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
t
                    Right String
script -> do
                        Id
id1 <- Id -> SCParser m Id
forall (m :: * -> *). Monad m => Id -> SCParser m Id
getNewIdFor Id
cmdId
                        Id
id2 <- Id -> SCParser m Id
forall (m :: * -> *). Monad m => Id -> SCParser m Id
getNewIdFor Id
cmdId

                        let included :: ParsecT String UserState (SCBase m) Token
included = do
                            Token
src <- String -> String -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
String -> String -> ParsecT String UserState (SCBase m) Token
subRead String
resolvedFile String
script
                            Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token -> Token
T_SourceCommand Id
id1 Token
t (Id -> Token -> Token
T_Include Id
id2 Token
src)

                        let failed :: ParsecT String UserState (SCBase m) Token
failed = do
                            Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseNoteAtId Id
fileId Severity
WarningC Integer
1094
                                String
"Parsing of sourced file failed. Ignoring it."
                            Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
t

                        SCParser m Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
included SCParser m Token -> SCParser m Token -> SCParser m Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> SCParser m Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
failed
  where
    getFile :: [Token] -> Maybe Token
    getFile :: [Token] -> Maybe Token
getFile (Token
first:[Token]
rest) =
        case Token -> Maybe String
getLiteralString Token
first of
            Just String
"--" -> [Token]
rest [Token] -> Line -> Maybe Token
forall {a}. [a] -> Line -> Maybe a
!!! Line
0
            Just String
"-p" -> [Token]
rest [Token] -> Line -> Maybe Token
forall {a}. [a] -> Line -> Maybe a
!!! Line
1
            Maybe String
_ -> Token -> Maybe Token
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
first
    getFile [Token]
_ = Maybe Token
forall a. Maybe a
Nothing

    getSourcePath :: Annotation -> Maybe String
getSourcePath Annotation
t =
        case Annotation
t of
            SourcePath String
x -> String -> Maybe String
forall a. a -> Maybe a
Just String
x
            Annotation
_ -> Maybe String
forall a. Maybe a
Nothing

    getExternalSources :: Annotation -> Maybe Bool
getExternalSources Annotation
t =
        case Annotation
t of
            ExternalSources Bool
b -> Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
b
            Annotation
_ -> Maybe Bool
forall a. Maybe a
Nothing

    -- If the word has a single expansion as the directory, try stripping it
    -- This affects `$foo/bar` but not `${foo}-dir/bar` or `/foo/$file`
    stripDynamicPrefix :: Token -> Maybe String
stripDynamicPrefix Token
word =
        case Token -> [Token]
getWordParts Token
word of
            Token
exp : [Token]
rest | Token -> Bool
isStringExpansion Token
exp -> do
                String
str <- Token -> Maybe String
getLiteralString (Id -> [Token] -> Token
T_NormalWord (Line -> Id
Id Line
0) [Token]
rest)
                Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ String
"/" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
str
                String -> Maybe String
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ String
"." String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
            [Token]
_ -> Maybe String
forall a. Maybe a
Nothing

    subRead :: String -> String -> ParsecT String UserState (SCBase m) Token
subRead String
name String
script =
        Context
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
Context -> ParsecT s u m b -> ParsecT s u m b
withContext (String -> Context
ContextSource String
name) (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$
            ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {s} {u} {b}.
MonadState s m =>
ParsecT s u m b -> ParsecT s u m b
inSeparateContext (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
                UserState
oldState <- ParsecT String UserState (SCBase m) UserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
                UserState -> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
setState (UserState -> ParsecT String UserState (SCBase m) ())
-> UserState -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ UserState
oldState { pendingHereDocs = [] }
                Token
result <- SourcePos
-> ParsecT String UserState (SCBase m) Token
-> String
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {u} {b}.
Monad m =>
SourcePos -> ParsecT s u m b -> s -> ParsecT s u m b
subParse (String -> SourcePos
initialPos String
name) (Bool -> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
Bool -> ParsecT String UserState (SCBase m) Token
readScriptFile Bool
True) String
script
                UserState
newState <- ParsecT String UserState (SCBase m) UserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
                UserState -> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
setState (UserState -> ParsecT String UserState (SCBase m) ())
-> UserState -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ UserState
newState { pendingHereDocs = pendingHereDocs oldState }
                Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
result
readSource Token
t = Token -> SCParser m Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Token
t


prop_readPipeline :: Bool
prop_readPipeline = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readPipeline String
"! cat /etc/issue | grep -i ubuntu"
prop_readPipeline2 :: Bool
prop_readPipeline2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readPipeline String
"!cat /etc/issue | grep -i ubuntu"
prop_readPipeline3 :: Bool
prop_readPipeline3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readPipeline String
"for f; do :; done|cat"
prop_readPipeline4 :: Bool
prop_readPipeline4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readPipeline String
"! ! true"
prop_readPipeline5 :: Bool
prop_readPipeline5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readPipeline String
"true | ! true"
readPipeline :: ParsecT String UserState (SCBase m) Token
readPipeline = do
    String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
forall {s} {u} {m :: * -> *} {a}.
String -> ParsecT s u m a -> ParsecT s u m ()
unexpecting String
"keyword/token" ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readKeyword
    ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token -> ParsecT s UserState m Token
readBanged ParsecT String UserState (SCBase m) Token
readPipeSequence

readBanged :: ParsecT s UserState m Token -> ParsecT s UserState m Token
readBanged ParsecT s UserState m Token
parser = do
    SourcePos
pos <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    (T_Bang Id
id) <- ParsecT s UserState m Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Bang
    Token
next <- ParsecT s UserState m Token -> ParsecT s UserState m Token
readBanged ParsecT s UserState m Token
parser
    Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token
T_Banged Id
id Token
next
 ParsecT s UserState m Token
-> ParsecT s UserState m Token -> ParsecT s UserState m Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s UserState m Token
parser

prop_readAndOr :: Bool
prop_readAndOr = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAndOr String
"grep -i lol foo || exit 1"
prop_readAndOr1 :: Bool
prop_readAndOr1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAndOr String
"# shellcheck disable=1\nfoo"
prop_readAndOr2 :: Bool
prop_readAndOr2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readAndOr String
"# shellcheck disable=1\n# lol\n# shellcheck disable=3\nfoo"
readAndOr :: ParsecT String UserState (SCBase m) Token
readAndOr = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
apos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    [Annotation]
annotations <- ParsecT String UserState (SCBase m) [Annotation]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Annotation]
readAnnotations
    Id
aid <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start

    Bool
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([Annotation] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Annotation]
annotations) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> (ParsecT String UserState (SCBase m) Token
    -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readKeyword
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
apos Severity
ErrorC Integer
1123 String
"ShellCheck directives are only valid in front of complete compound commands, like 'if', not e.g. individual 'elif' branches."

    Token
andOr <- [Annotation]
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
[Annotation] -> ParsecT s u m b -> ParsecT s u m b
withAnnotations [Annotation]
annotations (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$
        ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
chainl1 ParsecT String UserState (SCBase m) Token
readPipeline (ParsecT String UserState (SCBase m) (Token -> Token -> Token)
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
            Token
op <- ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_AND_IF ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_OR_IF
            ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak
            (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Token -> Token -> Token)
 -> ParsecT String UserState (SCBase m) (Token -> Token -> Token))
-> (Token -> Token -> Token)
-> ParsecT String UserState (SCBase m) (Token -> Token -> Token)
forall a b. (a -> b) -> a -> b
$ case Token
op of T_AND_IF Id
id -> Id -> Token -> Token -> Token
T_AndIf Id
id
                                T_OR_IF  Id
id -> Id -> Token -> Token -> Token
T_OrIf Id
id

    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ if [Annotation] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Annotation]
annotations
                then Token
andOr
                else Id -> [Annotation] -> Token -> Token
T_Annotation Id
aid [Annotation]
annotations Token
andOr

readTermOrNone :: ParsecT String UserState (SCBase m) [Token]
readTermOrNone = do
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    ParsecT String UserState (SCBase m) [Token]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Token]
readTerm ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
        [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return []

prop_readTerm :: Bool
prop_readTerm = ParsecT String UserState (SCBase Identity) [Token]
-> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) [Token]
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) [Token]
readTerm String
"time ( foo; bar; )"
readTerm :: ParsecT String UserState (SCBase m) [Token]
readTerm = do
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    Token
m <- ParsecT String UserState (SCBase m) Token
readAndOr
    Token -> ParsecT String UserState (SCBase m) [Token]
readTerm' Token
m
  where
    readTerm' :: Token -> ParsecT String UserState (SCBase m) [Token]
readTerm' Token
current =
        do
            (Char
sep, (SourcePos
start, SourcePos
end)) <- ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Char, (SourcePos, SourcePos))
readSeparator
            Id
id <- SourcePos -> SourcePos -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
SourcePos -> SourcePos -> ParsecT s UserState m Id
getNextIdBetween SourcePos
start SourcePos
end
            Token
more <- Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option (Id -> Token
T_EOF Id
id) ParsecT String UserState (SCBase m) Token
readAndOr
            case Token
more of (T_EOF Id
_) -> [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Id -> Char -> Token -> Token
transformWithSeparator Id
id Char
sep Token
current]
                         Token
_         -> do
                                    [Token]
list <- Token -> ParsecT String UserState (SCBase m) [Token]
readTerm' Token
more
                                    [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Char -> Token -> Token
transformWithSeparator Id
id Char
sep Token
current Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: [Token]
list)
          ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
            [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Token
current]
      where
        transformWithSeparator :: Id -> Char -> Token -> Token
transformWithSeparator Id
i Char
'&' = Id -> Token -> Token
T_Backgrounded Id
i
        transformWithSeparator Id
i Char
_  = Token -> Token
forall a. a -> a
id


readPipeSequence :: ParsecT String UserState (SCBase m) Token
readPipeSequence = do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ([Token]
cmds, [Token]
pipes) <- ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ([Token], [Token])
forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m ([a], [a])
sepBy1WithSeparators (ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token -> ParsecT s UserState m Token
readBanged ParsecT String UserState (SCBase m) Token
readCommand)
                        (ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
readPipe ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` (ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak))
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> [Token] -> Token
T_Pipeline Id
id [Token]
pipes [Token]
cmds
  where
    sepBy1WithSeparators :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m ([a], [a])
sepBy1WithSeparators ParsecT s u m a
p ParsecT s u m a
s = do
        let elems :: ParsecT s u m ([a], [a])
elems = (\a
x -> ([a
x], [])) (a -> ([a], [a])) -> ParsecT s u m a -> ParsecT s u m ([a], [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m a
p
        let seps :: ParsecT s u m (([a], [a]) -> ([a], [a]) -> ([a], [a]))
seps = do
            a
separator <- ParsecT s u m a
s
            (([a], [a]) -> ([a], [a]) -> ([a], [a]))
-> ParsecT s u m (([a], [a]) -> ([a], [a]) -> ([a], [a]))
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((([a], [a]) -> ([a], [a]) -> ([a], [a]))
 -> ParsecT s u m (([a], [a]) -> ([a], [a]) -> ([a], [a])))
-> (([a], [a]) -> ([a], [a]) -> ([a], [a]))
-> ParsecT s u m (([a], [a]) -> ([a], [a]) -> ([a], [a]))
forall a b. (a -> b) -> a -> b
$ \([a]
a,[a]
b) ([a]
c,[a]
d) -> ([a]
a[a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++[a]
c, [a]
b [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
d [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a
separator])
        ParsecT s u m ([a], [a])
forall {a}. ParsecT s u m ([a], [a])
elems ParsecT s u m ([a], [a])
-> ParsecT s u m (([a], [a]) -> ([a], [a]) -> ([a], [a]))
-> ParsecT s u m ([a], [a])
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (a -> a -> a) -> ParsecT s u m a
`chainl1` ParsecT s u m (([a], [a]) -> ([a], [a]) -> ([a], [a]))
forall {a}. ParsecT s u m (([a], [a]) -> ([a], [a]) -> ([a], [a]))
seps

readPipe :: ParsecT s UserState m Token
readPipe = do
    ParsecT s UserState m Token -> ParsecT s UserState m ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 ParsecT s UserState m Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_OR_IF
    IncompleteInterval
start <- ParsecT s UserState m IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Char -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|'
    String
qualifier <- String -> ParsecT s UserState m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"&" ParsecT s UserState m String
-> ParsecT s UserState m String -> ParsecT s UserState m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT s UserState m String
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return String
""
    Id
id <- IncompleteInterval -> ParsecT s UserState m Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    ParsecT s UserState m String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Token -> ParsecT s UserState m Token
forall a. a -> ParsecT s UserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT s UserState m Token)
-> Token -> ParsecT s UserState m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token
T_Pipe Id
id (Char
'|'Char -> String -> String
forall a. a -> [a] -> [a]
:String
qualifier)

readCommand :: ParsecT String UserState (SCBase m) Token
readCommand = [ParsecT String UserState (SCBase m) Token]
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
    ParsecT String UserState (SCBase m) Token
readCompoundCommand,
    ParsecT String UserState (SCBase m) Token
readConditionCommand,
    ParsecT String UserState (SCBase m) Token
readCoProc,
    ParsecT String UserState (SCBase m) Token
readSimpleCommand
    ]

readCmdName :: ParsecT String UserState (SCBase m) Token
readCmdName = do
    -- If the command name is `!` then
    ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) ())
-> (ParsecT String UserState (SCBase m) Char
    -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> (ParsecT String UserState (SCBase m) Char
    -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'!'
        ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
whitespace
    -- Ignore alias suppression
    ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) ())
-> (ParsecT String UserState (SCBase m) Char
    -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\'
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
variableChars ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
":."
    ParsecT String UserState (SCBase m) Token
readCmdWord

readCmdWord :: ParsecT String UserState (SCBase m) Token
readCmdWord = do
    ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m ()
skipAnnotationAndWarn
    ParsecT String UserState (SCBase m) Token
readNormalWord ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) Token
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing

-- Due to poor planning, annotations after commands isn't handled well.
-- At the time this function is used, it's usually too late to skip
-- comments, so you end up with a parse failure instead.
skipAnnotationAndWarn :: ParsecT s UserState m ()
skipAnnotationAndWarn = ParsecT s UserState m String -> ParsecT s UserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT s UserState m String -> ParsecT s UserState m ())
-> ParsecT s UserState m String -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ do
        ParsecT s UserState m String -> ParsecT s UserState m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s UserState m String -> ParsecT s UserState m String)
-> (ParsecT s UserState m String -> ParsecT s UserState m String)
-> ParsecT s UserState m String
-> ParsecT s UserState m String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT s UserState m String -> ParsecT s UserState m String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s UserState m String -> ParsecT s UserState m String)
-> ParsecT s UserState m String -> ParsecT s UserState m String
forall a b. (a -> b) -> a -> b
$ ParsecT s UserState m String
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
readAnnotationPrefix
        Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1126 String
"Place shellcheck directives before commands, not after."
        ParsecT s UserState m String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readAnyComment

prop_readIfClause :: Bool
prop_readIfClause = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if false; then foo; elif true; then stuff; more stuff; else cows; fi"
prop_readIfClause2 :: Bool
prop_readIfClause2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if false; then; echo oo; fi"
prop_readIfClause3 :: Bool
prop_readIfClause3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if false; then true; else; echo lol; fi"
prop_readIfClause4 :: Bool
prop_readIfClause4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if false; then true; else if true; then echo lol; fi; fi"
prop_readIfClause5 :: Bool
prop_readIfClause5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if false; then true; else\nif true; then echo lol; fi; fi"
prop_readIfClause6 :: Bool
prop_readIfClause6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readIfClause String
"if true\nthen\nDo the thing\nfi"
readIfClause :: ParsecT String UserState (SCBase m) Token
readIfClause = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"if expression" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ([Token]
condition, [Token]
action) <- ParsecT String UserState (SCBase m) ([Token], [Token])
readIfPart
    [([Token], [Token])]
elifs <- ParsecT String UserState (SCBase m) ([Token], [Token])
-> ParsecT String UserState (SCBase m) [([Token], [Token])]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) ([Token], [Token])
readElifPart
    [Token]
elses <- [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] ParsecT String UserState (SCBase m) [Token]
readElsePart

    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Fi ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) Token
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
`orFail` do
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1046 String
"Couldn't find 'fi' for this 'if'."
        Severity
-> Integer -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1047 String
"Expected 'fi' matching previously mentioned 'if'."
        String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"Expected 'fi'"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start

    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [([Token], [Token])] -> [Token] -> Token
T_IfExpression Id
id (([Token]
condition, [Token]
action)([Token], [Token]) -> [([Token], [Token])] -> [([Token], [Token])]
forall a. a -> [a] -> [a]
:[([Token], [Token])]
elifs) [Token]
elses


verifyNotEmptyIf :: String -> ParsecT String UserState (SCBase m) ()
verifyNotEmptyIf String
s =
    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (do
                SourcePos
emptyPos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> (ParsecT String UserState (SCBase m) Token
    -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ (ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Fi ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Elif ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Else)
                SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
emptyPos Severity
ErrorC Integer
1048 (String -> ParsecT String UserState (SCBase m) ())
-> String -> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ String
"Can't have empty " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" clauses (use 'true' as a no-op).")
readIfPart :: ParsecT String UserState (SCBase m) ([Token], [Token])
readIfPart = do
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_If
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    [Token]
condition <- ParsecT String UserState (SCBase m) [Token]
readTerm

    ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m ()
ifNextToken (ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Fi ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Elif ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Else) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1049 String
"Did you forget the 'then' for this 'if'?"

    String
-> ParsecT String UserState (SCBase m) ([Token], [Token])
-> ParsecT String UserState (SCBase m) ([Token], [Token])
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"then clause" (ParsecT String UserState (SCBase m) ([Token], [Token])
 -> ParsecT String UserState (SCBase m) ([Token], [Token]))
-> ParsecT String UserState (SCBase m) ([Token], [Token])
-> ParsecT String UserState (SCBase m) ([Token], [Token])
forall a b. (a -> b) -> a -> b
$ do
        ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Then ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) Token
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
`orFail` do
            Severity
-> Integer -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1050 String
"Expected 'then'."
            String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"Expected 'then'"

        ParsecT String UserState (SCBase m) Token
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Semi Severity
ErrorC Integer
1051 String
"Semicolons directly after 'then' are not allowed. Just remove it."
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
        String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) ()
verifyNotEmptyIf String
"then"

        [Token]
action <- ParsecT String UserState (SCBase m) [Token]
readTerm
        ([Token], [Token])
-> ParsecT String UserState (SCBase m) ([Token], [Token])
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Token]
condition, [Token]
action)

readElifPart :: ParsecT String UserState (SCBase m) ([Token], [Token])
readElifPart = String
-> ParsecT String UserState (SCBase m) ([Token], [Token])
-> ParsecT String UserState (SCBase m) ([Token], [Token])
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"elif clause" (ParsecT String UserState (SCBase m) ([Token], [Token])
 -> ParsecT String UserState (SCBase m) ([Token], [Token]))
-> ParsecT String UserState (SCBase m) ([Token], [Token])
-> ParsecT String UserState (SCBase m) ([Token], [Token])
forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Elif
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    [Token]
condition <- ParsecT String UserState (SCBase m) [Token]
readTerm
    ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m ()
ifNextToken (ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Fi ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Elif ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Else) (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1049 String
"Did you forget the 'then' for this 'elif'?"

    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Then
    ParsecT String UserState (SCBase m) Token
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Semi Severity
ErrorC Integer
1052 String
"Semicolons directly after 'then' are not allowed. Just remove it."
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) ()
verifyNotEmptyIf String
"then"
    [Token]
action <- ParsecT String UserState (SCBase m) [Token]
readTerm
    ([Token], [Token])
-> ParsecT String UserState (SCBase m) ([Token], [Token])
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Token]
condition, [Token]
action)

readElsePart :: ParsecT String UserState (SCBase m) [Token]
readElsePart = String
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"else clause" (ParsecT String UserState (SCBase m) [Token]
 -> ParsecT String UserState (SCBase m) [Token])
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Else
    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> (ParsecT String UserState (SCBase m) Token
    -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_If
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1075 String
"Use 'elif' instead of 'else if' (or put 'if' on new line if nesting)."

    ParsecT String UserState (SCBase m) Token
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Semi Severity
ErrorC Integer
1053 String
"Semicolons directly after 'else' are not allowed. Just remove it."
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
String -> ParsecT String UserState (SCBase m) ()
verifyNotEmptyIf String
"else"
    ParsecT String UserState (SCBase m) [Token]
readTerm

ifNextToken :: ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m ()
ifNextToken ParsecT s u m a
parser ParsecT s u m a
action =
    ParsecT s u m a -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT s u m a -> ParsecT s u m ())
-> ParsecT s u m a -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ do
        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)
-> ParsecT s u m a
-> ParsecT s u m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT s u m a -> ParsecT s u m a
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (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
$ ParsecT s u m a
parser
        ParsecT s u m a
action

prop_readSubshell :: Bool
prop_readSubshell = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSubshell String
"( cd /foo; tar cf stuff.tar * )"
readSubshell :: ParsecT String UserState (SCBase m) Token
readSubshell = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"explicit subshell" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'('
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    [Token]
list <- ParsecT String UserState (SCBase m) [Token]
readCompoundList
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
')' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Char
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected ) closing the subshell"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_Subshell Id
id [Token]
list

prop_readBraceGroup :: Bool
prop_readBraceGroup = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraceGroup String
"{ a; b | c | d; e; }"
prop_readBraceGroup2 :: Bool
prop_readBraceGroup2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraceGroup String
"{foo;}"
prop_readBraceGroup3 :: Bool
prop_readBraceGroup3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBraceGroup String
"{(foo)}"
readBraceGroup :: ParsecT String UserState (SCBase m) Token
readBraceGroup = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"brace group" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'{'
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacingOrFail ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (do
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"(" -- {( is legal
        Severity
-> Integer -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1054 String
"You need a space after the '{'.")
    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Char
 -> ParsecT String UserState (SCBase m) Char)
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1055 String
"You need at least one command here. Use 'true;' as a no-op."
    [Token]
list <- ParsecT String UserState (SCBase m) [Token]
readTerm
    Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        Severity
-> Integer -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1056 String
"Expected a '}'. If you have one, try a ; or \\n in front of it."
        String -> ParsecT String UserState (SCBase m) Char
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Missing '}'"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> Token
T_BraceGroup Id
id [Token]
list

prop_readBatsTest1 :: Bool
prop_readBatsTest1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBatsTest String
"@test 'can parse' {\n  true\n}"
prop_readBatsTest2 :: Bool
prop_readBatsTest2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBatsTest String
"@test random text !(@*$Y&! {\n  true\n}"
prop_readBatsTest3 :: Bool
prop_readBatsTest3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBatsTest String
"@test foo { bar { baz {\n  true\n}"
prop_readBatsTest4 :: Bool
prop_readBatsTest4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isNotOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readBatsTest String
"@test foo \n{\n true\n}"
readBatsTest :: ParsecT String UserState (SCBase m) Token
readBatsTest = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"bats @test" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"@test "
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    String
name <- ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readBatsName
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Token
test <- ParsecT String UserState (SCBase m) Token
readBraceGroup
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> Token -> Token
T_BatsTest Id
id String
name Token
test
  where
    readBatsName :: ParsecT s u m String
readBatsName = do
        String
line <- ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m String -> ParsecT s u m String)
-> (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String
-> ParsecT s u m String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT s u m String -> ParsecT s u m String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ ParsecT s u m Char -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT s u m Char -> ParsecT s u m String)
-> ParsecT s u m Char -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\n"
        let name :: String
name = String -> String
forall a. [a] -> [a]
reverse (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
f (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. [a] -> [a]
reverse String
line
        String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
name

    -- We want everything before the last " {" in a string, so we find everything after "{ " in its reverse
    f :: String -> String
f (Char
'{':Char
' ':String
rest) = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isSpace String
rest
    f (Char
a:String
rest) = String -> String
f String
rest
    f [] = String
""

prop_readWhileClause :: Bool
prop_readWhileClause = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readWhileClause String
"while [[ -e foo ]]; do sleep 1; done"
readWhileClause :: ParsecT String UserState (SCBase m) Token
readWhileClause = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"while loop" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Id
kwId <- Token -> Id
getId (Token -> Id)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Id
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_While
    [Token]
condition <- ParsecT String UserState (SCBase m) [Token]
readTerm
    [Token]
statements <- Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
kwId
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> [Token] -> Token
T_WhileExpression Id
id [Token]
condition [Token]
statements

prop_readUntilClause :: Bool
prop_readUntilClause = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readUntilClause String
"until kill -0 $PID; do sleep 1; done"
readUntilClause :: ParsecT String UserState (SCBase m) Token
readUntilClause = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"until loop" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    Id
kwId <- Token -> Id
getId (Token -> Id)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Id
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Until
    [Token]
condition <- ParsecT String UserState (SCBase m) [Token]
readTerm
    [Token]
statements <- Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
kwId
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> [Token] -> [Token] -> Token
T_UntilExpression Id
id [Token]
condition [Token]
statements

readDoGroup :: Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
kwId = do
    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (do
                ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> (ParsecT String UserState (SCBase m) Token
    -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Done
                Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId Id
kwId Severity
ErrorC Integer
1057 String
"Did you forget the 'do' for this loop?")

    Token
doKw <- ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Do ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) Token
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
`orFail` do
        Severity
-> Integer -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1058 String
"Expected 'do'."
        String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"Expected 'do'"

    ParsecT String UserState (SCBase m) Token
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Semi Severity
ErrorC Integer
1059 String
"Semicolon is not allowed directly after 'do'. You can just delete it."
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing

    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (do
                ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> (ParsecT String UserState (SCBase m) Token
    -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Done
                Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId (Token -> Id
getId Token
doKw) Severity
ErrorC Integer
1060 String
"Can't have empty do clauses (use 'true' as a no-op).")

    [Token]
commands <- ParsecT String UserState (SCBase m) [Token]
readCompoundList
    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Done ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) Token
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m a
`orFail` do
            Id
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall (m :: * -> *).
Monad m =>
Id -> Severity -> Integer -> String -> SCParser m ()
parseProblemAtId (Token -> Id
getId Token
doKw) Severity
ErrorC Integer
1061 String
"Couldn't find 'done' for this 'do'."
            Severity
-> Integer -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1062 String
"Expected 'done' matching previously mentioned 'do'."
            String -> ParsecT String UserState (SCBase m) String
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"Expected 'done'"

    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> (ParsecT String UserState (SCBase m) ()
    -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"<("
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1142 String
"Use 'done < <(cmd)' to redirect from process substitution (currently missing one '<')."
    [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
commands


prop_readForClause :: Bool
prop_readForClause = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for f in *; do rm \"$f\"; done"
prop_readForClause1 :: Bool
prop_readForClause1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for f in *; { rm \"$f\"; }"
prop_readForClause3 :: Bool
prop_readForClause3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for f; do foo; done"
prop_readForClause4 :: Bool
prop_readForClause4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for((i=0; i<10; i++)); do echo $i; done"
prop_readForClause5 :: Bool
prop_readForClause5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for ((i=0;i<10 && n>x;i++,--n))\ndo \necho $i\ndone"
prop_readForClause6 :: Bool
prop_readForClause6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for ((;;))\ndo echo $i\ndone"
prop_readForClause7 :: Bool
prop_readForClause7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for ((;;)) do echo $i\ndone"
prop_readForClause8 :: Bool
prop_readForClause8 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for ((;;)) ; do echo $i\ndone"
prop_readForClause9 :: Bool
prop_readForClause9 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for i do true; done"
prop_readForClause10 :: Bool
prop_readForClause10 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for ((;;)) { true; }"
prop_readForClause12 :: Bool
prop_readForClause12 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for $a in *; do echo \"$a\"; done"
prop_readForClause13 :: Bool
prop_readForClause13 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readForClause String
"for foo\nin\\\n  bar\\\n  baz\ndo true; done"
readForClause :: ParsecT String UserState (SCBase m) Token
readForClause = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"for loop" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    (T_For Id
id) <- ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_For
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Id -> ParsecT String UserState (SCBase m) Token
readArithmetic Id
id ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Id -> ParsecT String UserState (SCBase m) Token
readRegular Id
id
  where
    readArithmetic :: Id -> ParsecT String UserState (SCBase m) Token
readArithmetic Id
id = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"arithmetic for condition" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
        Char -> String -> ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
Char -> String -> ParsecT s UserState m ()
readArithmeticDelimiter Char
'(' String
"Missing second '(' to start arithmetic for ((;;)) loop"
        Token
x <- ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
        Token
y <- ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
        Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
';' ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
        Token
z <- ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readArithmeticContents
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
        Char -> String -> ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
Char -> String -> ParsecT s UserState m ()
readArithmeticDelimiter Char
')' String
"Missing second ')' to terminate 'for ((;;))' loop condition"
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readSequentialSep ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
        [Token]
group <- ParsecT String UserState (SCBase m) [Token]
readBraced ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
id
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> Token -> Token -> Token -> [Token] -> Token
T_ForArithmetic Id
id Token
x Token
y Token
z [Token]
group

    -- For c='(' read "((" and be lenient about spaces
    readArithmeticDelimiter :: Char -> String -> ParsecT s UserState m ()
readArithmeticDelimiter Char
c String
msg = do
        Char -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c
        SourcePos
startPos <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        String
sp <- ParsecT s UserState m String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
        SourcePos
endPos <- ParsecT s UserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        Char -> ParsecT s UserState m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c ParsecT s UserState m Char
-> ParsecT s UserState m Char -> ParsecT s UserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
            SourcePos
-> Severity -> Integer -> String -> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
startPos Severity
ErrorC Integer
1137 String
msg
            String -> ParsecT s UserState m Char
forall a. String -> ParsecT s UserState m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
""
        Bool -> ParsecT s UserState m () -> ParsecT s UserState m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
sp) (ParsecT s UserState m () -> ParsecT s UserState m ())
-> ParsecT s UserState m () -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$
            SourcePos
-> SourcePos
-> Severity
-> Integer
-> String
-> ParsecT s UserState m ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAtWithEnd SourcePos
startPos SourcePos
endPos Severity
ErrorC Integer
1138 (String -> ParsecT s UserState m ())
-> String -> ParsecT s UserState m ()
forall a b. (a -> b) -> a -> b
$ String
"Remove spaces between " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
c,Char
c] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" in arithmetic for loop."

    readBraced :: ParsecT String UserState (SCBase m) [Token]
readBraced = do
        (T_BraceGroup Id
_ [Token]
list) <- ParsecT String UserState (SCBase m) Token
readBraceGroup
        [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
list

    readRegular :: Id -> ParsecT String UserState (SCBase m) Token
readRegular Id
id = do
        ParsecT String UserState (SCBase m) Char
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {s} {m :: * -> *} {t} {m :: * -> *} {u} {a}.
(Stream s m t, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s u m a
-> Severity -> Integer -> String -> ParsecT s u m ()
acceptButWarn (Char -> ParsecT String UserState (SCBase m) Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'$') Severity
ErrorC Integer
1086
            String
"Don't use $ on the iterator name in for loops."
        String
name <- ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {t} {u} {a} {a}.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`thenSkip` ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
        [Token]
values <- ParsecT String UserState (SCBase m) [Token]
readInClause ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readSequentialSep ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [])
        [Token]
group <- ParsecT String UserState (SCBase m) [Token]
readBraced ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
id
        Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> [Token] -> Token
T_ForIn Id
id String
name [Token]
values [Token]
group

prop_readSelectClause1 :: Bool
prop_readSelectClause1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSelectClause String
"select foo in *; do echo $foo; done"
prop_readSelectClause2 :: Bool
prop_readSelectClause2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readSelectClause String
"select foo; do echo $foo; done"
readSelectClause :: ParsecT String UserState (SCBase m) Token
readSelectClause = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"select loop" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    (T_Select Id
id) <- ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Select
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    Id -> [Token] -> ParsecT String UserState (SCBase m) Token
typ <- ParsecT
  String
  UserState
  (SCBase m)
  (Id -> [Token] -> ParsecT String UserState (SCBase m) Token)
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) (Id -> [Token] -> m Token)
readRegular
    [Token]
group <- Id -> ParsecT String UserState (SCBase m) [Token]
readDoGroup Id
id
    Id -> [Token] -> ParsecT String UserState (SCBase m) Token
typ Id
id [Token]
group
  where
    readRegular :: ParsecT String UserState (SCBase m) (Id -> [Token] -> m Token)
readRegular = do
        String
name <- ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
ParsecT s u m String
readVariableName
        ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
        [Token]
values <- ParsecT String UserState (SCBase m) [Token]
readInClause ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readSequentialSep ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [])
        (Id -> [Token] -> m Token)
-> ParsecT String UserState (SCBase m) (Id -> [Token] -> m Token)
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Id -> [Token] -> m Token)
 -> ParsecT String UserState (SCBase m) (Id -> [Token] -> m Token))
-> (Id -> [Token] -> m Token)
-> ParsecT String UserState (SCBase m) (Id -> [Token] -> m Token)
forall a b. (a -> b) -> a -> b
$ \Id
id [Token]
group -> (Token -> m Token
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> m Token) -> Token -> m Token
forall a b. (a -> b) -> a -> b
$ Id -> String -> [Token] -> [Token] -> Token
T_SelectIn Id
id String
name [Token]
values [Token]
group)

readInClause :: ParsecT String UserState (SCBase m) [Token]
readInClause = do
    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_In
    [Token]
things <- ParsecT String UserState (SCBase m) Token
readCmdWord ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) [Token]
forall {s} {m :: * -> *} {t} {u} {a} {a}.
(Stream s m t, Show t) =>
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m [a]
`reluctantlyTill`
                (ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Semi ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Char
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) Char
forall (m :: * -> *). Monad m => SCParser m Char
linefeed ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Do)

    do {
        ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Do;
        Severity
-> Integer -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s UserState m ()
parseNote Severity
ErrorC Integer
1063 String
"You need a line feed or semicolon before the 'do'.";
    } ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do {
        ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Semi;
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing;
    }

    [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return [Token]
things

prop_readCaseClause :: Bool
prop_readCaseClause = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo in a ) lol; cow;; b|d) fooo; esac"
prop_readCaseClause2 :: Bool
prop_readCaseClause2 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo\n in * ) echo bar;; esac"
prop_readCaseClause3 :: Bool
prop_readCaseClause3 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo\n in * ) echo bar & ;; esac"
prop_readCaseClause4 :: Bool
prop_readCaseClause4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo\n in *) echo bar ;& bar) foo; esac"
prop_readCaseClause5 :: Bool
prop_readCaseClause5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo\n in *) echo bar;;& foo) baz;; esac"
prop_readCaseClause6 :: Bool
prop_readCaseClause6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readCaseClause String
"case foo\n in if) :;; done) :;; esac"
readCaseClause :: ParsecT String UserState (SCBase m) Token
readCaseClause = String
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"case expression" (ParsecT String UserState (SCBase m) Token
 -> ParsecT String UserState (SCBase m) Token)
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ do
    IncompleteInterval
start <- ParsecT String UserState (SCBase m) IncompleteInterval
forall {m :: * -> *} {s} {u}.
Monad m =>
ParsecT s u m IncompleteInterval
startSpan
    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Case
    Token
word <- ParsecT String UserState (SCBase m) Token
readNormalWord
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) String
allspacing
    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_In ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Token
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected 'in'"
    ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak
    [(CaseType, [Token], [Token])]
list <- ParsecT String UserState (SCBase m) [(CaseType, [Token], [Token])]
readCaseList
    ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Esac ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT String UserState (SCBase m) Token
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected 'esac' to close the case statement"
    Id
id <- IncompleteInterval -> ParsecT String UserState (SCBase m) Id
forall {m :: * -> *} {s}.
Monad m =>
IncompleteInterval -> ParsecT s UserState m Id
endSpan IncompleteInterval
start
    Token -> ParsecT String UserState (SCBase m) Token
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Token -> ParsecT String UserState (SCBase m) Token)
-> Token -> ParsecT String UserState (SCBase m) Token
forall a b. (a -> b) -> a -> b
$ Id -> Token -> [(CaseType, [Token], [Token])] -> Token
T_CaseExpression Id
id Token
word [(CaseType, [Token], [Token])]
list

readCaseList :: ParsecT String UserState (SCBase m) [(CaseType, [Token], [Token])]
readCaseList = ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
-> ParsecT
     String UserState (SCBase m) [(CaseType, [Token], [Token])]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
readCaseItem

readCaseItem :: ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
readCaseItem = String
-> ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
-> ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
forall {m :: * -> *} {s} {t} {u} {b}.
(Stream s m t, MonadState SystemState m) =>
String -> ParsecT s u m b -> ParsecT s u m b
called String
"case item" (ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
 -> ParsecT
      String UserState (SCBase m) (CaseType, [Token], [Token]))
-> ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
-> ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
forall a b. (a -> b) -> a -> b
$ do
    ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
forall {s} {u} {m :: * -> *} {a}.
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy2 ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Esac
    ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT String UserState (SCBase m) ()
 -> ParsecT String UserState (SCBase m) ())
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall a b. (a -> b) -> a -> b
$ do
        ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> (ParsecT String UserState (SCBase m) String
    -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) String
 -> ParsecT String UserState (SCBase m) String)
-> ParsecT String UserState (SCBase m) String
-> ParsecT String UserState (SCBase m) String
forall a b. (a -> b) -> a -> b
$ ParsecT String UserState (SCBase m) String
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
readAnnotationPrefix
        Severity
-> Integer -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1124 String
"ShellCheck directives are only valid in front of complete commands like 'case' statements, not individual case branches."
    ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Lparen
    ParsecT String UserState (SCBase m) String
forall {m :: * -> *} {s} {m :: * -> *}.
(MonadState SystemState m, Stream s m Char,
 MonadReader (Environment m) m) =>
ParsecT s UserState m String
spacing
    [Token]
pattern' <- ParsecT String UserState (SCBase m) [Token]
readPattern
    ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Rparen ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do
        Severity
-> Integer -> String -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *} {s} {u}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
Severity -> Integer -> String -> ParsecT s u m ()
parseProblem Severity
ErrorC Integer
1085
            String
"Did you forget to move the ;; after extending this case item?"
        String -> ParsecT String UserState (SCBase m) ()
forall a. String -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected ) to open a new case item"
    ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak
    [Token]
list <- (ParsecT String UserState (SCBase m) CaseType
-> ParsecT String UserState (SCBase m) CaseType
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT String UserState (SCBase m) CaseType
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) CaseType
readCaseSeparator ParsecT String UserState (SCBase m) CaseType
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Token] -> ParsecT String UserState (SCBase m) [Token]
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return []) ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
-> ParsecT String UserState (SCBase m) [Token]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String UserState (SCBase m) [Token]
readCompoundList
    CaseType
separator <- ParsecT String UserState (SCBase m) CaseType
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) CaseType
readCaseSeparator ParsecT String UserState (SCBase m) CaseType
-> ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) CaseType
forall {s} {u} {m :: * -> *} {a} {a}.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
`attempting` do
        SourcePos
pos <- ParsecT String UserState (SCBase m) SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_Rparen
        SourcePos
-> Severity
-> Integer
-> String
-> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {m :: * -> *}.
(MonadState SystemState m, MonadReader (Environment m) m) =>
SourcePos -> Severity -> Integer -> String -> m ()
parseProblemAt SourcePos
pos Severity
ErrorC Integer
1074
            String
"Did you forget the ;; after the previous case item?"
    ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak
    (CaseType, [Token], [Token])
-> ParsecT String UserState (SCBase m) (CaseType, [Token], [Token])
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (CaseType
separator, [Token]
pattern', [Token]
list)

readCaseSeparator :: ParsecT String UserState (SCBase m) CaseType
readCaseSeparator = [ParsecT String UserState (SCBase m) CaseType]
-> ParsecT String UserState (SCBase m) CaseType
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [
    String -> (Id -> ()) -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
";;&" (() -> Id -> ()
forall a b. a -> b -> a
const ()) ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) CaseType
-> ParsecT String UserState (SCBase m) CaseType
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CaseType -> ParsecT String UserState (SCBase m) CaseType
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return CaseType
CaseContinue,
    String -> (Id -> ()) -> ParsecT String UserState (SCBase m) ()
forall {m :: * -> *} {s} {m :: * -> *} {a}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
String -> (Id -> a) -> ParsecT s UserState m a
tryToken String
";&" (() -> Id -> ()
forall a b. a -> b -> a
const ()) ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) CaseType
-> ParsecT String UserState (SCBase m) CaseType
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CaseType -> ParsecT String UserState (SCBase m) CaseType
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return CaseType
CaseFallThrough,
    ParsecT String UserState (SCBase m) Token
forall {s} {m :: * -> *} {m :: * -> *}.
(Stream s m Char, MonadState SystemState m,
 MonadReader (Environment m) m) =>
ParsecT s UserState m Token
g_DSEMI ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) CaseType
-> ParsecT String UserState (SCBase m) CaseType
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CaseType -> ParsecT String UserState (SCBase m) CaseType
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return CaseType
CaseBreak,
    ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT String UserState (SCBase m) ()
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) ()
readLineBreak ParsecT String UserState (SCBase m) ()
-> ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) Token
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String UserState (SCBase m) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
g_Esac) ParsecT String UserState (SCBase m) Token
-> ParsecT String UserState (SCBase m) CaseType
-> ParsecT String UserState (SCBase m) CaseType
forall a b.
ParsecT String UserState (SCBase m) a
-> ParsecT String UserState (SCBase m) b
-> ParsecT String UserState (SCBase m) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CaseType -> ParsecT String UserState (SCBase m) CaseType
forall a. a -> ParsecT String UserState (SCBase m) a
forall (m :: * -> *) a. Monad m => a -> m a
return CaseType
CaseBreak
    ]

prop_readFunctionDefinition :: Bool
prop_readFunctionDefinition = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"foo() { command foo --lol \"$@\"; }"
prop_readFunctionDefinition1 :: Bool
prop_readFunctionDefinition1 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"foo   (){ command foo --lol \"$@\"; }"
prop_readFunctionDefinition4 :: Bool
prop_readFunctionDefinition4 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isWarning ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"foo(a, b) { true; }"
prop_readFunctionDefinition5 :: Bool
prop_readFunctionDefinition5 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
":(){ :|:;}"
prop_readFunctionDefinition6 :: Bool
prop_readFunctionDefinition6 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"?(){ foo; }"
prop_readFunctionDefinition7 :: Bool
prop_readFunctionDefinition7 = ParsecT String UserState (SCBase Identity) Token -> String -> Bool
forall {a}.
ParsecT String UserState (SCBase Identity) a -> String -> Bool
isOk ParsecT String UserState (SCBase Identity) Token
forall {m :: * -> *}.
Monad m =>
ParsecT String UserState (SCBase m) Token
readFunctionDefinition String
"..(){ cd ..; }"
prop_readFunctionDefinition8 :: Bool