{-# OPTIONS_GHC -Wunused-imports #-}
{-# LANGUAGE RecordWildCards #-}
module Mikan.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 Data.Text (Text)
import Data.Text qualified as T
import GHC.Exts (oneShot)
import Mikan.Syntax.Position
import Mikan.Syntax.Parser.Monad
import Mikan.Utils.Lens
import Mikan.Utils.Tuple
data AlexInput = AlexInput
{ AlexInput -> SrcFile
lexSrcFile :: !SrcFile
, AlexInput -> PositionWithoutFile
lexPos :: !PositionWithoutFile
, AlexInput -> Text
lexInput :: !Text
, AlexInput -> Char
lexPrevChar :: !Char
}
lensLexInput :: Lens' AlexInput Text
lensLexInput :: Lens' AlexInput Text
lensLexInput Text -> f Text
f AlexInput
r = Text -> f Text
f (AlexInput -> Text
lexInput AlexInput
r) f Text -> (Text -> AlexInput) -> f AlexInput
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \ Text
s -> AlexInput
r { lexInput = s }
alexInputPrevChar :: AlexInput -> Char
alexInputPrevChar :: AlexInput -> Char
alexInputPrevChar = AlexInput -> Char
lexPrevChar
alexGetChar :: AlexInput -> Maybe (Char, AlexInput)
alexGetChar :: AlexInput -> Maybe (Char, AlexInput)
alexGetChar AlexInput{Char
Text
SrcFile
PositionWithoutFile
lexSrcFile :: AlexInput -> SrcFile
lexPos :: AlexInput -> PositionWithoutFile
lexInput :: AlexInput -> Text
lexPrevChar :: AlexInput -> Char
lexSrcFile :: SrcFile
lexPos :: PositionWithoutFile
lexInput :: Text
lexPrevChar :: Char
..} = do
(c, rest) <- Text -> Maybe (Char, Text)
T.uncons Text
lexInput
pure (c, AlexInput { lexSrcFile, lexInput = rest, lexPos = movePos lexPos c, lexPrevChar = c })
alexGetByte :: AlexInput -> Maybe (Word8, AlexInput)
alexGetByte :: AlexInput -> Maybe (Word8, AlexInput)
alexGetByte AlexInput
ai =
(Char -> Word8) -> (Char, AlexInput) -> (Word8, AlexInput)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (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) -> Parser AlexInput
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ParseState -> AlexInput
getInp
where
getInp :: ParseState -> AlexInput
getInp ParseState
s = AlexInput
{ lexSrcFile :: SrcFile
lexSrcFile = ParseState -> SrcFile
parseSrcFile ParseState
s
, lexPos :: PositionWithoutFile
lexPos = ParseState -> PositionWithoutFile
parsePos ParseState
s
, lexInput :: Text
lexInput = ParseState -> Text
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 = lexSrcFile inp
, parsePos = lexPos inp
, parseInp = lexInput inp
, parsePrevChar = lexPrevChar inp
}
type PreviousInput = AlexInput
type CurrentInput = AlexInput
type TokenLength = Int
newtype LexAction r
= LexAction { forall r. LexAction r -> AlexInput -> AlexInput -> Int -> Parser r
runLexAction :: PreviousInput -> CurrentInput -> TokenLength -> Parser r }
deriving ((forall a b. (a -> b) -> LexAction a -> LexAction b)
-> (forall a b. a -> LexAction b -> LexAction a)
-> Functor LexAction
forall a b. a -> LexAction b -> LexAction a
forall a b. (a -> b) -> LexAction a -> LexAction b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> LexAction a -> LexAction b
fmap :: forall a b. (a -> b) -> LexAction a -> LexAction b
$c<$ :: forall a b. a -> LexAction b -> LexAction a
<$ :: forall a b. a -> LexAction b -> LexAction a
Functor)
instance Applicative LexAction where
{-# INLINE pure #-}
pure :: forall a. a -> LexAction a
pure a
r = (AlexInput -> AlexInput -> Int -> Parser a) -> LexAction a
forall r.
(AlexInput -> AlexInput -> Int -> Parser r) -> LexAction r
LexAction ((AlexInput -> AlexInput -> Int -> Parser a)
-> AlexInput -> AlexInput -> Int -> Parser a
forall a b. (a -> b) -> a -> b
oneShot \ AlexInput
_ AlexInput
_ Int
_ -> a -> Parser a
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
r)
{-# INLINE (<*>) #-}
LexAction (a -> b)
mf <*> :: forall a b. LexAction (a -> b) -> LexAction a -> LexAction b
<*> LexAction a
mr = (AlexInput -> AlexInput -> Int -> Parser b) -> LexAction b
forall r.
(AlexInput -> AlexInput -> Int -> Parser r) -> LexAction r
LexAction ((AlexInput -> AlexInput -> Int -> Parser b)
-> AlexInput -> AlexInput -> Int -> Parser b
forall a b. (a -> b) -> a -> b
oneShot \ AlexInput
a AlexInput
b Int
c -> LexAction (a -> b)
-> AlexInput -> AlexInput -> Int -> Parser (a -> b)
forall r. LexAction r -> AlexInput -> AlexInput -> Int -> Parser r
runLexAction LexAction (a -> b)
mf AlexInput
a AlexInput
b Int
c Parser (a -> b) -> Parser a -> Parser b
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> LexAction a -> AlexInput -> AlexInput -> Int -> Parser a
forall r. LexAction r -> AlexInput -> AlexInput -> Int -> Parser r
runLexAction LexAction a
mr AlexInput
a AlexInput
b Int
c)
instance Monad LexAction where
return :: forall a. a -> LexAction a
return = a -> LexAction a
forall a. a -> LexAction a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE (>>=) #-}
LexAction a
m >>= :: forall a b. LexAction a -> (a -> LexAction b) -> LexAction b
>>= a -> LexAction b
k = (AlexInput -> AlexInput -> Int -> Parser b) -> LexAction b
forall r.
(AlexInput -> AlexInput -> Int -> Parser r) -> LexAction r
LexAction ((AlexInput -> AlexInput -> Int -> Parser b)
-> AlexInput -> AlexInput -> Int -> Parser b
forall a b. (a -> b) -> a -> b
oneShot \ AlexInput
a AlexInput
b Int
c -> do
r <- LexAction a -> AlexInput -> AlexInput -> Int -> Parser a
forall r. LexAction r -> AlexInput -> AlexInput -> Int -> Parser r
runLexAction LexAction a
m AlexInput
a AlexInput
b Int
c
runLexAction (k r) a b c)
instance MonadState ParseState LexAction where
{-# INLINE get #-}
get :: LexAction ParseState
get = (AlexInput -> AlexInput -> Int -> Parser ParseState)
-> LexAction ParseState
forall r.
(AlexInput -> AlexInput -> Int -> Parser r) -> LexAction r
LexAction ((AlexInput -> AlexInput -> Int -> Parser ParseState)
-> AlexInput -> AlexInput -> Int -> Parser ParseState
forall a b. (a -> b) -> a -> b
oneShot (\ AlexInput
_ AlexInput
_ Int
_ -> Parser ParseState
forall s (m :: * -> *). MonadState s m => m s
get))
{-# INLINE put #-}
put :: ParseState -> LexAction ()
put ParseState
s = (AlexInput -> AlexInput -> Int -> Parser ()) -> LexAction ()
forall r.
(AlexInput -> AlexInput -> Int -> Parser r) -> LexAction r
LexAction ((AlexInput -> AlexInput -> Int -> Parser ())
-> AlexInput -> AlexInput -> Int -> Parser ()
forall a b. (a -> b) -> a -> b
oneShot (\ AlexInput
_ AlexInput
_ Int
_ -> ParseState -> Parser ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put ParseState
s))
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)