on master help sign in
Merge branch 'pr/833'
201f4d5Evan Czaplicki
src/Parse/Literal.hs+56−23
@@ -1,39 +1,72 @@
1module Parse.Literal (literal) where
1module Parse.Literal (literal) where
2
2
3+import Prelude hiding (exponent)
3import Control.Applicative ((<$>))
4import Control.Applicative ((<$>))
4−import Text.Parsec hiding (newline,spaces)
5+import Text.Parsec ((<|>), (<?>), digit, hexDigit, lookAhead, many1, oneOf, option, string, try)
5import Parse.Helpers (IParser, chr, str)
6import Parse.Helpers (IParser, chr, str)
6import qualified AST.Literal as L
7import qualified AST.Literal as L
7
8
9+
8literal :: IParser L.Literal
10literal :: IParser L.Literal
11+literal =
9−literal = num <|> (L.Str <$> str) <|> (L.Chr <$> chr) <?> "literal"
12+ num <|> (L.Str <$> str) <|> (L.Chr <$> chr) <?> "literal"
13+
10
14
11num :: IParser L.Literal
15num :: IParser L.Literal
12−num = toLit <$> (number <?> "number")
16+num =
13− where
17+ toLiteral <$> (rawNumber <?> "number")
14− toLit n
18+
19+
20+toLiteral :: String -> L.Literal
21+toLiteral n
22+ | 'x' `elem` n = L.IntNum (read n)
15− | any (`elem` ".eE") n = L.FloatNum (read n)
23+ | any (`elem` ".eE") n = L.FloatNum (read n)
16− | otherwise = L.IntNum (read n)
24+ | otherwise = L.IntNum (read n)
17−
25+
26+
27+rawNumber :: IParser String
28+rawNumber =
18− number = concat <$> sequence
29+ concat <$> sequence
19− [ option "" minus
30+ [ option "" minus
31+ , base16 <|> base10
32+ ]
33+
34+
35+base16 :: IParser String
36+base16 =
37+ do try (string "0x")
38+ digits <- many1 hexDigit
39+ return ("0x" ++ digits)
40+
41+
42+base10 :: IParser String
43+base10 =
44+ concat <$> sequence
20− , many1 digit
45+ [ many1 digit
21− , option "" decimals
46+ , option "" decimals
22− , option "" exponent ]
47+ , option "" exponent
23−
48+ ]
49+
50+
51+minus :: IParser String
52+minus =
24− minus = try $ do
53+ try $ do
25− string "-"
54+ string "-"
26− lookAhead digit
55+ lookAhead digit
27− return "-"
56+ return "-"
28−
57+
58+
29− decimals = do
59+decimals :: IParser String
60+decimals =
30− try $ lookAhead (string "." >> digit)
61+ do try $ lookAhead (string "." >> digit)
31 string "."
62 string "."
32 n <- many1 digit
63 n <- many1 digit
33 return ('.' : n)
64 return ('.' : n)
34
65
66+
67+exponent :: IParser String
35− exponent = do
68+exponent =
36− string "e" <|> string "E"
69+ do string "e" <|> string "E"
37 op <- option "" (string "+" <|> string "-")
70 op <- option "" (string "+" <|> string "-")
38 n <- many1 digit
71 n <- many1 digit
39 return ('e' : op ++ n)
72 return ('e' : op ++ n)