summaryrefslogtreecommitdiff
path: root/fig-utils/src/Fig
diff options
context:
space:
mode:
authorLLLL Colonq <llll@colonq>2025-10-05 19:53:36 -0400
committerLLLL Colonq <llll@colonq>2025-10-05 19:53:36 -0400
commit8f67f0c55b845c80973fcec0fbaef9879f677b91 (patch)
tree21204ea94ceb4d04c2096ea1c9f9cec478e6f2ee /fig-utils/src/Fig
parent874be6e6a13b89a87012af9d295d864632ad7cd6 (diff)
fig-monitor-twitch: Print failed poll
Diffstat (limited to 'fig-utils/src/Fig')
-rw-r--r--fig-utils/src/Fig/Utils/SExpr.hs24
1 files changed, 17 insertions, 7 deletions
diff --git a/fig-utils/src/Fig/Utils/SExpr.hs b/fig-utils/src/Fig/Utils/SExpr.hs
index 8156312..ecf06aa 100644
--- a/fig-utils/src/Fig/Utils/SExpr.hs
+++ b/fig-utils/src/Fig/Utils/SExpr.hs
@@ -35,11 +35,13 @@ deriving instance Data a => Data (SExprWith a)
deriving instance Functor SExprWith
escapeStr :: Char -> [Char]
+escapeStr '\n' = ['\\', 'n']
escapeStr c
| elem @[] c ['\\', '"'] || isSpace c = ['\\', c]
| otherwise = [c]
escapeSym :: Char -> [Char]
+escapeSym '\n' = ['\\', 'n']
escapeSym c
| elem @[] c ['\\', '"', '.', '(', ')'] || isSpace c = ['\\', c]
| otherwise = [c]
@@ -59,27 +61,35 @@ type Parser = Parsec Void Text
sexprWith :: forall a. Parser a -> Parser (SExprWith a)
sexprWith ext = spaces *>
( SExprExt <$> ext
- <|> SExprString . pack <$> (char '"' *> manyTill ((char '\\' *> anySingle) <|> strchar) (char '"'))
+ <|> SExprString . pack <$> (char '"' *> manyTill (escapedNewline <|> (char '\\' *> anyNonNewline) <|> strchar) (char '"'))
<|> parseNumber
- <|> SExprSymbol . pack <$> some ((char '\\' *> anySingle) <|> symchar)
+ <|> SExprSymbol . pack <$> some (escapedNewline <|> (char '\\' *> anyNonNewline) <|> symchar)
<|> SExprList <$> (char '(' *> spaces *> many (spaces *> sexprWith ext <* spaces) <* char ')')
)
where
+ escapedNewline = string "\\n" $> '\n'
+ anyNonNewline = satisfy (/='\n')
spaces = many spaceChar
symchar = satisfy $ \c -> not (isSpace c || c `elem` special)
- strchar = satisfy (/='"')
+ strchar = satisfy (\x -> x /= '"' && x /= '\n')
special :: [Char]
special = "\".()"
- classifyNumber :: [Char] -> Parser (SExprWith a)
- classifyNumber str = do
+ classifyNumber :: Bool -> [Char] -> Parser (SExprWith a)
+ classifyNumber neg str = do
let
- res = if '.' `elem` str then SExprFloat <$> readMaybe str else SExprInteger <$> readMaybe str
+ maybeNeg :: forall n. Num n => n -> n
+ maybeNeg = if neg then negate else id
+ res =
+ if '.' `elem` str
+ then SExprFloat . maybeNeg <$> readMaybe str
+ else SExprInteger . maybeNeg <$> readMaybe str
maybe mzero pure res
parseNumber :: Parser (SExprWith a)
parseNumber = do
+ neg <- option False $ char '-' $> True
leading <- many digitChar
trailing <- optional $ char '.' *> many digitChar
- classifyNumber $ leading <> maybe "" (\x -> if null x then "" else "." <> x) trailing
+ classifyNumber neg $ leading <> maybe "" (\x -> if null x then "" else "." <> x) trailing
parseSExprWith :: Parser a -> Text -> Maybe (SExprWith a)
parseSExprWith ext inp = case runParser (sexprWith ext) "" inp of