runtime(sh): Improve the matching of function definitions

Commit: 
https://github.com/vim/vim/commit/9c0d057e3d5a456b2f2879860e5e57bcdf130017
Author: Aliaksei Budavei <[email protected]>
Date:   Tue Mar 24 20:34:15 2026 +0000

    runtime(sh): Improve the matching of function definitions
    
    - Drop the remaining undefined "shFunctionStart" references
      (gone in v7.2b.000, c236c16d0).
    - Revise nestable contexts where function definitions are
      supported:
      * Stop looking for function definitions in arithmetic
        expressions.
      * Recognise function definitions enclosing other function
        definitions.
    - In addition to grouping commands "{}" and "()", also match
      other compound commands (e.g. "if"; see "shFunctionCmd*")
      whenever these commands are supported as complete function
      bodies.
    - Balance body delimiters "(" and ")" for "shFunctionFour"
      in Bash; match such function bodies whenever the use of
      the function parameter list "()" token is optional, i.e.
      when the "function" reserved word is present.
    - Enable the use of "shFunctionFour" definitions.
    - Do not claim optional leading whitespace characters before
      a matched function definition.
    - Prefer patterns with ASCII atoms (e.g. "\h") to equivalent
      collections (e.g. "[A-Za-z_]") for speed.
    - Accommodate word-boundary assertions in function name
      patterns to names that may start and/or end with supported
      non-word characters, e.g. "@test:".
    - Match more valid function names in Bash: non-ASCII names,
      non-word names.
    - Allow for function names with "do", "done", etc. prefixes;
      confine these name checks to "shDoError" and "shIfError".
    
    fixes:   #19619
    related: #19638
    
    References:
    
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_09_04
    
https://gitweb.git.savannah.gnu.org/gitweb/?p=bash.git;a=blob_plain;f=doc/bash.html;hb=637f5c8696a6adc9b4519f1cd74aa78492266b7f
    
https://web.archive.org/web/20151105130220/http://www.research.att.com/sw/download/man/man1/ksh88.html
    
https://web.archive.org/web/20151025145158/http://www2.research.att.com/sw/download/man/man1/ksh.html
    http://www.mirbsd.org/htman/i386/man1/mksh.htm
    
    Co-authored-by: Johnothan King <[email protected]>
    Co-authored-by: Doug Kearns <[email protected]>
    Signed-off-by: Aliaksei Budavei <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim
index 6b13ddacc..efe0b22c2 100644
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -22,6 +22,7 @@
 "              2026 Jan 15 highlight command switches that contain a digit
 "              2026 Feb 11 improve support for KornShell function names and 
variables
 "              2026 Feb 15 improve comment handling #19414
+"              2026 Mar 23 improve matching of function definitions #19638
 " }}}
 " Version:             208
 " Former URL:          http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
@@ -261,7 +262,7 @@ syn cluster shErrorList     
contains=shDoError,shIfError,shInError,shCaseError,shEsa
 if exists("b:is_kornshell") || exists("b:is_bash")
     syn cluster ErrorList add=shDTestError
 endif
-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,shNamespaceOne
+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
 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
@@ -278,7 +279,16 @@ syn cluster shDerefVarList 
contains=shDerefOffset,shDerefOp,shDerefVarArray,shDe
 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=shBracketExpr,@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
+syn cluster shFunctionCmds     
contains=shFor,shCaseEsac,shIf,shRepeat,shDblBrace,shDblParen
+if exists("b:is_ksh88") || exists("b:is_mksh")
+    " Offer "shFunctionCmds" as is.
+elseif exists("b:is_kornshell") || exists("b:is_bash")
+    syn cluster shFunctionCmds add=shForPP
+else
+    syn cluster shFunctionCmds remove=shDblBrace,shDblParen
+endif
+syn cluster shFunctionDefList  
contains=shDoError,shIfError,shFunctionKey,shFunctionOne,shFunctionThree,shFunctionCmdOne
+syn cluster shFunctionList     
contains=shBracketExpr,@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq,@shFunctionDefList
 if exists("b:is_kornshell") || exists("b:is_bash")
     syn cluster shFunctionList add=shRepeat,shDblBrace,shDblParen,shForPP
     syn cluster shDerefList    add=shCommandSubList,shEchoDeref
@@ -287,7 +297,7 @@ 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,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,shNamespaceOne
+syn cluster shIfList   
contains=@shLoopList,shDblBrace,shDblParen,@shFunctionDefList
 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
@@ -647,39 +657,49 @@ endif
 
 " Functions: {{{1
 if !exists("b:is_posix")
-    syn keyword shFunctionKey function skipwhite skipnl nextgroup=shFunctionTwo
+    syn keyword shFunctionKey function skipwhite skipnl 
nextgroup=shDoError,shIfError,shFunctionTwo,shFunctionFour,shFunctionCmdTwo
 endif
 
 if exists("b:is_bash")
     syn keyword shFunctionKey coproc
-    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*[A-Za-z_0-9:][-a-zA-Z_0-9:]*\s*()\_s*{"                end="}" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\%(do\)\@!\&\<[A-Za-z_0-9:][-a-zA-Z_0-9:]*\>\s*\%(()\)\=\_s*{"     
end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*[A-Za-z_0-9:][-a-zA-Z_0-9:]*\s*()\_s*("                end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionFour  matchgroup=shFunction 
start="\%(do\)\@!\&\<[A-Za-z_0-9:][-a-zA-Z_0-9:]*\>\s*\%(()\)\=\_s*)"     
end=")" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    syn match shFunctionCmdOne "^\s*\zs\%(\<\k\+\|[^()<>|&$;    
]\+\)\+\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)" 
       skipwhite skipnl nextgroup=@shFunctionCmds
+    syn match shFunctionCmdTwo "\%(\<\k\+\>\|[^()<>|&$;         
]\+\)\+\ze\s*\%(()\ze\)\=\_s*\%(\<\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)"
    contained skipwhite skipnl nextgroup=@shFunctionCmds
+    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*\zs\%(\<\k\+\|[^()<>|&$;        ]\+\)\+\s*()\_s*{"             
end="}" contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\%(\<\k\+\|[^()<>|&$;       ]\+\)\+\s*\%(()\)\=\_s*{"      end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*\zs\%(\<\k\+\|[^()<>|&$;        ]\+\)\+\s*()\_s*((\@!"         
end=")" contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionFour  matchgroup=shFunction 
start="\%(\<\k\+\|[^()<>|&$;       ]\+\)\+\s*\%(\%(()\)\=\)\@>\_s*((\@!"  
end=")" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shQuickComment
 elseif exists("b:is_ksh88")
     " AT&T ksh88
-    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*[A-Za-z_][A-Za-z_0-9]*\s*()\_s*{"              end="}" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\%(do\)\@!\&\<[A-Za-z_][A-Za-z_0-9]*\>\_s*{"               end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*[A-Za-z_][A-Za-z_0-9]*\s*()\_s*("              end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionFour  matchgroup=shFunction 
start="\%(do\)\@!\&\<[A-Za-z_][A-Za-z_0-9]*\>\_s*("               end=")" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    syn match shFunctionCmdOne 
"^\s*\zs\h\w*\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)"
   skipwhite skipnl nextgroup=@shFunctionCmds
+    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*\zs\h\w*\s*()\_s*{"            end="}" contains=@shFunctionList      
           skipwhite skipnl nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\<\h\w*\>\_s*{"            end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*\zs\h\w*\s*()\_s*((\@!"                end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shQuickComment
 elseif exists("b:is_mksh")
     " MirBSD ksh is the wild west of absurd and abstruse function names...
-    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\_s*{"              
end="}" contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\%(do\)\@!\&\<[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\>\s*\%(()\)\=\_s*{" 
  end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\_s*("              
end=")" contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionFour  matchgroup=shFunction 
start="\%(do\)\@!\&\<[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\>\s*\%(()\)\=\_s*(" 
  end=")" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    syn match shFunctionCmdOne 
"^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)"
  skipwhite skipnl nextgroup=@shFunctionCmds
+    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\_s*{"           
end="}" contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\%([@!+.%,:-]\+\|\<\w\+\)*[-A-Za-z_.%,0-9:]\s*\%(()\)\=\_s*{"      
end="}" contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*\zs[-A-Za-z_@!+.%,0-9:]*[-A-Za-z_.%,0-9:]\s*()\_s*((\@!"             
  end=")" contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shQuickComment
 elseif exists("b:is_kornshell")
     " ksh93
-    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*[A-Za-z_.][A-Za-z_.0-9]*\s*()\_s*{"            end="}" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\%(do\)\@!\&\<[A-Za-z_.][A-Za-z_.0-9]*\>\_s*{"             end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*[A-Za-z_.][A-Za-z_.0-9]*\s*()\_s*("            end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionFour  matchgroup=shFunction 
start="\%(do\)\@!\&\<[A-Za-z_.][A-Za-z_.0-9]*\>\_s*("             end=")" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shNamespaceOne  matchgroup=shFunction 
start="\%(do\)\@!\&\<\h\w*\>\_s*{"                        end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    syn match shFunctionCmdOne 
"^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\ze\_s*\%(\%(for\|case\|select\|if\|while\|until\)\>\|\[\[\s\|((\)"
        skipwhite skipnl nextgroup=@shFunctionCmds
+    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\_s*{"         end="}" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\%(\.\|\<\h\+\)[A-Za-z_.0-9]*\_s*{"                end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*\zs[A-Za-z_.][A-Za-z_.0-9]*\s*()\_s*((\@!"             end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shNamespaceOne  matchgroup=shFunction 
start="\<\h\w*\>\_s*{"                    end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shQuickComment
 else
-    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*\h\w*\s*()\_s*{"                       end="}" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*{"            end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*\h\w*\s*()\_s*("                       end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
-    ShFoldFunctions syn region shFunctionFour  matchgroup=shFunction 
start="\%(do\)\@!\&\<\h\w*\>\s*\%(()\)\=\_s*("            end=")" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shFunctionStart,shQuickComment
+    syn match shFunctionCmdOne 
"^\s*\zs\h\w*\s*()\ze\_s*\%(for\|case\|if\|while\|until\)\>"    skipwhite 
skipnl nextgroup=@shFunctionCmds
+    syn match shFunctionCmdTwo 
"\<\h\w*\s*()\ze\_s*\%(for\|case\|if\|while\|until\)\>" contained skipwhite 
skipnl nextgroup=@shFunctionCmds
+    ShFoldFunctions syn region shFunctionOne   matchgroup=shFunction 
start="^\s*\zs\h\w*\s*()\_s*{"                    end="}" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionTwo   matchgroup=shFunction 
start="\<\h\w*\>\s*()\_s*{"               end="}" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionThree matchgroup=shFunction 
start="^\s*\zs\h\w*\s*()\_s*("                    end=")" 
contains=@shFunctionList                 skipwhite skipnl 
nextgroup=shQuickComment
+    ShFoldFunctions syn region shFunctionFour  matchgroup=shFunction 
start="\<\h\w*\>\s*()\_s*("               end=")" 
contains=shFunctionKey,@shFunctionList contained skipwhite skipnl 
nextgroup=shQuickComment
+endif
+
+if !exists("g:sh_no_error")
+    syn match   shDoError "\<do\%(ne\)\=\s*()"
+    syn match   shIfError "\<then\s*()"
+    syn match   shIfError "\<else\s*()"
 endif
 
 " Parameter Dereferencing: {{{1
@@ -883,6 +903,8 @@ if !exists("skip_sh_syntax_inits")
     hi def link shEchoQuote    shString
     hi def link shForPP        shLoop
     hi def link shFunction     Function
+    hi def link shFunctionCmdOne       shFunction
+    hi def link shFunctionCmdTwo       shFunction
     hi def link shEmbeddedEcho shString
     hi def link shEscape       shCommandSub
     hi def link shExDoubleQuote        shDoubleQuote
diff --git a/runtime/syntax/testdir/dumps/sh_functions_bash_00.dump 
b/runtime/syntax/testdir/dumps/sh_functions_bash_00.dump
new file mode 100644
index 000000000..704545095
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_bash_00.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1>#+0&#ffffff0|!|/|b|i|n|/|b|a|s|h| +0#0000000&@61
+| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| 
|s|e|t|l|o|c|a|l| |f|e|n| |f|d|c|=|2| |f|d|l|=|8| |f|d|m|=|s|y|n|t|a|x| 
+0#0000000&@20
+| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| 
|g|:|s|h|_|f|o|l|d|_|e|n|a|b|l|e|d| |=| |1| |+| |2| |+| |4| +0#0000000&@22
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|t+0#af5f00255#ffffff0|y|p|e|s|e|t| 
+0#0000000&|-+0#e000e06&|i| +0#0000000&|n+0#00e0e07&|=+0#0000000&|0+0#e000002&| 
+0#0000000&@58
+| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(|)| 
+0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&|
 |d|o@1|s|i|e| @47
+| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(|)| 
+0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| 
+0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| 
|d|o|n|e@1| @46
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(|)| +0#0000000&@64
+| +0#0000e05#a8a8a8255@1|u+0#af5f00255#ffffff0|n|t|i|l| |:| +0#0000000&@65
+|-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:| @67
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| 
+0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| 
|w|h|i|l|e|s| @32
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| 
+0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56
+|i|s|_|b|a|s|h|:| |1|,| @45|1|,|1| @10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_bash_01.dump 
b/runtime/syntax/testdir/dumps/sh_functions_bash_01.dump
new file mode 100644
index 000000000..a7ee351d9
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_bash_01.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| 
+0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| 
|w|h|i|l|e|s| @32
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| 
+0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56
+||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| 
|e|l|s|e|w|h|e|r|e| @51
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(|)| 
+0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| 
+0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| 
|d+0#af5f00255&|o| +0#0000000&@42
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| 
+0#0000000&@63
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|e|l|e|c|t|o|r| 
|0+0#e000002&|<+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| 
|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| ||@1| |:| @35
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| 
+0#0000000&|c+0#af5f00255&|a|s|e| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| 
+0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| 
+0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| 
|c|a|s|e|d| @33
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(|)| +0#0000000&@66
+| +0#0000e05#a8a8a8255@1|f+0#af5f00255#ffffff0|o|r| +0#0000000&|x| 
|i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&| 
+0#0000000&@60
+|-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:| @67
+@57|1|9|,|1| @9|3|6|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_bash_02.dump 
b/runtime/syntax/testdir/dumps/sh_functions_bash_02.dump
new file mode 100644
index 000000000..fe4e93a88
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_bash_02.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:| @67
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o|r|e| @68
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|i+0#00e0e07#ffffff0|f@1|y|(|)| 
+0#0000000&|f+0#af5f00255&|o|r| |(@1|;@1|)@1| +0#0000000&@55
+|-+0#0000e05#a8a8a8255| >d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| 
+0#0000000&@63
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|i+0#0000000#ffffff0|f@1|y| @68
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |i+0#af5f00255#ffffff0|f| 
|:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@62
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|f+0#00e0e07&|u|n|c|t|i|o|n| 
+0#0000000&|!+0#00e0e07&|?|#|(|)| +0#0000000&@54
+|2+0#0000e05#a8a8a8255| | +0#00e0e07#ffffff0@3|(| +0#0000000&@67
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|f+0#00e0e07&|u|n|c|t|i|o|n| 
+0#0000000&|@+0#00e0e07&|α|!| |{| +0#0000000&@50
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@11|e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@51
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|}+0#00e0e07&| +0#0000000&@63
+|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|@|α|!+0#af5f00255&| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@56
+|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|)+0#00e0e07&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|e+0#af5f00255&|v|a|l| 
+0#0000000&|!+0#af5f00255&|?+0#0000000&|\+0#e000e06&|#| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@54
+@57|3|7|,|1| @9|8|6|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_bash_03.dump 
b/runtime/syntax/testdir/dumps/sh_functions_bash_03.dump
new file mode 100644
index 000000000..39a73d39c
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_bash_03.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|e+0#af5f00255&|v|a|l| 
+0#0000000&|!+0#af5f00255&|?+0#0000000&|\+0#e000e06&|#| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@54
+||+0#0000e05#a8a8a8255| |f+0#af5f00255#ffffff0|i| +0#0000000&@70
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |n+0#00e0e07#ffffff0|a|m|e|s|p|a|c|e| |(|)| 
+0#0000000&@60
+||+0#0000e05#a8a8a8255| |{+0#00e0e07#ffffff0| 
+0#0000000&|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|#|;+0#af5f00255&| 
+0#0000000&@62
+||+0#0000e05#a8a8a8255| >}+0#00e0e07#ffffff0|;+0#0000000&| |n|a|m|e|s|p|a|c|e| 
|$+0#e000e06&|@| +0#0000000&@57
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|5@1|,|1| @9|B|o|t| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_dash_00.dump 
b/runtime/syntax/testdir/dumps/sh_functions_dash_00.dump
new file mode 100644
index 000000000..f4465f4ea
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_dash_00.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1>#+0&#ffffff0|!|/|b|i|n|/|d|a|s|h| +0#0000000&@61
+| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| 
|s|e|t|l|o|c|a|l| |f|e|n| |f|d|c|=|2| |f|d|l|=|8| |f|d|m|=|s|y|n|t|a|x| 
+0#0000000&@20
+| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| 
|g|:|s|h|_|f|o|l|d|_|e|n|a|b|l|e|d| |=| |1| |+| |2| |+| |4| +0#0000000&@22
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(|)| +0#0000000&@64
+| +0#0000e05#a8a8a8255@1|u+0#af5f00255#ffffff0|n|t|i|l| |:| +0#0000000&@65
+|-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| 
+0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| 
|w|h|i|l|e|s| @32
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| 
+0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56
+||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| 
|e|l|s|e|w|h|e|r|e| @51
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| 
+0#0000000&|c+0#af5f00255&|a|s|e| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| 
+0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| 
+0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| 
|c|a|s|e|d| @33
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|i|s|_|d|a|s|h|:| |1|,| |i|s|_|p|o|s|i|x|:| |1|,| |i|s|_|s|h|:| |1|,| 
@22|1|,|1| @10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_dash_01.dump 
b/runtime/syntax/testdir/dumps/sh_functions_dash_01.dump
new file mode 100644
index 000000000..a0d7ba0e6
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_dash_01.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| 
+0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56
+||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| 
|e|l|s|e|w|h|e|r|e| @51
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| 
+0#0000000&|c+0#af5f00255&|a|s|e| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| 
+0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| 
+0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| 
|c|a|s|e|d| @33
+| +0#0000e05#a8a8a8255@1> +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(|)| +0#0000000&@66
+| +0#0000e05#a8a8a8255@1|f+0#af5f00255#ffffff0|o|r| +0#0000000&|x| 
|i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&| 
+0#0000000&@60
+|-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o|r|e| @68
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |i+0#af5f00255#ffffff0|f| 
|:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@62
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i+0#00e0e07&|d|2|(|)| 
+0#0000000&@63
+|2+0#0000e05#a8a8a8255| | +0#00e0e07#ffffff0@3|(| +0#0000000&@67
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|i+0#00e0e07&|d|1|(|)| |{| 
+0#0000000&@57
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@11|e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@51
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|}+0#00e0e07&| +0#0000000&@63
+@57|1|9|,|0|-|1| @7|6|1|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_dash_02.dump 
b/runtime/syntax/testdir/dumps/sh_functions_dash_02.dump
new file mode 100644
index 000000000..4f928ffc0
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_dash_02.dump
@@ -0,0 +1,20 @@
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|}+0#00e0e07&| +0#0000000&@63
+|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|i|d|1| 
|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@56
+|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|)+0#00e0e07&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i|d|2| 
|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@60
+||+0#0000e05#a8a8a8255| |f+0#af5f00255#ffffff0|i| +0#0000000&@70
+| +0#0000e05#a8a8a8255@1> +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |f+0#00e0e07#ffffff0|u|n|c|t|i|o|n| |(|)| 
+0#0000000&@61
+||+0#0000e05#a8a8a8255| |{+0#00e0e07#ffffff0| 
+0#0000000&|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|#|;+0#af5f00255&| 
+0#0000000&@62
+||+0#0000e05#a8a8a8255| |}+0#00e0e07#ffffff0|;+0#0000000&| |f|u|n|c|t|i|o|n| 
|$+0#e000e06&|@| +0#0000000&@58
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|3|7|,|0|-|1| @7|B|o|t| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh2020_00.dump 
b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_00.dump
new file mode 100644
index 000000000..8c4edd229
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_00.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1>#+0&#ffffff0|!|/|b|i|n|/|k|s|h|2|0|2|0| +0#0000000&@58
+| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| 
|s|e|t|l|o|c|a|l| |f|e|n| |f|d|c|=|2| |f|d|l|=|8| |f|d|m|=|s|y|n|t|a|x| 
+0#0000000&@20
+| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| 
|g|:|s|h|_|f|o|l|d|_|e|n|a|b|l|e|d| |=| |1| |+| |2| |+| |4| +0#0000000&@22
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|t+0#af5f00255#ffffff0|y|p|e|s|e|t| 
+0#0000000&|-+0#e000e06&|i| +0#0000000&|1+0#e000002&|0| 
+0#0000000&|n+0#00e0e07&|=+0#0000000&|0+0#e000002&| +0#0000000&@55
+| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(|)| 
+0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&|
 |d|o@1|s|i|e| @47
+| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(|)| 
+0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| 
+0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| 
|d|o|n|e@1| @46
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(|)| +0#0000000&@64
+| +0#0000e05#a8a8a8255@1|u+0#af5f00255#ffffff0|n|t|i|l| |:| +0#0000000&@65
+|-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| 
+0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| 
|w|h|i|l|e|s| @32
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| 
+0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56
+|i|s|_|k|o|r|n|s|h|e|l@1|:| |1|,| |i|s|_|k|s|h|2|0|2|0|:| |1|,| @25|1|,|1| 
@10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh2020_01.dump 
b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_01.dump
new file mode 100644
index 000000000..6e74c342d
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_01.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| 
+0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| 
|w|h|i|l|e|s| @32
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| 
+0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56
+||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| 
|e|l|s|e|w|h|e|r|e| @51
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(|)| 
+0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| 
+0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| 
|d+0#af5f00255&|o| +0#0000000&@42
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| 
+0#0000000&@63
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|e|l|e|c|t|o|r| 
|0+0#e000002&|<+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| 
|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| ||@1| |:| @35
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| 
+0#0000000&|c+0#af5f00255&|a|s|e| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| 
+0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| 
+0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| 
|c|a|s|e|d| @33
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(|)| +0#0000000&@66
+| +0#0000e05#a8a8a8255@1|f+0#af5f00255#ffffff0|o|r| +0#0000000&|x| 
|i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&| 
+0#0000000&@60
+|-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+@57|1|9|,|1| @9|4|0|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh2020_02.dump 
b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_02.dump
new file mode 100644
index 000000000..add584189
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_02.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o|r|e| @68
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|i+0#00e0e07#ffffff0|f@1|y|(|)| 
+0#0000000&|f+0#af5f00255&|o|r| |(@1|;@1|)@1| +0#0000000&@55
+|-+0#0000e05#a8a8a8255| >d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| 
+0#0000000&@63
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|i+0#0000000#ffffff0|f@1|y| @68
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |i+0#af5f00255#ffffff0|f| 
|:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@62
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i+0#00e0e07&|d|_|(|)| 
+0#0000000&@63
+|2+0#0000e05#a8a8a8255| | +0#00e0e07#ffffff0@3|(| +0#0000000&@67
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|f+0#00e0e07&|u|n|c|t|i|o|n| 
+0#0000000&|n+0#00e0e07&|.|s|e|t| |{| +0#0000000&@48
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@11|e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|n|"+0#af5f00255&| +0#0000000&@51
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|}+0#00e0e07&| +0#0000000&@63
+|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|d|o@1|s|i|e| @58
+|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|)+0#00e0e07&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i|d|_| 
|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@60
+@57|3|7|,|1| @9|9|6|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh2020_03.dump 
b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_03.dump
new file mode 100644
index 000000000..75a4b5a02
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_ksh2020_03.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i|d|_| 
|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@60
+||+0#0000e05#a8a8a8255| >f+0#af5f00255#ffffff0|i| +0#0000000&@70
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|5|1|,|1| @9|B|o|t| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh88_00.dump 
b/runtime/syntax/testdir/dumps/sh_functions_ksh88_00.dump
new file mode 100644
index 000000000..f4a6e0311
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_ksh88_00.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1>#+0&#ffffff0|!|/|b|i|n|/|k|s|h|8@1| +0#0000000&@60
+| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| 
|s|e|t|l|o|c|a|l| |f|e|n| |f|d|c|=|2| |f|d|l|=|8| |f|d|m|=|s|y|n|t|a|x| 
+0#0000000&@20
+| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| 
|g|:|s|h|_|f|o|l|d|_|e|n|a|b|l|e|d| |=| |1| |+| |2| |+| |4| +0#0000000&@22
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|t+0#af5f00255#ffffff0|y|p|e|s|e|t| 
+0#0000000&|-+0#e000e06&|i| +0#0000000&|1+0#e000002&|0| 
+0#0000000&|n+0#00e0e07&|=+0#0000000&|0+0#e000002&| +0#0000000&@55
+| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(|)| 
+0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&|
 |d|o@1|s|i|e| @47
+| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(|)| 
+0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| 
+0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| 
|d|o|n|e@1| @46
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(|)| +0#0000000&@64
+| +0#0000e05#a8a8a8255@1|u+0#af5f00255#ffffff0|n|t|i|l| |:| +0#0000000&@65
+|-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| 
+0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| 
|w|h|i|l|e|s| @32
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| 
+0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56
+|i|s|_|k|o|r|n|s|h|e|l@1|:| |1|,| |i|s|_|k|s|h|8@1|:| |1|,| @27|1|,|1| 
@10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh88_01.dump 
b/runtime/syntax/testdir/dumps/sh_functions_ksh88_01.dump
new file mode 100644
index 000000000..3426afb1a
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_ksh88_01.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| 
+0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| 
|w|h|i|l|e|s| @32
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| 
+0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56
+||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| 
|e|l|s|e|w|h|e|r|e| @51
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(|)| 
+0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| 
+0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| 
|d+0#af5f00255&|o| +0#0000000&@42
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| 
+0#0000000&@63
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|e|l|e|c|t|o|r| 
|0+0#e000002&|<+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| 
|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| ||@1| |:| @35
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| 
+0#0000000&|c+0#af5f00255&|a|s|e| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| 
+0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| 
+0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| 
|c|a|s|e|d| @33
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(|)| +0#0000000&@66
+| +0#0000e05#a8a8a8255@1|f+0#af5f00255#ffffff0|o|r| +0#0000000&|x| 
|i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&| 
+0#0000000&@60
+|-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+@57|1|9|,|1| @9|5|0|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_ksh88_02.dump 
b/runtime/syntax/testdir/dumps/sh_functions_ksh88_02.dump
new file mode 100644
index 000000000..967300cbb
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_ksh88_02.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o|r|e| @68
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |i+0#af5f00255#ffffff0|f| 
|:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@62
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3>i+0#00e0e07&|d|2|(|)| 
+0#0000000&@63
+|2+0#0000e05#a8a8a8255| | +0#00e0e07#ffffff0@3|(| +0#0000000&@67
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|f+0#00e0e07&|u|n|c|t|i|o|n| 
+0#0000000&|i+0#00e0e07&|d|1| |{| +0#0000000&@50
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@11|e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@51
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|}+0#00e0e07&| +0#0000000&@63
+|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|i|d|1| 
|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@56
+|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|)+0#00e0e07&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|i|d|2| 
|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@60
+||+0#0000e05#a8a8a8255| |f+0#af5f00255#ffffff0|i| +0#0000000&@70
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|3|7|,|5| @9|B|o|t| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_mksh_00.dump 
b/runtime/syntax/testdir/dumps/sh_functions_mksh_00.dump
new file mode 100644
index 000000000..ac300ee60
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_mksh_00.dump
@@ -0,0 +1,20 @@
+| +0#0000e05#a8a8a8255@1>#+0&#ffffff0|!|/|b|i|n|/|m|k|s|h| +0#0000000&@61
+| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| 
|s|e|t|l|o|c|a|l| |f|e|n| |f|d|c|=|2| |f|d|l|=|8| |f|d|m|=|s|y|n|t|a|x| 
+0#0000000&@20
+| +0#0000e05#a8a8a8255@1|#+0&#ffffff0| |V|I|M|_|T|E|S|T|_|S|E|T|U|P| |l|e|t| 
|g|:|s|h|_|f|o|l|d|_|e|n|a|b|l|e|d| |=| |1| |+| |2| |+| |4| +0#0000000&@22
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|t+0#af5f00255#ffffff0|y|p|e|s|e|t| 
+0#0000000&|-+0#e000e06&|i|1|0| 
+0#0000000&|n+0#00e0e07&|=+0#0000000&|0+0#e000002&| +0#0000000&@56
+| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o@1|s|i|e|(|)| 
+0#0000000&|(+0#e000e06&@1|n+0#0000000&|++0#af5f00255&|=|1+0#e000002&|)+0#e000e06&@1|;+0#0000000&|
 |d|o@1|s|i|e| @47
+| +0#0000e05#a8a8a8255@1|d+0#00e0e07#ffffff0|o|n|e@1|(|)| 
+0#0000000&|[+0#e000e06&@1| +0#0000000&|-+0#af5f00255&|n| 
+0#0000000&|$+0#e000e06&|#| +0#0000000&|]+0#e000e06&@1|;+0#0000000&| 
|d|o|n|e@1| @46
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|t+0#00e0e07#ffffff0|h|e|n|c|e|(|)| +0#0000000&@64
+| +0#0000e05#a8a8a8255@1|u+0#af5f00255#ffffff0|n|t|i|l| |:| +0#0000000&@65
+|-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| 
+0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| 
|w|h|i|l|e|s| @32
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| 
+0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56
+|i|s|_|k|o|r|n|s|h|e|l@1|:| |1|,| |i|s|_|m|k|s|h|:| |1|,| @28|1|,|1| 
@10|T|o|p| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_mksh_01.dump 
b/runtime/syntax/testdir/dumps/sh_functions_mksh_01.dump
new file mode 100644
index 000000000..3426afb1a
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_mksh_01.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|t+0#0000000#ffffff0|h|e|n|c|e| @66
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|w+0#00e0e07#ffffff0|h|i|l|e|s|(|)| 
+0#0000000&|w+0#af5f00255&|h|i|l|e| |f|a|l|s|e|;| |d|o| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|d+0#af5f00255&|o|n|e|;+0#0000000&| 
|w|h|i|l|e|s| @32
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| >e+0#00e0e07#ffffff0|l|s|e|w|h|e|r|e|(|)| 
+0#0000000&|i+0#af5f00255&|f| |:+0#0000000&| @56
+||+0#0000e05#a8a8a8255| |t+0#af5f00255#ffffff0|h|e|n| 
+0#0000000&|:|;+0#af5f00255&| +0#0000000&|f+0#af5f00255&|i|;+0#0000000&| 
|e|l|s|e|w|h|e|r|e| @51
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |s+0#00e0e07#ffffff0|e|l|e|c|t|o|r|(|)| 
+0#0000000&|s+0#af5f00255&|e|l|e|c|t| |x+0#0000000&| |i+0#af5f00255&|n| 
+0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&|;+0#0000000&| 
|d+0#af5f00255&|o| +0#0000000&@42
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|b+0#af5f00255&|r|e|a|k| 
+0#0000000&@63
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|s+0#0000000#ffffff0|e|l|e|c|t|o|r| 
|0+0#e000002&|<+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| 
|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1| ||@1| |:| @35
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|c+0#00e0e07#ffffff0|a|s|e|d|(|)| 
+0#0000000&|c+0#af5f00255&|a|s|e| 
+0#0000000&|"+0#af5f00255&|$+0#e000e06&|#|"+0#af5f00255&| 
+0#0000000&|i+0#af5f00255&|n| +0#0000000&|*|)+0#af5f00255&| 
+0#0000000&|:|;+0#af5f00255&@1| +0#0000000&|e+0#af5f00255&|s|a|c|;+0#0000000&| 
|c|a|s|e|d| @33
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+| +0#0000e05#a8a8a8255@1|f+0#00e0e07#ffffff0|o|r|e|(|)| +0#0000000&@66
+| +0#0000e05#a8a8a8255@1|f+0#af5f00255#ffffff0|o|r| +0#0000000&|x| 
|i+0#af5f00255&|n| +0#0000000&|1+0#e000002&| +0#0000000&|2+0#e000002&| 
+0#0000000&@60
+|-+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o| +0#0000000&@70
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+@57|1|9|,|1| @9|5|0|%| 
diff --git a/runtime/syntax/testdir/dumps/sh_functions_mksh_02.dump 
b/runtime/syntax/testdir/dumps/sh_functions_mksh_02.dump
new file mode 100644
index 000000000..a68196f10
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/sh_functions_mksh_02.dump
@@ -0,0 +1,20 @@
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|:+0#0000e05&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| |d+0#af5f00255#ffffff0|o|n|e| +0#0000000&@68
+| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0|o|r|e| @68
+| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@72
+|-+0#0000e05#a8a8a8255| |i+0#af5f00255#ffffff0|f| 
|:+0#0000000&|;+0#af5f00255&| +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@62
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3>%+0#00e0e07&@2|(|)| 
+0#0000000&@63
+|2+0#0000e05#a8a8a8255| | +0#00e0e07#ffffff0@3|(| +0#0000000&@67
+|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|f+0#00e0e07&|u|n|c|t|i|o|n| 
+0#0000000&|@+0#00e0e07&|a|:|(|)| |{| +0#0000000&@48
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@11|e+0#af5f00255&|c|h|o| 
+0#e000002&|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@51
+|3+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|}+0#00e0e07&| +0#0000000&@63
+|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@7|@|a|:| 
|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@56
+|2+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|)+0#00e0e07&| +0#0000000&@67
+||+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@3|%@2| 
|"+0#af5f00255&|$+0#e000e06&|1|"+0#af5f00255&| +0#0000000&@60
+||+0#0000e05#a8a8a8255| |f+0#af5f00255#ffffff0|i| +0#0000000&@70
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|3|7|,|5| @9|B|o|t| 
diff --git a/runtime/syntax/testdir/dumps/sh_generic_07.dump 
b/runtime/syntax/testdir/dumps/sh_generic_07.dump
index 2df86f775..0d12eeedb 100644
--- a/runtime/syntax/testdir/dumps/sh_generic_07.dump
+++ b/runtime/syntax/testdir/dumps/sh_generic_07.dump
@@ -3,7 +3,7 @@
 |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| 
|$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20
 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| 
+0#0000000&@43
 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| 
+0#0000000&|e+0#af5f00255&|v|a|l| 
+0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| 
|2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| 
+0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&|
 +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9
-| +0#00e0e07&@7>v|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
+@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50
 @8|}+0#00e0e07&| +0#0000000&@65
 @8|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{|||v|a|l|s|u|b|f|u|n|c| 
|t|e|n|}| +0#0000000&@43
diff --git a/runtime/syntax/testdir/dumps/sh_ksh2020_07.dump 
b/runtime/syntax/testdir/dumps/sh_ksh2020_07.dump
index e7b1f7c43..c2214f251 100644
--- a/runtime/syntax/testdir/dumps/sh_ksh2020_07.dump
+++ b/runtime/syntax/testdir/dumps/sh_ksh2020_07.dump
@@ -3,7 +3,7 @@
 |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| 
|$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20
 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| 
+0#0000000&@43
 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| 
+0#0000000&|e+0#af5f00255&|v|a|l| 
+0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| 
|2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| 
+0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&|
 +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9
-| +0#00e0e07&@7>v|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
+@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50
 @8|}+0#00e0e07&| +0#0000000&@65
 @8|e+0#af5f00255&|c|h|o| 
+0#e000002&|$+0#e000e06&|{||+0#ffffff16#ff404010|v|a|l|s|u|b|f|u|n|c| 
|t|e|n|}+0#e000e06#ffffff0| +0#0000000&@43
diff --git a/runtime/syntax/testdir/dumps/sh_ksh88_07.dump 
b/runtime/syntax/testdir/dumps/sh_ksh88_07.dump
index 9696c82b4..e7d559dac 100644
--- a/runtime/syntax/testdir/dumps/sh_ksh88_07.dump
+++ b/runtime/syntax/testdir/dumps/sh_ksh88_07.dump
@@ -3,7 +3,7 @@
 |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| 
|$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20
 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| 
+0#0000000&@43
 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| 
+0#0000000&|e+0#af5f00255&|v|a|l| 
+0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| 
|2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| 
+0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&|
 +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9
-| +0#00e0e07&@7>v|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
+@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50
 @8|}+0#00e0e07&| +0#0000000&@65
 @8|e+0#af5f00255&|c|h|o| 
+0#e000002&|$+0#e000e06&|{||+0#ffffff16#ff404010|v|a|l|s|u|b|f|u|n|c| 
|t|e|n|}+0#e000e06#ffffff0| +0#0000000&@43
diff --git a/runtime/syntax/testdir/dumps/sh_ksh93_generic_07.dump 
b/runtime/syntax/testdir/dumps/sh_ksh93_generic_07.dump
index e7b1f7c43..c2214f251 100644
--- a/runtime/syntax/testdir/dumps/sh_ksh93_generic_07.dump
+++ b/runtime/syntax/testdir/dumps/sh_ksh93_generic_07.dump
@@ -3,7 +3,7 @@
 |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| 
|$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20
 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| 
+0#0000000&@43
 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| 
+0#0000000&|e+0#af5f00255&|v|a|l| 
+0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| 
|2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| 
+0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&|
 +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9
-| +0#00e0e07&@7>v|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
+@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50
 @8|}+0#00e0e07&| +0#0000000&@65
 @8|e+0#af5f00255&|c|h|o| 
+0#e000002&|$+0#e000e06&|{||+0#ffffff16#ff404010|v|a|l|s|u|b|f|u|n|c| 
|t|e|n|}+0#e000e06#ffffff0| +0#0000000&@43
diff --git a/runtime/syntax/testdir/dumps/sh_ksh93u_07.dump 
b/runtime/syntax/testdir/dumps/sh_ksh93u_07.dump
index e7b1f7c43..c2214f251 100644
--- a/runtime/syntax/testdir/dumps/sh_ksh93u_07.dump
+++ b/runtime/syntax/testdir/dumps/sh_ksh93u_07.dump
@@ -3,7 +3,7 @@
 |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| 
|$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20
 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| 
+0#0000000&@43
 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| 
+0#0000000&|e+0#af5f00255&|v|a|l| 
+0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| 
|2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| 
+0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&|
 +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9
-| +0#00e0e07&@7>v|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
+@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50
 @8|}+0#00e0e07&| +0#0000000&@65
 @8|e+0#af5f00255&|c|h|o| 
+0#e000002&|$+0#e000e06&|{||+0#ffffff16#ff404010|v|a|l|s|u|b|f|u|n|c| 
|t|e|n|}+0#e000e06#ffffff0| +0#0000000&@43
diff --git a/runtime/syntax/testdir/dumps/sh_ksh93v_07.dump 
b/runtime/syntax/testdir/dumps/sh_ksh93v_07.dump
index e7b1f7c43..c2214f251 100644
--- a/runtime/syntax/testdir/dumps/sh_ksh93v_07.dump
+++ b/runtime/syntax/testdir/dumps/sh_ksh93v_07.dump
@@ -3,7 +3,7 @@
 |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| 
|$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20
 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| 
+0#0000000&@43
 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| 
+0#0000000&|e+0#af5f00255&|v|a|l| 
+0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| 
|2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| 
+0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&|
 +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9
-| +0#00e0e07&@7>v|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
+@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50
 @8|}+0#00e0e07&| +0#0000000&@65
 @8|e+0#af5f00255&|c|h|o| 
+0#e000002&|$+0#e000e06&|{||+0#ffffff16#ff404010|v|a|l|s|u|b|f|u|n|c| 
|t|e|n|}+0#e000e06#ffffff0| +0#0000000&@43
diff --git a/runtime/syntax/testdir/dumps/sh_mksh_07.dump 
b/runtime/syntax/testdir/dumps/sh_mksh_07.dump
index 2df86f775..0d12eeedb 100644
--- a/runtime/syntax/testdir/dumps/sh_mksh_07.dump
+++ b/runtime/syntax/testdir/dumps/sh_mksh_07.dump
@@ -3,7 +3,7 @@
 |#+0#0000e05&| |V|a|l|u|e| |s|u|b|s|t|i|t|u|t|i|o|n|s| |o|f| |t|h|e| |f|o|r|m| 
|$|{|||c|o|m@1|a|n|d|}| |a|r|e| |o|n|l|y| +0#0000000&@20
 |#+0#0000e05&| |s|u|p@1|o|r|t|e|d| |b|y| |m|k|s|h|,| |n|o|t| |k|s|h|9|3|.| 
+0#0000000&@43
 |i+0#af5f00255&|f| |!| +0#0000000&|c+0#af5f00255&|o|m@1|a|n|d| 
+0#0000000&|e+0#af5f00255&|v|a|l| 
+0#0000000&|'+0#af5f00255&|(+0#e000002&@1|.|s|h|.|v|e|r|s|i|o|n| |>|=| 
|2|0@1|7|0|7|0|3|)@1|'+0#af5f00255&| 
+0#0000000&|2+0#e000002&|>+0#af5f00255&|/+0#0000000&|d|e|v|/|n|u|l@1|;+0#af5f00255&|
 +0#0000000&|t+0#af5f00255&|h|e|n| +0#0000000&@9
-| +0#00e0e07&@7>v|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
+@8>v+0#00e0e07&|a|l|s|u|b|f|u|n|c|(|)| |{| +0#0000000&@52
 @16|R+0#e000e06&|E|P|L|Y|=+0#af5f00255&|$+0#e000e06&|1| +0#0000000&@50
 @8|}+0#00e0e07&| +0#0000000&@65
 @8|e+0#af5f00255&|c|h|o| +0#e000002&|$+0#e000e06&|{|||v|a|l|s|u|b|f|u|n|c| 
|t|e|n|}| +0#0000000&@43
diff --git a/runtime/syntax/testdir/dumps/sh_mksh_10.dump 
b/runtime/syntax/testdir/dumps/sh_mksh_10.dump
index 296f6a6e9..09847480a 100644
--- a/runtime/syntax/testdir/dumps/sh_mksh_10.dump
+++ b/runtime/syntax/testdir/dumps/sh_mksh_10.dump
@@ -3,9 +3,9 @@
 @8|t+0#af5f00255&|r|u|e| +0#0000000&@62
 |}+0#00e0e07&| +0#0000000&@73
 @75
->f+0#00e0e07&|u|n|c|t|i|o|n| 
+0#0000000&|.|s|h|.|t|i|l|d|e|.|s+0#af5f00255&|e|t| +0#00e0e07&|{+0#e000e06&| 
+0#0000000&@50
-| +0#00e0e07&@7|f+0#af5f00255&|a|l|s|e| +0#0000000&@61
-|}+0#e000e06&| +0#0000000&@73
+>f+0#00e0e07&|u|n|c|t|i|o|n| +0#0000000&|.+0#00e0e07&|s|h|.|t|i|l|d|e|.|s|e|t| 
|{| +0#0000000&@50
+@8|f+0#af5f00255&|a|l|s|e| +0#0000000&@61
+|}+0#00e0e07&| +0#0000000&@73
 @75
 |f+0#00e0e07&|u|n|c|t|i|o|n| +0#0000000&|f+0#00e0e07&|o@1|(|)| |{| 
+0#0000000&@58
 @8|:+0#0000e05&| +0#0000000&@1|#+0#0000e05&| |B|a|s|h|-|s|t|y|l|e| 
|f|u|n|c|t|i|o|n| |(|m|k|s|h|-|o|n|l|y|)| +0#0000000&@30
diff --git a/runtime/syntax/testdir/input/sh_functions_bash.sh 
b/runtime/syntax/testdir/input/sh_functions_bash.sh
new file mode 100644
index 000000000..161f14f97
--- /dev/null
+++ b/runtime/syntax/testdir/input/sh_functions_bash.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# VIM_TEST_SETUP setlocal fen fdc=2 fdl=8 fdm=syntax
+# VIM_TEST_SETUP let g:sh_fold_enabled = 1 + 2 + 4
+
+
+typeset -i n=0
+doosie() ((n+=1)); doosie
+donee() [[ -n $# ]]; donee
+
+thence()
+until :
+do
+    :
+done
+thence
+
+whiles() while false; do :; done; whiles
+
+elsewhere() if :
+then :; fi; elsewhere
+
+selector() select x in 1 2; do
+    break
+done
+selector 0</dev/null 2>/dev/null || :
+
+cased() case "$#" in *) :;; esac; cased
+
+fore()
+for x in 1 2
+do
+    :
+done
+fore
+
+iffy() for ((;;))
+do
+    break
+done
+iffy
+
+if :; then
+    function !?#()
+    (
+        function @α! {
+            echo "$1"
+        }
+        @α! "$1"
+    )
+    eval !?\# "$1"
+fi
+
+namespace ()
+{ echo $#;
+}; namespace $@
diff --git a/runtime/syntax/testdir/input/sh_functions_dash.sh 
b/runtime/syntax/testdir/input/sh_functions_dash.sh
new file mode 100644
index 000000000..15b133ab9
--- /dev/null
+++ b/runtime/syntax/testdir/input/sh_functions_dash.sh
@@ -0,0 +1,40 @@
+#!/bin/dash
+# VIM_TEST_SETUP setlocal fen fdc=2 fdl=8 fdm=syntax
+# VIM_TEST_SETUP let g:sh_fold_enabled = 1 + 2 + 4
+
+
+thence()
+until :
+do
+    :
+done
+thence
+
+whiles() while false; do :; done; whiles
+
+elsewhere() if :
+then :; fi; elsewhere
+
+cased() case "$#" in *) :;; esac; cased
+
+fore()
+for x in 1 2
+do
+    :
+done
+fore
+
+if :; then
+    id2()
+    (
+        id1() {
+            echo "$1"
+        }
+        id1 "$1"
+    )
+    id2 "$1"
+fi
+
+function ()
+{ echo $#;
+}; function $@
diff --git a/runtime/syntax/testdir/input/sh_functions_ksh2020.sh 
b/runtime/syntax/testdir/input/sh_functions_ksh2020.sh
new file mode 100644
index 000000000..0a1b21ede
--- /dev/null
+++ b/runtime/syntax/testdir/input/sh_functions_ksh2020.sh
@@ -0,0 +1,51 @@
+#!/bin/ksh2020
+# VIM_TEST_SETUP setlocal fen fdc=2 fdl=8 fdm=syntax
+# VIM_TEST_SETUP let g:sh_fold_enabled = 1 + 2 + 4
+
+
+typeset -i 10 n=0
+doosie() ((n+=1)); doosie
+donee() [[ -n $# ]]; donee
+
+thence()
+until :
+do
+    :
+done
+thence
+
+whiles() while false; do :; done; whiles
+
+elsewhere() if :
+then :; fi; elsewhere
+
+selector() select x in 1 2; do
+    break
+done
+selector 0</dev/null 2>/dev/null || :
+
+cased() case "$#" in *) :;; esac; cased
+
+fore()
+for x in 1 2
+do
+    :
+done
+fore
+
+iffy() for ((;;))
+do
+    break
+done
+iffy
+
+if :; then
+    id_()
+    (
+        function n.set {
+            echo "$n"
+        }
+        doosie
+    )
+    id_ "$1"
+fi
diff --git a/runtime/syntax/testdir/input/sh_functions_ksh88.sh 
b/runtime/syntax/testdir/input/sh_functions_ksh88.sh
new file mode 100644
index 000000000..d2eae00f8
--- /dev/null
+++ b/runtime/syntax/testdir/input/sh_functions_ksh88.sh
@@ -0,0 +1,45 @@
+#!/bin/ksh88
+# VIM_TEST_SETUP setlocal fen fdc=2 fdl=8 fdm=syntax
+# VIM_TEST_SETUP let g:sh_fold_enabled = 1 + 2 + 4
+
+
+typeset -i 10 n=0
+doosie() ((n+=1)); doosie
+donee() [[ -n $# ]]; donee
+
+thence()
+until :
+do
+    :
+done
+thence
+
+whiles() while false; do :; done; whiles
+
+elsewhere() if :
+then :; fi; elsewhere
+
+selector() select x in 1 2; do
+    break
+done
+selector 0</dev/null 2>/dev/null || :
+
+cased() case "$#" in *) :;; esac; cased
+
+fore()
+for x in 1 2
+do
+    :
+done
+fore
+
+if :; then
+    id2()
+    (
+        function id1 {
+            echo "$1"
+        }
+        id1 "$1"
+    )
+    id2 "$1"
+fi
diff --git a/runtime/syntax/testdir/input/sh_functions_mksh.sh 
b/runtime/syntax/testdir/input/sh_functions_mksh.sh
new file mode 100644
index 000000000..04b56bb5a
--- /dev/null
+++ b/runtime/syntax/testdir/input/sh_functions_mksh.sh
@@ -0,0 +1,45 @@
+#!/bin/mksh
+# VIM_TEST_SETUP setlocal fen fdc=2 fdl=8 fdm=syntax
+# VIM_TEST_SETUP let g:sh_fold_enabled = 1 + 2 + 4
+
+
+typeset -i10 n=0
+doosie() ((n+=1)); doosie
+donee() [[ -n $# ]]; donee
+
+thence()
+until :
+do
+    :
+done
+thence
+
+whiles() while false; do :; done; whiles
+
+elsewhere() if :
+then :; fi; elsewhere
+
+selector() select x in 1 2; do
+    break
+done
+selector 0</dev/null 2>/dev/null || :
+
+cased() case "$#" in *) :;; esac; cased
+
+fore()
+for x in 1 2
+do
+    :
+done
+fore
+
+if :; then
+    %%%()
+    (
+        function @a:() {
+            echo "$1"
+        }
+        @a: "$1"
+    )
+    %%% "$1"
+fi

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1w58cZ-004CdT-Tw%40256bit.org.

Raspunde prin e-mail lui