elm/compiler/Parse/Literal.hs

47 lines
1.6 KiB
Haskell
Raw Normal View History

2013-06-14 02:15:40 +00:00
module Parse.Literal (literal) where
import Control.Applicative ((<$>), (<*>))
import Control.Monad
import Text.Parsec hiding (newline,spaces)
import Text.Parsec.Indent
import Parse.Helpers
import SourceSyntax.Literal
literal = num <|> str <|> chr
num :: IParser Literal
num = fmap toLit (preNum <?> "number")
where toLit n | '.' `elem` n = FloatNum (read n)
| otherwise = IntNum (read n)
2013-10-14 20:59:37 +00:00
preNum = concat <$> sequence [ option "" minus, many1 digit, option "" postNum ]
2013-06-14 02:15:40 +00:00
postNum = do try $ lookAhead (string "." >> digit)
string "."
('.':) <$> many1 digit
2013-10-14 20:59:37 +00:00
minus = try $ do string "-"
lookAhead digit
return "-"
2013-06-14 02:15:40 +00:00
2013-08-07 16:12:53 +00:00
chr :: IParser Literal
chr = Chr <$> betwixt '\'' '\'' (backslashed <|> satisfy (/='\''))
<?> "character"
2013-06-14 02:15:40 +00:00
str :: IParser Literal
2013-08-07 16:12:53 +00:00
str = choice [ quote >> str <$> manyTill (backslashed <|> anyChar) quote
, liftM Str . expecting "string" . betwixt '"' '"' . many $
backslashed <|> satisfy (/='"')
]
2013-08-07 16:12:53 +00:00
where
quote = try (string "\"\"\"")
str = Str . dewindows
2013-06-14 02:15:40 +00:00
2013-08-07 16:12:53 +00:00
-- Remove \r from strings to fix generated JavaScript
dewindows [] = []
dewindows cs =
let (pre, suf) = break (`elem` ['\r','\n']) cs
in pre ++ case suf of
('\r':'\n':rest) -> '\n' : dewindows rest
('\n':rest) -> '\n' : dewindows rest
('\r':rest) -> '\n' : dewindows rest
_ -> []