module Pinchot.Locator where
import Pinchot.Types
import qualified Data.ListLike as ListLike
import Data.Sequence (Seq, (|>))
import qualified Data.Sequence as Seq
import qualified Text.Earley as Earley
advanceChar :: Char -> Loc -> Loc
advanceChar c (Loc !lin !col !pos)
| c == '\n' = Loc (lin + 1) 1 (pos + 1)
| c == '\t' = Loc lin (col + 8 ((col 1) `mod` 8)) (pos + 1)
| otherwise = Loc lin (col + 1) (pos + 1)
locations
:: ListLike.FoldableLL full Char
=> full
-> Seq (Char, Loc)
locations = fst . ListLike.foldl' f (Seq.empty, Loc 1 1 1)
where
f (!sq, !loc) c = (sq |> (c, loc), advanceChar c loc)
noLocations
:: ListLike.FoldableLL full item
=> full
-> Seq (item, ())
noLocations = ListLike.foldl' f Seq.empty
where
f !sq c = sq |> (c, ())
locatedFullParses
:: ListLike.FoldableLL full Char
=> (forall r. Earley.Grammar r (Earley.Prod r String (Char, Loc) (p Char Loc)))
-> full
-> ([p Char Loc], Earley.Report String (Seq (Char, Loc)))
locatedFullParses g
= Earley.fullParses (Earley.parser g)
. locations