morley-1.15.0: src/Michelson/Parser/Annotations.hs
-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ
module Michelson.Parser.Annotations
( note
, noteF
, noteV
, noteDef
, noteV2Def
, notesTVF
, notesTVF2Def
, notesVVFF
, notesTV
, notesTF
, notesVF
, fieldType
, permute2Def
, permute3Def
) where
import Prelude hiding (note)
import Control.Applicative.Permutations (runPermutation, toPermutationWithDefault)
import qualified Data.Text as T
import Text.Megaparsec (satisfy, takeWhileP)
import Text.Megaparsec.Char (string)
import Michelson.Parser.Helpers (parseDef)
import Michelson.Parser.Lexer
import Michelson.Parser.Types (Parser)
import Michelson.Untyped.Annotation
import Util.Default
-- | General T/V/F Annotation parser, including Special Annotations
note :: forall tag. KnownAnnTag tag => Parser (Annotation tag)
note = lexeme $ string (annPrefix @tag) >> (specialNote <|> note' <|> emptyNote)
where
-- TODO [#48] these are special annotations and should not always be accepted
specialVNote = unsafeMkAnnotation <$> asum (map string specialVarAnns)
specialFNote = unsafeMkAnnotation <$> string specialFieldAnn
specialNote = specialVNote <|> specialFNote
emptyNote = pure noAnn
note' = do
a <- satisfy isValidAnnStart
b <- takeWhileP Nothing isValidAnnBodyChar
return . unsafeMkAnnotation $ T.cons a b
noteV :: Parser VarAnn
noteV = note
noteDef :: KnownAnnTag tag => Parser (Annotation tag)
noteDef = parseDef note
noteF :: Parser FieldAnn
noteF = note
noteV2Def :: Parser (VarAnn, VarAnn)
noteV2Def = permute2Def note note
notesTVF :: Parser (TypeAnn, VarAnn, FieldAnn)
notesTVF = permute3Def note note note
notesTVF2Def :: Parser (TypeAnn, VarAnn, (FieldAnn, FieldAnn))
notesTVF2Def = permute3Def note note (permute2Def note note)
-- | Parse 0/1/2 var anns and 0/1/2 field anns.
-- It doesn't matter which come first, so long as annotations of the same type appear together.
--
-- E.g.:
--
-- * "" is valid
-- * "%a" is valid
-- * "%a @c" is valid
-- * "%a %b @c @d" is valid
-- * "@c @d %a %b" is valid
-- * "@c %a %b @d" is not valid, because the two var anns are not "grouped" together.
-- * "%a @c @d %b" is not valid, because the two fields anns are not "grouped" together.
notesVVFF :: Parser ((VarAnn, VarAnn), (FieldAnn, FieldAnn))
notesVVFF = permute2Def (liftA2 (,) note noteDef) (liftA2 (,) note noteDef)
notesVF :: Parser (VarAnn, FieldAnn)
notesVF = permute2Def note note
notesTV :: Parser (TypeAnn, VarAnn)
notesTV = permute2Def note note
notesTF :: Parser (TypeAnn, FieldAnn)
notesTF = permute2Def note note
fieldType :: Default a
=> Parser a
-> Parser (a, TypeAnn)
fieldType fp = runPermutation $
(,) <$> toPermutationWithDefault def fp
<*> toPermutationWithDefault noAnn note