| 1 | # This syntax is available with OSH too
 | 
| 2 | 
 | 
| 3 | #### ... with simple command
 | 
| 4 | ... echo  # comment
 | 
| 5 |     hi  # comment
 | 
| 6 |     there
 | 
| 7 |     ;
 | 
| 8 | echo ---
 | 
| 9 | ## STDOUT:
 | 
| 10 | hi there
 | 
| 11 | ---
 | 
| 12 | ## END
 | 
| 13 | 
 | 
| 14 | #### ... with pipeline
 | 
| 15 | ... { echo one; echo two; }
 | 
| 16 |   | sort
 | 
| 17 |   | wc -l
 | 
| 18 |   ;
 | 
| 19 | ## STDOUT:
 | 
| 20 | 2
 | 
| 21 | ## END
 | 
| 22 | 
 | 
| 23 | #### ... with multiline $()
 | 
| 24 | 
 | 
| 25 | # newlines mean the normal thing
 | 
| 26 | echo $(echo one
 | 
| 27 |        echo two)
 | 
| 28 | 
 | 
| 29 | ... echo
 | 
| 30 |     $(echo 3
 | 
| 31 |       echo 4)  # is this right?
 | 
| 32 |   | wc -l
 | 
| 33 |   ;
 | 
| 34 | ## STDOUT:
 | 
| 35 | one two
 | 
| 36 | 1
 | 
| 37 | ## END
 | 
| 38 | 
 | 
| 39 | #### ... inside command sub $()
 | 
| 40 | echo one $(... echo
 | 
| 41 |               two
 | 
| 42 |               three) four
 | 
| 43 | echo five
 | 
| 44 | ## STDOUT:
 | 
| 45 | one two three four
 | 
| 46 | five
 | 
| 47 | ## END
 | 
| 48 | 
 | 
| 49 | #### ... with && and [[
 | 
| 50 | echo one && false || echo two
 | 
| 51 | 
 | 
| 52 | ... echo three
 | 
| 53 |  && [[ 0 -eq 0 ]]
 | 
| 54 |  && echo four
 | 
| 55 |  && false
 | 
| 56 |  || echo five
 | 
| 57 |  ;
 | 
| 58 | 
 | 
| 59 | echo ---
 | 
| 60 | 
 | 
| 61 | ## STDOUT:
 | 
| 62 | one
 | 
| 63 | two
 | 
| 64 | three
 | 
| 65 | four
 | 
| 66 | five
 | 
| 67 | ---
 | 
| 68 | ## END
 | 
| 69 | 
 | 
| 70 | #### '... for' is allowed, but NOT recommended
 | 
| 71 | ... for x in foo bar; do echo $x; done
 | 
| 72 |     ;
 | 
| 73 | 
 | 
| 74 | ... for x in foo bar; do
 | 
| 75 |       echo $x;
 | 
| 76 |     done
 | 
| 77 |     ;
 | 
| 78 | 
 | 
| 79 | return
 | 
| 80 | 
 | 
| 81 | # This style gets messed up because of translation, but that is EXPECTED.
 | 
| 82 | ... for x in foo bar
 | 
| 83 |     do
 | 
| 84 |       echo $x;
 | 
| 85 |     done
 | 
| 86 |     ;
 | 
| 87 | 
 | 
| 88 | ## STDOUT:
 | 
| 89 | foo
 | 
| 90 | bar
 | 
| 91 | foo
 | 
| 92 | bar
 | 
| 93 | ## END
 | 
| 94 | 
 | 
| 95 | #### Blank line in multiline command is syntax error
 | 
| 96 | ... echo comment
 | 
| 97 |     # comment
 | 
| 98 |     is OK
 | 
| 99 |     ;
 | 
| 100 | 
 | 
| 101 | ... echo blank line
 | 
| 102 | 
 | 
| 103 |     is not OK
 | 
| 104 |     ;
 | 
| 105 | 
 | 
| 106 | ## status: 2
 | 
| 107 | ## STDOUT:
 | 
| 108 | comment is OK
 | 
| 109 | ## END
 | 
| 110 | 
 | 
| 111 | #### Blank line with spaces and tabs isn't OK either
 | 
| 112 | ... echo comment
 | 
| 113 |     # comment
 | 
| 114 |     is OK
 | 
| 115 |     ;
 | 
| 116 | 
 | 
| 117 | # NOTE: invisible spaces and tabs below (:set list in vim)
 | 
| 118 | ... echo blank line
 | 
| 119 |    
 | 
| 120 |     is not OK
 | 
| 121 |     ;
 | 
| 122 | ## status: 2
 | 
| 123 | ## STDOUT:
 | 
| 124 | comment is OK
 | 
| 125 | ## END
 | 
| 126 | 
 | 
| 127 | 
 | 
| 128 | 
 | 
| 129 | # Notes:
 | 
| 130 | # - MakeParserForCommandSub() instantiates a new WordParser, so we can safely
 | 
| 131 | # change state in the top-level one only
 | 
| 132 | # - BoolParser is called for [[ ]] and uses the same self.w_parser.  I think
 | 
| 133 | # that's OK?
 | 
| 134 | 
 | 
| 135 | # So I think we can change state in WordParser.  (Also possible in
 | 
| 136 | # CommandParser but meh).
 | 
| 137 | #
 | 
| 138 | # self.is_multiline = False
 | 
| 139 | #
 | 
| 140 | # When this is flag is on, then we
 | 
| 141 | #
 | 
| 142 | # Id.Op_Newline -> Id.WS_Space or Id.Ignored_LineCont
 | 
| 143 | #  - and then that is NOT passed to the command parser?
 | 
| 144 | #  - Or you can make it Id.Ignored_Newline
 | 
| 145 | #
 | 
| 146 | # BUT if you get 2 of them in a row without a comment, you can change it to:
 | 
| 147 | # - Id.Op_Newline?
 | 
| 148 | #
 | 
| 149 | # Actually this is very simple rule and maybe can be done without much
 | 
| 150 | # disturbance to the code.
 | 
| 151 | #
 | 
| 152 | # cursor_was_newline might need more state?
 | 
| 153 | 
 | 
| 154 | 
 | 
| 155 | #### Combine multi-line command and strings
 | 
| 156 | shopt -s oil:all
 | 
| 157 | 
 | 
| 158 | var x = 'one'
 | 
| 159 | 
 | 
| 160 | # Print 3 args without separators
 | 
| 161 | ... write --sep '' --end '' -- 
 | 
| 162 |     """
 | 
| 163 |     $x
 | 
| 164 |     """                         # 1. Double quoted
 | 
| 165 |     '''
 | 
| 166 |     two
 | 
| 167 |     three
 | 
| 168 |     '''                         # 2. Single quoted
 | 
| 169 |     $'four\n'                   # 3. C-style with explicit newline
 | 
| 170 |    | tac                        # Reverse
 | 
| 171 |    | tr a-z A-Z                 # Uppercase
 | 
| 172 |    ;
 | 
| 173 | 
 | 
| 174 | ## STDOUT:
 | 
| 175 | FOUR
 | 
| 176 | THREE
 | 
| 177 | TWO
 | 
| 178 | ONE
 | 
| 179 | ## END
 |