#611 Adds support for exponents in Float literals

This commit is contained in:
Scott Christopher 2019-07-31 23:06:38 +10:00
parent 9699723ca9
commit e8748fb24b
5 changed files with 80 additions and 6 deletions

View File

@ -19,3 +19,4 @@ The format for this list: name, GitHub handle, and then optional blurb about wha
* Billy Kaplan (@billy1kaplan)
* Tomas Mikula (@TomasMikula)
* William Carroll (@wpcarro)
* Scott Christopher (@scott-christopher)

View File

@ -30,6 +30,7 @@ data Err
| InvalidShortHash String
| Both Err Err
| MissingFractional String -- ex `1.` rather than `1.04`
| MissingExponent String -- ex `1e` rather than `1e3`
| UnknownLexeme
| TextLiteralMissingClosingQuote String
| InvalidEscapeCharacter Char
@ -507,11 +508,24 @@ numericLit = go
(fractional@(_:_), []) ->
pure $ pure (sign ++ num ++ "." ++ fractional, [])
(fractional@(_:_), c:rem)
| c `elem` "eE" -> goExp (sign ++ num ++ "." ++ fractional) rem
| isSep c -> pure $ pure (sign ++ num ++ "." ++ fractional, c:rem)
| otherwise -> pure Nothing
([], _) -> Left (MissingFractional (sign ++ num ++ "."))
(num@(_:_), c:rem) | c `elem` "eE" -> goExp (sign ++ num) rem
(num@(_:_), c:rem) -> pure $ pure (sign ++ num, c:rem)
([], _) -> pure Nothing
goExp signNum rem = case rem of
('+':s) -> goExp' signNum "+" s
('-':s) -> goExp' signNum "-" s
s -> goExp' signNum "" s
goExp' signNum expSign exp = case span isDigit exp of
((_:_), []) ->
pure $ pure (signNum ++ "e" ++ expSign ++ exp, [])
(exp'@(_:_), c:rem)
| isSep c -> pure $ pure (signNum ++ "e" ++ expSign ++ exp', c:rem)
| otherwise -> pure Nothing
([], _) -> Left (MissingExponent (signNum ++ "e" ++ expSign))
isSep :: Char -> Bool
isSep c = isSpace c || Set.member c delimiters

View File

@ -16,7 +16,6 @@ import Control.Monad.Reader (asks, local)
import Data.Foldable (asum)
import Data.Functor
import Data.Int (Int64)
import Data.List (elem)
import Data.Maybe (isJust, fromMaybe)
import Data.Word (Word64)
import Prelude hiding (and, or, seq)
@ -525,10 +524,11 @@ number'
-> P v a
number' i u f = fmap go numeric
where
go num@(L.payload -> p) | '.' `elem` p = f (read <$> num)
| take 1 p == "+" = i (read . drop 1 <$> num)
| take 1 p == "-" = i (read <$> num)
| otherwise = u (read <$> num)
go num@(L.payload -> p) | any (\c -> c == '.' || c == 'e') p && take 1 p == "+" = f (read . drop 1 <$> num)
| any (\c -> c == '.' || c == 'e') p = f (read <$> num)
| take 1 p == "+" = i (read . drop 1 <$> num)
| take 1 p == "-" = i (read <$> num)
| otherwise = u (read <$> num)
tupleOrParenthesizedTerm :: Var v => TermP v
tupleOrParenthesizedTerm = label "tuple" $ tupleOrParenthesized term DD.unitTerm pair

View File

@ -12,6 +12,44 @@ test =
, t "-1" [Numeric "-1"]
, t "-1.0" [Numeric "-1.0"]
, t "+1.0" [Numeric "+1.0"]
, t "1e3" [Numeric "1e3"]
, t "1e+3" [Numeric "1e+3"]
, t "1e-3" [Numeric "1e-3"]
, t "+1e3" [Numeric "+1e3"]
, t "+1e+3" [Numeric "+1e+3"]
, t "+1e-3" [Numeric "+1e-3"]
, t "-1e3" [Numeric "-1e3"]
, t "-1e+3" [Numeric "-1e+3"]
, t "-1e-3" [Numeric "-1e-3"]
, t "1.2e3" [Numeric "1.2e3"]
, t "1.2e+3" [Numeric "1.2e+3"]
, t "1.2e-3" [Numeric "1.2e-3"]
, t "+1.2e3" [Numeric "+1.2e3"]
, t "+1.2e+3" [Numeric "+1.2e+3"]
, t "+1.2e-3" [Numeric "+1.2e-3"]
, t "-1.2e3" [Numeric "-1.2e3"]
, t "-1.2e+3" [Numeric "-1.2e+3"]
, t "-1.2e-3" [Numeric "-1.2e-3"]
, t "1E3" [Numeric "1e3"]
, t "1E+3" [Numeric "1e+3"]
, t "1E-3" [Numeric "1e-3"]
, t "+1E3" [Numeric "+1e3"]
, t "+1E+3" [Numeric "+1e+3"]
, t "+1E-3" [Numeric "+1e-3"]
, t "-1E3" [Numeric "-1e3"]
, t "-1E+3" [Numeric "-1e+3"]
, t "-1E-3" [Numeric "-1e-3"]
, t "1.2E3" [Numeric "1.2e3"]
, t "1.2E+3" [Numeric "1.2e+3"]
, t "1.2E-3" [Numeric "1.2e-3"]
, t "+1.2E3" [Numeric "+1.2e3"]
, t "+1.2E+3" [Numeric "+1.2e+3"]
, t "+1.2E-3" [Numeric "+1.2e-3"]
, t "-1.2E3" [Numeric "-1.2e3"]
, t "-1.2E+3" [Numeric "-1.2e+3"]
, t "-1.2E-3" [Numeric "-1.2e-3"]
, t "1-1" [Numeric "1", simpleSymbolyId "-", Numeric "1"]
, t "1+1" [Numeric "1", simpleSymbolyId "+", Numeric "1"]
, t "1 +1" [Numeric "1", Numeric "+1"]

View File

@ -22,8 +22,29 @@ test1 = scope "termparser" . tests . map parses $
, "1.0"
, "+1"
, "-1"
, "+1.0"
, "-1.0"
, "4th"
, "1e3"
, "1e+3"
, "1e-3"
, "+1e3"
, "+1e+3"
, "+1e-3"
, "-1e3"
, "-1e+3"
, "-1e-3"
, "1.2e3"
, "1.2e+3"
, "1.2e-3"
, "+1.2e3"
, "+1.2e+3"
, "+1.2e-3"
, "-1.2e3"
, "-1.2e+3"
, "-1.2e-3"
, "-4th"
, "()"
, "(0)"
, "forty"