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
|