1module Language.Haskell.Lexer.Layout (layoutPre,PosToken) where 2 3import Language.Haskell.Lexer.Tokens 4import Language.Haskell.Lexer.Position 5 6type PosToken = (Token,(Pos,String)) 7 8-- | This is an implementation of Haskell layout, as specified in 9-- section 9.3 of the revised Haskell 98 report. 10-- This preprocessor inserts the extra \<n\> and {n} tokens. 11layoutPre :: [PosToken] -> [PosToken] 12layoutPre = indent . open 13 14open :: [PosToken] -> [PosToken] 15open = open1 16 17{-+ 18If the first lexeme of a module is not { or module, then it is preceded 19by {n} where n is the indentation of the lexeme. 20-} 21open1 :: [PosToken] -> [PosToken] 22open1 (t1@(Reservedid,(_,"module")):ts) = t1:open2 ts 23open1 (t1@(Special,(_,"{")):ts) = t1:open2 ts 24open1 ts@((_,(p,_)):_) = (Open (column p),(p,"")):open2 ts 25open1 [] = [] 26 27{-+ 28If a let, where, do, or of keyword is not followed by the lexeme {, 29the token {n} is inserted after the keyword, where n is the indentation of 30the next lexeme if there is one, or 0 if the end of file has been reached. 31-} 32open2 :: [PosToken] -> [PosToken] 33open2 (t1:ts1) | isLtoken t1 = 34 case ts1 of 35 t2@(_,(p,_)):ts2 -> 36 if notLBrace t2 37 then t1:(Open (column p),(p,"")):open2 ts1 38 else t1:t2:open2 ts2 39 [] -> t1:(Open 0,(fst (snd t1),"")):[] 40 where 41 isLtoken (Reservedid,(_,s)) = s `elem` ["let","where","do","of"] 42 isLtoken _ = False 43 44 notLBrace (Special,(_,"{")) = False 45 notLBrace _ = True 46open2 (t:ts) = t:open2 ts 47open2 [] = [] 48 49{-+ 50(This is from the original Haskell 98 report.) 51The first token on each line (not including tokens already annotated) is 52preceeded by <n>, where n is the indentation of the token. 53-} 54indent :: [PosToken] -> [PosToken] 55indent (t1@(Open _,(p,_)):ts) = t1:indent2 (line p) ts 56indent (t1@(_,(p,_)):ts) = (Indent (column p),(p,"")):t1:indent2 (line p) ts 57indent [] = [] 58 59indent2 :: Int -> [PosToken] -> [PosToken] 60indent2 r (t1@(_,(p,_)):ts) | line p==r = t1:indent2 r ts 61indent2 _ ts = indent ts 62