v / vlib / v2 / token / token.v
377 lines · 365 sloc · 7.4 KB · 09cc0c5133d075ee6dcff29286dce7eb7d4421da
Raw
1// Copyright (c) 2020-2024 Joe Conigliaro. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module token
5
6pub enum Token {
7 amp // &
8 and // &&
9 and_assign // &=
10 arrow // <-
11 assign // =
12 // at // @
13 attribute
14 bit_not // ~
15 char // `A` - rune
16 colon // :
17 comma // ,
18 comment
19 dec // --
20 decl_assign // :=
21 div // /
22 div_assign // /=
23 dollar // $
24 dot // .
25 dotdot // ..
26 ellipsis // ...
27 eof
28 eq // ==
29 ge // >=
30 gt // >
31 hash // #
32 inc // ++
33 key_as
34 key_asm
35 key_assert
36 key_atomic
37 key_break
38 key_const
39 key_continue
40 key_defer
41 key_dump
42 key_else
43 key_enum
44 key_false
45 key_fn
46 key_for
47 key_global
48 key_go
49 key_goto
50 key_if
51 key_import
52 key_in
53 key_interface
54 key_is
55 key_isreftype
56 key_likely
57 key_lock
58 key_match
59 key_module
60 key_mut
61 key_nil
62 key_none
63 key_offsetof
64 key_or
65 key_pub
66 key_return
67 key_rlock
68 key_select
69 key_shared
70 key_sizeof
71 key_spawn
72 key_static
73 key_struct
74 key_true
75 key_type
76 key_typeof
77 key_union
78 key_unlikely
79 key_unsafe
80 key_volatile
81 lcbr // {
82 le // <=
83 left_shift // <<
84 left_shift_assign // >>=
85 logical_or // ||
86 lpar // (
87 lsbr // [
88 lt // <
89 minus // -
90 minus_assign // -=
91 mod // %
92 mod_assign // %=
93 mul // *
94 mul_assign // *=
95 name // user
96 ne // !=
97 not // !
98 not_in // !in
99 not_is // !is
100 number // 123
101 or_assign // |=
102 pipe // |
103 plus // +
104 plus_assign // +=
105 question // ?
106 rcbr // }
107 right_shift // >>
108 right_shift_assign // <<=
109 right_shift_unsigned // >>>
110 right_shift_unsigned_assign // >>>=
111 rpar // )
112 rsbr // ]
113 semicolon // ;
114 str_dollar
115 string // 'foo'
116 unknown
117 xor // ^
118 xor_assign // ^=
119}
120
121pub enum BindingPower {
122 lowest
123 logical_or // ||
124 logical_and // &&
125 compare // ==, !=, <, <=, >, >=, in, !in, is, !is
126 bit_or // |
127 bit_xor // ^
128 shift // <<, >>, >>>
129 add // +, -
130 product // *, /, %, &
131 highest
132}
133
134@[inline]
135pub fn (t Token) left_binding_power() BindingPower {
136 return match t {
137 // `||`
138 .logical_or {
139 BindingPower.logical_or
140 }
141 // `&&`
142 .and {
143 BindingPower.logical_and
144 }
145 // `==` | `!=` | `<` | `<=` | `>` | `>=` | `in` | `!in` | `is` | `!is`
146 .eq, .ne, .lt, .le, .gt, .ge, .key_in, .not_in, .key_is, .not_is {
147 BindingPower.compare
148 }
149 // `|`
150 .pipe {
151 BindingPower.bit_or
152 }
153 // `^`
154 .xor {
155 BindingPower.bit_xor
156 }
157 // `<<` | `>>` | `>>>`
158 .left_shift, .right_shift, .right_shift_unsigned {
159 BindingPower.shift
160 }
161 // `+` | `-`
162 .plus, .minus {
163 BindingPower.add
164 }
165 // `*` | `/` | `%` | `&`
166 .mul, .div, .mod, .amp {
167 BindingPower.product
168 }
169 else {
170 BindingPower.lowest
171 }
172 }
173}
174
175// TODO: double check / fix this. just use what is needed instead of this
176@[inline]
177pub fn (t Token) right_binding_power() BindingPower {
178 return unsafe { BindingPower((int(t.left_binding_power()) + 1)) }
179}
180
181@[inline]
182pub fn (t Token) is_keyword() bool {
183 return int(t) >= int(Token.key_as) && int(t) <= int(Token.key_volatile)
184}
185
186@[inline]
187pub fn (t Token) is_prefix() bool {
188 return t in [.minus, .amp, .mul, .not, .bit_not, .arrow]
189}
190
191@[inline]
192pub fn (t Token) is_infix() bool {
193 return t in [
194 .amp,
195 .and,
196 .arrow,
197 .div,
198 // .dot,
199 .eq,
200 .ge,
201 .gt,
202 // .key_as,
203 .key_in,
204 .key_is,
205 .le,
206 .left_shift,
207 .logical_or,
208 .lt,
209 .minus,
210 .mod,
211 .mul,
212 .ne,
213 .not_in,
214 .not_is,
215 .pipe,
216 .plus,
217 .right_shift,
218 .right_shift_unsigned,
219 .xor,
220 ]
221}
222
223@[inline]
224pub fn (t Token) is_postfix() bool {
225 return t in [.dec, .inc]
226 // return t in [.dec, .inc, .not, .question]
227}
228
229@[inline]
230pub fn (t Token) is_assignment() bool {
231 return t in [
232 .and_assign,
233 .assign,
234 .decl_assign,
235 .div_assign,
236 .left_shift_assign,
237 .minus_assign,
238 .mod_assign,
239 .mul_assign,
240 .or_assign,
241 .plus_assign,
242 .right_shift_assign,
243 .right_shift_unsigned_assign,
244 .xor_assign,
245 ]
246}
247
248@[inline]
249pub fn (t Token) is_overloadable() bool {
250 // `/` | `==` | `>=` | `>` | `<=` | `<` | `-` | `%` | `*` | `!=` | `|` | `+` | `^`
251 return t in [.div, .eq, .ge, .gt, .le, .lt, .minus, .mod, .mul, .ne, .pipe, .plus, .xor]
252}
253
254@[inline]
255pub fn (t Token) is_comparison() bool {
256 // `==` | `>=` | `>` | `in` | `is` | `<=` | `<` | `!=` | `!in` | `!is`
257 return t in [.eq, .ge, .gt, .key_in, .key_is, .le, .lt, .ne, .not_in, .not_is]
258}
259
260// NOTE: probably switch back to map again later.
261// for dev this is easier to see if any tokens are missing.
262pub fn (t Token) str() string {
263 return match t {
264 .amp { '&' }
265 .and { '&&' }
266 .and_assign { '&=' }
267 .arrow { '<-' }
268 .assign { '=' }
269 // .at { '@' }
270 .attribute { '@[' }
271 .bit_not { '~' }
272 .char { 'char' }
273 .colon { ':' }
274 .comma { ',' }
275 .comment { '// comment' }
276 .dec { '--' }
277 .decl_assign { ':=' }
278 .div { '/' }
279 .div_assign { '/=' }
280 .dollar { '$' }
281 .dot { '.' }
282 .dotdot { '..' }
283 .ellipsis { '...' }
284 .eof { 'eof' }
285 .eq { '==' }
286 .ge { '>=' }
287 .gt { '>' }
288 .hash { '#' }
289 .inc { '++' }
290 .key_as { 'as' }
291 .key_asm { 'asm' }
292 .key_assert { 'assert' }
293 .key_atomic { 'atomic' }
294 .key_break { 'break' }
295 .key_const { 'const' }
296 .key_continue { 'continue' }
297 .key_defer { 'defer' }
298 .key_dump { 'dump' }
299 .key_else { 'else' }
300 .key_enum { 'enum' }
301 .key_false { 'false' }
302 .key_fn { 'fn' }
303 .key_for { 'for' }
304 .key_global { '__global' }
305 .key_go { 'go' }
306 .key_goto { 'goto' }
307 .key_if { 'if' }
308 .key_import { 'import' }
309 .key_in { 'in' }
310 .key_interface { 'interface' }
311 .key_is { 'is' }
312 .key_isreftype { 'isreftype' }
313 .key_likely { '_likely_' }
314 .key_lock { 'lock' }
315 .key_match { 'match' }
316 .key_module { 'module' }
317 .key_mut { 'mut' }
318 .key_nil { 'nil' }
319 .key_none { 'none' }
320 .key_offsetof { '__offsetof' }
321 .key_or { 'or' }
322 .key_pub { 'pub' }
323 .key_return { 'return' }
324 .key_rlock { 'rlock' }
325 .key_select { 'select' }
326 .key_shared { 'shared' }
327 .key_sizeof { 'sizeof' }
328 .key_spawn { 'spawn' }
329 .key_static { 'static' }
330 .key_struct { 'struct' }
331 .key_true { 'true' }
332 .key_type { 'type' }
333 .key_typeof { 'typeof' }
334 .key_union { 'union' }
335 .key_unlikely { '_unlikely_' }
336 .key_unsafe { 'unsafe' }
337 .key_volatile { 'volatile' }
338 .lcbr { '{' }
339 .le { '<=' }
340 .left_shift { '<<' }
341 .left_shift_assign { '<<=' }
342 .logical_or { '||' }
343 .lpar { '(' }
344 .lsbr { '[' }
345 .lt { '<' }
346 .minus { '-' }
347 .minus_assign { '-=' }
348 .mod { '%' }
349 .mod_assign { '%=' }
350 .mul { '*' }
351 .mul_assign { '*=' }
352 .name { 'name' }
353 .ne { '!=' }
354 .not { '!' }
355 .not_in { '!in' }
356 .not_is { '!is' }
357 .number { 'number' }
358 .or_assign { '|=' }
359 .pipe { '|' }
360 .plus { '+' }
361 .plus_assign { '+=' }
362 .question { '?' }
363 .rcbr { '}' }
364 .right_shift { '>>' }
365 .right_shift_assign { '>>=' }
366 .right_shift_unsigned { '>>>' }
367 .right_shift_unsigned_assign { '>>>=' }
368 .rpar { ')' }
369 .rsbr { ']' }
370 .semicolon { ';' }
371 .str_dollar { '\${' }
372 .string { 'string' }
373 .unknown { 'unknown' }
374 .xor { '^' }
375 .xor_assign { '^=' }
376 }
377}
378