ether-code 0.1.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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +130 -0
  3. package/cli/compiler.js +298 -0
  4. package/cli/ether.js +532 -0
  5. package/cli/watcher.js +106 -0
  6. package/generators/css-generator.js +583 -0
  7. package/generators/graphql-generator.js +868 -0
  8. package/generators/html-generator.js +745 -0
  9. package/generators/js-generator.js +909 -0
  10. package/generators/node-generator.js +467 -0
  11. package/generators/php-generator.js +706 -0
  12. package/generators/python-generator.js +913 -0
  13. package/generators/react-generator.js +599 -0
  14. package/generators/ruby-generator.js +904 -0
  15. package/generators/sql-generator.js +988 -0
  16. package/generators/ts-generator.js +569 -0
  17. package/i18n/i18n-css.json +743 -0
  18. package/i18n/i18n-graphql.json +1531 -0
  19. package/i18n/i18n-html.json +572 -0
  20. package/i18n/i18n-js.json +2790 -0
  21. package/i18n/i18n-node.json +2442 -0
  22. package/i18n/i18n-php.json +4306 -0
  23. package/i18n/i18n-python.json +3080 -0
  24. package/i18n/i18n-react.json +1784 -0
  25. package/i18n/i18n-ruby.json +1858 -0
  26. package/i18n/i18n-sql.json +3466 -0
  27. package/i18n/i18n-ts.json +442 -0
  28. package/lexer/ether-lexer.js +728 -0
  29. package/lexer/tokens.js +292 -0
  30. package/package.json +45 -0
  31. package/parsers/ast-css.js +545 -0
  32. package/parsers/ast-graphql.js +424 -0
  33. package/parsers/ast-html.js +886 -0
  34. package/parsers/ast-js.js +750 -0
  35. package/parsers/ast-node.js +2440 -0
  36. package/parsers/ast-php.js +957 -0
  37. package/parsers/ast-react.js +580 -0
  38. package/parsers/ast-ruby.js +895 -0
  39. package/parsers/ast-ts.js +1352 -0
  40. package/parsers/css-parser.js +1981 -0
  41. package/parsers/graphql-parser.js +2011 -0
  42. package/parsers/html-parser.js +1181 -0
  43. package/parsers/js-parser.js +2564 -0
  44. package/parsers/node-parser.js +2644 -0
  45. package/parsers/php-parser.js +3037 -0
  46. package/parsers/react-parser.js +1035 -0
  47. package/parsers/ruby-parser.js +2680 -0
  48. package/parsers/ts-parser.js +3881 -0
@@ -0,0 +1,728 @@
1
+ const {
2
+ Token,
3
+ TokenType,
4
+ LANG_BLOCKS,
5
+ normalizeAccents,
6
+ isCompoundKeyword,
7
+ couldBeCompoundStart
8
+ } = require('./tokens')
9
+
10
+ class EtherLexer {
11
+ constructor(source, options = {}) {
12
+ this.source = source
13
+ this.pos = 0
14
+ this.line = 1
15
+ this.column = 1
16
+ this.tokens = []
17
+ this.indentStack = [0]
18
+ this.currentIndent = 0
19
+ this.atLineStart = true
20
+
21
+ this.options = {
22
+ trackComments: options.trackComments || false,
23
+ allowUnicode: options.allowUnicode !== false,
24
+ tabSize: options.tabSize || 2
25
+ }
26
+ }
27
+
28
+ peek(offset = 0) {
29
+ const idx = this.pos + offset
30
+ return idx < this.source.length ? this.source[idx] : null
31
+ }
32
+
33
+ advance() {
34
+ const char = this.source[this.pos]
35
+ this.pos++
36
+ if (char === '\n') {
37
+ this.line++
38
+ this.column = 1
39
+ this.atLineStart = true
40
+ } else {
41
+ this.column++
42
+ }
43
+ return char
44
+ }
45
+
46
+ match(expected) {
47
+ if (this.peek() === expected) {
48
+ this.advance()
49
+ return true
50
+ }
51
+ return false
52
+ }
53
+
54
+ isAtEnd() {
55
+ return this.pos >= this.source.length
56
+ }
57
+
58
+ isDigit(char) {
59
+ if (!char) return false
60
+ return char >= '0' && char <= '9'
61
+ }
62
+
63
+ isHexDigit(char) {
64
+ if (!char) return false
65
+ return this.isDigit(char) || (char >= 'a' && char <= 'f') || (char >= 'A' && char <= 'F')
66
+ }
67
+
68
+ isAlpha(char) {
69
+ if (!char) return false
70
+ const code = char.charCodeAt(0)
71
+ if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) return true
72
+ if (char === '_') return true
73
+ if (this.options.allowUnicode) {
74
+ if (code >= 0x00C0 && code <= 0x024F) return true
75
+ if (code >= 0x0400 && code <= 0x04FF) return true
76
+ if (code >= 0x4E00 && code <= 0x9FFF) return true
77
+ if (code >= 0x3040 && code <= 0x30FF) return true
78
+ if (code >= 0x0600 && code <= 0x06FF) return true
79
+ if (code >= 0x0370 && code <= 0x03FF) return true
80
+ }
81
+ return false
82
+ }
83
+
84
+ isAlphaNumeric(char) {
85
+ return this.isAlpha(char) || this.isDigit(char)
86
+ }
87
+
88
+ isWhitespace(char) {
89
+ if (!char) return false
90
+ return char === ' ' || char === '\t' || char === '\r'
91
+ }
92
+
93
+ addToken(type, value, startColumn = null) {
94
+ const col = startColumn !== null ? startColumn : this.column
95
+ this.tokens.push(new Token(type, value, this.line, col, this.currentIndent))
96
+ }
97
+
98
+ tokenize() {
99
+ while (!this.isAtEnd()) {
100
+ this.scanToken()
101
+ }
102
+
103
+ while (this.indentStack.length > 1) {
104
+ this.indentStack.pop()
105
+ this.tokens.push(new Token(TokenType.DEDENT, '', this.line, this.column, 0))
106
+ }
107
+
108
+ this.tokens.push(new Token(TokenType.EOF, '', this.line, this.column, 0))
109
+ return this.tokens
110
+ }
111
+
112
+ scanToken() {
113
+ if (this.atLineStart) {
114
+ this.handleIndentation()
115
+ if (this.isAtEnd()) return
116
+ }
117
+
118
+ const char = this.peek()
119
+
120
+ if (char === '\n') {
121
+ this.advance()
122
+ this.addToken(TokenType.NEWLINE, '\n')
123
+ return
124
+ }
125
+
126
+ if (this.isWhitespace(char)) {
127
+ this.advance()
128
+ return
129
+ }
130
+
131
+ if (char === '#') {
132
+ this.scanComment()
133
+ return
134
+ }
135
+
136
+ if (char === '/' && this.peek(1) === '/') {
137
+ this.scanComment()
138
+ return
139
+ }
140
+
141
+ if (char === '/' && this.peek(1) === '*') {
142
+ this.scanBlockComment()
143
+ return
144
+ }
145
+
146
+ if (char === '"' || char === "'") {
147
+ this.scanString(char)
148
+ return
149
+ }
150
+
151
+ if (char === '`') {
152
+ this.scanTemplateString()
153
+ return
154
+ }
155
+
156
+ if (this.isDigit(char) || (char === '-' && this.isDigit(this.peek(1)))) {
157
+ this.scanNumber()
158
+ return
159
+ }
160
+
161
+ if (this.isAlpha(char)) {
162
+ this.scanIdentifier()
163
+ return
164
+ }
165
+
166
+ this.scanOperator()
167
+ }
168
+
169
+ handleIndentation() {
170
+ let indent = 0
171
+ while (!this.isAtEnd() && (this.peek() === ' ' || this.peek() === '\t')) {
172
+ if (this.peek() === '\t') {
173
+ indent += this.options.tabSize
174
+ } else {
175
+ indent++
176
+ }
177
+ this.advance()
178
+ }
179
+
180
+ if (this.isAtEnd() || this.peek() === '\n' || this.peek() === '#') {
181
+ this.atLineStart = false
182
+ return
183
+ }
184
+
185
+ if (this.peek() === '/' && this.peek(1) === '/') {
186
+ this.atLineStart = false
187
+ return
188
+ }
189
+
190
+ this.currentIndent = indent
191
+ this.atLineStart = false
192
+
193
+ const currentLevel = this.indentStack[this.indentStack.length - 1]
194
+
195
+ if (indent > currentLevel) {
196
+ this.indentStack.push(indent)
197
+ this.tokens.push(new Token(TokenType.INDENT, indent, this.line, 1, indent))
198
+ } else if (indent < currentLevel) {
199
+ while (this.indentStack.length > 1 && this.indentStack[this.indentStack.length - 1] > indent) {
200
+ this.indentStack.pop()
201
+ this.tokens.push(new Token(TokenType.DEDENT, '', this.line, 1, indent))
202
+ }
203
+ if (this.indentStack[this.indentStack.length - 1] !== indent) {
204
+ this.tokens.push(new Token(TokenType.ERROR, 'Indentation incohérente', this.line, 1, indent))
205
+ }
206
+ }
207
+ }
208
+
209
+ scanComment() {
210
+ const startLine = this.line
211
+ const startCol = this.column
212
+ let comment = ''
213
+
214
+ if (this.peek() === '#') {
215
+ this.advance()
216
+ } else {
217
+ this.advance()
218
+ this.advance()
219
+ }
220
+
221
+ while (!this.isAtEnd() && this.peek() !== '\n') {
222
+ comment += this.advance()
223
+ }
224
+
225
+ if (this.options.trackComments) {
226
+ this.tokens.push(new Token(TokenType.COMMENT, comment.trim(), startLine, startCol, this.currentIndent))
227
+ }
228
+ }
229
+
230
+ scanBlockComment() {
231
+ const startLine = this.line
232
+ const startCol = this.column
233
+ let comment = ''
234
+
235
+ this.advance()
236
+ this.advance()
237
+
238
+ while (!this.isAtEnd()) {
239
+ if (this.peek() === '*' && this.peek(1) === '/') {
240
+ this.advance()
241
+ this.advance()
242
+ break
243
+ }
244
+ comment += this.advance()
245
+ }
246
+
247
+ if (this.options.trackComments) {
248
+ this.tokens.push(new Token(TokenType.BLOCK_COMMENT, comment.trim(), startLine, startCol, this.currentIndent))
249
+ }
250
+ }
251
+
252
+ scanString(quote) {
253
+ const startLine = this.line
254
+ const startCol = this.column
255
+ let value = ''
256
+ let isBlock = false
257
+
258
+ this.advance()
259
+
260
+ if (this.peek() === quote && this.peek(1) === quote) {
261
+ this.advance()
262
+ this.advance()
263
+ isBlock = true
264
+ }
265
+
266
+ while (!this.isAtEnd()) {
267
+ if (isBlock) {
268
+ if (this.peek() === quote && this.peek(1) === quote && this.peek(2) === quote) {
269
+ this.advance()
270
+ this.advance()
271
+ this.advance()
272
+ break
273
+ }
274
+ } else {
275
+ if (this.peek() === quote) {
276
+ this.advance()
277
+ break
278
+ }
279
+ if (this.peek() === '\n') {
280
+ this.tokens.push(new Token(TokenType.ERROR, 'Chaîne non terminée', startLine, startCol, this.currentIndent))
281
+ return
282
+ }
283
+ }
284
+
285
+ if (this.peek() === '\\' && !isBlock) {
286
+ this.advance()
287
+ const escaped = this.advance()
288
+ switch (escaped) {
289
+ case 'n': value += '\n'; break
290
+ case 't': value += '\t'; break
291
+ case 'r': value += '\r'; break
292
+ case '\\': value += '\\'; break
293
+ case "'": value += "'"; break
294
+ case '"': value += '"'; break
295
+ case '0': value += '\0'; break
296
+ case 'x':
297
+ let hex = ''
298
+ for (let i = 0; i < 2 && this.isHexDigit(this.peek()); i++) {
299
+ hex += this.advance()
300
+ }
301
+ value += String.fromCharCode(parseInt(hex, 16))
302
+ break
303
+ case 'u':
304
+ let unicode = ''
305
+ if (this.peek() === '{') {
306
+ this.advance()
307
+ while (this.isHexDigit(this.peek())) {
308
+ unicode += this.advance()
309
+ }
310
+ if (this.peek() === '}') this.advance()
311
+ } else {
312
+ for (let i = 0; i < 4 && this.isHexDigit(this.peek()); i++) {
313
+ unicode += this.advance()
314
+ }
315
+ }
316
+ value += String.fromCodePoint(parseInt(unicode, 16))
317
+ break
318
+ default:
319
+ value += escaped
320
+ }
321
+ } else {
322
+ value += this.advance()
323
+ }
324
+ }
325
+
326
+ this.tokens.push(new Token(
327
+ isBlock ? TokenType.BLOCK_STRING : TokenType.STRING,
328
+ value,
329
+ startLine,
330
+ startCol,
331
+ this.currentIndent
332
+ ))
333
+ }
334
+
335
+ scanTemplateString() {
336
+ const startLine = this.line
337
+ const startCol = this.column
338
+ let value = ''
339
+
340
+ this.advance()
341
+
342
+ while (!this.isAtEnd() && this.peek() !== '`') {
343
+ if (this.peek() === '\\') {
344
+ this.advance()
345
+ value += this.advance()
346
+ } else {
347
+ value += this.advance()
348
+ }
349
+ }
350
+
351
+ if (this.peek() === '`') {
352
+ this.advance()
353
+ }
354
+
355
+ this.tokens.push(new Token(TokenType.BLOCK_STRING, value, startLine, startCol, this.currentIndent))
356
+ }
357
+
358
+ scanNumber() {
359
+ const startLine = this.line
360
+ const startCol = this.column
361
+ let value = ''
362
+ let type = TokenType.INTEGER
363
+
364
+ if (this.peek() === '-') {
365
+ value += this.advance()
366
+ }
367
+
368
+ if (this.peek() === '0' && (this.peek(1) === 'x' || this.peek(1) === 'X')) {
369
+ value += this.advance()
370
+ value += this.advance()
371
+ while (this.isHexDigit(this.peek())) {
372
+ value += this.advance()
373
+ }
374
+ this.tokens.push(new Token(TokenType.HEX, value, startLine, startCol, this.currentIndent))
375
+ return
376
+ }
377
+
378
+ if (this.peek() === '0' && (this.peek(1) === 'b' || this.peek(1) === 'B')) {
379
+ this.advance()
380
+ this.advance()
381
+ let binValue = ''
382
+ while (this.peek() === '0' || this.peek() === '1') {
383
+ binValue += this.advance()
384
+ }
385
+ this.tokens.push(new Token(TokenType.INTEGER, parseInt(binValue, 2), startLine, startCol, this.currentIndent))
386
+ return
387
+ }
388
+
389
+ if (this.peek() === '0' && (this.peek(1) === 'o' || this.peek(1) === 'O')) {
390
+ this.advance()
391
+ this.advance()
392
+ let octValue = ''
393
+ while (this.peek() >= '0' && this.peek() <= '7') {
394
+ octValue += this.advance()
395
+ }
396
+ this.tokens.push(new Token(TokenType.INTEGER, parseInt(octValue, 8), startLine, startCol, this.currentIndent))
397
+ return
398
+ }
399
+
400
+ while (this.isDigit(this.peek()) || this.peek() === '_') {
401
+ if (this.peek() !== '_') {
402
+ value += this.advance()
403
+ } else {
404
+ this.advance()
405
+ }
406
+ }
407
+
408
+ if (this.peek() === '.' && this.isDigit(this.peek(1))) {
409
+ type = TokenType.FLOAT
410
+ value += this.advance()
411
+ while (this.isDigit(this.peek()) || this.peek() === '_') {
412
+ if (this.peek() !== '_') {
413
+ value += this.advance()
414
+ } else {
415
+ this.advance()
416
+ }
417
+ }
418
+ }
419
+
420
+ if (this.peek() === 'e' || this.peek() === 'E') {
421
+ type = TokenType.FLOAT
422
+ value += this.advance()
423
+ if (this.peek() === '+' || this.peek() === '-') {
424
+ value += this.advance()
425
+ }
426
+ while (this.isDigit(this.peek())) {
427
+ value += this.advance()
428
+ }
429
+ }
430
+
431
+ if (type === TokenType.FLOAT) {
432
+ this.tokens.push(new Token(type, parseFloat(value), startLine, startCol, this.currentIndent))
433
+ } else {
434
+ this.tokens.push(new Token(type, parseInt(value, 10), startLine, startCol, this.currentIndent))
435
+ }
436
+ }
437
+
438
+ scanIdentifier() {
439
+ const startLine = this.line
440
+ const startCol = this.column
441
+ let value = ''
442
+
443
+ while (this.isAlphaNumeric(this.peek()) || this.peek() === '-' || this.peek() === '_') {
444
+ value += this.advance()
445
+ }
446
+
447
+ let keepLooking = true
448
+ while (keepLooking && this.peek() === ' ') {
449
+ const savedPos = this.pos
450
+ const savedLine = this.line
451
+ const savedCol = this.column
452
+
453
+ this.advance()
454
+
455
+ let nextWord = ''
456
+ while (this.isAlphaNumeric(this.peek()) || this.peek() === '-' || this.peek() === '_') {
457
+ nextWord += this.advance()
458
+ }
459
+
460
+ if (nextWord) {
461
+ const combined = value + ' ' + nextWord
462
+ if (isCompoundKeyword(combined) || couldBeCompoundStart(combined)) {
463
+ value = combined
464
+ } else {
465
+ this.pos = savedPos
466
+ this.line = savedLine
467
+ this.column = savedCol
468
+ keepLooking = false
469
+ }
470
+ } else {
471
+ this.pos = savedPos
472
+ this.line = savedLine
473
+ this.column = savedCol
474
+ keepLooking = false
475
+ }
476
+ }
477
+
478
+ const lowerValue = value.toLowerCase()
479
+ if (this.peek() === ':' && LANG_BLOCKS.includes(lowerValue)) {
480
+ this.advance()
481
+ this.tokens.push(new Token(TokenType.LANG_BLOCK, lowerValue, startLine, startCol, this.currentIndent))
482
+ return
483
+ }
484
+
485
+ this.tokens.push(new Token(TokenType.IDENTIFIER, value, startLine, startCol, this.currentIndent))
486
+ }
487
+
488
+ scanOperator() {
489
+ const startLine = this.line
490
+ const startCol = this.column
491
+ const char = this.advance()
492
+
493
+ switch (char) {
494
+ case ':':
495
+ if (this.match(':')) {
496
+ this.tokens.push(new Token(TokenType.DOUBLE_COLON, '::', startLine, startCol, this.currentIndent))
497
+ } else {
498
+ this.tokens.push(new Token(TokenType.COLON, ':', startLine, startCol, this.currentIndent))
499
+ }
500
+ break
501
+
502
+ case '=':
503
+ if (this.match('=')) {
504
+ if (this.match('=')) {
505
+ this.tokens.push(new Token(TokenType.TRIPLE_EQUALS, '===', startLine, startCol, this.currentIndent))
506
+ } else {
507
+ this.tokens.push(new Token(TokenType.DOUBLE_EQUALS, '==', startLine, startCol, this.currentIndent))
508
+ }
509
+ } else if (this.match('>')) {
510
+ this.tokens.push(new Token(TokenType.FAT_ARROW, '=>', startLine, startCol, this.currentIndent))
511
+ } else {
512
+ this.tokens.push(new Token(TokenType.EQUALS, '=', startLine, startCol, this.currentIndent))
513
+ }
514
+ break
515
+
516
+ case '!':
517
+ if (this.match('=')) {
518
+ if (this.match('=')) {
519
+ this.tokens.push(new Token(TokenType.NOT_DOUBLE_EQUALS, '!==', startLine, startCol, this.currentIndent))
520
+ } else {
521
+ this.tokens.push(new Token(TokenType.NOT_EQUALS, '!=', startLine, startCol, this.currentIndent))
522
+ }
523
+ } else {
524
+ this.tokens.push(new Token(TokenType.BANG, '!', startLine, startCol, this.currentIndent))
525
+ }
526
+ break
527
+
528
+ case ',':
529
+ this.tokens.push(new Token(TokenType.COMMA, ',', startLine, startCol, this.currentIndent))
530
+ break
531
+
532
+ case '.':
533
+ if (this.match('.')) {
534
+ if (this.match('.')) {
535
+ this.tokens.push(new Token(TokenType.SPREAD, '...', startLine, startCol, this.currentIndent))
536
+ } else {
537
+ this.tokens.push(new Token(TokenType.DOT, '.', startLine, startCol, this.currentIndent))
538
+ this.tokens.push(new Token(TokenType.DOT, '.', startLine, startCol + 1, this.currentIndent))
539
+ }
540
+ } else {
541
+ this.tokens.push(new Token(TokenType.DOT, '.', startLine, startCol, this.currentIndent))
542
+ }
543
+ break
544
+
545
+ case '+':
546
+ if (this.match('+')) {
547
+ this.tokens.push(new Token(TokenType.PLUS_PLUS, '++', startLine, startCol, this.currentIndent))
548
+ } else if (this.match('=')) {
549
+ this.tokens.push(new Token(TokenType.PLUS_EQUALS, '+=', startLine, startCol, this.currentIndent))
550
+ } else {
551
+ this.tokens.push(new Token(TokenType.PLUS, '+', startLine, startCol, this.currentIndent))
552
+ }
553
+ break
554
+
555
+ case '-':
556
+ if (this.match('-')) {
557
+ this.tokens.push(new Token(TokenType.MINUS_MINUS, '--', startLine, startCol, this.currentIndent))
558
+ } else if (this.match('>')) {
559
+ this.tokens.push(new Token(TokenType.ARROW, '->', startLine, startCol, this.currentIndent))
560
+ } else if (this.match('=')) {
561
+ this.tokens.push(new Token(TokenType.MINUS_EQUALS, '-=', startLine, startCol, this.currentIndent))
562
+ } else {
563
+ this.tokens.push(new Token(TokenType.MINUS, '-', startLine, startCol, this.currentIndent))
564
+ }
565
+ break
566
+
567
+ case '*':
568
+ if (this.match('*')) {
569
+ if (this.match('=')) {
570
+ this.tokens.push(new Token(TokenType.DOUBLE_STAR_EQUALS, '**=', startLine, startCol, this.currentIndent))
571
+ } else {
572
+ this.tokens.push(new Token(TokenType.DOUBLE_STAR, '**', startLine, startCol, this.currentIndent))
573
+ }
574
+ } else if (this.match('=')) {
575
+ this.tokens.push(new Token(TokenType.STAR_EQUALS, '*=', startLine, startCol, this.currentIndent))
576
+ } else {
577
+ this.tokens.push(new Token(TokenType.STAR, '*', startLine, startCol, this.currentIndent))
578
+ }
579
+ break
580
+
581
+ case '/':
582
+ if (this.match('=')) {
583
+ this.tokens.push(new Token(TokenType.SLASH_EQUALS, '/=', startLine, startCol, this.currentIndent))
584
+ } else if (this.match('/')) {
585
+ this.tokens.push(new Token(TokenType.DOUBLE_SLASH, '//', startLine, startCol, this.currentIndent))
586
+ } else {
587
+ this.tokens.push(new Token(TokenType.SLASH, '/', startLine, startCol, this.currentIndent))
588
+ }
589
+ break
590
+
591
+ case '%':
592
+ if (this.match('=')) {
593
+ this.tokens.push(new Token(TokenType.PERCENT_EQUALS, '%=', startLine, startCol, this.currentIndent))
594
+ } else {
595
+ this.tokens.push(new Token(TokenType.PERCENT, '%', startLine, startCol, this.currentIndent))
596
+ }
597
+ break
598
+
599
+ case '<':
600
+ if (this.match('=')) {
601
+ if (this.match('>')) {
602
+ this.tokens.push(new Token(TokenType.SPACESHIP, '<=>', startLine, startCol, this.currentIndent))
603
+ } else {
604
+ this.tokens.push(new Token(TokenType.LTE, '<=', startLine, startCol, this.currentIndent))
605
+ }
606
+ } else if (this.match('<')) {
607
+ this.tokens.push(new Token(TokenType.LT_LT, '<<', startLine, startCol, this.currentIndent))
608
+ } else {
609
+ this.tokens.push(new Token(TokenType.LT, '<', startLine, startCol, this.currentIndent))
610
+ }
611
+ break
612
+
613
+ case '>':
614
+ if (this.match('=')) {
615
+ this.tokens.push(new Token(TokenType.GTE, '>=', startLine, startCol, this.currentIndent))
616
+ } else if (this.match('>')) {
617
+ if (this.match('>')) {
618
+ this.tokens.push(new Token(TokenType.GT_GT_GT, '>>>', startLine, startCol, this.currentIndent))
619
+ } else {
620
+ this.tokens.push(new Token(TokenType.GT_GT, '>>', startLine, startCol, this.currentIndent))
621
+ }
622
+ } else {
623
+ this.tokens.push(new Token(TokenType.GT, '>', startLine, startCol, this.currentIndent))
624
+ }
625
+ break
626
+
627
+ case '&':
628
+ if (this.match('&')) {
629
+ this.tokens.push(new Token(TokenType.DOUBLE_AMPERSAND, '&&', startLine, startCol, this.currentIndent))
630
+ } else if (this.match('=')) {
631
+ this.tokens.push(new Token(TokenType.AMPERSAND_EQUALS, '&=', startLine, startCol, this.currentIndent))
632
+ } else {
633
+ this.tokens.push(new Token(TokenType.AMPERSAND, '&', startLine, startCol, this.currentIndent))
634
+ }
635
+ break
636
+
637
+ case '|':
638
+ if (this.match('|')) {
639
+ this.tokens.push(new Token(TokenType.DOUBLE_PIPE, '||', startLine, startCol, this.currentIndent))
640
+ } else if (this.match('=')) {
641
+ this.tokens.push(new Token(TokenType.PIPE_EQUALS, '|=', startLine, startCol, this.currentIndent))
642
+ } else if (this.match('>')) {
643
+ this.tokens.push(new Token(TokenType.PIPE_GT, '|>', startLine, startCol, this.currentIndent))
644
+ } else {
645
+ this.tokens.push(new Token(TokenType.PIPE, '|', startLine, startCol, this.currentIndent))
646
+ }
647
+ break
648
+
649
+ case '^':
650
+ if (this.match('=')) {
651
+ this.tokens.push(new Token(TokenType.CARET_EQUALS, '^=', startLine, startCol, this.currentIndent))
652
+ } else {
653
+ this.tokens.push(new Token(TokenType.CARET, '^', startLine, startCol, this.currentIndent))
654
+ }
655
+ break
656
+
657
+ case '~':
658
+ this.tokens.push(new Token(TokenType.TILDE, '~', startLine, startCol, this.currentIndent))
659
+ break
660
+
661
+ case '?':
662
+ if (this.match('?')) {
663
+ if (this.match('=')) {
664
+ this.tokens.push(new Token(TokenType.QUESTION_QUESTION_EQUALS, '??=', startLine, startCol, this.currentIndent))
665
+ } else {
666
+ this.tokens.push(new Token(TokenType.DOUBLE_QUESTION, '??', startLine, startCol, this.currentIndent))
667
+ }
668
+ } else if (this.match('.')) {
669
+ this.tokens.push(new Token(TokenType.QUESTION_DOT, '?.', startLine, startCol, this.currentIndent))
670
+ } else {
671
+ this.tokens.push(new Token(TokenType.QUESTION, '?', startLine, startCol, this.currentIndent))
672
+ }
673
+ break
674
+
675
+ case '@':
676
+ this.tokens.push(new Token(TokenType.AT, '@', startLine, startCol, this.currentIndent))
677
+ break
678
+
679
+ case '#':
680
+ this.tokens.push(new Token(TokenType.HASH, '#', startLine, startCol, this.currentIndent))
681
+ break
682
+
683
+ case '\\':
684
+ this.tokens.push(new Token(TokenType.BACKSLASH, '\\', startLine, startCol, this.currentIndent))
685
+ break
686
+
687
+ case '(':
688
+ this.tokens.push(new Token(TokenType.LPAREN, '(', startLine, startCol, this.currentIndent))
689
+ break
690
+
691
+ case ')':
692
+ this.tokens.push(new Token(TokenType.RPAREN, ')', startLine, startCol, this.currentIndent))
693
+ break
694
+
695
+ case '[':
696
+ this.tokens.push(new Token(TokenType.LBRACKET, '[', startLine, startCol, this.currentIndent))
697
+ break
698
+
699
+ case ']':
700
+ this.tokens.push(new Token(TokenType.RBRACKET, ']', startLine, startCol, this.currentIndent))
701
+ break
702
+
703
+ case '{':
704
+ this.tokens.push(new Token(TokenType.LBRACE, '{', startLine, startCol, this.currentIndent))
705
+ break
706
+
707
+ case '}':
708
+ this.tokens.push(new Token(TokenType.RBRACE, '}', startLine, startCol, this.currentIndent))
709
+ break
710
+
711
+ case ';':
712
+ this.tokens.push(new Token(TokenType.SEMICOLON, ';', startLine, startCol, this.currentIndent))
713
+ break
714
+
715
+ default:
716
+ this.tokens.push(new Token(TokenType.ERROR, `Caractère inattendu: ${char}`, startLine, startCol, this.currentIndent))
717
+ }
718
+ }
719
+
720
+ static tokenize(source, options = {}) {
721
+ const lexer = new EtherLexer(source, options)
722
+ return lexer.tokenize()
723
+ }
724
+ }
725
+
726
+ module.exports = {
727
+ EtherLexer
728
+ }