1
1
mirror of https://github.com/github/semantic.git synced 2024-12-24 23:42:31 +03:00
semantic/src/Renderer/SExpression.hs

66 lines
2.8 KiB
Haskell
Raw Normal View History

{-# LANGUAGE GADTs, RankNTypes, ScopedTypeVariables #-}
2017-04-20 21:00:02 +03:00
module Renderer.SExpression
( renderSExpressionDiff
, renderSExpressionTerm
2017-04-20 21:00:02 +03:00
) where
2017-09-10 21:14:44 +03:00
import Data.Bifunctor (bimap)
import Data.Bifunctor.Join
2017-09-10 21:14:44 +03:00
import Data.ByteString.Char8 hiding (intersperse, foldr, spanEnd, length)
2017-09-10 01:01:51 +03:00
import Data.Foldable (fold)
import Data.Functor.Binding (Metavar(..))
2017-09-09 18:55:32 +03:00
import Data.Functor.Foldable (cata)
2017-09-09 20:14:05 +03:00
import Data.List (intersperse)
2017-03-31 23:12:26 +03:00
import Data.Record
2017-07-28 21:37:02 +03:00
import Data.Semigroup
import Diff
import Patch
2017-07-28 21:37:02 +03:00
import Prelude hiding (replicate)
2017-09-08 18:40:23 +03:00
import Term
-- | Returns a ByteString SExpression formatted diff.
2017-09-09 18:55:32 +03:00
renderSExpressionDiff :: (ConstrainAll Show fields, Foldable f, Functor f) => Diff f (Record fields) -> ByteString
renderSExpressionDiff diff = cata printDiffF diff 0 <> "\n"
-- | Returns a ByteString SExpression formatted term.
2017-09-09 18:55:32 +03:00
renderSExpressionTerm :: (ConstrainAll Show fields, Foldable f, Functor f) => Term f (Record fields) -> ByteString
renderSExpressionTerm term = cata (\ term n -> nl n <> replicate (2 * n) ' ' <> printTermF term n) term 0 <> "\n"
2017-04-20 21:00:02 +03:00
printDiffF :: (ConstrainAll Show fields, Foldable f, Functor f) => DiffF f (Record fields) (Int -> ByteString) -> Int -> ByteString
printDiffF diff n = case diff of
2017-09-09 13:23:57 +03:00
Patch patch -> case patch of
Insert term -> nl n <> pad (n - 1) <> "{+" <> printTermF term n <> "+}"
Delete term -> nl n <> pad (n - 1) <> "{-" <> printTermF term n <> "-}"
Replace a b -> nl n <> pad (n - 1) <> "{ " <> printTermF a n
<> nl (n + 1) <> pad (n - 1) <> "->" <> printTermF b n <> " }"
2017-09-10 21:40:48 +03:00
Copy vs (Join (_, annotation) :< syntax) -> nl n <> pad n <> "(" <> showBindings (fmap (\ b -> b n) <$> vs) <> showAnnotation annotation <> foldMap (\ d -> d (n + 1)) syntax <> ")"
2017-09-10 20:28:21 +03:00
Var v -> nl n <> pad n <> showMetavar v
printTermF :: (ConstrainAll Show fields, Foldable f, Functor f) => TermF f (Record fields) (Int -> ByteString) -> Int -> ByteString
printTermF (annotation :< syntax) n = "(" <> showAnnotation annotation <> foldMap (\t -> t (n + 1)) syntax <> ")"
nl :: Int -> ByteString
nl n | n <= 0 = ""
| otherwise = "\n"
pad :: Int -> ByteString
pad n = replicate (2 * n) ' '
2017-09-09 23:36:18 +03:00
showAnnotation :: ConstrainAll Show fields => Record fields -> ByteString
showAnnotation Nil = ""
2017-07-28 21:37:02 +03:00
showAnnotation (only :. Nil) = pack (show only)
showAnnotation (first :. rest) = pack (show first) <> " " <> showAnnotation rest
2017-09-09 20:14:05 +03:00
2017-09-10 20:28:21 +03:00
showBindings :: [(Metavar, ByteString)] -> ByteString
2017-09-09 20:14:05 +03:00
showBindings [] = ""
2017-09-10 01:01:51 +03:00
showBindings bindings = "[ " <> fold (intersperse "\n, " (showBinding <$> bindings)) <> " ]"
2017-09-10 20:28:21 +03:00
where showBinding (var, val) = showMetavar var <> "/" <> val
2017-09-09 20:14:05 +03:00
2017-09-10 20:28:21 +03:00
showMetavar :: Metavar -> ByteString
2017-09-10 21:14:44 +03:00
showMetavar (Metavar i) = pack (toName i)
where toName i | i < 0 = ""
| otherwise = uncurry (++) (bimap (toName . pred) (pure . (alphabet !!)) (i `divMod` la))
alphabet = ['a'..'z']
la = length alphabet