1 {-# LANGUAGE DeriveFunctor #-}
2 {-# LANGUAGE FlexibleInstances #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 module Language.TCT.Cell where
6 import Data.Eq (Eq(..))
7 import Data.Foldable (toList)
8 import Data.Function (($), (.))
9 import Data.Functor (Functor)
10 import Data.List.NonEmpty (NonEmpty(..))
11 import Data.Ord (Ord(..))
12 import Data.Semigroup (Semigroup(..))
13 import Data.Text (Text)
14 import Prelude (Int, Num(..), fromIntegral)
15 import System.FilePath (FilePath)
16 import Text.Show (Show(..), showChar, showString, showParen)
17 import qualified Data.Text as Text
18 import qualified Data.Text.Lazy as TL
20 import Language.TCT.Debug
23 -- | Relative position
26 { pos_line :: {-# UNPACK #-} !LineNum
27 , pos_column :: {-# UNPACK #-} !ColNum
30 instance Semigroup Pos where
31 Pos lx cx <> Pos ly cy =
33 instance Monoid Pos where
37 instance Show Pos where
38 showsPrec _p Pos{..} =
39 showsPrec 11 pos_line .
41 showsPrec 11 pos_column
56 { span_file :: !FilePath
60 instance Show Span where
61 showsPrec _p Span{..} =
62 showString span_file .
63 showChar '#' . showsPrec 10 span_begin .
64 showChar '-' . showsPrec 10 span_end
67 type Spans = NonEmpty Span
72 { cell_spans :: !Spans
74 } deriving (Eq, Ord, Functor)
75 instance Show a => Show (Cell a) where
76 showsPrec p Cell{..} =
79 showChar ' ' . showsPrec 11 unCell .
80 showChar ' ' . showsPrec 10 (toList cell_spans)
81 instance (Pretty a, Show a) => Pretty (Cell a)
82 instance (FromPad a, Semigroup a) => Semigroup (Cell a) where
83 Cell (Span fx bx ex :| sx) x <> Cell (Span _fy by ey :| _sy) y =
84 Cell (Span fx bx ey :| sx) $
85 x<>fromPad (Pos lines columns)<>y
87 lines = pos_line by - pos_line ex
88 columns = pos_column by - pos_column (if lines <= 0 then ex else bx)
90 instance (FromPad a, Semigroup a, Monoid a) => Monoid (Cell a) where
96 cell0 = Cell (span0 :| [])
97 where span0 = Span "" pos1 pos1
100 class FromPad a where
102 instance FromPad Text where
104 Text.replicate pos_line "\n" <>
105 Text.replicate pos_column " "
106 instance FromPad TL.Text where
108 TL.replicate (fromIntegral pos_line) "\n" <>
109 TL.replicate (fromIntegral pos_column) " "