Fix #1892: Use pattern synonyms to clean up AST

This commit is contained in:
Joseph C. Sible 2020-03-28 18:29:22 -04:00
parent 37e78141bd
commit 8cf037fe5e
1 changed files with 214 additions and 331 deletions

View File

@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
-} -}
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric, DeriveAnyClass, DeriveTraversable, PatternSynonyms #-}
module ShellCheck.AST where module ShellCheck.AST where
import GHC.Generics (Generic) import GHC.Generics (Generic)
@ -37,110 +37,112 @@ newtype FunctionParentheses = FunctionParentheses Bool deriving (Show, Eq)
data CaseType = CaseBreak | CaseFallThrough | CaseContinue deriving (Show, Eq) data CaseType = CaseBreak | CaseFallThrough | CaseContinue deriving (Show, Eq)
newtype Root = Root Token newtype Root = Root Token
data Token = data Token = OuterToken Id (InnerToken Token) deriving (Show)
TA_Binary Id String Token Token
| TA_Assignment Id String Token Token data InnerToken t =
| TA_Variable Id String [Token] Inner_TA_Binary String t t
| TA_Expansion Id [Token] | Inner_TA_Assignment String t t
| TA_Sequence Id [Token] | Inner_TA_Variable String [t]
| TA_Trinary Id Token Token Token | Inner_TA_Expansion [t]
| TA_Unary Id String Token | Inner_TA_Sequence [t]
| TC_And Id ConditionType String Token Token | Inner_TA_Trinary t t t
| TC_Binary Id ConditionType String Token Token | Inner_TA_Unary String t
| TC_Group Id ConditionType Token | Inner_TC_And ConditionType String t t
| TC_Nullary Id ConditionType Token | Inner_TC_Binary ConditionType String t t
| TC_Or Id ConditionType String Token Token | Inner_TC_Group ConditionType t
| TC_Unary Id ConditionType String Token | Inner_TC_Nullary ConditionType t
| TC_Empty Id ConditionType | Inner_TC_Or ConditionType String t t
| T_AND_IF Id | Inner_TC_Unary ConditionType String t
| T_AndIf Id Token Token | Inner_TC_Empty ConditionType
| T_Arithmetic Id Token | Inner_T_AND_IF
| T_Array Id [Token] | Inner_T_AndIf t t
| T_IndexedElement Id [Token] Token | Inner_T_Arithmetic t
| Inner_T_Array [t]
| Inner_T_IndexedElement [t] t
-- Store the index as string, and parse as arithmetic or string later -- Store the index as string, and parse as arithmetic or string later
| T_UnparsedIndex Id SourcePos String | Inner_T_UnparsedIndex SourcePos String
| T_Assignment Id AssignmentMode String [Token] Token | Inner_T_Assignment AssignmentMode String [t] t
| T_Backgrounded Id Token | Inner_T_Backgrounded t
| T_Backticked Id [Token] | Inner_T_Backticked [t]
| T_Bang Id | Inner_T_Bang
| T_Banged Id Token | Inner_T_Banged t
| T_BraceExpansion Id [Token] | Inner_T_BraceExpansion [t]
| T_BraceGroup Id [Token] | Inner_T_BraceGroup [t]
| T_CLOBBER Id | Inner_T_CLOBBER
| T_Case Id | Inner_T_Case
| T_CaseExpression Id Token [(CaseType, [Token], [Token])] | Inner_T_CaseExpression t [(CaseType, [t], [t])]
| T_Condition Id ConditionType Token | Inner_T_Condition ConditionType t
| T_DGREAT Id | Inner_T_DGREAT
| T_DLESS Id | Inner_T_DLESS
| T_DLESSDASH Id | Inner_T_DLESSDASH
| T_DSEMI Id | Inner_T_DSEMI
| T_Do Id | Inner_T_Do
| T_DollarArithmetic Id Token | Inner_T_DollarArithmetic t
| T_DollarBraced Id Bool Token | Inner_T_DollarBraced Bool t
| T_DollarBracket Id Token | Inner_T_DollarBracket t
| T_DollarDoubleQuoted Id [Token] | Inner_T_DollarDoubleQuoted [t]
| T_DollarExpansion Id [Token] | Inner_T_DollarExpansion [t]
| T_DollarSingleQuoted Id String | Inner_T_DollarSingleQuoted String
| T_DollarBraceCommandExpansion Id [Token] | Inner_T_DollarBraceCommandExpansion [t]
| T_Done Id | Inner_T_Done
| T_DoubleQuoted Id [Token] | Inner_T_DoubleQuoted [t]
| T_EOF Id | Inner_T_EOF
| T_Elif Id | Inner_T_Elif
| T_Else Id | Inner_T_Else
| T_Esac Id | Inner_T_Esac
| T_Extglob Id String [Token] | Inner_T_Extglob String [t]
| T_FdRedirect Id String Token | Inner_T_FdRedirect String t
| T_Fi Id | Inner_T_Fi
| T_For Id | Inner_T_For
| T_ForArithmetic Id Token Token Token [Token] | Inner_T_ForArithmetic t t t [t]
| T_ForIn Id String [Token] [Token] | Inner_T_ForIn String [t] [t]
| T_Function Id FunctionKeyword FunctionParentheses String Token | Inner_T_Function FunctionKeyword FunctionParentheses String t
| T_GREATAND Id | Inner_T_GREATAND
| T_Glob Id String | Inner_T_Glob String
| T_Greater Id | Inner_T_Greater
| T_HereDoc Id Dashed Quoted String [Token] | Inner_T_HereDoc Dashed Quoted String [t]
| T_HereString Id Token | Inner_T_HereString t
| T_If Id | Inner_T_If
| T_IfExpression Id [([Token],[Token])] [Token] | Inner_T_IfExpression [([t],[t])] [t]
| T_In Id | Inner_T_In
| T_IoFile Id Token Token | Inner_T_IoFile t t
| T_IoDuplicate Id Token String | Inner_T_IoDuplicate t String
| T_LESSAND Id | Inner_T_LESSAND
| T_LESSGREAT Id | Inner_T_LESSGREAT
| T_Lbrace Id | Inner_T_Lbrace
| T_Less Id | Inner_T_Less
| T_Literal Id String | Inner_T_Literal String
| T_Lparen Id | Inner_T_Lparen
| T_NEWLINE Id | Inner_T_NEWLINE
| T_NormalWord Id [Token] | Inner_T_NormalWord [t]
| T_OR_IF Id | Inner_T_OR_IF
| T_OrIf Id Token Token | Inner_T_OrIf t t
| T_ParamSubSpecialChar Id String -- e.g. '%' in ${foo%bar} or '/' in ${foo/bar/baz} | Inner_T_ParamSubSpecialChar String -- e.g. '%' in ${foo%bar} or '/' in ${foo/bar/baz}
| T_Pipeline Id [Token] [Token] -- [Pipe separators] [Commands] | Inner_T_Pipeline [t] [t] -- [Pipe separators] [Commands]
| T_ProcSub Id String [Token] | Inner_T_ProcSub String [t]
| T_Rbrace Id | Inner_T_Rbrace
| T_Redirecting Id [Token] Token | Inner_T_Redirecting [t] t
| T_Rparen Id | Inner_T_Rparen
| T_Script Id Token [Token] -- Shebang T_Literal, followed by script. | Inner_T_Script t [t] -- Shebang T_Literal, followed by script.
| T_Select Id | Inner_T_Select
| T_SelectIn Id String [Token] [Token] | Inner_T_SelectIn String [t] [t]
| T_Semi Id | Inner_T_Semi
| T_SimpleCommand Id [Token] [Token] | Inner_T_SimpleCommand [t] [t]
| T_SingleQuoted Id String | Inner_T_SingleQuoted String
| T_Subshell Id [Token] | Inner_T_Subshell [t]
| T_Then Id | Inner_T_Then
| T_Until Id | Inner_T_Until
| T_UntilExpression Id [Token] [Token] | Inner_T_UntilExpression [t] [t]
| T_While Id | Inner_T_While
| T_WhileExpression Id [Token] [Token] | Inner_T_WhileExpression [t] [t]
| T_Annotation Id [Annotation] Token | Inner_T_Annotation [Annotation] t
| T_Pipe Id String | Inner_T_Pipe String
| T_CoProc Id (Maybe String) Token | Inner_T_CoProc (Maybe String) t
| T_CoProcBody Id Token | Inner_T_CoProcBody t
| T_Include Id Token | Inner_T_Include t
| T_SourceCommand Id Token Token | Inner_T_SourceCommand t t
| T_BatsTest Id Token Token | Inner_T_BatsTest t t
deriving (Show) deriving (Show, Eq, Functor, Foldable, Traversable)
data Annotation = data Annotation =
DisableComment Integer DisableComment Integer
@ -151,244 +153,125 @@ data Annotation =
deriving (Show, Eq) deriving (Show, Eq)
data ConditionType = DoubleBracket | SingleBracket deriving (Show, Eq) data ConditionType = DoubleBracket | SingleBracket deriving (Show, Eq)
-- This is an abomination. pattern T_AND_IF id = OuterToken id Inner_T_AND_IF
tokenEquals :: Token -> Token -> Bool pattern T_Bang id = OuterToken id Inner_T_Bang
tokenEquals a b = kludge a == kludge b pattern T_Case id = OuterToken id Inner_T_Case
where kludge s = Re.subRegex (Re.mkRegex "\\(Id [0-9]+\\)") (show s) "(Id 0)" pattern TC_Empty id typ = OuterToken id (Inner_TC_Empty typ)
pattern T_CLOBBER id = OuterToken id Inner_T_CLOBBER
pattern T_DGREAT id = OuterToken id Inner_T_DGREAT
pattern T_DLESS id = OuterToken id Inner_T_DLESS
pattern T_DLESSDASH id = OuterToken id Inner_T_DLESSDASH
pattern T_Do id = OuterToken id Inner_T_Do
pattern T_DollarSingleQuoted id str = OuterToken id (Inner_T_DollarSingleQuoted str)
pattern T_Done id = OuterToken id Inner_T_Done
pattern T_DSEMI id = OuterToken id Inner_T_DSEMI
pattern T_Elif id = OuterToken id Inner_T_Elif
pattern T_Else id = OuterToken id Inner_T_Else
pattern T_EOF id = OuterToken id Inner_T_EOF
pattern T_Esac id = OuterToken id Inner_T_Esac
pattern T_Fi id = OuterToken id Inner_T_Fi
pattern T_For id = OuterToken id Inner_T_For
pattern T_Glob id str = OuterToken id (Inner_T_Glob str)
pattern T_GREATAND id = OuterToken id Inner_T_GREATAND
pattern T_Greater id = OuterToken id Inner_T_Greater
pattern T_If id = OuterToken id Inner_T_If
pattern T_In id = OuterToken id Inner_T_In
pattern T_Lbrace id = OuterToken id Inner_T_Lbrace
pattern T_Less id = OuterToken id Inner_T_Less
pattern T_LESSAND id = OuterToken id Inner_T_LESSAND
pattern T_LESSGREAT id = OuterToken id Inner_T_LESSGREAT
pattern T_Literal id str = OuterToken id (Inner_T_Literal str)
pattern T_Lparen id = OuterToken id Inner_T_Lparen
pattern T_NEWLINE id = OuterToken id Inner_T_NEWLINE
pattern T_OR_IF id = OuterToken id Inner_T_OR_IF
pattern T_ParamSubSpecialChar id str = OuterToken id (Inner_T_ParamSubSpecialChar str)
pattern T_Pipe id str = OuterToken id (Inner_T_Pipe str)
pattern T_Rbrace id = OuterToken id Inner_T_Rbrace
pattern T_Rparen id = OuterToken id Inner_T_Rparen
pattern T_Select id = OuterToken id Inner_T_Select
pattern T_Semi id = OuterToken id Inner_T_Semi
pattern T_SingleQuoted id str = OuterToken id (Inner_T_SingleQuoted str)
pattern T_Then id = OuterToken id Inner_T_Then
pattern T_UnparsedIndex id pos str = OuterToken id (Inner_T_UnparsedIndex pos str)
pattern T_Until id = OuterToken id Inner_T_Until
pattern T_While id = OuterToken id Inner_T_While
pattern TA_Assignment id op t1 t2 = OuterToken id (Inner_TA_Assignment op t1 t2)
pattern TA_Binary id op t1 t2 = OuterToken id (Inner_TA_Binary op t1 t2)
pattern TA_Expansion id t = OuterToken id (Inner_TA_Expansion t)
pattern T_AndIf id t u = OuterToken id (Inner_T_AndIf t u)
pattern T_Annotation id anns t = OuterToken id (Inner_T_Annotation anns t)
pattern T_Arithmetic id c = OuterToken id (Inner_T_Arithmetic c)
pattern T_Array id t = OuterToken id (Inner_T_Array t)
pattern TA_Sequence id l = OuterToken id (Inner_TA_Sequence l)
pattern T_Assignment id mode var indices value = OuterToken id (Inner_T_Assignment mode var indices value)
pattern TA_Trinary id t1 t2 t3 = OuterToken id (Inner_TA_Trinary t1 t2 t3)
pattern TA_Unary id op t1 = OuterToken id (Inner_TA_Unary op t1)
pattern TA_Variable id str t = OuterToken id (Inner_TA_Variable str t)
pattern T_Backgrounded id l = OuterToken id (Inner_T_Backgrounded l)
pattern T_Backticked id list = OuterToken id (Inner_T_Backticked list)
pattern T_Banged id l = OuterToken id (Inner_T_Banged l)
pattern T_BatsTest id name t = OuterToken id (Inner_T_BatsTest name t)
pattern T_BraceExpansion id list = OuterToken id (Inner_T_BraceExpansion list)
pattern T_BraceGroup id l = OuterToken id (Inner_T_BraceGroup l)
pattern TC_And id typ str t1 t2 = OuterToken id (Inner_TC_And typ str t1 t2)
pattern T_CaseExpression id word cases = OuterToken id (Inner_T_CaseExpression word cases)
pattern TC_Binary id typ op lhs rhs = OuterToken id (Inner_TC_Binary typ op lhs rhs)
pattern TC_Group id typ token = OuterToken id (Inner_TC_Group typ token)
pattern TC_Nullary id typ token = OuterToken id (Inner_TC_Nullary typ token)
pattern T_Condition id typ token = OuterToken id (Inner_T_Condition typ token)
pattern T_CoProcBody id t = OuterToken id (Inner_T_CoProcBody t)
pattern T_CoProc id var body = OuterToken id (Inner_T_CoProc var body)
pattern TC_Or id typ str t1 t2 = OuterToken id (Inner_TC_Or typ str t1 t2)
pattern TC_Unary id typ op token = OuterToken id (Inner_TC_Unary typ op token)
pattern T_DollarArithmetic id c = OuterToken id (Inner_T_DollarArithmetic c)
pattern T_DollarBraceCommandExpansion id list = OuterToken id (Inner_T_DollarBraceCommandExpansion list)
pattern T_DollarBraced id braced op = OuterToken id (Inner_T_DollarBraced braced op)
pattern T_DollarBracket id c = OuterToken id (Inner_T_DollarBracket c)
pattern T_DollarDoubleQuoted id list = OuterToken id (Inner_T_DollarDoubleQuoted list)
pattern T_DollarExpansion id list = OuterToken id (Inner_T_DollarExpansion list)
pattern T_DoubleQuoted id list = OuterToken id (Inner_T_DoubleQuoted list)
pattern T_Extglob id str l = OuterToken id (Inner_T_Extglob str l)
pattern T_FdRedirect id v t = OuterToken id (Inner_T_FdRedirect v t)
pattern T_ForArithmetic id a b c group = OuterToken id (Inner_T_ForArithmetic a b c group)
pattern T_ForIn id v w l = OuterToken id (Inner_T_ForIn v w l)
pattern T_Function id a b name body = OuterToken id (Inner_T_Function a b name body)
pattern T_HereDoc id d q str l = OuterToken id (Inner_T_HereDoc d q str l)
pattern T_HereString id word = OuterToken id (Inner_T_HereString word)
pattern T_IfExpression id conditions elses = OuterToken id (Inner_T_IfExpression conditions elses)
pattern T_Include id script = OuterToken id (Inner_T_Include script)
pattern T_IndexedElement id indices t = OuterToken id (Inner_T_IndexedElement indices t)
pattern T_IoDuplicate id op num = OuterToken id (Inner_T_IoDuplicate op num)
pattern T_IoFile id op file = OuterToken id (Inner_T_IoFile op file)
pattern T_NormalWord id list = OuterToken id (Inner_T_NormalWord list)
pattern T_OrIf id t u = OuterToken id (Inner_T_OrIf t u)
pattern T_Pipeline id l1 l2 = OuterToken id (Inner_T_Pipeline l1 l2)
pattern T_ProcSub id typ l = OuterToken id (Inner_T_ProcSub typ l)
pattern T_Redirecting id redirs cmd = OuterToken id (Inner_T_Redirecting redirs cmd)
pattern T_Script id shebang list = OuterToken id (Inner_T_Script shebang list)
pattern T_SelectIn id v w l = OuterToken id (Inner_T_SelectIn v w l)
pattern T_SimpleCommand id vars cmds = OuterToken id (Inner_T_SimpleCommand vars cmds)
pattern T_SourceCommand id includer t_include = OuterToken id (Inner_T_SourceCommand includer t_include)
pattern T_Subshell id l = OuterToken id (Inner_T_Subshell l)
pattern T_UntilExpression id c l = OuterToken id (Inner_T_UntilExpression c l)
pattern T_WhileExpression id c l = OuterToken id (Inner_T_WhileExpression c l)
{-# COMPLETE T_AND_IF, T_Bang, T_Case, TC_Empty, T_CLOBBER, T_DGREAT, T_DLESS, T_DLESSDASH, T_Do, T_DollarSingleQuoted, T_Done, T_DSEMI, T_Elif, T_Else, T_EOF, T_Esac, T_Fi, T_For, T_Glob, T_GREATAND, T_Greater, T_If, T_In, T_Lbrace, T_Less, T_LESSAND, T_LESSGREAT, T_Literal, T_Lparen, T_NEWLINE, T_OR_IF, T_ParamSubSpecialChar, T_Pipe, T_Rbrace, T_Rparen, T_Select, T_Semi, T_SingleQuoted, T_Then, T_UnparsedIndex, T_Until, T_While, TA_Assignment, TA_Binary, TA_Expansion, T_AndIf, T_Annotation, T_Arithmetic, T_Array, TA_Sequence, T_Assignment, TA_Trinary, TA_Unary, TA_Variable, T_Backgrounded, T_Backticked, T_Banged, T_BatsTest, T_BraceExpansion, T_BraceGroup, TC_And, T_CaseExpression, TC_Binary, TC_Group, TC_Nullary, T_Condition, T_CoProcBody, T_CoProc, TC_Or, TC_Unary, T_DollarArithmetic, T_DollarBraceCommandExpansion, T_DollarBraced, T_DollarBracket, T_DollarDoubleQuoted, T_DollarExpansion, T_DoubleQuoted, T_Extglob, T_FdRedirect, T_ForArithmetic, T_ForIn, T_Function, T_HereDoc, T_HereString, T_IfExpression, T_Include, T_IndexedElement, T_IoDuplicate, T_IoFile, T_NormalWord, T_OrIf, T_Pipeline, T_ProcSub, T_Redirecting, T_Script, T_SelectIn, T_SimpleCommand, T_SourceCommand, T_Subshell, T_UntilExpression, T_WhileExpression #-}
instance Eq Token where instance Eq Token where
(==) = tokenEquals OuterToken _ a == OuterToken _ b = a == b
analyze :: Monad m => (Token -> m ()) -> (Token -> m ()) -> (Token -> m Token) -> Token -> m Token analyze :: Monad m => (Token -> m ()) -> (Token -> m ()) -> (Token -> m Token) -> Token -> m Token
analyze f g i = analyze f g i =
round round
where where
round t = do round t@(OuterToken id it) = do
f t f t
newT <- delve t newIt <- traverse round it
g t g t
i newT i (OuterToken id newIt)
roundAll = mapM round
dl l v = do
x <- roundAll l
return $ v x
dll l m v = do
x <- roundAll l
y <- roundAll m
return $ v x y
d1 t v = do
x <- round t
return $ v x
d2 t1 t2 v = do
x <- round t1
y <- round t2
return $ v x y
delve (T_NormalWord id list) = dl list $ T_NormalWord id
delve (T_DoubleQuoted id list) = dl list $ T_DoubleQuoted id
delve (T_DollarDoubleQuoted id list) = dl list $ T_DollarDoubleQuoted id
delve (T_DollarExpansion id list) = dl list $ T_DollarExpansion id
delve (T_DollarBraceCommandExpansion id list) = dl list $ T_DollarBraceCommandExpansion id
delve (T_BraceExpansion id list) = dl list $ T_BraceExpansion id
delve (T_Backticked id list) = dl list $ T_Backticked id
delve (T_DollarArithmetic id c) = d1 c $ T_DollarArithmetic id
delve (T_DollarBracket id c) = d1 c $ T_DollarBracket id
delve (T_IoFile id op file) = d2 op file $ T_IoFile id
delve (T_IoDuplicate id op num) = d1 op $ \x -> T_IoDuplicate id x num
delve (T_HereString id word) = d1 word $ T_HereString id
delve (T_FdRedirect id v t) = d1 t $ T_FdRedirect id v
delve (T_Assignment id mode var indices value) = do
a <- roundAll indices
b <- round value
return $ T_Assignment id mode var a b
delve (T_Array id t) = dl t $ T_Array id
delve (T_IndexedElement id indices t) = do
a <- roundAll indices
b <- round t
return $ T_IndexedElement id a b
delve (T_Redirecting id redirs cmd) = do
a <- roundAll redirs
b <- round cmd
return $ T_Redirecting id a b
delve (T_SimpleCommand id vars cmds) = dll vars cmds $ T_SimpleCommand id
delve (T_Pipeline id l1 l2) = dll l1 l2 $ T_Pipeline id
delve (T_Banged id l) = d1 l $ T_Banged id
delve (T_AndIf id t u) = d2 t u $ T_AndIf id
delve (T_OrIf id t u) = d2 t u $ T_OrIf id
delve (T_Backgrounded id l) = d1 l $ T_Backgrounded id
delve (T_Subshell id l) = dl l $ T_Subshell id
delve (T_ProcSub id typ l) = dl l $ T_ProcSub id typ
delve (T_Arithmetic id c) = d1 c $ T_Arithmetic id
delve (T_IfExpression id conditions elses) = do
newConds <- mapM (\(c, t) -> do
x <- mapM round c
y <- mapM round t
return (x,y)
) conditions
newElses <- roundAll elses
return $ T_IfExpression id newConds newElses
delve (T_BraceGroup id l) = dl l $ T_BraceGroup id
delve (T_WhileExpression id c l) = dll c l $ T_WhileExpression id
delve (T_UntilExpression id c l) = dll c l $ T_UntilExpression id
delve (T_ForIn id v w l) = dll w l $ T_ForIn id v
delve (T_SelectIn id v w l) = dll w l $ T_SelectIn id v
delve (T_CaseExpression id word cases) = do
newWord <- round word
newCases <- mapM (\(o, c, t) -> do
x <- mapM round c
y <- mapM round t
return (o, x,y)
) cases
return $ T_CaseExpression id newWord newCases
delve (T_ForArithmetic id a b c group) = do
x <- round a
y <- round b
z <- round c
list <- mapM round group
return $ T_ForArithmetic id x y z list
delve (T_Script id shebang list) = do
newShebang <- round shebang
newList <- roundAll list
return $ T_Script id newShebang newList
delve (T_Function id a b name body) = d1 body $ T_Function id a b name
delve (T_Condition id typ token) = d1 token $ T_Condition id typ
delve (T_Extglob id str l) = dl l $ T_Extglob id str
delve (T_DollarBraced id braced op) = d1 op $ T_DollarBraced id braced
delve (T_HereDoc id d q str l) = dl l $ T_HereDoc id d q str
delve (TC_And id typ str t1 t2) = d2 t1 t2 $ TC_And id typ str
delve (TC_Or id typ str t1 t2) = d2 t1 t2 $ TC_Or id typ str
delve (TC_Group id typ token) = d1 token $ TC_Group id typ
delve (TC_Binary id typ op lhs rhs) = d2 lhs rhs $ TC_Binary id typ op
delve (TC_Unary id typ op token) = d1 token $ TC_Unary id typ op
delve (TC_Nullary id typ token) = d1 token $ TC_Nullary id typ
delve (TA_Binary id op t1 t2) = d2 t1 t2 $ TA_Binary id op
delve (TA_Assignment id op t1 t2) = d2 t1 t2 $ TA_Assignment id op
delve (TA_Unary id op t1) = d1 t1 $ TA_Unary id op
delve (TA_Sequence id l) = dl l $ TA_Sequence id
delve (TA_Trinary id t1 t2 t3) = do
a <- round t1
b <- round t2
c <- round t3
return $ TA_Trinary id a b c
delve (TA_Expansion id t) = dl t $ TA_Expansion id
delve (TA_Variable id str t) = dl t $ TA_Variable id str
delve (T_Annotation id anns t) = d1 t $ T_Annotation id anns
delve (T_CoProc id var body) = d1 body $ T_CoProc id var
delve (T_CoProcBody id t) = d1 t $ T_CoProcBody id
delve (T_Include id script) = d1 script $ T_Include id
delve (T_SourceCommand id includer t_include) = d2 includer t_include $ T_SourceCommand id
delve (T_BatsTest id name t) = d2 name t $ T_BatsTest id
delve t = return t
getId :: Token -> Id getId :: Token -> Id
getId t = case t of getId (OuterToken id _) = id
T_AND_IF id -> id
T_OR_IF id -> id
T_DSEMI id -> id
T_Semi id -> id
T_DLESS id -> id
T_DGREAT id -> id
T_LESSAND id -> id
T_GREATAND id -> id
T_LESSGREAT id -> id
T_DLESSDASH id -> id
T_CLOBBER id -> id
T_If id -> id
T_Then id -> id
T_Else id -> id
T_Elif id -> id
T_Fi id -> id
T_Do id -> id
T_Done id -> id
T_Case id -> id
T_Esac id -> id
T_While id -> id
T_Until id -> id
T_For id -> id
T_Select id -> id
T_Lbrace id -> id
T_Rbrace id -> id
T_Lparen id -> id
T_Rparen id -> id
T_Bang id -> id
T_In id -> id
T_NEWLINE id -> id
T_EOF id -> id
T_Less id -> id
T_Greater id -> id
T_SingleQuoted id _ -> id
T_Literal id _ -> id
T_NormalWord id _ -> id
T_DoubleQuoted id _ -> id
T_DollarExpansion id _ -> id
T_DollarBraced id _ _ -> id
T_DollarArithmetic id _ -> id
T_BraceExpansion id _ -> id
T_ParamSubSpecialChar id _ -> id
T_DollarBraceCommandExpansion id _ -> id
T_IoFile id _ _ -> id
T_IoDuplicate id _ _ -> id
T_HereDoc id _ _ _ _ -> id
T_HereString id _ -> id
T_FdRedirect id _ _ -> id
T_Assignment id _ _ _ _ -> id
T_Array id _ -> id
T_IndexedElement id _ _ -> id
T_Redirecting id _ _ -> id
T_SimpleCommand id _ _ -> id
T_Pipeline id _ _ -> id
T_Banged id _ -> id
T_AndIf id _ _ -> id
T_OrIf id _ _ -> id
T_Backgrounded id _ -> id
T_IfExpression id _ _ -> id
T_Subshell id _ -> id
T_BraceGroup id _ -> id
T_WhileExpression id _ _ -> id
T_UntilExpression id _ _ -> id
T_ForIn id _ _ _ -> id
T_SelectIn id _ _ _ -> id
T_CaseExpression id _ _ -> id
T_Function id _ _ _ _ -> id
T_Arithmetic id _ -> id
T_Script id _ _ -> id
T_Condition id _ _ -> id
T_Extglob id _ _ -> id
T_Backticked id _ -> id
TC_And id _ _ _ _ -> id
TC_Or id _ _ _ _ -> id
TC_Group id _ _ -> id
TC_Binary id _ _ _ _ -> id
TC_Unary id _ _ _ -> id
TC_Nullary id _ _ -> id
TA_Binary id _ _ _ -> id
TA_Assignment id _ _ _ -> id
TA_Unary id _ _ -> id
TA_Sequence id _ -> id
TA_Trinary id _ _ _ -> id
TA_Expansion id _ -> id
T_ProcSub id _ _ -> id
T_Glob id _ -> id
T_ForArithmetic id _ _ _ _ -> id
T_DollarSingleQuoted id _ -> id
T_DollarDoubleQuoted id _ -> id
T_DollarBracket id _ -> id
T_Annotation id _ _ -> id
T_Pipe id _ -> id
T_CoProc id _ _ -> id
T_CoProcBody id _ -> id
T_Include id _ -> id
T_SourceCommand id _ _ -> id
T_UnparsedIndex id _ _ -> id
TC_Empty id _ -> id
TA_Variable id _ _ -> id
T_BatsTest id _ _ -> id
blank :: Monad m => Token -> m () blank :: Monad m => Token -> m ()
blank = const $ return () blank = const $ return ()