{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wno-missing-signatures #-}

module Wrench.Translator.Parser.Misc (
    literal,
    byteLiteral,
    intLiteral,
    wordLiteral,
    name,
    labelRef,
    comment,
    comma,
    nothing,
    eol',
    label,
    reference,
    referenceWithDirective,
    referenceWithFn,
    constantRef,
    SectionItem (..),
    orgDirective,
    sectionItems,
    sectionOrg,
) where

import Data.Bits
import Data.Text qualified as T
import Relude
import Relude.Unsafe as Unsafe
import Text.Megaparsec (
    SourcePos,
    anySingle,
    anySingleBut,
    choice,
    getOffset,
    getSourcePos,
    manyTill,
    setOffset,
    single,
    try,
 )
import Text.Megaparsec.Char (
    char,
    digitChar,
    eol,
    hexDigitChar,
    hspace,
    hspace1,
    letterChar,
    string,
 )
import Wrench.Machine.Word (fitSigned)
import Wrench.Translator.Parser.Types
import Wrench.Translator.Types

data SectionItem i = Item i | Org Int

sectionItems :: [SectionItem i] -> [i]
sectionItems :: forall i. [SectionItem i] -> [i]
sectionItems = (SectionItem i -> Maybe i) -> [SectionItem i] -> [i]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((SectionItem i -> Maybe i) -> [SectionItem i] -> [i])
-> (SectionItem i -> Maybe i) -> [SectionItem i] -> [i]
forall a b. (a -> b) -> a -> b
$ \case
    Item i
i -> i -> Maybe i
forall a. a -> Maybe a
Just i
i
    Org Int
_ -> Maybe i
forall a. Maybe a
Nothing

sectionOrg :: [SectionItem i] -> Maybe Int
sectionOrg :: forall i. [SectionItem i] -> Maybe Int
sectionOrg [SectionItem i]
items =
    case [Int
i | Org Int
i <- [SectionItem i]
items] of
        [] -> Maybe Int
forall a. Maybe a
Nothing
        [Int
x] -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
x
        (Int
_ : Int
_ : [Int]
_) -> Text -> Maybe Int
forall a t. (HasCallStack, IsText t) => t -> a
error Text
"error: multiple .org directives not allowed"

orgDirective :: String -> Parser Int
orgDirective :: String -> Parser Int
orgDirective String
cstart = do
    ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Void String Identity (Tokens String)
 -> ParsecT Void String Identity ())
-> ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
forall a b. (a -> b) -> a -> b
$ Tokens String -> ParsecT Void String Identity (Tokens String)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string Tokens String
".org"
    ParsecT Void String Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace1
    value <- Parser Int
intLiteral
    eol' cstart
    return value

removeUnderscores :: String -> String
removeUnderscores :: String -> String
removeUnderscores = Text -> String
forall a. ToString a => a -> String
toString (Text -> String) -> (String -> Text) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"_" Text
"" (Text -> Text) -> (String -> Text) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
forall a. ToText a => a -> Text
toText

-- | A literal has to start with a digit, which the @_@ separators may then be
-- mixed into. Without that requirement both parsers also match the empty string,
-- and @read@ dies on it as a bare @Prelude.read: no parse@ with no position.
num :: Parser String
num :: Parser String
num = do
    s <-
        [Parser String] -> Parser String
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
            [ Parser String -> Parser String
forall a.
ParsecT Void String Identity a -> ParsecT Void String Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Parser String -> Parser String) -> Parser String -> Parser String
forall a b. (a -> b) -> a -> b
$ Token String -> ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token String
'-' ParsecT Void String Identity Char -> Parser String -> Parser String
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser String
decDigits Parser String -> (String -> String) -> Parser String
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (:) Char
'-'
            , Parser String
decDigits
            ]
    return $ removeUnderscores s
    where
        decDigits :: Parser String
decDigits = (:) (Char -> String -> String)
-> ParsecT Void String Identity Char
-> ParsecT Void String Identity (String -> String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void String Identity Char
ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
digitChar ParsecT Void String Identity (String -> String)
-> Parser String -> Parser String
forall a b.
ParsecT Void String Identity (a -> b)
-> ParsecT Void String Identity a -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void String Identity Char -> Parser String
forall a.
ParsecT Void String Identity a -> ParsecT Void String Identity [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (ParsecT Void String Identity Char
ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
digitChar ParsecT Void String Identity Char
-> ParsecT Void String Identity Char
-> ParsecT Void String Identity Char
forall a.
ParsecT Void String Identity a
-> ParsecT Void String Identity a -> ParsecT Void String Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Token String -> ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token String
'_')

hexNum :: Parser String
hexNum :: Parser String
hexNum = Parser String -> Parser String
forall a.
ParsecT Void String Identity a -> ParsecT Void String Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Parser String -> Parser String) -> Parser String -> Parser String
forall a b. (a -> b) -> a -> b
$ do
    ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Void String Identity (Tokens String)
 -> ParsecT Void String Identity ())
-> ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
forall a b. (a -> b) -> a -> b
$ Tokens String -> ParsecT Void String Identity (Tokens String)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string Tokens String
"0x"
    ds <- (:) (Char -> String -> String)
-> ParsecT Void String Identity Char
-> ParsecT Void String Identity (String -> String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void String Identity Char
ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
hexDigitChar ParsecT Void String Identity (String -> String)
-> Parser String -> Parser String
forall a b.
ParsecT Void String Identity (a -> b)
-> ParsecT Void String Identity a -> ParsecT Void String Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void String Identity Char -> Parser String
forall a.
ParsecT Void String Identity a -> ParsecT Void String Identity [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (ParsecT Void String Identity Char
ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
hexDigitChar ParsecT Void String Identity Char
-> ParsecT Void String Identity Char
-> ParsecT Void String Identity Char
forall a.
ParsecT Void String Identity a
-> ParsecT Void String Identity a -> ParsecT Void String Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Token String -> ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token String
'_')
    return $ "0x" <> removeUnderscores ds

literal :: Parser Integer
literal :: Parser Integer
literal = String -> Integer
forall a. Read a => String -> a
Unsafe.read (String -> Integer) -> Parser String -> Parser Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Parser String] -> Parser String
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice [Parser String
hexNum, Parser String
num]

wordLiteral :: forall w. (IsWord w) => Parser w
wordLiteral :: forall w. IsWord w => Parser w
wordLiteral = Text -> Parser w
forall a. (FiniteBits a, Integral a) => Text -> Parser a
anyPattern (Text -> Parser w) -> Text -> Parser w
forall a b. (a -> b) -> a -> b
$ Text
"a " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall b a. (Show a, IsString b) => a -> b
show (w -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (w
forall a. Bits a => a
zeroBits :: w)) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"-bit machine word"

byteLiteral :: Parser Word8
byteLiteral :: Parser Word8
byteLiteral = Text -> Parser Word8
forall a. (FiniteBits a, Integral a) => Text -> Parser a
anyPattern Text
"a byte"

intLiteral :: Parser Int
intLiteral :: Parser Int
intLiteral = Text -> Integer -> Integer -> Parser Int
forall a. Integral a => Text -> Integer -> Integer -> Parser a
narrowed Text
"an Int" (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int
forall a. Bounded a => a
minBound :: Int)) (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int
forall a. Bounded a => a
maxBound :: Int))

-- | Any pattern the type's own bits can spell, read as signed or unsigned.
anyPattern :: forall a. (FiniteBits a, Integral a) => Text -> Parser a
anyPattern :: forall a. (FiniteBits a, Integral a) => Text -> Parser a
anyPattern Text
what = Text -> Integer -> Integer -> Parser a
forall a. Integral a => Text -> Integer -> Integer -> Parser a
narrowed Text
what (Integer -> Integer
forall a. Num a => a -> a
negate (Int -> Integer
forall a. Bits a => Int -> a
bit (Int
width Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))) (Int -> Integer
forall a. Bits a => Int -> a
bit Int
width Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1)
    where
        width :: Int
width = a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (a
forall a. Bits a => a
zeroBits :: a)

narrowed :: (Integral a) => Text -> Integer -> Integer -> Parser a
narrowed :: forall a. Integral a => Text -> Integer -> Integer -> Parser a
narrowed Text
what Integer
lo Integer
hi = do
    literalPos <- Parser Int
forall e s (m :: * -> *). MonadParsec e s m => m Int
getOffset
    value <- literal
    if lo <= value && value <= hi
        then return $ fromInteger value
        else do
            setOffset literalPos
            fail $
                concat
                    [ "literal "
                    , show value
                    , " doesn't fit "
                    , toString what
                    , ", expected "
                    , show lo
                    , ".."
                    , show hi
                    ]

comma :: Parser ()
comma :: ParsecT Void String Identity ()
comma = ParsecT Void String Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Void String Identity Char
-> ParsecT Void String Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Token String -> ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token String
',') ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Void String Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace

eol' :: String -> ParsecT Void String Identity ()
eol' String
cstart = ParsecT Void String Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
hspace ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
-> ParsecT Void String Identity ()
forall a b.
ParsecT Void String Identity a
-> ParsecT Void String Identity b -> ParsecT Void String Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser String -> ParsecT Void String Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser String
ParsecT Void String Identity (Tokens String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Tokens s)
eol Parser String -> Parser String -> Parser String
forall a.
ParsecT Void String Identity a
-> ParsecT Void String Identity a -> ParsecT Void String Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> Parser String
comment String
cstart)

name :: Parser Text
name :: Parser Text
name = do
    x <- ParsecT Void String Identity Char
ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Token s)
letterChar ParsecT Void String Identity Char
-> ParsecT Void String Identity Char
-> ParsecT Void String Identity Char
forall a.
ParsecT Void String Identity a
-> ParsecT Void String Identity a -> ParsecT Void String Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Token String -> ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token String
'_'
    xs <- many (letterChar <|> digitChar <|> char '_')
    return $ toText (x : xs)

comment :: String -> Parser String
comment :: String -> Parser String
comment String
cstart = do
    ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Void String Identity (Tokens String)
 -> ParsecT Void String Identity ())
-> ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
forall a b. (a -> b) -> a -> b
$ Tokens String -> ParsecT Void String Identity (Tokens String)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string String
Tokens String
cstart
    ParsecT Void String Identity Char
-> ParsecT Void String Identity (Tokens String) -> Parser String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
manyTill ParsecT Void String Identity Char
ParsecT Void String Identity (Token String)
forall e s (m :: * -> *). MonadParsec e s m => m (Token s)
anySingle ParsecT Void String Identity (Tokens String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m (Tokens s)
eol

nothing :: (Monad m) => m a -> m (Maybe b)
nothing :: forall (m :: * -> *) a b. Monad m => m a -> m (Maybe b)
nothing m a
p = m a
p m a -> m (Maybe b) -> m (Maybe b)
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe b -> m (Maybe b)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe b
forall a. Maybe a
Nothing

label :: Parser Text
label :: Parser Text
label = Parser Text -> Parser Text
forall a.
ParsecT Void String Identity a -> ParsecT Void String Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Parser Text -> Parser Text) -> Parser Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ do
    n <- Parser Text
name
    void $ single ':'
    return n

labelRef :: Parser Text
labelRef = Parser Text
name

referenceWithFn :: (IsWord w) => (w -> w) -> Parser (Ref w)
referenceWithFn :: forall w. IsWord w => (w -> w) -> Parser (Ref w)
referenceWithFn w -> w
f = do
    pos <- ParsecT Void String Identity SourcePos
forall s e (m :: * -> *).
(TraversableStream s, MonadParsec e s m) =>
m SourcePos
getSourcePos
    choice
        [ constantAt f pos
        , Ref f pos <$> labelRef
        ]

constantRef :: (IsWord w) => Parser (Ref w)
constantRef :: forall w. IsWord w => Parser (Ref w)
constantRef = ParsecT Void String Identity SourcePos
forall s e (m :: * -> *).
(TraversableStream s, MonadParsec e s m) =>
m SourcePos
getSourcePos ParsecT Void String Identity SourcePos
-> (SourcePos -> ParsecT Void String Identity (Ref w))
-> ParsecT Void String Identity (Ref w)
forall a b.
ParsecT Void String Identity a
-> (a -> ParsecT Void String Identity b)
-> ParsecT Void String Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (w -> w) -> SourcePos -> ParsecT Void String Identity (Ref w)
forall w. IsWord w => (w -> w) -> SourcePos -> Parser (Ref w)
constantAt w -> w
forall a. a -> a
id

constantAt :: (IsWord w) => (w -> w) -> SourcePos -> Parser (Ref w)
constantAt :: forall w. IsWord w => (w -> w) -> SourcePos -> Parser (Ref w)
constantAt w -> w
f SourcePos
pos =
    [ParsecT Void String Identity (Ref w)]
-> ParsecT Void String Identity (Ref w)
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
        [ do
            ParsecT Void String Identity (Token String)
-> ParsecT Void String Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT Void String Identity (Token String)
quote
            c <- Token String -> ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
MonadParsec e s m =>
Token s -> m (Token s)
anySingleBut Char
Token String
'\''
            void quote
            return $ ValueR f pos $ fromIntegral $ ord c
        , (w -> w) -> SourcePos -> w -> Ref w
forall w. (w -> w) -> SourcePos -> w -> Ref w
ValueR w -> w
f SourcePos
pos (w -> Ref w)
-> ParsecT Void String Identity w
-> ParsecT Void String Identity (Ref w)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void String Identity w
forall w. IsWord w => Parser w
wordLiteral
        ]
    where
        quote :: ParsecT Void String Identity (Token String)
quote = Token String -> ParsecT Void String Identity (Token String)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token String
'\''

-- | A reference that may be wrapped in a @%hi@ \/ @%lo@ relocation directive.
--
-- The two directives are designed to be used as a pair:
--
-- > lui  rd, %hi(x)
-- > addi rd, rd, %lo(x)
--
-- @%lo@ keeps the low 12 bits and sign-extends them from bit 11, because that is
-- what the instructions consuming the field do with it (see 'fitSigned'):
-- @%lo(0xFFFFFFFF)@ is @-1@, not @0xFFF@. To compensate for that borrow, @%hi@
-- rounds the value up by half a field (@+0x800@) before taking its upper 20 bits,
-- so the pair reconstructs @x@ exactly for every 32-bit @x@.
referenceWithDirective :: (IsWord w) => Parser (Ref w)
referenceWithDirective :: forall w. IsWord w => Parser (Ref w)
referenceWithDirective =
    [ParsecT Void String Identity (Ref w)]
-> ParsecT Void String Identity (Ref w)
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
        [ do
            ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Void String Identity (Tokens String)
 -> ParsecT Void String Identity ())
-> ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
forall a b. (a -> b) -> a -> b
$ Tokens String -> ParsecT Void String Identity (Tokens String)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string Tokens String
"%hi("
            ref <- (w -> w) -> ParsecT Void String Identity (Ref w)
forall w. IsWord w => (w -> w) -> Parser (Ref w)
referenceWithFn (\w
w -> ((w
w w -> w -> w
forall a. Num a => a -> a -> a
+ w
0x800) w -> Int -> w
forall a. Bits a => a -> Int -> a
`shiftR` Int
12) w -> w -> w
forall a. Bits a => a -> a -> a
.&. w
0xFFFFF)
            void $ string ")"
            return ref
        , do
            ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT Void String Identity (Tokens String)
 -> ParsecT Void String Identity ())
-> ParsecT Void String Identity (Tokens String)
-> ParsecT Void String Identity ()
forall a b. (a -> b) -> a -> b
$ Tokens String -> ParsecT Void String Identity (Tokens String)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string Tokens String
"%lo("
            ref <- (w -> w) -> ParsecT Void String Identity (Ref w)
forall w. IsWord w => (w -> w) -> Parser (Ref w)
referenceWithFn (Int -> w -> w
forall w. IsWord w => Int -> w -> w
fitSigned Int
12)
            void $ string ")"
            return ref
        , ParsecT Void String Identity (Ref w)
forall w. IsWord w => Parser (Ref w)
reference
        ]

reference :: (IsWord w) => Parser (Ref w)
reference :: forall w. IsWord w => Parser (Ref w)
reference = (w -> w) -> Parser (Ref w)
forall w. IsWord w => (w -> w) -> Parser (Ref w)
referenceWithFn w -> w
forall a. a -> a
id