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
|
2013-06-27 16:55:01 +00:00
|
|
|
, 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
|
|
|
|
_ -> []
|