yi-0.4.3: Yi/Syntax/Linear.hs
-- Copyright (C) 2008 JP Bernardy
module Yi.Syntax.Linear
(tokAtOrBefore, getStrokes, incrScanner, Result)
where
import Yi.Prelude
import Prelude ()
import Data.List (takeWhile, dropWhile, reverse)
import Yi.Syntax
import Yi.Region
import Yi.Lexer.Alex
import Data.Maybe (listToMaybe)
data Result tok = Result [tok] [tok]
instance Functor Result where
fmap f (Result a b) = Result (fmap f a) (fmap f b)
-- | linear scanner
incrScanner :: forall st tok. Scanner st tok -> Scanner (st, [tok]) (Result tok)
incrScanner input = Scanner
{
scanInit = (scanInit input, []),
scanLooked = scanLooked input . fst,
scanRun = run,
scanEmpty = Result [] []
}
where
run (st,partial) = updateState partial $ scanRun input st
updateState _ [] = []
updateState curState toks@((st,tok):rest) = ((st, curState), result) : updateState nextState rest
where nextState = tok : curState
result = Result curState (fmap snd toks)
tokAtOrBefore :: Point -> Result (Tok a) -> Maybe (Tok a)
tokAtOrBefore p res = listToMaybe $ reverse $ toksInRegion (mkRegion 0 (p+1)) res
toksInRegion :: Region -> Result (Tok a) -> [Tok a]
toksInRegion reg (Result lefts rights) = reverse (usefulsL lefts) ++ usefulsR rights
where
usefulsR = dropWhile (\t -> tokEnd t <= regionStart reg) .
takeWhile (\t -> tokBegin t <= regionEnd reg)
usefulsL = dropWhile (\t -> tokBegin t >= regionEnd reg) .
takeWhile (\t -> tokEnd t >= regionStart reg)
getStrokes :: Point -> Point -> Point -> Result Stroke -> [Stroke]
getStrokes _point begin end (Result leftHL rightHL) = reverse (usefulsL leftHL) ++ usefulsR rightHL
where
usefulsR = dropWhile (\(_l,_s,r) -> r <= begin) .
takeWhile (\(l,_s,_r) -> l <= end)
usefulsL = dropWhile (\(l,_s,_r) -> l >= end) .
takeWhile (\(_l,_s,r) -> r >= begin)