1 {-# LANGUAGE DeriveFunctor #-}
2 {-# LANGUAGE FlexibleInstances #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 module Language.TCT.Cell where
6 import Data.Eq (Eq(..))
7 import Data.Function (($), (.))
8 import Data.Functor (Functor)
9 import Data.Monoid (Monoid(..))
10 import Data.Ord (Ord(..))
11 import Data.Semigroup (Semigroup(..))
12 import Data.Text (Text)
13 import Prelude (Int, Num(..), fromIntegral)
14 import Text.Show (Show(..), showParen, showString, showChar)
15 import qualified Data.Text as Text
16 import qualified Data.Text.Lazy as TL
19 -- | Relative position
22 { pos_line :: {-# UNPACK #-} !LineNum
23 , pos_column :: {-# UNPACK #-} !ColNum
25 instance Semigroup Pos where
26 Pos lx cx <> Pos ly cy =
28 instance Monoid Pos where
31 instance Show Pos where
32 showsPrec _p Pos{..} =
33 showsPrec 11 pos_line .
35 showsPrec 11 pos_column
46 { cell_begin :: {-# UNPACK #-} !Pos
47 , cell_end :: {-# UNPACK #-} !Pos
49 } deriving (Eq, Functor)
50 instance Show a => Show (Cell a) where
51 showsPrec p Cell{..} =
54 showChar ' ' . showsPrec 10 cell_begin .
55 showChar ' ' . showsPrec 10 cell_end .
56 showChar ' ' . showsPrec 11 unCell
57 instance (FromPad a, Semigroup a) => Semigroup (Cell a) where
58 Cell bx (Pos lx _cx) x <> Cell (Pos ly cy) ey y =
59 Cell bx ey $ x <> fromPad (Pos (ly - lx) cy) <> y
60 instance (FromPad a, Semigroup a, Monoid a) => Monoid (Cell a) where
64 cell0 = Cell mempty mempty
69 instance FromPad Text where
71 Text.replicate pos_line "\n" <>
72 Text.replicate pos_column " "
73 instance FromPad TL.Text where
75 TL.replicate (fromIntegral pos_line) "\n" <>
76 TL.replicate (fromIntegral pos_column) " "
79 instance (FromPad a, Semigroup a) => Semigroup (Cell a) where
80 Cell bx ex x <> Cell by ey y =
81 Cell bx ey $ x <> fromPad by <> y
82 instance Applicative Cell where
83 pure = Cell mempty mempty
84 Cell of_ sf f <*> Cell bx ex x =
85 Cell of_ (sf<>bx<>ex) (f x)
90 -- * Class 'Cellified'
91 class Cellified a where
93 reachOf a = offsetOf a <> sizeOf a
96 instance Cellified (Cell a) where
99 instance Cellified a => Cellified [a] where
100 reachOf = foldMap reachOf
104 if sizeOf s0 == mempty
105 then offsetOf s0 <> offsetOf ss
107 sizeOf = foldMap sizeOf
108 instance Cellified a => Cellified (Seq a) where
109 reachOf = foldMap reachOf
110 offsetOf s = case Seq.viewl s of
113 if sizeOf s0 == mempty
114 then offsetOf s0 <> offsetOf ss
116 sizeOf = foldMap sizeOf
117 instance (Cellified k, Cellified a) => Cellified (Tree k a) where
119 TreeN k _ts -> reachOf k
122 TreeN k _ts -> offsetOf k
123 Tree0 a -> offsetOf a
125 TreeN k _ts -> sizeOf k
131 class Cellify a where
132 cellify :: a -> Cell a
133 instance Cellify Text where
134 cellify t = Cell mempty s t
137 Text.foldl' (\acc -> \case
138 '\n' -> acc{pos_line = pos_line acc + 1}
139 _ -> acc{pos_column = pos_column acc + 1})
154 -- | Absolute position
157 { pos_line :: {-# UNPACK #-} !LineNum
158 , pos_column :: {-# UNPACK #-} !ColNum
160 instance Show Pos where
161 showsPrec _p Pos{..} = showsPrec 11 (pos_line,pos_column)
174 instance Applicative (Cell a) where
176 cf@(Cell bf ef f) <*> ca@(Cell ba ea a) =
177 | isCell0 cf || isCell0 ca = cell0 (f a)
179 isCell0 :: Cell a -> Bool
180 isCell0 (Cell bp ep _) = isPos0 bp && isPos0 ep
184 lineCell :: Cell a -> LineNum
185 lineCell = pos_line . cell_begin
186 columnCell :: Cell a -> ColNum
187 columnCell = pos_column . cell_begin
190 cell1 = Cell pos1 pos1
194 posSeq :: Seq (Cell a) -> Maybe (Pos,Pos)
196 case Seq.viewl toks of
198 Cell bp _ep _ :< _ ->
199 case Seq.viewr toks of
201 _ :> Cell _bp ep _ ->
203 posTrees :: Seq (Trees (Cell k) a) -> Maybe (Pos,Pos)
205 case Seq.viewl trees of
209 Nothing -> posTrees ts
212 case Seq.viewr trees of
214 _ :> TreeN _ toks | iiiii->
216 TreeN (Cell bp _ep _) _ :< _ ->
217 case Seq.viewr trees of
219 _ :> TreeN _ toks | iiiii->
224 posTree :: Tree (Cell k) (Cell a) -> Pos
225 posTree (TreeN c _) = cell_begin c
226 posTree (Tree0 c) = cell_begin c
228 posEndTree :: Tree (Cell k) (Cell a) -> Pos
229 posEndTree (TreeN c _) = cell_end c
230 posEndTree (Tree0 c) = cell_end c
236 instance Ord Pos where
237 Pos lx cx `compare` Pos ly cy =
241 isPos0 :: Pos -> Bool
242 isPos0 (Pos 0 0 ) = True
249 firstCellOf :: a -> Maybe (Cell ())
250 instance CellOf (Cell a) where
251 firstCellOf = Just . (() <$)
252 instance CellOf a => CellOf (Seq a) where
259 instance CellOf a => CellOf [a] where
265 instance (CellOf k, CellOf a) => CellOf (Tree k a) where
267 Tree0 a -> firstCellOf a
268 TreeN k a -> firstCellOf k <|> firstCellOf a