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