Finished Haskell float parser
Getty Ritter
10 years ago
| 106 | 106 | | otherwise = error ("Unknown letter in number: " ++ show c) |
| 107 | 107 | |
| 108 | 108 | pFloat :: Parser Double |
| 109 |
pFloat = |
|
| 109 | pFloat = do | |
| 110 | n <- decimal | |
| 111 | withDot n <|> noDot n | |
| 112 | where withDot n = do | |
| 113 | char '.' | |
| 114 | m <- decimal | |
| 115 | e <- option 1.0 exponent | |
| 116 | return ((fromIntegral n + asDec m 0) * e) | |
| 117 | noDot n = do | |
| 118 | e <- exponent | |
| 119 | return (fromIntegral n * e) | |
| 120 | exponent = do | |
| 121 | oneOf "eE" | |
| 122 | s <- power | |
| 123 | x <- decimal | |
| 124 | return (10 ** s (fromIntegral x)) | |
| 125 | asDec 0 k = k | |
| 126 | asDec n k = | |
| 127 | asDec (n `div` 10) ((fromIntegral (n `rem` 10) + k) * 0.1) | |
| 128 | ||
| 129 | power :: Num a => Parser (a -> a) | |
| 130 | power = negate <$ char '-' <|> id <$ char '+' <|> return id | |
| 110 | 131 | |
| 111 | 132 | pInt :: Parser Integer |
| 112 | 133 | pInt = do |
| 113 |
s <- |
|
| 134 | s <- power | |
| 114 | 135 | n <- pZeroNum <|> decimal |
| 115 |
return ( |
|
| 136 | return (fromIntegral (s n)) | |
| 116 | 137 | |
| 117 | 138 | pZeroNum :: Parser Integer |
| 118 | 139 | pZeroNum = char '0' >> |
| 123 | 144 | ) |
| 124 | 145 | |
| 125 | 146 | pHaskLikeAtom :: Parser HaskLikeAtom |
| 126 | pHaskLikeAtom = | |
| 127 | HSInt <$> (try pInt <?> "integer") | |
| 128 | <|> HSFloat <$> (try pFloat <?> "float") | |
| 147 | pHaskLikeAtom | |
| 148 | = HSFloat <$> (try pFloat <?> "float") | |
| 149 | <|> HSInt <$> (try pInt <?> "integer") | |
| 129 | 150 | <|> HSString <$> (pString <?> "string literal") |
| 130 | 151 | <|> HSIdent <$> (pToken <?> "token") |
| 131 | 152 | |