vinter 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +13 -0
- data/README.md +1 -5
- data/lib/vinter/lexer.rb +125 -32
- data/lib/vinter/parser.rb +913 -50
- data/lib/vinter.rb +1 -1
- metadata +4 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 7a7797098bc2eb7d9b046c4aa38d9d485fbee3016a709bda2f29ad0664b9d0de
         | 
| 4 | 
            +
              data.tar.gz: 807321a96f56c648922fc2b5923d8ccdfea6f6d8c8faa5fc3b844ddd4b6840ac
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4eb35205f6802d60d1c3070d7e8ff705d556367b4afc9c969cdfad3e560af3be646dcf13b4f7d59eaba0b0ed6cc61b130ce4cd952a529b5a4d5adfcae8339d6b
         | 
| 7 | 
            +
              data.tar.gz: '09ace9f8871da9f426f7efcf77e37962b466dcafbbc053725b2ffda42d51d47bd9c98a57dcaa191d51f7dface73ee2a8885fff5f30619c8c67636ff1e5218113'
         | 
    
        data/LICENSE
    ADDED
    
    | @@ -0,0 +1,13 @@ | |
| 1 | 
            +
                       DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
         | 
| 2 | 
            +
                               Version 2, December 2004
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Everyone is permitted to copy and distribute verbatim or modified
         | 
| 7 | 
            +
            copies of this license document, and changing it is allowed as long
         | 
| 8 | 
            +
            as the name is changed.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                       DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
         | 
| 11 | 
            +
              TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
         | 
| 12 | 
            +
             | 
| 13 | 
            +
             0. You just DO WHAT THE FUCK YOU WANT TO.
         | 
    
        data/README.md
    CHANGED
    
    | @@ -88,8 +88,4 @@ issues = linter.lint(content) | |
| 88 88 | 
             
            2. Create a feature branch: `git checkout -b my-new-feature`
         | 
| 89 89 | 
             
            3. Commit your changes: `git commit -am 'Add some feature'`
         | 
| 90 90 | 
             
            4. Push to the branch: `git push origin my-new-feature`
         | 
| 91 | 
            -
            5. Submit a pull request
         | 
| 92 | 
            -
             | 
| 93 | 
            -
            ## License
         | 
| 94 | 
            -
             | 
| 95 | 
            -
            This project is licensed under the MIT License - see the LICENSE file for details.
         | 
| 91 | 
            +
            5. Submit a pull request
         | 
    
        data/lib/vinter/lexer.rb
    CHANGED
    
    | @@ -2,7 +2,7 @@ module Vinter | |
| 2 2 | 
             
              class Lexer
         | 
| 3 3 | 
             
                TOKEN_TYPES = {
         | 
| 4 4 | 
             
                  # Vim9 specific keywords
         | 
| 5 | 
            -
                  keyword: /\b(if|else|elseif|endif|while|endwhile|for|endfor|def|enddef|function|endfunction|return|const|var|final|import|export|class|extends|static|enum|type|vim9script|abort)\b/,
         | 
| 5 | 
            +
                  keyword: /\b(if|else|elseif|endif|while|endwhile|for|endfor|def|enddef|function|endfunction|return|const|var|final|import|export|class|extends|static|enum|type|vim9script|abort|autocmd|echohl|echomsg|let|execute)\b/,
         | 
| 6 6 | 
             
                  # Identifiers can include # and special characters
         | 
| 7 7 | 
             
                  identifier: /\b[a-zA-Z_][a-zA-Z0-9_#]*\b/,
         | 
| 8 8 | 
             
                  # Single-character operators
         | 
| @@ -23,8 +23,10 @@ module Vinter | |
| 23 23 | 
             
                  colon: /:/,
         | 
| 24 24 | 
             
                  semicolon: /;/,
         | 
| 25 25 | 
             
                  comma: /,/,
         | 
| 26 | 
            +
                  backslash: /\\/,
         | 
| 26 27 | 
             
                }
         | 
| 27 28 |  | 
| 29 | 
            +
                CONTINUATION_OPERATORS = %w(. .. + - * / = == != > < >= <= && || ? : -> =>)
         | 
| 28 30 | 
             
                def initialize(input)
         | 
| 29 31 | 
             
                  @input = input
         | 
| 30 32 | 
             
                  @tokens = []
         | 
| @@ -37,32 +39,110 @@ module Vinter | |
| 37 39 | 
             
                  until @position >= @input.length
         | 
| 38 40 | 
             
                    chunk = @input[@position..-1]
         | 
| 39 41 |  | 
| 40 | 
            -
                    # Handle  | 
| 41 | 
            -
                    if match = chunk.match(/\A | 
| 42 | 
            -
                      @tokens << { | 
| 43 | 
            -
                        type: : | 
| 44 | 
            -
                        value: match[0], | 
| 45 | 
            -
                        line: @line_num, | 
| 46 | 
            -
                        column: @column | 
| 42 | 
            +
                    # Handle Vim option variables with & prefix
         | 
| 43 | 
            +
                    if match = chunk.match(/\A&[a-zA-Z_][a-zA-Z0-9_]*/)
         | 
| 44 | 
            +
                      @tokens << {
         | 
| 45 | 
            +
                        type: :option_variable,
         | 
| 46 | 
            +
                        value: match[0],
         | 
| 47 | 
            +
                        line: @line_num,
         | 
| 48 | 
            +
                        column: @column
         | 
| 49 | 
            +
                      }
         | 
| 50 | 
            +
                      @column += match[0].length
         | 
| 51 | 
            +
                      @position += match[0].length
         | 
| 52 | 
            +
                      next
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
                    
         | 
| 55 | 
            +
                    # Handle Vim special variables with v: prefix
         | 
| 56 | 
            +
                    if match = chunk.match(/\Av:[a-zA-Z_][a-zA-Z0-9_]*/)
         | 
| 57 | 
            +
                      @tokens << {
         | 
| 58 | 
            +
                        type: :special_variable,
         | 
| 59 | 
            +
                        value: match[0],
         | 
| 60 | 
            +
                        line: @line_num,
         | 
| 61 | 
            +
                        column: @column
         | 
| 62 | 
            +
                      }
         | 
| 63 | 
            +
                      @column += match[0].length
         | 
| 64 | 
            +
                      @position += match[0].length
         | 
| 65 | 
            +
                      next
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                    
         | 
| 68 | 
            +
                    # Handle script-local identifiers with s: prefix
         | 
| 69 | 
            +
                    if match = chunk.match(/\As:[a-zA-Z_][a-zA-Z0-9_]*/)
         | 
| 70 | 
            +
                      @tokens << {
         | 
| 71 | 
            +
                        type: :script_local,
         | 
| 72 | 
            +
                        value: match[0],
         | 
| 73 | 
            +
                        line: @line_num,
         | 
| 74 | 
            +
                        column: @column
         | 
| 75 | 
            +
                      }
         | 
| 76 | 
            +
                      @column += match[0].length
         | 
| 77 | 
            +
                      @position += match[0].length
         | 
| 78 | 
            +
                      next
         | 
| 79 | 
            +
                    end
         | 
| 80 | 
            +
                    
         | 
| 81 | 
            +
                    # Handle global variables with g: prefix
         | 
| 82 | 
            +
                    if match = chunk.match(/\Ag:[a-zA-Z_][a-zA-Z0-9_]*/)
         | 
| 83 | 
            +
                      @tokens << {
         | 
| 84 | 
            +
                        type: :global_variable,
         | 
| 85 | 
            +
                        value: match[0],
         | 
| 86 | 
            +
                        line: @line_num,
         | 
| 87 | 
            +
                        column: @column
         | 
| 88 | 
            +
                      }
         | 
| 89 | 
            +
                      @column += match[0].length
         | 
| 90 | 
            +
                      @position += match[0].length
         | 
| 91 | 
            +
                      next
         | 
| 92 | 
            +
                    end
         | 
| 93 | 
            +
                    
         | 
| 94 | 
            +
                    # Handle argument variables with a: prefix
         | 
| 95 | 
            +
                    if match = chunk.match(/\Aa:[a-zA-Z_][a-zA-Z0-9_]*/)
         | 
| 96 | 
            +
                      @tokens << {
         | 
| 97 | 
            +
                        type: :arg_variable,
         | 
| 98 | 
            +
                        value: match[0],
         | 
| 99 | 
            +
                        line: @line_num,
         | 
| 100 | 
            +
                        column: @column
         | 
| 47 101 | 
             
                      }
         | 
| 48 102 | 
             
                      @column += match[0].length
         | 
| 49 103 | 
             
                      @position += match[0].length
         | 
| 50 104 | 
             
                      next
         | 
| 51 105 | 
             
                    end
         | 
| 52 106 |  | 
| 107 | 
            +
                    # Handle compound assignment operators
         | 
| 108 | 
            +
                    if match = chunk.match(/\A(\+=|-=|\*=|\/=|\.\.=)/)
         | 
| 109 | 
            +
                      @tokens << {
         | 
| 110 | 
            +
                        type: :compound_operator,
         | 
| 111 | 
            +
                        value: match[0],
         | 
| 112 | 
            +
                        line: @line_num,
         | 
| 113 | 
            +
                        column: @column
         | 
| 114 | 
            +
                      }
         | 
| 115 | 
            +
                      @column += match[0].length
         | 
| 116 | 
            +
                      @position += match[0].length
         | 
| 117 | 
            +
                      next
         | 
| 118 | 
            +
                    end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                    # Handle multi-character operators explicitly
         | 
| 121 | 
            +
                    if match = chunk.match(/\A(==|!=|=>|->|\.\.|\|\||&&)/)
         | 
| 122 | 
            +
                      @tokens << {
         | 
| 123 | 
            +
                        type: :operator,
         | 
| 124 | 
            +
                        value: match[0],
         | 
| 125 | 
            +
                        line: @line_num,
         | 
| 126 | 
            +
                        column: @column
         | 
| 127 | 
            +
                      }
         | 
| 128 | 
            +
                      @column += match[0].length
         | 
| 129 | 
            +
                      @position += match[0].length
         | 
| 130 | 
            +
                      next
         | 
| 131 | 
            +
                    end
         | 
| 132 | 
            +
             | 
| 53 133 | 
             
                    # Handle ellipsis for variable args
         | 
| 54 134 | 
             
                    if chunk.start_with?('...')
         | 
| 55 | 
            -
                      @tokens << { | 
| 56 | 
            -
                        type: :ellipsis, | 
| 57 | 
            -
                        value: '...', | 
| 58 | 
            -
                        line: @line_num, | 
| 59 | 
            -
                        column: @column | 
| 135 | 
            +
                      @tokens << {
         | 
| 136 | 
            +
                        type: :ellipsis,
         | 
| 137 | 
            +
                        value: '...',
         | 
| 138 | 
            +
                        line: @line_num,
         | 
| 139 | 
            +
                        column: @column
         | 
| 60 140 | 
             
                      }
         | 
| 61 141 | 
             
                      @column += 3
         | 
| 62 142 | 
             
                      @position += 3
         | 
| 63 143 | 
             
                      next
         | 
| 64 144 | 
             
                    end
         | 
| 65 | 
            -
             | 
| 145 | 
            +
             | 
| 66 146 | 
             
                    # Skip whitespace but track position
         | 
| 67 147 | 
             
                    if match = chunk.match(/\A(\s+)/)
         | 
| 68 148 | 
             
                      whitespace = match[0]
         | 
| @@ -77,20 +157,33 @@ module Vinter | |
| 77 157 | 
             
                      @position += whitespace.length
         | 
| 78 158 | 
             
                      next
         | 
| 79 159 | 
             
                    end
         | 
| 80 | 
            -
             | 
| 160 | 
            +
             | 
| 161 | 
            +
                    # Handle backslash for line continuation
         | 
| 162 | 
            +
                    if chunk.start_with?('\\')
         | 
| 163 | 
            +
                      @tokens << {
         | 
| 164 | 
            +
                        type: :backslash,
         | 
| 165 | 
            +
                        value: '\\',
         | 
| 166 | 
            +
                        line: @line_num,
         | 
| 167 | 
            +
                        column: @column
         | 
| 168 | 
            +
                      }
         | 
| 169 | 
            +
                      @column += 1
         | 
| 170 | 
            +
                      @position += 1
         | 
| 171 | 
            +
                      next
         | 
| 172 | 
            +
                    end
         | 
| 173 | 
            +
             | 
| 81 174 | 
             
                    match_found = false
         | 
| 82 | 
            -
             | 
| 175 | 
            +
             | 
| 83 176 | 
             
                    TOKEN_TYPES.each do |type, pattern|
         | 
| 84 177 | 
             
                      if match = chunk.match(/\A(#{pattern})/)
         | 
| 85 178 | 
             
                        value = match[0]
         | 
| 86 | 
            -
                        token = { | 
| 87 | 
            -
                          type: type, | 
| 88 | 
            -
                          value: value, | 
| 89 | 
            -
                          line: @line_num, | 
| 90 | 
            -
                          column: @column | 
| 179 | 
            +
                        token = {
         | 
| 180 | 
            +
                          type: type,
         | 
| 181 | 
            +
                          value: value,
         | 
| 182 | 
            +
                          line: @line_num,
         | 
| 183 | 
            +
                          column: @column
         | 
| 91 184 | 
             
                        }
         | 
| 92 185 | 
             
                        @tokens << token unless type == :whitespace
         | 
| 93 | 
            -
             | 
| 186 | 
            +
             | 
| 94 187 | 
             
                        # Update position
         | 
| 95 188 | 
             
                        if value.include?("\n")
         | 
| 96 189 | 
             
                          lines = value.split("\n")
         | 
| @@ -103,33 +196,33 @@ module Vinter | |
| 103 196 | 
             
                        else
         | 
| 104 197 | 
             
                          @column += value.length
         | 
| 105 198 | 
             
                        end
         | 
| 106 | 
            -
             | 
| 199 | 
            +
             | 
| 107 200 | 
             
                        @position += value.length
         | 
| 108 201 | 
             
                        match_found = true
         | 
| 109 202 | 
             
                        break
         | 
| 110 203 | 
             
                      end
         | 
| 111 204 | 
             
                    end
         | 
| 112 | 
            -
             | 
| 205 | 
            +
             | 
| 113 206 | 
             
                    unless match_found
         | 
| 114 207 | 
             
                      # Try to handle unknown characters
         | 
| 115 | 
            -
                      @tokens << { | 
| 116 | 
            -
                        type: :unknown, | 
| 117 | 
            -
                        value: chunk[0], | 
| 118 | 
            -
                        line: @line_num, | 
| 119 | 
            -
                        column: @column | 
| 208 | 
            +
                      @tokens << {
         | 
| 209 | 
            +
                        type: :unknown,
         | 
| 210 | 
            +
                        value: chunk[0],
         | 
| 211 | 
            +
                        line: @line_num,
         | 
| 212 | 
            +
                        column: @column
         | 
| 120 213 | 
             
                      }
         | 
| 121 | 
            -
             | 
| 214 | 
            +
             | 
| 122 215 | 
             
                      if chunk[0] == "\n"
         | 
| 123 216 | 
             
                        @line_num += 1
         | 
| 124 217 | 
             
                        @column = 1
         | 
| 125 218 | 
             
                      else
         | 
| 126 219 | 
             
                        @column += 1
         | 
| 127 220 | 
             
                      end
         | 
| 128 | 
            -
             | 
| 221 | 
            +
             | 
| 129 222 | 
             
                      @position += 1
         | 
| 130 223 | 
             
                    end
         | 
| 131 224 | 
             
                  end
         | 
| 132 | 
            -
             | 
| 225 | 
            +
             | 
| 133 226 | 
             
                  @tokens
         | 
| 134 227 | 
             
                end
         | 
| 135 228 | 
             
              end
         |