module Agda.Syntax.Parser.Alex
(
AlexInput(..)
, lensLexInput
, alexInputPrevChar
, alexGetChar, alexGetByte
, LexAction, LexPredicate
, (.&&.), (.||.), not'
, PreviousInput, CurrentInput, TokenLength
, getLexInput, setLexInput
)
where
import Control.Monad.State
import Data.Char
import Data.Word
import Agda.Syntax.Position
import Agda.Syntax.Parser.Monad
import Agda.Utils.Lens
import Agda.Utils.Tuple
data AlexInput = AlexInput
{ AlexInput -> SrcFile
lexSrcFile :: !SrcFile
, AlexInput -> PositionWithoutFile
lexPos :: !PositionWithoutFile
, AlexInput -> String
lexInput :: String
, AlexInput -> Char
lexPrevChar :: !Char
}
lensLexInput :: Lens' String AlexInput
lensLexInput :: (String -> f String) -> AlexInput -> f AlexInput
lensLexInput String -> f String
f AlexInput
r = String -> f String
f (AlexInput -> String
lexInput AlexInput
r) f String -> (String -> AlexInput) -> f AlexInput
forall (m :: * -> *) a b. Functor m => m a -> (a -> b) -> m b
<&> \ String
s -> AlexInput
r { lexInput :: String
lexInput = String
s }
alexInputPrevChar :: AlexInput -> Char
alexInputPrevChar :: AlexInput -> Char
alexInputPrevChar = AlexInput -> Char
lexPrevChar
alexGetChar :: AlexInput -> Maybe (Char, AlexInput)
alexGetChar :: AlexInput -> Maybe (Char, AlexInput)
alexGetChar (AlexInput { lexInput :: AlexInput -> String
lexInput = [] }) = Maybe (Char, AlexInput)
forall a. Maybe a
Nothing
alexGetChar inp :: AlexInput
inp@(AlexInput { lexInput :: AlexInput -> String
lexInput = Char
c:String
s, lexPos :: AlexInput -> PositionWithoutFile
lexPos = PositionWithoutFile
p }) =
(Char, AlexInput) -> Maybe (Char, AlexInput)
forall a. a -> Maybe a
Just (Char
c, AlexInput :: SrcFile -> PositionWithoutFile -> String -> Char -> AlexInput
AlexInput
{ lexSrcFile :: SrcFile
lexSrcFile = AlexInput -> SrcFile
lexSrcFile AlexInput
inp
, lexInput :: String
lexInput = String
s
, lexPos :: PositionWithoutFile
lexPos = PositionWithoutFile -> Char -> PositionWithoutFile
forall a. Position' a -> Char -> Position' a
movePos PositionWithoutFile
p Char
c
, lexPrevChar :: Char
lexPrevChar = Char
c
}
)
alexGetByte :: AlexInput -> Maybe (Word8, AlexInput)
alexGetByte :: AlexInput -> Maybe (Word8, AlexInput)
alexGetByte AlexInput
ai =
(Char -> Word8) -> (Char, AlexInput) -> (Word8, AlexInput)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> (Char -> Int) -> Char -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
forall a. Enum a => a -> Int
fromEnum (Char -> Int) -> (Char -> Char) -> Char -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Char
toASCII) ((Char, AlexInput) -> (Word8, AlexInput))
-> Maybe (Char, AlexInput) -> Maybe (Word8, AlexInput)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AlexInput -> Maybe (Char, AlexInput)
alexGetChar AlexInput
ai
where
toASCII :: Char -> Char
toASCII Char
c
| Char -> Bool
isSpace Char
c Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\t' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\n' = Char
' '
| Char -> Bool
isAscii Char
c = Char
c
| Char -> Bool
isPrint Char
c = if Char -> Bool
isAlpha Char
c then Char
'z'
else Char
'+'
| Bool
otherwise = Char
'\1'
getLexInput :: Parser AlexInput
getLexInput :: Parser AlexInput
getLexInput = ParseState -> AlexInput
getInp (ParseState -> AlexInput) -> Parser ParseState -> Parser AlexInput
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ParseState
forall s (m :: * -> *). MonadState s m => m s
get
where
getInp :: ParseState -> AlexInput
getInp ParseState
s = AlexInput :: SrcFile -> PositionWithoutFile -> String -> Char -> AlexInput
AlexInput
{ lexSrcFile :: SrcFile
lexSrcFile = ParseState -> SrcFile
parseSrcFile ParseState
s
, lexPos :: PositionWithoutFile
lexPos = ParseState -> PositionWithoutFile
parsePos ParseState
s
, lexInput :: String
lexInput = ParseState -> String
parseInp ParseState
s
, lexPrevChar :: Char
lexPrevChar = ParseState -> Char
parsePrevChar ParseState
s
}
setLexInput :: AlexInput -> Parser ()
setLexInput :: AlexInput -> Parser ()
setLexInput AlexInput
inp = (ParseState -> ParseState) -> Parser ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ParseState -> ParseState
upd
where
upd :: ParseState -> ParseState
upd ParseState
s = ParseState
s { parseSrcFile :: SrcFile
parseSrcFile = AlexInput -> SrcFile
lexSrcFile AlexInput
inp
, parsePos :: PositionWithoutFile
parsePos = AlexInput -> PositionWithoutFile
lexPos AlexInput
inp
, parseInp :: String
parseInp = AlexInput -> String
lexInput AlexInput
inp
, parsePrevChar :: Char
parsePrevChar = AlexInput -> Char
lexPrevChar AlexInput
inp
}
type PreviousInput = AlexInput
type CurrentInput = AlexInput
type TokenLength = Int
type LexAction r = PreviousInput -> CurrentInput -> TokenLength -> Parser r
type LexPredicate = ([LexState], ParseFlags) -> PreviousInput -> TokenLength -> CurrentInput -> Bool
(.&&.) :: LexPredicate -> LexPredicate -> LexPredicate
LexPredicate
p1 .&&. :: LexPredicate -> LexPredicate -> LexPredicate
.&&. LexPredicate
p2 = \([Int], ParseFlags)
x AlexInput
y Int
z AlexInput
u -> LexPredicate
p1 ([Int], ParseFlags)
x AlexInput
y Int
z AlexInput
u Bool -> Bool -> Bool
&& LexPredicate
p2 ([Int], ParseFlags)
x AlexInput
y Int
z AlexInput
u
(.||.) :: LexPredicate -> LexPredicate -> LexPredicate
LexPredicate
p1 .||. :: LexPredicate -> LexPredicate -> LexPredicate
.||. LexPredicate
p2 = \([Int], ParseFlags)
x AlexInput
y Int
z AlexInput
u -> LexPredicate
p1 ([Int], ParseFlags)
x AlexInput
y Int
z AlexInput
u Bool -> Bool -> Bool
|| LexPredicate
p2 ([Int], ParseFlags)
x AlexInput
y Int
z AlexInput
u
not' :: LexPredicate -> LexPredicate
not' :: LexPredicate -> LexPredicate
not' LexPredicate
p = \([Int], ParseFlags)
x AlexInput
y Int
z AlexInput
u -> Bool -> Bool
not (LexPredicate
p ([Int], ParseFlags)
x AlexInput
y Int
z AlexInput
u)