Skip to content

Commit

Permalink
Some progress on parsing principals
Browse files Browse the repository at this point in the history
  • Loading branch information
0xd34df00d committed Oct 25, 2023
1 parent d46b91e commit f7311ae
Showing 1 changed file with 79 additions and 0 deletions.
79 changes: 79 additions & 0 deletions pact-core/Pact/Core/Principal.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE OverloadedStrings #-}

module Pact.Core.Principal where

import Control.Applicative
import Data.Attoparsec.Text
import Data.ByteString.Char8 qualified as BS
import Data.Char(isHexDigit)
import Data.Functor
import Data.HashSet qualified as HS
import Data.Text(Text)
import Data.Text qualified as T
import Text.Parser.Char(oneOf)
import Text.Parser.Combinators(eof)
import Text.Parser.Token
import Text.Parser.Token.Highlight

import Pact.Core.Guards
import Pact.Core.Names
Expand Down Expand Up @@ -42,3 +54,70 @@ mkPrincipalIdent = \case
U n ph -> "u:" <> n <> ":" <> ph
M mn n -> "m:" <> renderModuleName mn <> ":" <> n
C c -> "c:" <> c

principalParser :: Parser Principal
principalParser = alts <* void eof
where
alts = kParser
<|> wParser
{-
<|> rParser
<|> uParser
<|> mParser
<|> pParser
<|> cParser
-}

kParser = do
prefix 'k'
K <$> hexKeyFormat

wParser = do
prefix 'w'
h <- base64UrlHashParser
char' ':'
n <- nameMatcher
pure $ W h n

hexKeyFormat = PublicKeyText . T.pack <$> count 64 (satisfy isHexDigit)

base64UrlUnpaddedAlphabet :: BS.ByteString
base64UrlUnpaddedAlphabet =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"

base64UrlHashParser = T.pack <$> count 43 (satisfy (`BS.elem` base64UrlUnpaddedAlphabet))

char' = void . char
prefix ch = char ch >> char' ':'

asMatcher :: Parser a -> Parser Text
asMatcher = fmap fst . match

nameMatcher :: Parser Text
nameMatcher = asMatcher $ qualifiedNameMatcher
<|> bareNameMatcher

qualifiedNameMatcher :: Parser ()
qualifiedNameMatcher = do
void $ ident' style
void $ dot *> ident' style
void $ optional (dot *> ident' style)

bareNameMatcher :: Parser ()
bareNameMatcher = void $ ident' style

-- type-specialized version of `ident`
-- to avoid defaulting warnings on the `IsString` constraint
ident' :: IdentifierStyle Parser -> Parser Text
ident' = ident

style :: IdentifierStyle Parser
style = IdentifierStyle "atom"
(letter <|> symbols)
(letter <|> digit <|> symbols)
(HS.fromList ["true", "false"])
Symbol
ReservedIdentifier
where
symbols :: Parser Char
symbols = oneOf "%#+-_&$@<>=^?*!|/~"

0 comments on commit f7311ae

Please sign in to comment.