{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
module BNFC.Utils
( ModuleName
, when, unless, unlessNull, unlessNull'
, applyWhen, applyUnless
, for, whenJust
, caseMaybe, (>.>)
, curry3, uncurry3
, singleton, headWithDefault, mapHead, spanEnd
, duplicatesOn, groupOn, uniqOn
, hasNumericSuffix
, (+++), (++++), (+-+), (+.+), parensIf
, pad, table
, mkName, mkNames, NameStyle(..)
, lowerCase, upperCase, mixedCase
, camelCase, camelCase_
, snakeCase, snakeCase_
, replace
, writeFileRep
, cstring
, getZonedTimeTruncatedToSeconds
, symbolToName
) where
import Control.Arrow ((&&&))
import Control.DeepSeq (rnf)
import Data.Char
import Data.List (intercalate)
import Data.List.NonEmpty (pattern (:|), (<|))
import Data.Map (Map)
import Data.Semigroup (Semigroup(..))
import Data.Time
import qualified Data.Foldable as Fold
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.List.NonEmpty as List1
import System.IO (IOMode(ReadMode),hClose,hGetContents,openFile)
import System.IO.Error (tryIOError)
import BNFC.PrettyPrint (Doc, text)
type List1 = List1.NonEmpty
type ModuleName = String
#if __GLASGOW_HASKELL__ <= 710
instance {-# OVERLAPPING #-} Semigroup (IO ()) where
(<>) = (>>)
instance {-# OVERLAPPING #-} Monoid (IO ()) where
mempty = return ()
mappend = (<>)
mconcat = sequence_
#endif
when :: Monoid m => Bool -> m -> m
when :: forall m. Monoid m => Bool -> m -> m
when Bool
True m
m = m
m
when Bool
False m
_ = m
forall a. Monoid a => a
mempty
unless :: Monoid m => Bool -> m -> m
unless :: forall m. Monoid m => Bool -> m -> m
unless Bool
False m
m = m
m
unless Bool
True m
_ = m
forall a. Monoid a => a
mempty
applyWhen :: Bool -> (a -> a) -> a -> a
applyWhen :: forall a. Bool -> (a -> a) -> a -> a
applyWhen Bool
True a -> a
f = a -> a
f
applyWhen Bool
False a -> a
_ = a -> a
forall a. a -> a
id
applyUnless :: Bool -> (a -> a) -> a -> a
applyUnless :: forall a. Bool -> (a -> a) -> a -> a
applyUnless Bool
False a -> a
f = a -> a
f
applyUnless Bool
True a -> a
_ = a -> a
forall a. a -> a
id
unlessNull :: Monoid m => [a] -> ([a] -> m) -> m
unlessNull :: forall m a. Monoid m => [a] -> ([a] -> m) -> m
unlessNull [a]
l [a] -> m
k = case [a]
l of
[] -> m
forall a. Monoid a => a
mempty
[a]
as -> [a] -> m
k [a]
as
unlessNull' :: Monoid m => [a] -> (a -> [a] -> m) -> m
unlessNull' :: forall m a. Monoid m => [a] -> (a -> [a] -> m) -> m
unlessNull' [a]
l a -> [a] -> m
k = case [a]
l of
[] -> m
forall a. Monoid a => a
mempty
(a
a:[a]
as) -> a -> [a] -> m
k a
a [a]
as
infixr 8 >.>
(>.>) :: (a -> b) -> (b -> c) -> a -> c
a -> b
g >.> :: forall a b c. (a -> b) -> (b -> c) -> a -> c
>.> b -> c
f = b -> c
f (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
g
for :: [a] -> (a -> b) -> [b]
for :: forall a b. [a] -> (a -> b) -> [b]
for = ((a -> b) -> [a] -> [b]) -> [a] -> (a -> b) -> [b]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> b) -> [a] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map
whenJust :: Monoid m => Maybe a -> (a -> m) -> m
whenJust :: forall m a. Monoid m => Maybe a -> (a -> m) -> m
whenJust = ((a -> m) -> Maybe a -> m) -> Maybe a -> (a -> m) -> m
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap
caseMaybe :: Maybe a -> b -> (a -> b) -> b
caseMaybe :: forall a b. Maybe a -> b -> (a -> b) -> b
caseMaybe Maybe a
ma b
b a -> b
f = b -> (a -> b) -> Maybe a -> b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe b
b a -> b
f Maybe a
ma
curry3 :: ((a, b, c) -> d) -> a -> b -> c -> d
curry3 :: forall a b c d. ((a, b, c) -> d) -> a -> b -> c -> d
curry3 (a, b, c) -> d
f a
a b
b c
c = (a, b, c) -> d
f (a
a,b
b,c
c)
uncurry3 :: (a -> b -> c -> d) -> ((a, b, c) -> d)
uncurry3 :: forall a b c d. (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 a -> b -> c -> d
f ~(a
a,b
b,c
c) = a -> b -> c -> d
f a
a b
b c
c
infixr 5 +++, ++++, +-+, +.+
(+++) :: String -> String -> String
String
a +++ :: String -> String -> String
+++ String
b = String
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
b
(++++) :: String -> String -> String
String
a ++++ :: String -> String -> String
++++ String
b = String
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
b
(+-+) :: String -> String -> String
String
a +-+ :: String -> String -> String
+-+ String
b = String
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
b
(+.+) :: String -> String -> String
String
a +.+ :: String -> String -> String
+.+ String
b = String
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"." String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
b
parensIf :: Bool -> String -> String
parensIf :: Bool -> String -> String
parensIf = \case
Bool
True -> (String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")")
Bool
False -> String -> String
forall a. a -> a
id
pad :: Int -> String -> String
pad :: Int -> String -> String
pad Int
n String
s = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String -> String
forall a. Int -> [a] -> [a]
drop (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s) (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
n Char
' ')
table :: String -> [[String]] -> [String]
table :: String -> [[String]] -> [String]
table String
sep [[String]]
m = ([String] -> String) -> [[String]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
sep ([String] -> String)
-> ([String] -> [String]) -> [String] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> String -> String) -> [Int] -> [String] -> [String]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> String -> String
pad [Int]
widths) [[String]]
m
where
widths :: [Int]
widths :: [Int]
widths = ([Int] -> Int) -> [[Int]] -> [Int]
forall a b. ([a] -> b) -> [[a]] -> [b]
columns [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([[Int]] -> [Int]) -> [[Int]] -> [Int]
forall a b. (a -> b) -> a -> b
$ ([String] -> [Int]) -> [[String]] -> [[Int]]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> Int) -> [String] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length) [[String]]
m
columns :: ([a] -> b) -> [[a]] -> [b]
columns :: forall a b. ([a] -> b) -> [[a]] -> [b]
columns [a] -> b
f [[a]]
rows =
case [[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (([a] -> [a]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
1) [[a]]
rows) of
[] -> []
[a]
col -> [a] -> b
f [a]
col b -> [b] -> [b]
forall a. a -> [a] -> [a]
: ([a] -> b) -> [[a]] -> [b]
forall a b. ([a] -> b) -> [[a]] -> [b]
columns [a] -> b
f (([a] -> [a]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop Int
1) [[a]]
rows)
singleton :: a -> [a]
singleton :: forall a. a -> [a]
singleton = (a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[])
headWithDefault :: a -> [a] -> a
headWithDefault :: forall a. a -> [a] -> a
headWithDefault a
a [] = a
a
headWithDefault a
_ (a
a:[a]
_) = a
a
mapHead :: (a -> a) -> [a] -> [a]
mapHead :: forall a. (a -> a) -> [a] -> [a]
mapHead a -> a
f = \case
[] -> []
a
a:[a]
as -> a -> a
f a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
as
spanEnd :: (a -> Bool) -> [a] -> ([a], [a])
spanEnd :: forall a. (a -> Bool) -> [a] -> ([a], [a])
spanEnd a -> Bool
p [a]
l = [a] -> [a] -> [a] -> [a] -> ([a], [a])
go [a]
l [] [] [a]
l
where
go :: [a] -> [a] -> [a] -> [a] -> ([a], [a])
go [a]
yes [a]
_ [a]
rev_no [] = ([a]
yes, [a] -> [a]
forall a. [a] -> [a]
reverse [a]
rev_no)
go [a]
yes [a]
rev_yes [a]
rev_no (a
x:[a]
xs)
| a -> Bool
p a
x = [a] -> [a] -> [a] -> [a] -> ([a], [a])
go [a]
yes (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
rev_yes) [a]
rev_no [a]
xs
| Bool
otherwise = [a] -> [a] -> [a] -> [a] -> ([a], [a])
go [a]
xs [] (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
rev_yes [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
rev_no) [a]
xs
replace :: Eq a =>
a
-> a
-> [a] -> [a]
replace :: forall a. Eq a => a -> a -> [a] -> [a]
replace a
x a
y [a]
xs = [ if a
z a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
x then a
y else a
z | a
z <- [a]
xs]
duplicatesOn :: (Foldable t, Ord b) => (a -> b) -> t a -> [List1 a]
duplicatesOn :: forall (t :: * -> *) b a.
(Foldable t, Ord b) =>
(a -> b) -> t a -> [List1 a]
duplicatesOn a -> b
nf
= (NonEmpty a -> Bool) -> [NonEmpty a] -> [NonEmpty a]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Int
2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<=) (Int -> Bool) -> (NonEmpty a -> Int) -> NonEmpty a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty a -> Int
forall a. NonEmpty a -> Int
List1.length)
([NonEmpty a] -> [NonEmpty a])
-> (t a -> [NonEmpty a]) -> t a -> [NonEmpty a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map b (NonEmpty a) -> [NonEmpty a]
forall k a. Map k a -> [a]
Map.elems
(Map b (NonEmpty a) -> [NonEmpty a])
-> (t a -> Map b (NonEmpty a)) -> t a -> [NonEmpty a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Map b (NonEmpty a) -> Map b (NonEmpty a))
-> Map b (NonEmpty a) -> t a -> Map b (NonEmpty a)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
Fold.foldr (\ a
a -> (NonEmpty a -> NonEmpty a -> NonEmpty a)
-> b -> NonEmpty a -> Map b (NonEmpty a) -> Map b (NonEmpty a)
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith NonEmpty a -> NonEmpty a -> NonEmpty a
forall a. Semigroup a => a -> a -> a
(<>) (a -> b
nf a
a) (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [])) Map b (NonEmpty a)
forall k a. Map k a
Map.empty
groupOn :: Eq b => (a -> b) -> [a] -> [List1 a]
groupOn :: forall b a. Eq b => (a -> b) -> [a] -> [List1 a]
groupOn a -> b
nf = [a] -> [NonEmpty a]
loop
where
loop :: [a] -> [NonEmpty a]
loop = \case
[] -> []
a
a:[a]
xs | let ([a]
as, [a]
rest) = (a -> Bool) -> [a] -> ([a], [a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span ((a -> b
nf a
a b -> b -> Bool
forall a. Eq a => a -> a -> Bool
==) (b -> Bool) -> (a -> b) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
nf) [a]
xs
-> (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as) NonEmpty a -> [NonEmpty a] -> [NonEmpty a]
forall a. a -> [a] -> [a]
: [a] -> [NonEmpty a]
loop [a]
rest
uniqOn :: Eq b => (a -> b) -> [a] -> [a]
uniqOn :: forall b a. Eq b => (a -> b) -> [a] -> [a]
uniqOn a -> b
nf = (NonEmpty a -> a) -> [NonEmpty a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map NonEmpty a -> a
forall a. NonEmpty a -> a
List1.head ([NonEmpty a] -> [a]) -> ([a] -> [NonEmpty a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> [a] -> [NonEmpty a]
forall b a. Eq b => (a -> b) -> [a] -> [List1 a]
groupOn a -> b
nf
hasNumericSuffix :: String -> Maybe (String, Integer)
hasNumericSuffix :: String -> Maybe (String, Integer)
hasNumericSuffix String
s = case (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
spanEnd Char -> Bool
isDigit String
s of
([], String
_) -> Maybe (String, Integer)
forall a. Maybe a
Nothing
(String
num, String
front) -> (String, Integer) -> Maybe (String, Integer)
forall a. a -> Maybe a
Just (String
front, String -> Integer
forall a. Read a => String -> a
read String
num)
truncateZonedTimeToSeconds :: ZonedTime -> ZonedTime
truncateZonedTimeToSeconds :: ZonedTime -> ZonedTime
truncateZonedTimeToSeconds (ZonedTime (LocalTime Day
day (TimeOfDay Int
h Int
m Pico
s)) TimeZone
zone) =
LocalTime -> TimeZone -> ZonedTime
ZonedTime (Day -> TimeOfDay -> LocalTime
LocalTime Day
day (Int -> Int -> Pico -> TimeOfDay
TimeOfDay Int
h Int
m Pico
s')) TimeZone
zone
where s' :: Pico
s' = Integer -> Pico
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Pico) -> Integer -> Pico
forall a b. (a -> b) -> a -> b
$ Pico -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate Pico
s
getZonedTimeTruncatedToSeconds :: IO ZonedTime
getZonedTimeTruncatedToSeconds :: IO ZonedTime
getZonedTimeTruncatedToSeconds = ZonedTime -> ZonedTime
truncateZonedTimeToSeconds (ZonedTime -> ZonedTime) -> IO ZonedTime -> IO ZonedTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO ZonedTime
getZonedTime
writeFileRep :: FilePath -> String -> IO ()
writeFileRep :: String -> String -> IO ()
writeFileRep String
path String
s =
(IOError -> IO ())
-> (String -> IO ()) -> Either IOError String -> IO ()
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either IOError -> IO ()
forall {p}. p -> IO ()
newFile String -> IO ()
updateFile (Either IOError String -> IO ())
-> IO (Either IOError String) -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO String -> IO (Either IOError String)
forall a. IO a -> IO (Either IOError a)
tryIOError (String -> IO String
readFile' String
path)
where
newFile :: p -> IO ()
newFile p
_ = do
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"writing new file " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
path
String -> String -> IO ()
writeFile String
path String
s
updateFile :: String -> IO ()
updateFile String
old = do
String -> String -> IO ()
writeFile String
path String
s
if String
s String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
old
then do
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"refreshing unchanged file " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
path
else do
let bak :: String
bak = String
path String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".bak"
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"writing file " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
path String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (saving old file as " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
bak String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
String -> String -> IO ()
writeFile String
bak String
old
readFile' :: FilePath -> IO String
readFile' :: String -> IO String
readFile' String
path' = do
Handle
inFile <- String -> IOMode -> IO Handle
openFile String
path' IOMode
ReadMode
String
contents <- Handle -> IO String
hGetContents Handle
inFile
String -> ()
forall a. NFData a => a -> ()
rnf String
contents () -> IO () -> IO ()
`seq` Handle -> IO ()
hClose Handle
inFile
String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
contents
data NameStyle
= LowerCase
| UpperCase
| SnakeCase
| CamelCase
| MixedCase
| OrigCase
deriving (Int -> NameStyle -> String -> String
[NameStyle] -> String -> String
NameStyle -> String
(Int -> NameStyle -> String -> String)
-> (NameStyle -> String)
-> ([NameStyle] -> String -> String)
-> Show NameStyle
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [NameStyle] -> String -> String
$cshowList :: [NameStyle] -> String -> String
show :: NameStyle -> String
$cshow :: NameStyle -> String
showsPrec :: Int -> NameStyle -> String -> String
$cshowsPrec :: Int -> NameStyle -> String -> String
Show, NameStyle -> NameStyle -> Bool
(NameStyle -> NameStyle -> Bool)
-> (NameStyle -> NameStyle -> Bool) -> Eq NameStyle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NameStyle -> NameStyle -> Bool
$c/= :: NameStyle -> NameStyle -> Bool
== :: NameStyle -> NameStyle -> Bool
$c== :: NameStyle -> NameStyle -> Bool
Eq)
mkName :: [String] -> NameStyle -> String -> String
mkName :: [String] -> NameStyle -> String -> String
mkName [String]
reserved NameStyle
style String
s = String -> String
notReserved String
name'
where
notReserved :: String -> String
notReserved String
s
| String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
reserved = String -> String
notReserved (String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_")
| Bool
otherwise = String
s
tokens :: [String]
tokens = String -> [String]
parseIdent String
s
name' :: String
name' = case NameStyle
style of
NameStyle
LowerCase -> (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ([String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
tokens)
NameStyle
UpperCase -> (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toUpper ([String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String]
tokens)
NameStyle
CamelCase -> (String -> String) -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap String -> String
capitalize [String]
tokens
NameStyle
MixedCase -> case (String -> String) -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap String -> String
capitalize [String]
tokens of
String
"" -> String
""
Char
c:String
cs -> Char -> Char
toLower Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
cs
NameStyle
SnakeCase -> (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"_" [String]
tokens)
NameStyle
OrigCase -> String
s
capitalize :: String -> String
capitalize [] = []
capitalize (Char
c:String
cs) = Char -> Char
toUpper Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
cs
mkNames :: [String] -> NameStyle -> [String] -> [String]
mkNames :: [String] -> NameStyle -> [String] -> [String]
mkNames [String]
reserved NameStyle
style = [String] -> [String]
disambiguateNames ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ([String] -> NameStyle -> String -> String
mkName [String]
reserved NameStyle
style)
disambiguateNames :: [String] -> [String]
disambiguateNames :: [String] -> [String]
disambiguateNames = [String] -> [String] -> [String]
disamb []
where
disamb :: [String] -> [String] -> [String]
disamb [String]
ns1 (String
n:[String]
ns2)
| String
n String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([String]
ns1 [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
ns2) = let i :: Int
i = [String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> String -> Bool
forall a. Eq a => a -> a -> Bool
==String
n) [String]
ns1) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
in (String
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i) String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String] -> [String] -> [String]
disamb (String
nString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
ns1) [String]
ns2
| Bool
otherwise = String
n String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String] -> [String] -> [String]
disamb (String
nString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
ns1) [String]
ns2
disamb [String]
_ [] = []
parseIdent :: String -> [String]
parseIdent :: String -> [String]
parseIdent = String -> [(CharClass, Char)] -> [String]
p [] ([(CharClass, Char)] -> [String])
-> (String -> [(CharClass, Char)]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> (CharClass, Char)) -> String -> [(CharClass, Char)]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> CharClass
classify (Char -> CharClass) -> (Char -> Char) -> Char -> (CharClass, Char)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& Char -> Char
forall a. a -> a
id)
where
classify :: Char -> CharClass
classify :: Char -> CharClass
classify Char
c
| Char -> Bool
isUpper Char
c = CharClass
U
| Char -> Bool
isLower Char
c = CharClass
L
| Bool
otherwise = CharClass
O
p :: String -> [(CharClass,Char)] -> [String]
p :: String -> [(CharClass, Char)] -> [String]
p String
acc [] = String -> [String] -> [String]
emit String
acc []
p String
acc ((CharClass
L,Char
c) : cs :: [(CharClass, Char)]
cs@((CharClass
L,Char
_) : [(CharClass, Char)]
_)) = String -> [(CharClass, Char)] -> [String]
p (Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
acc) [(CharClass, Char)]
cs
p String
acc ((CharClass
U,Char
c) : cs :: [(CharClass, Char)]
cs@((CharClass
U,Char
_) : [(CharClass, Char)]
_)) = String -> [(CharClass, Char)] -> [String]
p (Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
acc) [(CharClass, Char)]
cs
p String
acc ((CharClass
U,Char
c) : cs :: [(CharClass, Char)]
cs@((CharClass
L,Char
_) : [(CharClass, Char)]
_)) = String -> [String] -> [String]
emit String
acc ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ String -> [(CharClass, Char)] -> [String]
p [Char
c] [(CharClass, Char)]
cs
p String
acc ((CharClass
L,Char
c) : cs :: [(CharClass, Char)]
cs@((CharClass
U,Char
_) : [(CharClass, Char)]
_)) = String -> [String] -> [String]
emit (Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
acc) ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ String -> [(CharClass, Char)] -> [String]
p [] [(CharClass, Char)]
cs
p String
acc ((CharClass
U,Char
c) : (CharClass
O,Char
_) : [(CharClass, Char)]
cs) = String -> [String] -> [String]
emit (Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
acc) ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ String -> [(CharClass, Char)] -> [String]
p [] [(CharClass, Char)]
cs
p String
acc ((CharClass
L,Char
c) : (CharClass
O,Char
_) : [(CharClass, Char)]
cs) = String -> [String] -> [String]
emit (Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
acc) ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ String -> [(CharClass, Char)] -> [String]
p [] [(CharClass, Char)]
cs
p String
acc ((CharClass
O,Char
_) : [(CharClass, Char)]
cs) = String -> [String] -> [String]
emit String
acc ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ String -> [(CharClass, Char)] -> [String]
p [] [(CharClass, Char)]
cs
p String
acc [(CharClass
_,Char
c)] = String -> [(CharClass, Char)] -> [String]
p (Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
acc) []
emit :: String -> [String] -> [String]
emit :: String -> [String] -> [String]
emit [] [String]
rest = [String]
rest
emit String
acc [String]
rest = String -> String
forall a. [a] -> [a]
reverse String
acc String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
rest
data CharClass = U | L | O
lowerCase :: String -> Doc
lowerCase :: String -> Doc
lowerCase = String -> Doc
text (String -> Doc) -> (String -> String) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> NameStyle -> String -> String
mkName [] NameStyle
LowerCase
upperCase :: String -> Doc
upperCase :: String -> Doc
upperCase = String -> Doc
text (String -> Doc) -> (String -> String) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> NameStyle -> String -> String
mkName [] NameStyle
UpperCase
camelCase :: String -> Doc
camelCase :: String -> Doc
camelCase = String -> Doc
text (String -> Doc) -> (String -> String) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
camelCase_
camelCase_ :: String -> String
camelCase_ :: String -> String
camelCase_ = [String] -> NameStyle -> String -> String
mkName [] NameStyle
CamelCase
mixedCase :: String -> Doc
mixedCase :: String -> Doc
mixedCase = String -> Doc
text (String -> Doc) -> (String -> String) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> NameStyle -> String -> String
mkName [] NameStyle
MixedCase
snakeCase :: String -> Doc
snakeCase :: String -> Doc
snakeCase = String -> Doc
text (String -> Doc) -> (String -> String) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
snakeCase_
snakeCase_ :: String -> String
snakeCase_ :: String -> String
snakeCase_ = [String] -> NameStyle -> String -> String
mkName [] NameStyle
SnakeCase
cstring :: String -> Doc
cstring :: String -> Doc
cstring = String -> Doc
text (String -> Doc) -> (String -> String) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. Show a => a -> String
show
symbolToName :: String -> Maybe String
symbolToName :: String -> Maybe String
symbolToName = (String -> Map String String -> Maybe String
forall k a. Ord k => k -> Map k a -> Maybe a
`Map.lookup` Map String String
symbolTokenMap)
symbolTokenMap :: Map String String
symbolTokenMap :: Map String String
symbolTokenMap = [(String, String)] -> Map String String
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(String, String)]
symbolTokenList
symbolTokenList :: [(String, String)]
symbolTokenList :: [(String, String)]
symbolTokenList =
[ (String
"{" , String
"LBRACE")
, (String
"}" , String
"RBRACE")
, (String
"(" , String
"LPAREN")
, (String
")" , String
"RPAREN")
, (String
"[" , String
"LBRACK")
, (String
"]" , String
"RBRACK")
, (String
"[]" , String
"EMPTYBRACK")
, (String
"." , String
"DOT")
, (String
".." , String
"DDOT")
, (String
"...", String
"ELLIPSIS")
, (String
"," , String
"COMMA")
, (String
",," , String
"DCOMMA")
, (String
";" , String
"SEMI")
, (String
";;" , String
"DSEMI")
, (String
":" , String
"COLON")
, (String
"::" , String
"DCOLON")
, (String
":=" , String
"COLONEQ")
, (String
"::=", String
"DCOLONEQ")
, (String
":-" , String
"COLONMINUS")
, (String
"::-", String
"DCOLONMINUS")
, (String
":--", String
"COLONDMINUS")
, (String
"+" , String
"PLUS")
, (String
"++" , String
"DPLUS")
, (String
"+=" , String
"PLUSEQ")
, (String
"+-" , String
"PLUSMINUS")
, (String
"-" , String
"MINUS")
, (String
"--" , String
"DMINUS")
, (String
"-=" , String
"MINUSEQ")
, (String
"-+" , String
"MINUSPLUS")
, (String
"-*" , String
"MINUSSTAR")
, (String
"*" , String
"STAR")
, (String
"**" , String
"DSTAR")
, (String
"*=" , String
"STAREQ")
, (String
"*-" , String
"STARMINUS")
, (String
"/" , String
"SLASH")
, (String
"//" , String
"DSLASH")
, (String
"/=" , String
"SLASHEQ")
, (String
"\\" , String
"BACKSLASH")
, (String
"\\\\",String
"DBACKSLASH")
, (String
"/\\", String
"WEDGE")
, (String
"\\/", String
"VEE")
, (String
"&" , String
"AMP")
, (String
"&&" , String
"DAMP")
, (String
"&=" , String
"AMPEQ")
, (String
"|" , String
"BAR")
, (String
"||" , String
"DBAR")
, (String
"|=" , String
"BAREQ")
, (String
"<" , String
"LT")
, (String
"<<" , String
"DLT")
, (String
"<<<", String
"TLT")
, (String
"<=" , String
"LTEQ")
, (String
"<<=", String
"DLTEQ")
, (String
"<<<=",String
"TLTEQ")
, (String
">" , String
"GT")
, (String
">>" , String
"DGT")
, (String
">>>", String
"TGT")
, (String
">=" , String
"GTEQ")
, (String
">>=", String
"DGTEQ")
, (String
">>>=",String
"TGTEQ")
, (String
"<>" , String
"LTGT")
, (String
"=" , String
"EQ")
, (String
"==" , String
"DEQ")
, (String
"_" , String
"UNDERSCORE")
, (String
"!" , String
"BANG")
, (String
"!=" , String
"BANGEQ")
, (String
"?" , String
"QUESTION")
, (String
"?=" , String
"QUESTIONEQ")
, (String
"#" , String
"HASH")
, (String
"##" , String
"DHASH")
, (String
"###", String
"THASH")
, (String
"@" , String
"AT")
, (String
"@@" , String
"DAT")
, (String
"@=" , String
"ATEQ")
, (String
"$" , String
"DOLLAR")
, (String
"$$" , String
"DDOLLAR")
, (String
"%" , String
"PERCENT")
, (String
"%%" , String
"DPERCENT")
, (String
"%=" , String
"PERCENTEQ")
, (String
"^" , String
"CARET")
, (String
"^^" , String
"DCARET")
, (String
"^=" , String
"CARETEQ")
, (String
"~" , String
"TILDE")
, (String
"~~" , String
"DTILDE")
, (String
"~=" , String
"TILDEEQ")
, (String
"'" , String
"APOSTROPHE")
, (String
"''" , String
"DAPOSTROPHE")
, (String
"'''", String
"TAPOSTROPHE")
, (String
"<-" , String
"LARROW")
, (String
"->" , String
"RARROW")
, (String
"<=" , String
"LDARROW")
, (String
"=>" , String
"RDARROW")
, (String
"|->", String
"MAPSTO")
]