2017-05-31 22:22:55 +03:00
|
|
|
{-# LANGUAGE GADTs, RankNTypes, ScopedTypeVariables #-}
|
2017-04-20 21:00:02 +03:00
|
|
|
module Renderer.SExpression
|
2017-05-29 23:51:32 +03:00
|
|
|
( renderSExpressionDiff
|
|
|
|
, renderSExpressionTerm
|
2017-04-20 21:00:02 +03:00
|
|
|
) where
|
2016-12-09 19:31:13 +03:00
|
|
|
|
|
|
|
import Data.Bifunctor.Join
|
2017-09-09 20:14:05 +03:00
|
|
|
import Data.ByteString.Char8 hiding (intersperse, foldr, spanEnd)
|
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
|
2016-12-09 19:31:13 +03:00
|
|
|
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
|
2016-12-09 19:31:13 +03:00
|
|
|
|
2017-04-21 01:13:28 +03:00
|
|
|
-- | 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
|
2017-05-29 23:51:32 +03:00
|
|
|
renderSExpressionDiff diff = printDiff diff 0 <> "\n"
|
2017-02-22 01:01:39 +03:00
|
|
|
|
2017-04-21 01:13:28 +03:00
|
|
|
-- | 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
|
2017-05-29 23:51:32 +03:00
|
|
|
renderSExpressionTerm term = printTerm term 0 <> "\n"
|
2017-04-20 21:00:02 +03:00
|
|
|
|
2017-09-09 18:55:32 +03:00
|
|
|
printDiff :: (ConstrainAll Show fields, Foldable f, Functor f) => Diff f (Record fields) -> Int -> ByteString
|
|
|
|
printDiff = cata $ \ diff level -> case diff of
|
2017-09-09 13:23:57 +03:00
|
|
|
Patch patch -> case patch of
|
2017-09-09 23:36:18 +03:00
|
|
|
Insert term -> pad (level - 1) <> "{+" <> printTermF term level <> "+}"
|
|
|
|
Delete term -> pad (level - 1) <> "{-" <> printTermF term level <> "-}"
|
|
|
|
Replace a b -> pad (level - 1) <> "{ " <> printTermF a level <> pad (level - 1) <> "->" <> printTermF b level <> " }"
|
2017-09-10 00:27:46 +03:00
|
|
|
Copy vs (Join (_, annotation)) syntax -> pad level <> "(" <> showBindings (fmap ($ 0) <$> vs) <> showAnnotation annotation <> foldr (\d acc -> d (level + 1) <> acc) "" syntax <> ")"
|
|
|
|
Var v -> pad level <> showMetaVar v
|
2017-03-08 22:05:49 +03:00
|
|
|
|
2017-09-09 18:58:41 +03:00
|
|
|
printTerm :: (ConstrainAll Show fields, Foldable f, Functor f) => Term f (Record fields) -> Int -> ByteString
|
2017-09-09 23:36:18 +03:00
|
|
|
printTerm term level = cata printTermF term level
|
|
|
|
|
|
|
|
printTermF :: (ConstrainAll Show fields, Foldable f, Functor f) => TermF f (Record fields) (Int -> ByteString) -> Int -> ByteString
|
|
|
|
printTermF (annotation :< syntax) level =
|
|
|
|
pad level <> "(" <> showAnnotation annotation <> foldr (\t -> (t (level + 1) <>)) "" syntax <> ")"
|
|
|
|
|
|
|
|
pad :: Int -> ByteString
|
2017-09-09 23:48:40 +03:00
|
|
|
pad n | n <= 0 = ""
|
2017-09-09 23:36:18 +03:00
|
|
|
| otherwise = "\n" <> replicate (2 * n) ' '
|
|
|
|
|
2016-12-09 22:30:37 +03:00
|
|
|
|
2017-05-31 22:22:55 +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
|
|
|
|
|
|
|
showBindings :: [(MetaVar, ByteString)] -> ByteString
|
|
|
|
showBindings [] = ""
|
|
|
|
showBindings bindings = "[ " <> foldr (<>) "" (intersperse "\n, " (showBinding <$> bindings)) <> " ]"
|
|
|
|
where showBinding (var, val) = showMetaVar var <> "/" <> val
|
|
|
|
|
|
|
|
showMetaVar :: MetaVar -> ByteString
|
|
|
|
showMetaVar (MetaVar s) = pack ('$' : s)
|