syntax(sh): Improve the recognition of bracket expressions

- Define a general non-"contained" "shBracketExpr" group,
  and replace with it the "contained" bracket variant of
  "shOperator", adjusting the patterns for the competing
  conditional commands "[" and "[[".
- Accommodate some unbalanced brackets (e.g. "[!][!]").
- Make the leading "!" (or "^") stand out in NON-matching
  bracket expressions.
- Support literal newlines in parametric patterns (along
  with pathname globbings and "case" patterns).
- Also match bracket expressions in:
  * parametric patterns (e.g. "${1#[ab]_}");
  * pathname globbings (e.g. "[ab]*.txt");
  * arguments for the "[[", "echo", and "print" commands.
- Recognise collating symbols (e.g. "[.a.]") and equivalence
  classes (e.g. "[=a=]").
- Recognise end patterns for a pattern substitution form of
  parameter expansion and match bracket expressions in such
  patterns (e.g. "${1/%[.!]/;}").

fixes #15799
closes: #15941

References:
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap09.html#tag_09_03_05
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_14
https://git.savannah.gnu.org/gitweb/?p=bash.git;a=blob_plain;f=doc/bash.html;hb=37b7e91d64ad10b1a1815d12128c9475636df670
http://www.mirbsd.org/htman/i386/man1/mksh.htm

Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim
index 97e74d2..0a8fb47 100644
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -4,6 +4,7 @@
 " Previous Maintainers:	Charles E. Campbell
 " 		Lennart Schultz <Lennart.Schultz@ecmwf.int>
 " Last Change:		2024 Mar 04 by Vim Project
+"		2024 Nov 03 by Aliaksei Budavei <0x000c70 AT gmail DOT com> (improved bracket expressions, #15941)
 " Version:		208
 " Former URL:		http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
 " For options and settings, please use:      :help ft-sh-syntax
@@ -127,6 +128,50 @@
  com! -nargs=* ShFoldIfDoFor <args>
 endif
 
+" Generate bracket expression items {{{1
+" =================================
+" Note that the following function can be invoked as many times as necessary
+" provided that these constraints hold for the passed dictionary argument:
+" - every time a unique group-name value is assigned to the "itemGroup" key;
+" - only ONCE either the "extraArgs" key is not entered or it is entered and
+"   its value does not have "contained" among other optional arguments (":help
+"   :syn-arguments").
+fun! s:GenerateBracketExpressionItems(dict) abort
+ let itemGroup = a:dict.itemGroup
+ let bracketGroup = a:dict.bracketGroup
+ let invGroup = itemGroup . 'Inv'
+ let skipLeftBracketGroup = itemGroup . 'SkipLeftBracket'
+ let skipRightBracketGroup = itemGroup . 'SkipRightBracket'
+ let extraArgs = has_key(a:dict, 'extraArgs') ? a:dict.extraArgs : ''
+
+ " Make the leading "[!^]" stand out in a NON-matching expression.
+ exec 'syn match ' . invGroup . ' contained "\[\@<=[!^]"'
+
+ " Set up indirections for unbalanced-bracket highlighting.
+ exec 'syn region ' . skipRightBracketGroup . ' contained matchgroup=' . bracketGroup . ' start="\[\%([!^]\=\\\=\]\)\@=" matchgroup=shCollSymb end="\[\.[^]]\{-}\][^]]\{-}\.\]" matchgroup=' . itemGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . invGroup
+ exec 'syn region ' . skipLeftBracketGroup . ' contained matchgroup=' . bracketGroup . ' start="\[\%([!^]\=\\\=\]\)\@=" skip="[!^]\=\\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\%(\[[:.=]\@!\)\@=" matchgroup=' . itemGroup . ' end="\[[:.=]\@!" contains=@shBracketExprList,shDoubleQuote,' . invGroup
+
+ " Look for a general matching expression.
+ exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' start="\[\S\@=" end="\]" contains=@shBracketExprList,shDoubleQuote ' . extraArgs
+ " Look for a general NON-matching expression.
+ exec 'syn region ' . itemGroup . ' matchgroup=' . bracketGroup . ' start="\[[!^]\@=" end="\]" contains=@shBracketExprList,shDoubleQuote,' . invGroup . ' ' . extraArgs
+
+ " Accommodate unbalanced brackets in bracket expressions.  The supported
+ " syntax for a plain "]" can be: "[]ws]" and "[^]ws]"; or, "[ws[.xs]ys.]zs]"
+ " and "[^ws[.xs]ys.]zs]"; see §9.3.5 RE Bracket Expression (in XBD).
+ exec 'syn region ' . itemGroup . ' matchgroup=NONE start="\[[!^]\=\\\=\]" matchgroup=' . bracketGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . skipRightBracketGroup . ' ' . extraArgs
+ " Strive to handle "[]...[]" etc.
+ exec 'syn region ' . itemGroup . ' matchgroup=NONE start="\[[!^]\=\\\=\]\%(\[[^]]\+\]\|[^]]\)\{-}\[[:.=]\@!" matchgroup=' . bracketGroup . ' end="\]" contains=@shBracketExprList,shDoubleQuote,' . skipLeftBracketGroup . ' ' . extraArgs
+
+ if !exists("g:skip_sh_syntax_inits")
+  exec 'hi def link ' . skipLeftBracketGroup . ' ' . itemGroup
+  exec 'hi def link ' . skipRightBracketGroup . ' ' . itemGroup
+  exec 'hi def link ' . invGroup . ' Underlined'
+ endif
+endfun
+
+call s:GenerateBracketExpressionItems({'itemGroup': 'shBracketExpr', 'bracketGroup': 'shBracketExprDelim'})
+
 " sh syntax is case sensitive {{{1
 syn case match
 
@@ -136,23 +181,24 @@
 if exists("b:is_kornshell") || exists("b:is_bash")
  syn cluster ErrorList add=shDTestError
 endif
-syn cluster shArithParenList	contains=shArithmetic,shArithParen,shCaseEsac,shComment,shDeref,shDo,shDerefSimple,shEcho,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shExDoubleQuote,shHereString,shRedir,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen,bashSpecialVariables,bashStatement,shIf,shFor,shFunctionKey,shFunctionOne,shFunctionTwo
+syn cluster shArithParenList	contains=shArithmetic,shArithParen,shCaseEsac,shComment,shDeref,shDerefVarArray,shDo,shDerefSimple,shEcho,shEscape,shExpr,shNumber,shOperator,shPosnParm,shExSingleQuote,shExDoubleQuote,shHereString,shRedir,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen,bashSpecialVariables,bashStatement,shIf,shFor,shFunctionKey,shFunctionOne,shFunctionTwo
 syn cluster shArithList	contains=@shArithParenList,shParenError
+syn cluster shBracketExprList	contains=shCharClassOther,shCharClass,shCollSymb,shEqClass
 syn cluster shCaseEsacList	contains=shCaseStart,shCaseLabel,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial,shCaseRange
 syn cluster shCaseList	contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shComment,shDblBrace,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
 if exists("b:is_kornshell") || exists("b:is_bash")
  syn cluster shCaseList	add=shForPP,shDblParen
 endif
-syn cluster shCommandSubList	contains=shAlias,shArithmetic,shCmdParenRegion,shCommandSub,shComment,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
+syn cluster shCommandSubList	contains=shAlias,shArithmetic,shBracketExpr,shCmdParenRegion,shCommandSub,shComment,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
 syn cluster shCurlyList	contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
 " COMBAK: removing shEscape from shDblQuoteList fails ksh04:43 -- Jun 09, 2022: I don't see the problem with ksh04, so am reinstating shEscape
 syn cluster shDblQuoteList	contains=shArithmetic,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shPosnParm,shCtrlSeq,shSpecial,shSpecialDQ
 syn cluster shDerefList	contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPSR,shDerefPPS
 syn cluster shDerefVarList	contains=shDerefOffset,shDerefOp,shDerefVarArray,shDerefOpError
-syn cluster shEchoList	contains=shArithmetic,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
-syn cluster shExprList1	contains=shCharClass,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
+syn cluster shEchoList	contains=shArithmetic,shBracketExpr,shCommandSub,shCommandSubBQ,shDerefVarArray,shSubshare,shValsub,shDeref,shDerefSimple,shEscape,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
+syn cluster shExprList1	contains=shBracketExpr,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
 syn cluster shExprList2	contains=@shExprList1,@shCaseList,shTest
-syn cluster shFunctionList	contains=@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
+syn cluster shFunctionList	contains=shBracketExpr,@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
 if exists("b:is_kornshell") || exists("b:is_bash")
  syn cluster shFunctionList	add=shRepeat,shDblBrace,shDblParen,shForPP
  syn cluster shDerefList	add=shCommandSubList,shEchoDeref
@@ -160,16 +206,16 @@
 syn cluster shHereBeginList	contains=@shCommandSubList
 syn cluster shHereList	contains=shBeginHere,shHerePayload
 syn cluster shHereListDQ	contains=shBeginHere,@shDblQuoteList,shHerePayload
-syn cluster shIdList	contains=shArithmetic,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shWrapLineOperator,shSetOption,shComment,shDeref,shDerefSimple,shHereString,shNumber,shOperator,shRedir,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial,shAtExpr
+syn cluster shIdList	contains=shArithmetic,shCommandSub,shCommandSubBQ,shDerefVarArray,shSubshare,shValsub,shWrapLineOperator,shSetOption,shComment,shDeref,shDerefSimple,shHereString,shNumber,shOperator,shRedir,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial,shAtExpr
 syn cluster shIfList	contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey,shFunctionOne,shFunctionTwo
 syn cluster shLoopList	contains=@shCaseList,@shErrorList,shCaseEsac,shConditional,shDblBrace,shExpr,shFor,shIf,shOption,shSet,shTest,shTestOpr,shTouch
 if exists("b:is_kornshell") || exists("b:is_bash")
  syn cluster shLoopList	add=shForPP,shDblParen
 endif
-syn cluster shPPSLeftList	contains=shAlias,shArithmetic,shCmdParenRegion,shCommandSub,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
+syn cluster shPPSLeftList	contains=shAlias,shArithmetic,shBracketExpr,shCmdParenRegion,shCommandSub,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
 syn cluster shPPSRightList	contains=shDeref,shDerefSimple,shEscape,shPosnParm
-syn cluster shSubShList	contains=@shCommandSubList,shCommandSubBQ,shSubshare,shValsub,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator
-syn cluster shTestList	contains=shArithmetic,shCharClass,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shSpecialDQ,shExDoubleQuote,shExpr,shExSingleQuote,shNumber,shOperator,shSingleQuote,shTest,shTestOpr
+syn cluster shSubShList	contains=shBracketExpr,@shCommandSubList,shCommandSubBQ,shSubshare,shValsub,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator
+syn cluster shTestList	contains=shArithmetic,shBracketExpr,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shSpecialDQ,shExDoubleQuote,shExpr,shExSingleQuote,shNumber,shOperator,shSingleQuote,shTest,shTestOpr
 syn cluster shNoZSList	contains=shSpecialNoZS
 syn cluster shForList	contains=shTestOpr,shNumber,shDerefSimple,shDeref,shCommandSub,shCommandSubBQ,shSubshare,shValsub,shArithmetic
 
@@ -190,7 +236,7 @@
 syn match  shEchoQuote contained	'\%(\\\\\)*\\["`'()]'
 
 " This must be after the strings, so that ... \" will be correct
-syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="\s#"me=e-2 contains=shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shOperator,shExDoubleQuote,shDoubleQuote,shCharClass,shCtrlSeq
+syn region shEmbeddedEcho contained matchgroup=shStatement start="\<print\>" skip="\\$" matchgroup=shEchoDelim end="$" matchgroup=NONE end="[<>;&|`)]"me=e-1 end="\d[<>]"me=e-2 end="\s#"me=e-2 contains=shBracketExpr,shNumber,shExSingleQuote,shSingleQuote,shDeref,shDerefSimple,shSpecialVar,shOperator,shExDoubleQuote,shDoubleQuote,shCtrlSeq
 
 " Alias: {{{1
 " =====
@@ -240,7 +286,6 @@
 " ==========
 syn match   shOperator	"<<\|>>"		contained
 syn match   shOperator	"[!&;|]"		contained
-syn match   shOperator	"\[[[^:]\|\]]"		contained
 syn match   shOperator	"[-=/*+%]\=="		skipwhite nextgroup=shPattern
 syn match   shPattern	"\<\S\+\())\)\@="	contained contains=shExSingleQuote,shSingleQuote,shExDoubleQuote,shDoubleQuote,shDeref
 
@@ -251,9 +296,9 @@
 
 " Tests: {{{1
 "=======
-syn region shExpr	matchgroup=shRange start="\[" skip=+\\\\\|\\$\|\[+ end="\]" contains=@shTestList,shSpecial
+syn region shExpr	matchgroup=shRange start="\[\s\@=" skip=+\\\\\|\\$\|\[+ end="\]" contains=@shTestList,shSpecial
 syn region shTest	transparent matchgroup=shStatement start="\<test\s" skip=+\\\\\|\\$+ matchgroup=NONE end="[;&|]"me=e-1 end="$" contains=@shExprList1
-syn region shNoQuote	start='\S'	skip='\%(\\\\\)*\\.'	end='\ze\s' end="\ze['"]"	contained contains=shDerefSimple,shDeref
+syn region shNoQuote	start='\S'	skip='\%(\\\\\)*\\.'	end='\ze\s' end="\ze['"]"	contained contains=shBracketExpr,shDerefSimple,shDeref
 syn match  shAstQuote	contained	'\*\ze"'	nextgroup=shString
 syn match  shTestOpr	contained	'[^-+/%]\zs=' skipwhite nextgroup=shTestDoubleQuote,shTestSingleQuote,shTestPattern
 syn match  shTestOpr	contained	"<=\|>=\|!=\|==\|=\~\|-.\>\|-\(nt\|ot\|ef\|eq\|ne\|lt\|le\|gt\|ge\)\>\|[!<>]"
@@ -262,13 +307,16 @@
 syn match  shTestSingleQuote	contained	'\\.'	nextgroup=shTestSingleQuote
 syn match  shTestSingleQuote	contained	"'[^']*'"
 if exists("b:is_kornshell") || exists("b:is_bash")
- syn region  shDblBrace matchgroup=Delimiter start="\[\["	skip=+\%(\\\\\)*\\$+ end="\]\]"	contains=@shTestList,shAstQuote,shNoQuote,shComment
+ syn region  shDblBrace matchgroup=Delimiter start="\[\[\s\@="	skip=+\%(\\\\\)*\\$+ end="\]\]"	contains=@shTestList,shAstQuote,shNoQuote,shComment
  syn region  shDblParen matchgroup=Delimiter start="(("	skip=+\%(\\\\\)*\\$+ end="))"	contains=@shTestList,shComment
 endif
 
 " Character Class In Range: {{{1
 " =========================
+syn match   shCharClassOther	contained	"\[:\w\{-}:\]"
 syn match   shCharClass	contained	"\[:\(backspace\|escape\|return\|xdigit\|alnum\|alpha\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|tab\):\]"
+syn match   shCollSymb	contained	"\[\..\{-}\.\]"
+syn match   shEqClass	contained	"\[=.\{-}=\]"
 
 " Loops: do, if, while, until {{{1
 " ======
@@ -298,7 +346,7 @@
 " ====
 syn match shCaseBar	contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|"		nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
 syn match shCaseStart	contained skipwhite skipnl "("			nextgroup=shCase,shCaseBar
-syn match shCaseLabel	contained skipwhite	"\%(\\.\|[-a-zA-Z0-9_*.]\)\+"	contains=shCharClass
+syn match shCaseLabel	contained skipwhite	"\%(\\.\|[-a-zA-Z0-9_*.]\)\+"	contains=shBracketExpr
 if exists("b:is_bash")
  ShFoldIfDoFor syn region	shCase	contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)"  end=";;" end=";&" end=";;&" end="esac"me=s-1	contains=@shCaseList	nextgroup=shCaseStart,shCase,shComment
 elseif exists("b:is_kornshell")
@@ -317,11 +365,9 @@
 syn region  shCaseSingleQuote	matchgroup=shQuote start=+'+ end=+'+		contains=shStringSpecial		skipwhite skipnl nextgroup=shCaseBar	contained
 syn region  shCaseDoubleQuote	matchgroup=shQuote start=+"+ skip=+\\\\\|\\.+ end=+"+	contains=@shDblQuoteList,shStringSpecial	skipwhite skipnl nextgroup=shCaseBar	contained
 syn region  shCaseCommandSub	start=+`+ skip=+\\\\\|\\.+ end=+`+		contains=@shCommandSubList		skipwhite skipnl nextgroup=shCaseBar	contained
+call s:GenerateBracketExpressionItems({'itemGroup': 'shCaseRange', 'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'skip=+\\\\+ contained'})
 if exists("b:is_bash")
- syn region  shCaseRange	matchgroup=Delimiter start=+\[+ skip=+\\\\+ end=+\]+	contained	contains=shCharClass
  syn match   shCharClass	'\[:\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|or\|xdigit\):\]'			contained
-else
- syn region  shCaseRange	matchgroup=Delimiter start=+\[+ skip=+\\\\+ end=+\]+	contained
 endif
 " Misc: {{{1
 "======
@@ -453,7 +499,18 @@
 "=============
 syn match  shSetOption	"\s\zs[-+][a-zA-Z0-9]\+\>"	contained
 syn match  shVariable	"\<\h\w*\ze="			nextgroup=shVarAssign
-syn match  shVarAssign	"="		contained	nextgroup=shCmdParenRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
+if exists("b:is_bash")
+ " The subscript form for array values, e.g. "foo=([2]=10 [4]=100)".
+ syn region shArrayValue	contained	start="\[\%(..\{-}\]=\)\@=" end="\]=\@="	contains=@shArrayValueList nextgroup=shVarAssign
+ syn cluster shArrayValueList	contains=shArithmetic,shArithParen,shCommandSub,shDeref,shDerefSimple,shExpr,shNumber,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shSpecial,shParen,bashSpecialVariables,shParenError
+endif
+if exists("b:is_bash") || exists("b:is_kornshell")
+ syn match shVariable	"\<\h\w*\%(\[..\{-}\]\)\=\ze\%([|^&*/%+-]\|[<^]<\|[>^]>\)\=="	contains=shDerefVarArray nextgroup=shVarAssign
+ syn match shVarAssign	contained	"\%([|^&*/%+-]\|[<^]<\|[>^]>\)\=="	nextgroup=shArrayRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
+ syn region shArrayRegion	contained matchgroup=shShellVariables start="(" skip='\\\\\|\\.' end=")" contains=@shArrayValueList,shArrayValue,shComment
+else
+ syn match  shVarAssign	contained	"="	nextgroup=shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote,shVar
+endif
 syn match  shVar	contained	"\h\w*"
 syn region shAtExpr	contained	start="@(" end=")" contains=@shIdList
 if exists("b:is_bash")
@@ -571,8 +628,11 @@
 if exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix")
  syn match  shDerefOp	contained	"#\{1,2}"		nextgroup=@shDerefPatternList
  syn match  shDerefOp	contained	"%\{1,2}"		nextgroup=@shDerefPatternList
- syn match  shDerefPattern	contained	"[^{}]\+"		contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern
+ syn match  shDerefPattern	contained	"[^{}]\+"		contains=shDeref,shDerefSimple,shDerefPattern,shDerefString,shCommandSub,shDerefEscape nextgroup=shDerefPattern skipnl
  syn region shDerefPattern	contained	start="{" end="}"	contains=shDeref,shDerefSimple,shDerefString,shCommandSub nextgroup=shDerefPattern
+ " Match parametric bracket expressions with a leading whitespace character.
+ syn region shDerefPattern	contained	matchgroup=shBracketExprDelim start="\[" end="\]"	contains=@shBracketExprList,shDoubleQuote nextgroup=shDerefPattern
+ call s:GenerateBracketExpressionItems({'itemGroup': 'shDerefPattern', 'bracketGroup': 'shBracketExprDelim', 'extraArgs': 'contained nextgroup=shDerefPattern'})
  syn match  shDerefEscape	contained	'\%(\\\\\)*\\.'
 endif
 if exists("b:is_bash")
@@ -592,15 +652,16 @@
 endif
 
 if exists("b:is_bash")
+ " bash : ${parameter/pattern/string}
  " bash : ${parameter//pattern/string}
- " bash : ${parameter//pattern}
  syn match  shDerefPPS	contained	'/\{1,2}'	nextgroup=shDerefPPSleft
  syn region shDerefPPSleft	contained	start='.'	skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp	end='/' end='\ze}' end='"'	nextgroup=shDerefPPSright	contains=@shPPSLeftList
  syn region shDerefPPSright	contained	start='.'	skip=@\%(\\\\\)\+@		end='\ze}'				contains=@shPPSRightList
 
- " bash : ${parameter/#substring/replacement}
- syn match  shDerefPSR	contained	'/#'	nextgroup=shDerefPSRleft,shDoubleQuote,shSingleQuote
- syn region shDerefPSRleft	contained	start='[^"']'	skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp	end='/' end='\ze}'	nextgroup=shDerefPSRright
+ " bash : ${parameter/#pattern/string}
+ " bash : ${parameter/%pattern/string}
+ syn match  shDerefPSR	contained	'/[#%]'	nextgroup=shDerefPSRleft,shDoubleQuote,shSingleQuote
+ syn region shDerefPSRleft	contained	start='[^"']'	skip=@\%(\\\\\)*\\/@ matchgroup=shDerefOp	end='/' end='\ze}'	nextgroup=shDerefPSRright	contains=shBracketExpr
  syn region shDerefPSRright	contained	start='.'	skip=@\%(\\\\\)\+@		end='\ze}'
 endif
 
@@ -670,6 +731,7 @@
 " =====================
 if !exists("skip_sh_syntax_inits")
  hi def link shArithRegion	shShellVariables
+ hi def link shArrayValue	shDeref
  hi def link shAstQuote	shDoubleQuote
  hi def link shAtExpr	shSetList
  hi def link shBkslshSnglQuote	shSingleQuote
@@ -764,7 +826,10 @@
  endif
 
  hi def link shArithmetic		Special
+ hi def link shBracketExprDelim		Delimiter
  hi def link shCharClass		Identifier
+ hi def link shCollSymb		shCharClass
+ hi def link shEqClass		shCharClass
  hi def link shSnglCase		Statement
  hi def link shCommandSub		Special
  hi def link shCommandSubBQ		shCommandSub
@@ -814,6 +879,10 @@
 delc ShFoldHereDoc
 delc ShFoldIfDoFor
 
+" Delete the bracket expression function {{{1
+" ======================================
+delfun s:GenerateBracketExpressionItems
+
 " Set Current Syntax: {{{1
 " ===================
 if exists("b:is_bash")
diff --git a/runtime/syntax/testdir/dumps/sh_04_01.dump b/runtime/syntax/testdir/dumps/sh_04_01.dump
index 5a0ebe8..c536106 100644
--- a/runtime/syntax/testdir/dumps/sh_04_01.dump
+++ b/runtime/syntax/testdir/dumps/sh_04_01.dump
@@ -7,14 +7,14 @@
 |#+0#0000e05&| |T|h|i|s| |i|s| |O|K| +0#0000000&@62
 |:+0#0000e05&| +0#0000000&|$+0#e000e06&|{|V|a|r|i|a|b|l|e|B|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|C|:+0#af5f00255&|-|e+0#0000000&|n|g|}+0#e000e06&@1| +0#0000000&@41
 |:+0#0000e05&| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|{|V|a|r|i|a|b|l|e|B|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|C|:+0#af5f00255&|-|e+0#0000000&|n|g|}+0#e000e06&@1|"+0#af5f00255&| +0#0000000&@39
-@75
-|#+0#0000e05&| |F|i|r|s|t| |l|i|n|e| |i|s| |O|K| |e|x|c|e|p|t| |i|t|s| |m|i|s@1|i|n|g| |a| |c|l|o|s|i|n|g| |"|}|"|,| +0#0000000&@22
-|#+0#0000e05&| |s|o| |s|e|c|o|n|d| |l|i|n|e| |s|h|o|u|l|d| |h|a|v|e| |s|o|m|e| |e|r@1|o|r| |h|i|g|h|l|i|g|h|t|i|n|g| +0#0000000&@22
-|V+0#00e0e07&|a|r|i|a|b|l|e|=+0#0000000&|$+0#e000e06&|{|V|a|r|i|a|b|l|e|B|:+0#af5f00255&|=|$+0#e000e06&|{|V|a|r|i|a|b|l|e|C|:+0#af5f00255&|=|{+0#0000000&|V|a|r|3|:|=|$+0#e000e06&|{|V|a|r|4|:+0#af5f00255&|-|e+0#0000000&|n|g|}+0#e000e06&|}+0#0000000&|}+0#e000e06&| +0#0000000&@18
-|V+0#ffffff16#ff404010|a|r|i|a|b|l|e|=|$+0#e000e06#ffffff0|{|V|a|r|i|a|b|l|e|B|:+0#af5f00255&|-|$+0#e000e06&|{|V|a|r|i|a|b|l|e|C|:+0#af5f00255&|-|{+0#0000000&|V|a|r|3|:|=|e|n|g|}|}+0#e000e06&| +0#0000000&@27
 |~+0#4040ff13&| @73
 |~| @73
 |~| @73
 |~| @73
 |~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
 | +0#0000000&@56|1|9|,|0|-|1| @7|B|o|t| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_00.dump b/runtime/syntax/testdir/dumps/sh_12_00.dump
new file mode 100644
index 0000000..d2d9928
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_00.dump
@@ -0,0 +1,20 @@
+>#+0#0000e05#ffffff0|!|/|b|i|n|/|b|a|s|h| +0#0000000&@63
+|#+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |h|i|g|h|l|i|g|h|t| |l|i|n|k| |s|h|A|r@1|a|y|V|a|l|u|e| |I|d|e|n|t|i|f|i|e|r| +0#0000000&@19
+|#+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |h|i|g|h|l|i|g|h|t| |l|i|n|k| |s|h|B|r|a|c|k|e|t|E|x|p|r|D|e|l|i|m| |S|t|r|u|c|t|u|r|e| +0#0000000&@14
+|#+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |h|i|g|h|l|i|g|h|t| |l|i|n|k| |s|h|C|h|a|r|C|l|a|s@1| |T|o|d|o| +0#0000000&@26
+|#+0#0000e05&| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |h|i|g|h|l|i|g|h|t| |l|i|n|k| |s|h|R|a|n|g|e| |C|u|r|s|o|r|L|i|n|e| +0#0000000&@24
+@75
+@75
+@75
+@75
+|[+0#e000e06&@1| +0#0000000&|(+0#e000002&| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&|=+0#af5f00255&@1| +0#0000000&|?+0#e000002&|(|-|)|+|(|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|)+0#e000002&| +0#0000000&|&+0#e000002&@1| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&|=+0#af5f00255&|~| +0#0000000&|^+0#e000002&|-|?|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|++0#e000002&|$| +0#0000000&|&+0#e000002&@1| +0#0000000&@18
+|'+0#af5f00255&|^+0#e000002&|?|(|-|)|+|(|[@1|:|d|i|g|i|t|:|]@1|)|$|'+0#af5f00255&| +0#0000000&|=+0#af5f00255&@1| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| +0#0000000&|&+0#e000002&@1| +0#0000000&|!+0#af5f00255&| +0#0000000&|"+0#af5f00255&|^+0#e000002&|-|?|[|0|-|9|]|+|$|"+0#af5f00255&| +0#0000000&|=+0#af5f00255&|~| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| +0#0000000&|)+0#e000002&| +0#0000000&|]+0#e000e06&@1| +0#0000000&||@1| |:| @8
+@75
+|[+8&&| +0&&|\+0#e000e06&|(| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&|!+0#af5f00255&|=| +0#0000000&|"+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[|0|-|9|]|)|"+0#af5f00255&| +0#0000000&|-+0#af5f00255&|a| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&|!+0#af5f00255&|=| +0#0000000&|'+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[@1|:|d|i|g|i|t|:|]@1|)|'+0#af5f00255&| +0#0000000&|\+0#e000e06&|)| +0#0000000&|]+8&&| +0&&|&@1| @7
+|[+8&&| +0&&|\+0#e000e06&|(| +0#0000000&|"+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[@1|:|d|i|g|i|t|:|]@1|)|"+0#af5f00255&| +0#0000000&|!+0#af5f00255&|=| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| +0#0000000&|-+0#af5f00255&|a| +0#0000000&|'+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[|0|-|9|]|)|'+0#af5f00255&| +0#0000000&|!+0#af5f00255&|=| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| +0#0000000&|\+0#e000e06&|)| +0#0000000&|]+8&&| +0&&||@1| |:| @5
+@75
+|#+0#0000e05&| |M|a|t|c|h| |"|\|[|0|\|]|\|[|0|\|]|"|,| |"|{|0|}|{|0|}|"|,| |e|t|c|.| +0#0000000&@38
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@38
+|:| |[+0#00e0003&|\+0#0000000&| @70
+|[|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@41
+|i|s|_|b|a|s|h|:| |1|,| @45|1|,|1| @10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_01.dump b/runtime/syntax/testdir/dumps/sh_12_01.dump
new file mode 100644
index 0000000..fbc0082
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_01.dump
@@ -0,0 +1,20 @@
+|[+8&#ffffff0| +0&&|\+0#e000e06&|(| +0#0000000&|"+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[@1|:|d|i|g|i|t|:|]@1|)|"+0#af5f00255&| +0#0000000&|!+0#af5f00255&|=| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| +0#0000000&|-+0#af5f00255&|a| +0#0000000&|'+0#af5f00255&|?+0#e000002&|(|-|)|+|(|[|0|-|9|]|)|'+0#af5f00255&| +0#0000000&|!+0#af5f00255&|=| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|2|"+0#af5f00255&| +0#0000000&|\+0#e000e06&|)| +0#0000000&|]+8&&| +0&&||@1| |:| @5
+@75
+|#+0#0000e05&| |M|a|t|c|h| |"|\|[|0|\|]|\|[|0|\|]|"|,| |"|{|0|}|{|0|}|"|,| |e|t|c|.| +0#0000000&@38
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@38
+|:| |[+0#00e0003&|\+0#0000000&| @70
+>[|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@41
+|:| |[+0#00e0003&|[+0#0000000&|\| @69
+|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@42
+|:| |[+0#00e0003&|[+0#0000000&|{|\| @68
+|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@43
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|\+0#af5f00255&| +0#0000000&@67
+|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@44
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&| @66
+|0|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@45
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|\| @63
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@48
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|\+0#af5f00255&| +0#0000000&@62
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@49
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|\+0#af5f00255&| +0#0000000&@61
+@57|1|9|,|1| @10|6|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_02.dump b/runtime/syntax/testdir/dumps/sh_12_02.dump
new file mode 100644
index 0000000..a2cfb6c
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_02.dump
@@ -0,0 +1,20 @@
+|:+0&#ffffff0| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|\+0#af5f00255&| +0#0000000&@61
+|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@50
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\| @59
+|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@52
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\| @58
+>]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@53
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|\+0#af5f00255&| +0#0000000&@57
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@54
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|\+0#0000000&| @56
+|[|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@55
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|\| @55
+|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@56
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|\| @54
+|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@57
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|\+0#af5f00255&| +0#0000000&@53
+|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@58
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&| @52
+|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@59
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|\+0#0000000#ffffff0| @43
+@57|3|7|,|1| @9|1|6|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_03.dump b/runtime/syntax/testdir/dumps/sh_12_03.dump
new file mode 100644
index 0000000..e1e9af7
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_03.dump
@@ -0,0 +1,20 @@
+|:+0&#ffffff0| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|\+0#0000000#ffffff0| @43
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@68
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|\+0#af5f00255&| +0#0000000&@42
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@69
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|\+0#af5f00255&| +0#0000000&@41
+>[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&| +0#0000000&@70
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\| @39
+|}|]+0#00e0003&| +0#0000000&@72
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\| @38
+|]+0#00e0003&| +0#0000000&@73
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&| +0#0000000&@34
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|\+0#0000000&| @40
+|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&| +0#0000000&@67
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|\+0#0000000#ffffff0| @35
+|}|]+0#00e0003&| +0#0000000&@72
+|:| |[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|\| @34
+|]+0#00e0003&| +0#0000000&@73
+@75
+|#+0#0000e05&| |M|a|t|c|h| |"|\|[|0|\|]|\|[|0|\|]|"|,| |"|{|0|}|{|0|}|"|,| |e|t|c|.| +0#0000000&@38
+@57|5@1|,|1| @9|2|6|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_04.dump b/runtime/syntax/testdir/dumps/sh_12_04.dump
new file mode 100644
index 0000000..535ca23
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_04.dump
@@ -0,0 +1,20 @@
+|#+0#0000e05#ffffff0| |M|a|t|c|h| |"|\|[|0|\|]|\|[|0|\|]|"|,| |"|{|0|}|{|0|}|"|,| |e|t|c|.| +0#0000000&@38
+|c+0#af5f00255&|a|s|e| +0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&|i+0#af5f00255&|n| +0#0000000&@62
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|!+8#e000e06&|0+0#0000000&|-|9|]+0#00e0003&|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|^+8#e000e06&|0+0#0000000&|-|9|]+0#00e0003&|;+0#af5f00255&@1| +0#0000000&@8
+|[+0#00e0003&|\+0#0000000&| @72
+|[|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|0+0#0000000&|1|2|3|]+0#00e0003&|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|!+8#e000e06&|0+0#0000000&|1|2|3|]+0#00e0003&|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|^+8#e000e06&|0+0#0000000&|1|2|3|]+0#00e0003&|;+0#af5f00255&@1| +0#0000000&@6
+>[+0#00e0003&|[+0#0000000&|\| @71
+|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|1+0#0000000&|[+0#0000001#ffff4012|.|0|.|]|]+0#00e0003#ffffff0|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|!+8#e000e06&|[+0#0000001#ffff4012|.|0|.|]|]+0#00e0003#ffffff0|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|^+8#e000e06&|[+0#0000001#ffff4012|.|0|.|]|^+0#0000000#ffffff0|]+0#00e0003&|;+0#af5f00255&@1| +0#0000000&@2
+|[+0#00e0003&|[+0#0000000&|{|\| @70
+|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|1+0#0000000&|[+0#0000001#ffff4012|=|0|=|]|]+0#00e0003#ffffff0|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|!+8#e000e06&|[+0#0000001#ffff4012|=|0|=|]|!+0#0000000#ffffff0|]+0#00e0003&|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|^+8#e000e06&|[+0#0000001#ffff4012|=|0|=|]|]+0#00e0003#ffffff0|;+0#af5f00255&@1| +0#0000000&@3
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|\+0#0000000&| @69
+|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@39
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&| @68
+|0|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@40
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|\| @65
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |?|[+0#00e0003&|[+0#0000000&|:|f|o@1|:|]|]+0#00e0003&|?+0#0000000&|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|!+8#e000e06&|[+0#0000000&|:|f|o@1|:|]|]+0#00e0003&|?+0#0000000&|;+0#af5f00255&| +0#0000000&|:| |?|[+0#00e0003&|^+8#e000e06&|[+0#0000000&|:|f|o@1|:|]|]+0#00e0003&|;+0#af5f00255&@1| +0#0000000&
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|\+0#0000000&| @64
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|!+8#e000e06&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|;+0#af5f00255&| +0#0000000&|:| |[+0#00e0003&|^+8#e000e06&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|;+0#af5f00255&@1
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|\| @63
+|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|^+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|:|l|o|w|e|r|:|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|^+0#af5f00255&@1|[+0#00e0003&|a+0#0000000&|-|z|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1| +0#0000000&@8
+@57|7|3|,|1| @9|3|5|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_05.dump b/runtime/syntax/testdir/dumps/sh_12_05.dump
new file mode 100644
index 0000000..9df4ef7
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_05.dump
@@ -0,0 +1,20 @@
+|[+0#00e0003#ffffff0|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|^+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|:|l|o|w|e|r|:|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|^+0#af5f00255&@1|[+0#00e0003&|a+0#0000000&|-|z|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1| +0#0000000&@8
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\| @61
+|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|,+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|:|u|p@1|e|r|:|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|,+0#af5f00255&@1|[+0#00e0003&|A+0#0000000&|-|Z|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1| +0#0000000&@10
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\| @60
+|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@48
+>[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|\+0#0000000&| @59
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@49
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|\+0#0000000&| @58
+|[|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&@1|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1| +0#0000000&@13
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|\| @57
+|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1| +0#0000000&@14
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|\| @56
+|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|/+0#af5f00255&|[+0#00e0003&|]+0#0000000&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|[+0#0000000#ffffff0|]+0#00e0003&|/+0#af5f00255&|[+0#0000000&|0|-|9|]|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|/+0#af5f00255&@1|[+0#00e0003&|]+0#0000000&|0|-|9|[|]+0#00e0003&|/+0#af5f00255&|[+0#0000000&|0|-|9|]|}+0#e000e06&|"+0#af5f00255&|;@1
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|\+0#0000000&| @55
+|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|/+0#af5f00255&|#|[+0#00e0003&|]+0#0000000&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|[+0#0000000#ffffff0|]+0#00e0003&|/+0#af5f00255&|[+0#0000000&|0|-|9|]|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|/+0#af5f00255&|%|[+0#00e0003&|]+0#0000000&|0|-|9|[|]+0#00e0003&|/+0#af5f00255&|[+0#0000000&|0|-|9|]|}+0#e000e06&|"+0#af5f00255&|;@1
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&| @54
+|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@54
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|\+0#0000000#ffffff0| @45
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@63
+@57|9|1|,|1| @9|4|5|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_06.dump b/runtime/syntax/testdir/dumps/sh_12_06.dump
new file mode 100644
index 0000000..ab66951
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_06.dump
@@ -0,0 +1,20 @@
+|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@63
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|\+0#0000000&| @44
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|[|.|]|[|.|]|.|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|[|.|[|.|]|]+0#00e0003#ffffff0|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|"+0#af5f00255&| +0#e000002&|"+0#af5f00255&|[+0#00e0003&|]+0#0000000&|[|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|\| @43
+|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|=|[|=|]|[|=|]|=|]|]+0#00e0003#ffffff0|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|[+0#0000001#ffff4012|=|]|=|]|[|=|[|=|]|]+0#00e0003#ffffff0|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|\| |[+0#00e0003&|!+8#e000e06&|]+0#0000000&|[|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;@1| +0#0000000&
+>[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\| @41
+|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|!+8#e000e06&|]+0#0000000&|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|^+8#e000e06&|]+0#0000000&|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|!+8#e000e06&|[+0#0000000&|]+0#00e0003&|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|^+8#e000e06&|[+0#0000000&|]+0#00e0003&|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;@1| +0#0000000&@5
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\| @40
+|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|!+8#e000e06&|\+0#0000000&|]|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|^+8#e000e06&|\+0#0000000&|]|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|!+8#e000e06&|\+0#0000000&|[|]+0#00e0003&|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;| +0#0000000&|:| |"+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&|[+0#00e0003&|^+8#e000e06&|\+0#0000000&|[|]+0#00e0003&|*+0#0000000&|}+0#e000e06&|"+0#af5f00255&|;@1| +0#0000000&@2
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|\+0#0000000&| @39
+|*|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@69
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|\+0#0000000&| @35
+|*|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@69
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|\+0#0000000&| @42
+|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@62
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|\+0#0000000#ffffff0| @37
+|}|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@67
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|\| @36
+|]+0#00e0003&|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@68
+@57|1|0|9|,|1| @8|5@1|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_07.dump b/runtime/syntax/testdir/dumps/sh_12_07.dump
new file mode 100644
index 0000000..d265221
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_07.dump
@@ -0,0 +1,20 @@
+|]+0#00e0003#ffffff0|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@68
+|[+0#00e0003&|!+8#e000e06&|]+0#0000000&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|[|:|x|d|i|g|i|t|:|]|\+0#0000000#ffffff0| |[|^|[+0#0000001#ffff4012|:|l|o|w|e|r|:|]|!+0#0000000#ffffff0|[+0#0000001#ffff4012|:|u|p@1|e|r|:|]|]+0#00e0003#ffffff0|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@23
+|[+0#00e0003&|^+8#e000e06&|]+0#0000000&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|0+0#0000000#ffffff0|-|9|a|-|f|A|-|F|\| |[|!|[+0#0000001#ffff4012|:|l|o|w|e|r|:|]|^+0#0000000#ffffff0|[+0#0000001#ffff4012|:|u|p@1|e|r|:|]|]+0#00e0003#ffffff0|*+0#0000000&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@24
+|[+0#00e0003&|!+8#e000e06&|!+0#0000000&|]+0#00e0003&| +0#0000000&||+0#af5f00255&| +0#0000000&|[+0#00e0003&|!+8#e000e06&|!+0#0000000&|[|]+0#00e0003&| +0#0000000&||+0#af5f00255&| +0#0000000&|[+0#00e0003&|!+8#e000e06&|]+0#0000000&|!|]+0#00e0003&| +0#0000000&||+0#af5f00255&| +0#0000000&|[+0#00e0003&|!+8#e000e06&|^+0#0000000&|]+0#00e0003&| +0#0000000&||+0#af5f00255&| +0#0000000&|[+0#00e0003&|!+8#e000e06&|^+0#0000000&|[|]+0#00e0003&| +0#0000000&||+0#af5f00255&| +0#0000000&|[+0#00e0003&|!+8#e000e06&|]+0#0000000&|^|]+0#00e0003&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@27
+|[+0#00e0003&|^+8#e000e06&|!+0#0000000&|]+0#00e0003&| +0#0000000&||+0#af5f00255&| +0#0000000&|[+0#00e0003&|^+8#e000e06&|!+0#0000000&|[|]+0#00e0003&| +0#0000000&||+0#af5f00255&| +0#0000000&|[+0#00e0003&|^+8#e000e06&|]+0#0000000&|!|]+0#00e0003&| +0#0000000&||+0#af5f00255&| +0#0000000&|[+0#00e0003&|^+8#e000e06&|^+0#0000000&|]+0#00e0003&| +0#0000000&||+0#af5f00255&| +0#0000000&|[+0#00e0003&|^+8#e000e06&|^+0#0000000&|[|]+0#00e0003&| +0#0000000&||+0#af5f00255&| +0#0000000&|[+0#00e0003&|^+8#e000e06&|]+0#0000000&|^|]+0#00e0003&|)+0#af5f00255&| +0#0000000&|;+0#af5f00255&@1| +0#0000000&@27
+>e+0#af5f00255&|s|a|c| +0#0000000&@70
+@75
+|#+0#0000e05&| |M|a|t|c|h| |"|\|[|0|\|]|\|[|0|\|]|"|,| |"|{|0|}|{|0|}|"|,| |e|t|c|.| +0#0000000&@38
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@30
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|\| @65
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@38
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|\+0#0000000&| @64
+|[|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@39
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|\| @63
+|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@40
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|\| @62
+|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@41
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|\+0#0000000&| @61
+|[+0#00e0003&|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@42
+@57|1|2|7|,|1| @8|6|4|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_08.dump b/runtime/syntax/testdir/dumps/sh_12_08.dump
new file mode 100644
index 0000000..ddbabda
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_08.dump
@@ -0,0 +1,20 @@
+|[+0#00e0003#ffffff0|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@42
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&| @60
+|0|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@43
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|\| @57
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@46
+>:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|\+0#0000000&| @56
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@47
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|\| @55
+|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@48
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\| @53
+|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@50
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\| @52
+|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@51
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|\+0#0000000&| @51
+|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@52
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|\+0#0000000&| @50
+|[|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@53
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|\| @49
+|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@54
+@57|1|4|5|,|1| @8|7|4|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_09.dump b/runtime/syntax/testdir/dumps/sh_12_09.dump
new file mode 100644
index 0000000..35ba1f8
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_09.dump
@@ -0,0 +1,20 @@
+|{+0&#ffffff0|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@54
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|\| @48
+|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@55
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|\+0#0000000&| @47
+|[+0#00e0003&|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@56
+>:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|\+0#0000000&| @46
+|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@57
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|\+0#0000000#ffffff0| @37
+|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@66
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|\+0#0000000&| @36
+|*|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@67
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|\| @35
+|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@68
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|\| @33
+|}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@70
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|\| @32
+|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@71
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|\+0#0000000&| @31
+|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@72
+@57|1|6|3|,|1| @8|8|3|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_10.dump b/runtime/syntax/testdir/dumps/sh_12_10.dump
new file mode 100644
index 0000000..f6d8ca0
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_10.dump
@@ -0,0 +1,20 @@
+|}+0#e000e06#ffffff0|"+0#af5f00255&| +0#0000000&@72
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@26
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|\+0#0000000&| @34
+|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@65
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|\+0#0000000#ffffff0| @29
+>}|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@70
+|:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|*+0#0000000&|[+0#00e0003&|[+0#0000000&|{|]+0#00e0003&|[|0+0#0000000&|-|9|]+0#00e0003&|*+0#0000000&|[+0#00e0003&|]+0#0000000&|}|]+0#00e0003&|[|[+0#0000000&|{|]+0#00e0003&|[|[+0#0000001#ffff4012|:|d|i|g|i|t|:|]|]+0#00e0003#ffffff0|*+0#0000000&|[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|}+0#0000000#ffffff0|]+0#00e0003&|\+0#0000000&| @27
+|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@72
+@75
+|:| |*|[+0#00e0003&|x+0#0000000&|[+0#0000001#ffff4012|=|[|=|]|[|=|]|=|]|]+0#00e0003#ffffff0|;+0#0000000&| |:| |[+0#00e0003&|x+0#0000000&|[+0#0000001#ffff4012|=|]|=|]|[|=|[|=|]|]+0#00e0003#ffffff0|*+0#0000000&|;| |:| |*|[+0#00e0003&|x+0#0000000&|[+0#0000001#ffff4012|.|[|.|]|[|.|]|.|]|]+0#00e0003#ffffff0|;+0#0000000&| |:| |[+0#00e0003&|x+0#0000000&|[+0#0000001#ffff4012|.|]|.|]|[|.|[|.|]|]+0#00e0003#ffffff0|*+0#0000000&| @4
+|:| |*|[+0#00e0003&|[+0#0000001#ffff4012|=|[|=|]|x+0#0000000#ffffff0|[+0#0000001#ffff4012|=|]|=|]|]+0#00e0003#ffffff0|;+0#0000000&| |:| |[+0#00e0003&|[+0#0000001#ffff4012|=|]|=|]|x+0#0000000#ffffff0|[+0#0000001#ffff4012|=|[|=|]|]+0#00e0003#ffffff0|*+0#0000000&|;| |:| |*|[+0#00e0003&|[+0#0000001#ffff4012|.|[|.|]|x+0#0000000#ffffff0|[+0#0000001#ffff4012|.|]|.|]|]+0#00e0003#ffffff0|;+0#0000000&| |:| |[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|x+0#0000000#ffffff0|[+0#0000001#ffff4012|.|[|.|]|]+0#00e0003#ffffff0|*+0#0000000&| @4
+|:| |*|[+0#00e0003&|[+0#0000001#ffff4012|=|[|=|]|[|=|]|=|]|x+0#0000000#ffffff0|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|[+0#0000001#ffff4012|=|]|=|]|[|=|[|=|]|x+0#0000000#ffffff0|]+0#00e0003&|*+0#0000000&|;| |:| |*|[+0#00e0003&|[+0#0000001#ffff4012|.|[|.|]|[|.|]|.|]|x+0#0000000#ffffff0|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|[+0#0000001#ffff4012|.|]|.|]|[|.|[|.|]|x+0#0000000#ffffff0|]+0#00e0003&|*+0#0000000&| @4
+|:| |[+0#00e0003&|!+8#e000e06&|]+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|^+8#e000e06&|]+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|!+8#e000e06&|[+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|^+8#e000e06&|[+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|!+8#e000e06&|\+0#0000000&|]|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|^+8#e000e06&|\+0#0000000&|]|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|!+8#e000e06&|\+0#0000000&|[|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|^+8#e000e06&|\+0#0000000&|[|]+0#00e0003&| +0#0000000&@8
+|:| |[+0#00e0003&|$+0#0000000&|'|\|x|5|b|'|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|$+0#0000000&|'|\|x|5|d|'|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|]+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|[+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|\+0#0000000&|]|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|\+0#0000000&|[|]+0#00e0003&| +0#0000000&@20
+|:| |[+0#00e0003&|$+0#0000000&|'|\|x|2|0|'|[|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|"+0#af5f00255&| +0#e000002&|"+0#af5f00255&|[+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|'+0#0000000&| |'|[|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|\+0#0000000&| |[|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|\+0#0000000&| |\|[|]+0#00e0003&|;+0#0000000&| |:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|[+0#00e0003&| +0#0000000&@2|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@7
+|:| |[+0#00e0003&|[+0#0000000&|$|'|\|x|2|0|'|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|[+0#0000000&|"+0#af5f00255&| +0#e000002&|"+0#af5f00255&|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|[+0#0000000&|'| |'|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|[+0#0000000&|\| |]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|\+0#0000000&|[|\| |]+0#00e0003&|;+0#0000000&| |:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|[+0#00e0003&| +0#0000000&@3|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@6
+|:| |[+0#00e0003&|^+8#e000e06&|$+0#0000000&|'|\|x|2|0|'|[|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|!+8#e000e06&|"+0#af5f00255&| +0#e000002&|"+0#af5f00255&|[+0#0000000&|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|^+8#e000e06&|'+0#0000000&| |'|[|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|!+8#e000e06&|\+0#0000000&| |[|]+0#00e0003&|;+0#0000000&| |:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|[+0#00e0003&|^+8#e000e06&| +0#0000000&@7|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@7
+|:| |[+0#00e0003&|!+8#e000e06&|[+0#0000000&|$|'|\|x|2|0|'|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|^+8#e000e06&|[+0#0000000&|"+0#af5f00255&| +0#e000002&|"+0#af5f00255&|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|!+8#e000e06&|[+0#0000000&|'| |'|]+0#00e0003&|;+0#0000000&| |:| |[+0#00e0003&|^+8#e000e06&|[+0#0000000&|\| |]+0#00e0003&|;+0#0000000&| |:| |"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|[+0#00e0003&|!+8#e000e06&| +0#0000000&@8|]+0#00e0003&|}+0#e000e06&|"+0#af5f00255&| +0#0000000&@6
+@75
+@57|1|8|1|,|1| @8|9|3|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_12_11.dump b/runtime/syntax/testdir/dumps/sh_12_11.dump
new file mode 100644
index 0000000..21edbc8
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_12_11.dump
@@ -0,0 +1,20 @@
+| +0&#ffffff0@74
+|n+0#00e0e07&|l|=+0#0000000&|'+0#af5f00255&| +0#0000000&@70
+|'+0#af5f00255&| +0#0000000&@73
+|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|"+0#af5f00255&|$+0#e000e06&|{|n|l|}|"+0#af5f00255&|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&|;+0#0000000&| |e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|'+0#0000000&|$|{|n|l|}|'|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&| +0#0000000&@14
+|e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|\+0#0000000&|"|$|{|n|l|}|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&|;+0#0000000&| |e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|\+0#0000000&|'|$|{|n|l|}|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&| +0#0000000&@14
+>e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|$+0#0000000&|{|n|l|}|\|"|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&|;+0#0000000&| |e+0#af5f00255&|c|h|o| +0#e000002&|"+0#af5f00255&|$+0#e000e06&|{|1|#+0#af5f00255&|$+0#e000e06&|{|1|%+0#af5f00255&@1|[+0#00e0003&|!+8#e000e06&|$+0#0000000&|{|n|l|}|\|'|]+0#00e0003&|*+0#0000000&|}+0#e000e06&@1|"+0#af5f00255&| +0#0000000&@14
+@75
+|b+0#00e0e07&|i|n|s|=+0#0000000&|(+0#e000e06&|)|;+0#0000000&| |b+0#00e0e07&|i|n|s|=+0#0000000&|(+0#e000e06&|0+0#e000002&| +0#0000000&|1+0#e000002&|)+0#e000e06&|;+0#0000000&| |e+0#af5f00255&|v|a|l| +0#0000000&|b+0#00e0e07&|i|n|s|++0#0000000&|=|(+0#e000e06&|{|0+0#e000002&|.+0#0000000&@1|1+0#e000002&|}+0#e000e06&|)| +0#0000000&@34
+|b+0#00e0e07&|i|n|s|[+0#e000e06&|0+0#e000002&|]+0#e000e06&|=+0#0000000&|0+0#e000002&|;+0#0000000&| |b+0#00e0e07&|i|n|s|[+0#e000e06&|1+0#e000002&|]+0#e000e06&|=+0#0000000&|1+0#e000002&|;+0#0000000&| |e+0#af5f00255&|v|a|l| +0#0000000&|b+0#00e0e07&|i|n|s|++0#0000000&|=|(+0#e000e06&|\+0#0000000&|$+0#e000e06&|{|b|i|n|s|[|{|1+0#e000002&|.+0#0000000&@1|0+0#e000002&|}+0#e000e06&|]|}|)|;+0#0000000&| |u+0#af5f00255&|n|s|e|t| +0#00e0e07&|b|i|n|s|[+0#e000e06&|3+0#e000002&|]+0#e000e06&| +0#00e0e07&|b|i|n|s|[+0#e000e06&|2+0#e000002&|]+0#e000e06&| +0#0000000&
+|b+0#00e0e07&|i|n|s|=+0#0000000&|(+0#e000e06&|[+0#00e0e07&|8+0#e000002&|#|0|]+0#00e0e07&|=+0#0000000&|$+0#e000e06&|(@1|2+0#e000002&|#|1|0@1|)+0#e000e06&@1| +0#0000000&|[+0#00e0e07&|$+0#e000e06&|(@1|8+0#e000002&|#|1|)+0#e000e06&@1|]+0#00e0e07&|=+0#0000000&|$+0#e000e06&|(@1|2+0#e000002&|#|1|0|)+0#e000e06&@1| +0#0000000&|[+0#00e0e07&|3+0#e000002&|]+0#00e0e07&|=+0#0000000&|$+0#e000e06&|{|b|i|n|s|[|2+0#e000002&|#|1|]+0#e000e06&|}| +0#0000000&|$+0#e000e06&|{|b|i|n|s|[|0+0#e000002&|]+0#e000e06&|}|)| +0#0000000&@2
+|(+0#e000e06&|e+0#af5f00255&|c|h|o| +0#e000002&|s|u|m|[+0#e000e06&|$|(@1|b|i|n|s|[|1+0#e000002&|6|#|3|]+0#e000e06&| |+| |b|i|n|s|[|8+0#e000002&|#|2|]+0#e000e06&| |+| |b|i|n|s|[|2+0#e000002&|#|1|]+0#e000e06&| |+| |b|i|n|s|[|0+0#e000002&|]+0#e000e06&|)@1|]|)| +0#0000000&@13
+|e+0#af5f00255&|v|a|l| +0#0000000&|u+0#af5f00255&|n|s|e|t| +0#00e0e07&|b|i|n|s|[+0#e000e06&|{|0+0#e000002&|.+0#0000000&@1|$+0#e000e06&|(@1|$|{|#|b|i|n|s|[|*+0#0000000&|]+0#e000e06&|}| |-| |1+0#e000002&|)+0#e000e06&@1|}|]| +0#0000000&@32
+|:| @73
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|9@1|,|1| @8|B|o|t| 
diff --git a/runtime/syntax/testdir/input/sh_04.sh b/runtime/syntax/testdir/input/sh_04.sh
index e9ec5fe..1503790 100644
--- a/runtime/syntax/testdir/input/sh_04.sh
+++ b/runtime/syntax/testdir/input/sh_04.sh
@@ -20,8 +20,3 @@
 # This is OK
 : ${VariableB:-${VariableC:-eng}}
 : "${VariableB:-${VariableC:-eng}}"
-
-# First line is OK except its missing a closing "}",
-# so second line should have some error highlighting
-Variable=${VariableB:=${VariableC:={Var3:=${Var4:-eng}}}
-Variable=${VariableB:-${VariableC:-{Var3:=eng}}
diff --git a/runtime/syntax/testdir/input/sh_12.sh b/runtime/syntax/testdir/input/sh_12.sh
new file mode 100644
index 0000000..dcfa553
--- /dev/null
+++ b/runtime/syntax/testdir/input/sh_12.sh
@@ -0,0 +1,206 @@
+#!/bin/bash
+# VIM_TEST_SETUP highlight link shArrayValue Identifier
+# VIM_TEST_SETUP highlight link shBracketExprDelim Structure
+# VIM_TEST_SETUP highlight link shCharClass Todo
+# VIM_TEST_SETUP highlight link shRange CursorLine
+
+
+
+
+[[ ( "$1" == ?(-)+([0-9]) && "$1" =~ ^-?[[:digit:]]+$ &&
+'^?(-)+([[:digit:]])$' == "$2" && ! "^-?[0-9]+$" =~ "$2" ) ]] || :
+
+[ \( "$1" != "?(-)+([0-9])" -a "$1" != '?(-)+([[:digit:]])' \) ] &&
+[ \( "?(-)+([[:digit:]])" != "$2" -a '?(-)+([0-9])' != "$2" \) ] || :
+
+# Match "\[0\]\[0\]", "{0}{0}", etc.
+: [[{][0-9]*[]}][[{][[:digit:]]*[]}]
+: [\
+[{][0-9]*[]}][[{][[:digit:]]*[]}]
+: [[\
+{][0-9]*[]}][[{][[:digit:]]*[]}]
+: [[{\
+][0-9]*[]}][[{][[:digit:]]*[]}]
+: [[{]\
+[0-9]*[]}][[{][[:digit:]]*[]}]
+: [[{][\
+0-9]*[]}][[{][[:digit:]]*[]}]
+: [[{][0-9\
+]*[]}][[{][[:digit:]]*[]}]
+: [[{][0-9]\
+*[]}][[{][[:digit:]]*[]}]
+: [[{][0-9]*\
+[]}][[{][[:digit:]]*[]}]
+: [[{][0-9]*[]\
+}][[{][[:digit:]]*[]}]
+: [[{][0-9]*[]}\
+][[{][[:digit:]]*[]}]
+: [[{][0-9]*[]}]\
+[[{][[:digit:]]*[]}]
+: [[{][0-9]*[]}][\
+[{][[:digit:]]*[]}]
+: [[{][0-9]*[]}][[\
+{][[:digit:]]*[]}]
+: [[{][0-9]*[]}][[{\
+][[:digit:]]*[]}]
+: [[{][0-9]*[]}][[{]\
+[[:digit:]]*[]}]
+: [[{][0-9]*[]}][[{][\
+[:digit:]]*[]}]
+: [[{][0-9]*[]}][[{][[:digit:]\
+]*[]}]
+: [[{][0-9]*[]}][[{][[:digit:]]\
+*[]}]
+: [[{][0-9]*[]}][[{][[:digit:]]*\
+[]}]
+: [[{][0-9]*[]}][[{][[:digit:]]*[]\
+}]
+: [[{][0-9]*[]}][[{][[:digit:]]*[]}\
+]
+: [[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]
+: [[{][0-9]*[]}][[{][[:digit:]]*[\
+[.].]}]
+: [[{][0-9]*[]}][[{][[:digit:]]*[[.].]\
+}]
+: [[{][0-9]*[]}][[{][[:digit:]]*[[.].]}\
+]
+
+# Match "\[0\]\[0\]", "{0}{0}", etc.
+case "$1" in
+[[{][0-9]*[]}][[{][[:digit:]]*[]}]*) : [0-9]; : [!0-9]; : [^0-9];;
+[\
+[{][0-9]*[]}][[{][[:digit:]]*[]}]*) : [0123]; : [!0123]; : [^0123];;
+[[\
+{][0-9]*[]}][[{][[:digit:]]*[]}]*) : [1[.0.]]; : [![.0.]]; : [^[.0.]^];;
+[[{\
+][0-9]*[]}][[{][[:digit:]]*[]}]*) : [1[=0=]]; : [![=0=]!]; : [^[=0=]];;
+[[{]\
+[0-9]*[]}][[{][[:digit:]]*[]}]*) ;;
+[[{][\
+0-9]*[]}][[{][[:digit:]]*[]}]*) ;;
+[[{][0-9\
+]*[]}][[{][[:digit:]]*[]}]*) : ?[[:foo:]]?; : [![:foo:]]?; : ?[^[:foo:]];;
+[[{][0-9]\
+*[]}][[{][[:digit:]]*[]}]*) : [[:digit:]]; : [![:digit:]]; : [^[:digit:]];;
+[[{][0-9]*\
+[]}][[{][[:digit:]]*[]}]*) : "${1^[[:lower:]]}"; : "${1^^[a-z]}";;
+[[{][0-9]*[]\
+}][[{][[:digit:]]*[]}]*) : "${1,[[:upper:]]}"; : "${1,,[A-Z]}";;
+[[{][0-9]*[]}\
+][[{][[:digit:]]*[]}]*) ;;
+[[{][0-9]*[]}]\
+[[{][[:digit:]]*[]}]*) ;;
+[[{][0-9]*[]}][\
+[{][[:digit:]]*[]}]*) : "${1#[[:digit:]]}"; : "${1##[0-9]}";;
+[[{][0-9]*[]}][[\
+{][[:digit:]]*[]}]*) : "${1%[[:digit:]]}"; : "${1%%[0-9]}";;
+[[{][0-9]*[]}][[{\
+][[:digit:]]*[]}]*) : "${1/[][:digit:][]/[0-9]}"; : "${1//[]0-9[]/[0-9]}";;
+[[{][0-9]*[]}][[{]\
+[[:digit:]]*[]}]*) : "${1/#[][:digit:][]/[0-9]}"; : "${1/%[]0-9[]/[0-9]}";;
+[[{][0-9]*[]}][[{][\
+[:digit:]]*[]}]*) ;;
+[[{][0-9]*[]}][[{][[:digit:]\
+]*[]}]*) ;;
+[[{][0-9]*[]}][[{][[:digit:]]\
+*[]}]*) : "${1#*[[.[.][.].]]}"; : "${1%[[.].][.[.]]*}"; : "${1#*" "[][]}";;
+[[{][0-9]*[]}][[{][[:digit:]]*\
+[]}]*) : "${1#*[[=[=][=]=]]}"; : "${1%[[=]=][=[=]]*}"; : "${1#*\ [!][]}";;
+[[{][0-9]*[]}][[{][[:digit:]]*[]\
+}]*) : "${1#*[!]]}"; : "${1#*[^]]}"; : "${1%[![]*}"; : "${1%[^[]*}";;
+[[{][0-9]*[]}][[{][[:digit:]]*[]}\
+]*) : "${1#*[!\]]}"; : "${1#*[^\]]}"; : "${1%[!\[]*}"; : "${1%[^\[]*}";;
+[[{][0-9]*[]}][[{][[:digit:]]*[]}]\
+*) ;;
+[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]\
+*) ;;
+[[{][0-9]*[]}][[{][[:digit:]]*[\
+[.].]}]*) ;;
+[[{][0-9]*[]}][[{][[:digit:]]*[[.].]\
+}]*) ;;
+[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}\
+]*) ;;
+[!][:digit:][:xdigit:]\ [^[:lower:]![:upper:]]*) ;;
+[^][:digit:]0-9a-fA-F\ [![:lower:]^[:upper:]]*) ;;
+[!!] | [!![] | [!]!] | [!^] | [!^[] | [!]^]) ;;
+[^!] | [^![] | [^]!] | [^^] | [^^[] | [^]^]) ;;
+esac
+
+# Match "\[0\]\[0\]", "{0}{0}", etc.
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*\
+[[{][0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[\
+[{][0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[\
+{][0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{\
+][0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{]\
+[0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][\
+0-9]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9\
+]*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]\
+*[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*\
+[]}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]\
+}][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}\
+][[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}]\
+[[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][\
+[{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[\
+{][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{\
+][[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{]\
+[[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{][\
+[:digit:]]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]\
+]*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]\
+*[]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*\
+[]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]\
+}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]}\
+]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[]}]\
+}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[\
+[.].]}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[[.].]\
+}]}"
+: "${1#*[[{][0-9]*[]}][[{][[:digit:]]*[[.].]}]\
+}"
+
+: *[x[=[=][=]=]]; : [x[=]=][=[=]]*; : *[x[.[.][.].]]; : [x[.].][.[.]]*
+: *[[=[=]x[=]=]]; : [[=]=]x[=[=]]*; : *[[.[.]x[.].]]; : [[.].]x[.[.]]*
+: *[[=[=][=]=]x]; : [[=]=][=[=]x]*; : *[[.[.][.].]x]; : [[.].][.[.]x]*
+: [!]]; : [^]]; : [![]; : [^[]; : [!\]]; : [^\]]; : [!\[]; : [^\[]
+: [$'\x5b']; : [$'\x5d']; : []]; : [[]; : [\]]; : [\[]
+: [$'\x20'[]; : [" "[]; : [' '[]; : [\ []; : [\ \[]; : "${1#[ 	]}"
+: [[$'\x20']; : [[" "]; : [[' ']; : [[\ ]; : [\[\ ]; : "${1#[	 ]}"
+: [^$'\x20'[]; : [!" "[]; : [^' '[]; : [!\ []; : "${1#[^ 	]}"
+: [![$'\x20']; : [^[" "]; : [![' ']; : [^[\ ]; : "${1#[!	 ]}"
+
+nl='
+'
+echo "${1#${1%%[!"${nl}"]*}}"; echo "${1#${1%%[!'${nl}']*}}"
+echo "${1#${1%%[!\"${nl}]*}}"; echo "${1#${1%%[!\'${nl}]*}}"
+echo "${1#${1%%[!${nl}\"]*}}"; echo "${1#${1%%[!${nl}\']*}}"
+
+bins=(); bins=(0 1); eval bins+=({0..1})
+bins[0]=0; bins[1]=1; eval bins+=(\${bins[{1..0}]}); unset bins[3] bins[2]
+bins=([8#0]=$((2#100)) [$((8#1))]=$((2#10)) [3]=${bins[2#1]} ${bins[0]})
+(echo sum[$((bins[16#3] + bins[8#2] + bins[2#1] + bins[0]))])
+eval unset bins[{0..$((${#bins[*]} - 1))}]
+: