Skip to content

Commit 905f945

Browse files
authored
perf: make parser a bit faster (#1553)
1 parent 547aa45 commit 905f945

1 file changed

Lines changed: 34 additions & 55 deletions

File tree

src/Parsing.hs

Lines changed: 34 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -66,61 +66,28 @@ otherBases = do
6666
withBases :: Parsec.Parsec String ParseState (Maybe Info, String)
6767
withBases = Parsec.try otherBases <|> maybeSigned
6868

69-
double :: Parsec.Parsec String ParseState XObj
70-
double = do
71-
(i, num) <- maybeSigned
72-
_ <- Parsec.char '.'
73-
incColumn 1
74-
decimals <- Parsec.many1 Parsec.digit
75-
incColumn (length decimals)
76-
pure (XObj (Num DoubleTy (Floating (read (num ++ "." ++ decimals)))) i Nothing)
77-
78-
float :: Parsec.Parsec String ParseState XObj
79-
float = do
80-
(i, num) <- maybeSigned
81-
_ <- Parsec.char '.'
82-
incColumn 1
83-
decimals <- Parsec.many1 Parsec.digit
84-
incColumn (length decimals)
85-
_ <- Parsec.char 'f'
86-
incColumn 1
87-
pure (XObj (Num FloatTy (Floating (read (num ++ "." ++ decimals)))) i Nothing)
88-
89-
floatNoPeriod :: Parsec.Parsec String ParseState XObj
90-
floatNoPeriod =
91-
do
92-
(i, num) <- withBases
93-
_ <- Parsec.char 'f'
94-
incColumn 1
95-
pure (XObj (Num FloatTy (Floating (read num))) i Nothing)
96-
97-
integer :: Parsec.Parsec String ParseState XObj
98-
integer = do
99-
(i, num) <- withBases
100-
pure (XObj (Num IntTy (Integral (read num))) i Nothing)
101-
102-
byte :: Parsec.Parsec String ParseState XObj
103-
byte = do
104-
(i, num) <- withBases
105-
_ <- Parsec.char 'b'
106-
incColumn 1
107-
pure (XObj (Num ByteTy (Integral (read num))) i Nothing)
108-
109-
long :: Parsec.Parsec String ParseState XObj
110-
long = do
111-
(i, num) <- withBases
112-
_ <- Parsec.char 'l'
113-
incColumn 1
114-
pure (XObj (Num LongTy (Integral (read num))) i Nothing)
115-
11669
number :: Parsec.Parsec String ParseState XObj
117-
number =
118-
Parsec.try float
119-
<|> Parsec.try floatNoPeriod
120-
<|> Parsec.try byte
121-
<|> Parsec.try double
122-
<|> Parsec.try long
123-
<|> Parsec.try integer
70+
number = Parsec.try $ do
71+
(i, num) <- withBases
72+
suffix <- Parsec.optionMaybe (Parsec.oneOf ".blf")
73+
case suffix of
74+
Just '.' -> do
75+
incColumn 1
76+
decimals <- Parsec.many1 Parsec.digit
77+
incColumn (length decimals)
78+
hasF <- Parsec.option False (Parsec.char 'f' *> incColumn 1 *> pure True)
79+
let n = read (num ++ "." ++ decimals)
80+
pure (XObj (Num (if hasF then FloatTy else DoubleTy) (Floating n)) i Nothing)
81+
Just 'b' -> do
82+
incColumn 1
83+
pure (XObj (Num ByteTy (Integral (read num))) i Nothing)
84+
Just 'l' -> do
85+
incColumn 1
86+
pure (XObj (Num LongTy (Integral (read num))) i Nothing)
87+
Just 'f' -> do
88+
incColumn 1
89+
pure (XObj (Num FloatTy (Floating (read num))) i Nothing)
90+
_ -> pure (XObj (Num IntTy (Integral (read num))) i Nothing)
12491

12592
rawString :: Parsec.Parsec String ParseState XObj
12693
rawString = do
@@ -593,7 +560,19 @@ unquote = symReaderMacro "%" "unquote"
593560

594561
sexpr :: Parsec.Parsec String ParseState XObj
595562
sexpr = do
596-
x <- Parsec.choice [ref, deref, copy, quote, quasiquote, unquoteSplicing, unquote, list, staticArray, array, dictionary, atom]
563+
c <- Parsec.lookAhead Parsec.anyChar
564+
x <- case c of
565+
'&' -> ref
566+
'~' -> deref
567+
'@' -> copy
568+
'\'' -> quote
569+
'`' -> quasiquote
570+
'%' -> Parsec.try unquoteSplicing <|> unquote
571+
'(' -> list
572+
'[' -> array
573+
'$' -> staticArray
574+
'{' -> dictionary
575+
_ -> atom
597576
_ <- whitespaceOrNothing
598577
pure x
599578

0 commit comments

Comments
 (0)