Agda-2.8.0.2: src/full/Agda/Utils/Suffix.hs
{-# OPTIONS_GHC -Wunused-imports #-}
module Agda.Utils.Suffix where
import Data.Char
import qualified Data.List as List
import Agda.Utils.Impossible
------------------------------------------------------------------------
-- Subscript digits
-- | Is the character one of the subscripts @'₀'@-@'₉'@?
isSubscriptDigit :: Char -> Bool
isSubscriptDigit c = '₀' <= c && c <= '₉'
-- | Converts @'0'@-@'9'@ to @'₀'@-@'₉'@
--
-- Precondition: The digit needs to be in range.
toSubscriptDigit :: Char -> Char
toSubscriptDigit d
| isDigit d = toEnum (fromEnum '₀' + (fromEnum d - fromEnum '0'))
| otherwise = __IMPOSSIBLE__
-- | Converts @'₀'@-@'₉'@ to @'0'@-@'9'@.
--
-- Precondition: The digit needs to be in range.
fromSubscriptDigit :: Char -> Char
fromSubscriptDigit d
| isSubscriptDigit d = toEnum (fromEnum '0' + (fromEnum d - fromEnum '₀'))
| otherwise = __IMPOSSIBLE__
------------------------------------------------------------------------
-- Suffices
-- | Classification of identifier variants.
data Suffix
= Prime Integer -- ^ Identifier ends in @Integer@ many primes.
| Index Integer -- ^ Identifier ends in number @Integer@ (ordinary digits).
| Subscript Integer -- ^ Identifier ends in number @Integer@ (subscript digits).
-- | Increase the suffix by one.
nextSuffix :: Suffix -> Suffix
nextSuffix (Prime i) = Prime $ i + 1
nextSuffix (Index i) = Index $ i + 1
nextSuffix (Subscript i) = Subscript $ i + 1
-- | Parse suffix.
suffixView :: String -> (String, Maybe Suffix)
suffixView s
| (ps@(_:_), s') <- span (== '\'') rs = (reverse s', Just $ Prime $ List.genericLength ps)
| (ns@(_:_), s') <- span isDigit rs = (reverse s', Just $ Index $ read $ reverse ns)
| (ns@(_:_), s') <- span isSubscriptDigit rs = (reverse s', Just $ Subscript $ read $
map fromSubscriptDigit $ reverse ns)
| otherwise = (s, Nothing)
where rs = reverse s
-- Note: suffixView could be implemented using spanEnd, but the implementation using reverse
-- looks more efficient, since the reversal is only done once.
--
-- suffixView :: String -> (String, Maybe Suffix)
-- suffixView s
-- | (s', ps@(_:_)) <- spanEnd (=='\'') s = (s', Just $ Prime $ length ps)
-- | (s', ns@(_:_)) <- spanEnd isDigit s = (s', Just $ Index $ read ns)
-- | (s', ns@(_:_)) <- spanEnd isSubscriptDigit s = (s', Just $ Subscript $ read $ map fromSubscriptDigit ns)
-- | otherwise = (s, Nothing)
-- | Print suffix.
renderSuffix :: Suffix -> String
renderSuffix (Prime n) = List.genericReplicate n '\''
renderSuffix (Index i) = show i
renderSuffix (Subscript i) = map toSubscriptDigit (show i)
addSuffix :: String -> Suffix -> String
addSuffix str suffix = str ++ renderSuffix suffix