16
16
# #
17
17
# # The main entry point is `doParse`.
18
18
19
- # TODO (VM/parser) General cleanup needed
20
- # There are various pieces of commented-out code that make the final result pretty much illegible. Let's clean this up.
19
+ # TODO (VM/parser) Enhance/rewrite the whole file
20
+ # - The parser is currently a bit of a mess
21
+ # - It should be rewritten to be cleaner & more efficient
22
+ # - It should also be more error-aware
21
23
# labels: vm, parser, cleanup
22
24
23
25
# =======================================
@@ -30,6 +32,8 @@ import strutils, tables, unicode
30
32
import vm/ [errors, values/ value]
31
33
import vm/ values/ custom/ [vquantity, vsymbol]
32
34
35
+ import helpers/ strings
36
+
33
37
# =======================================
34
38
# Types
35
39
# =======================================
@@ -513,36 +517,75 @@ template parseIdentifier(p: var Parser, alsoAddCurrent: bool) =
513
517
inc (pos)
514
518
p.bufpos = pos
515
519
516
- template parseNumber (p: var Parser ) =
520
+ template parseNumber (p: var Parser , inPath: bool = false ) =
517
521
var pos = p.bufpos
518
- while p.buf[pos] in Digits :
519
- add (p.value, p.buf[pos])
520
- inc (pos)
522
+ var alreadyParsedNumber = false
521
523
522
- var hasDot{.inject .} = false
524
+ when not inPath:
525
+ var numBase = 10
526
+ if p.buf[pos] == '0' :
527
+ add (p.value, p.buf[pos])
528
+ var numAllowedChars = {'0' .. '9' }
529
+
530
+ if p.buf[pos+ 1 ] in {'x' }:
531
+ numBase = 16
532
+ numAllowedChars = {'0' .. '9' , 'a' .. 'f' , 'A' .. 'F' }
533
+ add (p.value, p.buf[pos+ 1 ])
534
+ inc (pos, 2 )
535
+ elif p.buf[pos+ 1 ] in {'b' }:
536
+ numBase = 2
537
+ numAllowedChars = {'0' ,'1' }
538
+ add (p.value, p.buf[pos+ 1 ])
539
+ inc (pos, 2 )
540
+ elif p.buf[pos+ 1 ] in {'o' }:
541
+ numBase = 8
542
+ numAllowedChars = {'0' .. '7' }
543
+ add (p.value, p.buf[pos+ 1 ])
544
+ inc (pos, 2 )
545
+ else :
546
+ numAllowedChars = {}
547
+
548
+ if p.buf[pos] in numAllowedChars:
549
+ while p.buf[pos] in numAllowedChars:
550
+ add (p.value, p.buf[pos])
551
+ inc (pos)
523
552
524
- if p.buf[pos] == Dot and p.buf[pos+ 1 ] in Digits :
525
- hasDot = true
553
+ p.value = $ (parseNumFromString (p.value, numBase))
554
+ p.bufpos = pos
555
+ alreadyParsedNumber = true
556
+ else :
557
+ pos = p.bufpos
558
+ p.value = " "
526
559
527
- add (p.value, Dot )
528
- inc (pos)
560
+ var hasDot{.inject .} = false
529
561
562
+ if likely (not alreadyParsedNumber):
530
563
while p.buf[pos] in Digits :
531
564
add (p.value, p.buf[pos])
532
565
inc (pos)
533
566
534
- if p.buf[pos] == Dot :
535
- if p.buf[pos+ 1 ] in Digits :
536
- add (p.value, Dot )
567
+ if p.buf[pos] == Dot and p.buf[pos+ 1 ] in Digits :
568
+ hasDot = true
569
+
570
+ add (p.value, Dot )
571
+ inc (pos)
572
+
573
+ while p.buf[pos] in Digits :
574
+ add (p.value, p.buf[pos])
537
575
inc (pos)
538
- while p.buf[pos] in Digits :
539
- add (p.value, p.buf[pos])
576
+
577
+ if p.buf[pos] == Dot :
578
+ if p.buf[pos+ 1 ] in Digits :
579
+ add (p.value, Dot )
540
580
inc (pos)
541
-
542
- if p.buf[pos] in {'+' ,'-' }:
543
- while p.buf[pos] in SemVerExtra :
581
+ while p.buf[pos] in Digits :
544
582
add (p.value, p.buf[pos])
545
583
inc (pos)
584
+
585
+ if p.buf[pos] in {'+' ,'-' }:
586
+ while p.buf[pos] in SemVerExtra :
587
+ add (p.value, p.buf[pos])
588
+ inc (pos)
546
589
547
590
p.bufpos = pos
548
591
@@ -806,7 +849,7 @@ template parsePath(p: var Parser, root: Value, curLevel: int, asLiteral: bool =
806
849
p.values[^ 1 ].add (newLiteral (p.value))
807
850
of PermittedNumbers_Start:
808
851
setLen (p.value, 0 )
809
- parseNumber (p)
852
+ parseNumber (p, inPath = true )
810
853
if hasDot: p.values[^ 1 ].add (newFloating (p.value))
811
854
else : p.values[^ 1 ].add (newInteger (p.value))
812
855
of LBracket :
0 commit comments