1{-# LANGUAGE DeriveGeneric #-}
2module TutorialD.Interpreter.Base where
4import Text.Megaparsec.Text
5import qualified Text.Megaparsec.Lexer as Lex
7import ProjectM36.AtomType
8import Data.Text hiding (count)
9import qualified Data.Text as T
10import qualified Data.List as L
11import qualified Data.Vector as V
12import qualified Data.Text.IO as TIO
14import ProjectM36.Relation.Show.Term
17import Control.Monad (void)
18import qualified Data.UUID as U
20displayOpResult :: TutorialDOperatorResult -> IO ()
21displayOpResult QuitResult = return ()
22displayOpResult (DisplayResult out) = TIO.putStrLn out
23displayOpResult (DisplayIOResult ioout) = ioout
24displayOpResult (DisplayErrorResult err) = let outputf = if T.length err > 0 && T.last err /= '\n' then TIO.hPutStrLn else TIO.hPutStr in
25 outputf stderr ("ERR: " <> err)
26displayOpResult QuietSuccessResult = return ()
27displayOpResult (DisplayRelationResult rel) = TIO.putStrLn (showRelation rel)
28displayOpResult (DisplayParseErrorResult promptLength err) = TIO.putStrLn pointyString >> TIO.putStrLn ("ERR:" <> T.pack (show err))
30 pointyString = T.justifyRight (promptLength + (sourceColumn (errorPos err))) ' ' "^"
32spaceConsumer :: Parser ()
33spaceConsumer = Lex.space (void spaceChar) (Lex.skipLineComment "--") (Lex.skipBlockComment "{-" "-}")
36opChar = oneOf (":!#$%&*+./<=>?\\^|-~" :: String)-- remove "@" so it can be used as attribute marker without spaces
38reserved :: String -> Parser ()
39reserved word = try (string word *> notFollowedBy opChar *> spaceConsumer)
41reservedOp :: String -> Parser ()
42reservedOp op = try (string op *> notFollowedBy opChar *> spaceConsumer)
44parens :: Parser a -> Parser a
45parens = between (symbol "(") (symbol ")")
47braces :: Parser a -> Parser a
48braces = between (symbol "{") (symbol "}")
50identifier :: Parser Text
52 istart <- letterChar <|> char '_'
53 irest <- many (alphaNumChar <|> char '_' <|> char '#')
55 pure (pack (istart:irest))
57symbol :: String -> Parser Text
58symbol sym = pack <$> Lex.symbol spaceConsumer sym
69tripleQuote :: Parser Text
70tripleQuote = symbol "\"\"\""
79whiteSpace :: Parser ()
80whiteSpace = Token.whiteSpace lexer
83integer :: Parser Integer
89capitalizedIdentifier :: Parser Text
90capitalizedIdentifier = do
92 rest <- option "" identifier
94 pure (T.cons fletter rest)
96uncapitalizedIdentifier :: Parser Text
97uncapitalizedIdentifier = do
99 rest <- option "" identifier
101 pure (T.cons fletter rest)
103showRelationAttributes :: Attributes -> Text
104showRelationAttributes attrs = "{" <> T.concat (L.intersperse ", " $ L.map showAttribute attrsL) <> "}"
106 showAttribute (Attribute name atomType) = name <> " " <> prettyAtomType atomType
107 attrsL = V.toList attrs
109data TutorialDOperatorResult = QuitResult |
110 DisplayResult StringType |
111 DisplayIOResult (IO ()) |
112 DisplayRelationResult Relation |
113 DisplayErrorResult StringType |
114 DisplayParseErrorResult Int ParseError | -- Int refers to length of prompt text
118type TransactionGraphWasUpdated = Bool
120--allow for python-style triple quoting because guessing the correct amount of escapes in different contexts is annoying
121tripleQuotedString :: Parser Text
122tripleQuotedString = do
124 pack <$> manyTill anyChar (try (tripleQuote >> notFollowedBy quote))
126normalQuotedString :: Parser Text
127normalQuotedString = quote *> (T.pack <$> manyTill Lex.charLiteral quote)
129quotedString :: Parser Text
130quotedString = try tripleQuotedString <|> normalQuotedString
132uuidP :: Parser U.UUID
134 uuidStart <- count 8 hexDigitChar
135 _ <- char '-' -- min 28 with no dashes, maximum 4 dashes
136 uuidMid1 <- count 4 hexDigitChar
138 uuidMid2 <- count 4 hexDigitChar
140 uuidMid3 <- count 4 hexDigitChar
142 uuidEnd <- count 12 hexDigitChar
143 let uuidStr = L.intercalate "-" [uuidStart, uuidMid1, uuidMid2, uuidMid3, uuidEnd]
144 case U.fromString uuidStr of
145 Nothing -> fail "Invalid uuid string"
146 Just uuid -> return uuid
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list