module HsLexMerge where import HsLexerPos(Pos(..),startPos,nextPos,nextPos1) import HsTokens --import OpTypes(eqBy) import List(groupBy) import Unlit(CommentClass(..)) {-+ #mergeLex#: Merge literate comments with a token stream Note: this may split tokens, so the result is not suitable for parsing!! -} --mergeLex :: ([String], [PosToken]) -> [PosToken] mergeLex ([],ts) = ts -- for efficiency when tokens are not from a literal file mergeLex (litcmnts,ts) = rejoin . addSpace startPos . merge (groupLit (addPos litcmnts)) . concatMap split . filter notSpace $ ts where addPos = zipWith pos [1..] where pos l s = (Pos 0 l 1,s) -- dummy character position notSpace (t,_) = t/=Whitespace split (t,(Pos n y x,s)) = [(t,(Pos n y' x',l))|((y',x'),l)<-zip ps (lines s),l/=""] where ps = zip [y..] (x:repeat 1) rejoin [] = [] rejoin (t@(tt,(p@Pos{char=n},s)):ts) = case rejoin ts of t'@(tt',(Pos{char=n'},s')):ts' | n>0 && tt==tt' && n'==n -> (tt,(p,s++s')):ts' ts' -> t:ts' groupLit = map join . groupBy bothLitCmnt where bothLitCmnt (_,(LitCmnt,_)) (_,(LitCmnt,_)) = True bothLitCmnt _ _ = False join ((p,(LitCmnt,s)):cs) = (p,(LitCmnt,unlines (s:map (snd.snd) cs))) join [l] = l litc (p,(cc,c)) = (conv cc,(p,c)) where conv LitCmnt = LiterateComment conv _ = Whitespace merge [] ts = ts merge cmnts [] = map litc cmnts merge cs0@(c@(pc,sc):cs) ts0@(t@(tt,(pt,s)):ts) = if pc<=pt then litc c:merge cs ts0 else --if pt'<=pc then t:merge cs0 ts --else error "literate comment inside token not handled yet" -- TODO: handle tokens containing literate comments {- where pc' = nextPos pc sc pt' = nextPos pt s overlap1 pc sc pt s = case compare pc pt of LT -> litc (pc,sc1):overlap pt sc2 s where (sc1,sc2) = split pc pt sc GT -> (t,(pt,s1)):overlap pc sc s2 where (s1,s2) = split pt pc s EQ -> overlap pc sc s split pc pt (c:cs) | pc