module Agda.Utils.Suffix where
import Data.Char
import Agda.Utils.Impossible
import Data.IORef
import qualified System.IO.Unsafe as UNSAFE
import Agda.Interaction.Options.IORefs
subscriptAllowed :: UnicodeOrAscii
subscriptAllowed :: UnicodeOrAscii
subscriptAllowed = IO UnicodeOrAscii -> UnicodeOrAscii
forall a. IO a -> a
UNSAFE.unsafePerformIO (IORef UnicodeOrAscii -> IO UnicodeOrAscii
forall a. IORef a -> IO a
readIORef IORef UnicodeOrAscii
unicodeOrAscii)
isSubscriptDigit :: Char -> Bool
isSubscriptDigit :: Char -> Bool
isSubscriptDigit Char
c = Char
'₀' Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'₉'
toSubscriptDigit :: Char -> Char
toSubscriptDigit :: Char -> Char
toSubscriptDigit Char
d
| Char -> Bool
isDigit Char
d = Int -> Char
forall a. Enum a => Int -> a
toEnum (Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
'₀' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
d Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
'0'))
| Bool
otherwise = Char
forall a. HasCallStack => a
__IMPOSSIBLE__
fromSubscriptDigit :: Char -> Char
fromSubscriptDigit :: Char -> Char
fromSubscriptDigit Char
d
| Char -> Bool
isSubscriptDigit Char
d = Int -> Char
forall a. Enum a => Int -> a
toEnum (Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
'0' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
d Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
'₀'))
| Bool
otherwise = Char
forall a. HasCallStack => a
__IMPOSSIBLE__
data Suffix
= NoSuffix
| Prime Int
| Index Int
| Subscript Int
nextSuffix :: Suffix -> Suffix
nextSuffix :: Suffix -> Suffix
nextSuffix Suffix
NoSuffix = case UnicodeOrAscii
subscriptAllowed of
UnicodeOrAscii
UnicodeOk -> Int -> Suffix
Subscript Int
1
UnicodeOrAscii
AsciiOnly -> Int -> Suffix
Index Int
1
nextSuffix (Prime Int
i) = Int -> Suffix
Prime (Int -> Suffix) -> Int -> Suffix
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
nextSuffix (Index Int
i) = Int -> Suffix
Index (Int -> Suffix) -> Int -> Suffix
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
nextSuffix (Subscript Int
i) = Int -> Suffix
Subscript (Int -> Suffix) -> Int -> Suffix
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
suffixView :: String -> (String, Suffix)
suffixView :: String -> (String, Suffix)
suffixView String
s
| (ps :: String
ps@(Char
_:String
_), String
s') <- (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'\'') String
rs = (String -> String
forall a. [a] -> [a]
reverse String
s', Int -> Suffix
Prime (Int -> Suffix) -> Int -> Suffix
forall a b. (a -> b) -> a -> b
$ String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
ps)
| (ns :: String
ns@(Char
_:String
_), String
s') <- (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Char -> Bool
isDigit String
rs = (String -> String
forall a. [a] -> [a]
reverse String
s', Int -> Suffix
Index (Int -> Suffix) -> Int -> Suffix
forall a b. (a -> b) -> a -> b
$ String -> Int
forall a. Read a => String -> a
read (String -> Int) -> String -> Int
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. [a] -> [a]
reverse String
ns)
| (ns :: String
ns@(Char
_:String
_), String
s') <- (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Char -> Bool
isSubscriptDigit String
rs = (String -> String
forall a. [a] -> [a]
reverse String
s', Int -> Suffix
Subscript (Int -> Suffix) -> Int -> Suffix
forall a b. (a -> b) -> a -> b
$ String -> Int
forall a. Read a => String -> a
read (String -> Int) -> String -> Int
forall a b. (a -> b) -> a -> b
$
(Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
fromSubscriptDigit (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. [a] -> [a]
reverse String
ns)
| Bool
otherwise = (String
s, Suffix
NoSuffix)
where rs :: String
rs = String -> String
forall a. [a] -> [a]
reverse String
s
addSuffix :: String -> Suffix -> String
addSuffix :: String -> Suffix -> String
addSuffix String
s Suffix
NoSuffix = String
s
addSuffix String
s (Prime Int
n) = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
n Char
'\''
addSuffix String
s (Index Int
i) = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i
addSuffix String
s (Subscript Int
i) = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toSubscriptDigit (Int -> String
forall a. Show a => a -> String
show Int
i)