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) preNum = concat <$> sequence [ option "" minus, many1 digit, option "" postNum ] postNum = do try $ lookAhead (string "." >> digit) string "." ('.':) <$> many1 digit minus = try $ do string "-" lookAhead digit return "-" chr :: IParser Literal chr = Chr <$> betwixt '\'' '\'' (backslashed <|> satisfy (/='\'')) "character" str :: IParser Literal str = choice [ quote >> str <$> manyTill (backslashed <|> anyChar) quote , liftM Str . expecting "string" . betwixt '"' '"' . many $ backslashed <|> satisfy (/='"') ] where quote = try (string "\"\"\"") str = Str . dewindows -- 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 _ -> []