module RhsCheck(checkRhs,checkBlock,checkTy) where import Language.Haskell.Exts (parseExpWithMode, parseModuleWithMode, parseTypeWithMode, srcLine, srcColumn, srcFilename, baseFixities, glasgowExts, ParseMode (..), defaultParseMode, ParseResult (..), Extension (..)) import ErrorMessages import Expression import HsToken import UU.Scanner.Position checkRhs,checkBlock,checkTy :: Expression -> Errors checkRhs = check parseExpWithMode checkBlock = check parseModuleWithMode checkTy = check parseTypeWithMode check :: (ParseMode -> String -> ParseResult a) -> Expression -> Errors check p (Expression pos tks) = case res of ParseOk _ -> [] ParseFailed loc msg -> let pos' = Pos (srcLine loc + line pos - 1) (srcColumn loc) (srcFilename loc) in [HsParseError pos' msg] where pos0 = Pos (line pos) 1 (file pos) str = toString pos0 tks res = p mode str bf = case baseFixities of [] -> Nothing xs -> Just xs mode = defaultParseMode { parseFilename = file pos, ignoreLanguagePragmas = False, extensions = exts , ignoreLinePragmas = False, fixities = bf } exts :: [Extension] exts = glasgowExts toString :: Pos -> HsTokens -> String toString _ [] = "" toString cPos (tk:tks) = move ++ current ++ next where tkPos = getPos tk move = addSpacing (line tkPos - line cPos) (column cPos) (column tkPos) current = fmt tk nPos = upd tkPos current next = toString nPos tks getPos :: HsToken -> Pos getPos (AGLocal _ pos _) = pos getPos (AGField _ _ pos _) = pos getPos (HsToken _ pos) = pos getPos (CharToken _ pos) = pos getPos (StrToken _ pos) = pos getPos (Err _ pos) = pos fmt :: HsToken -> String fmt (AGLocal var _ _) = "_" ++ show var fmt (AGField field attr _ _) = "_" ++ show field ++ "_" ++ show attr fmt (HsToken val _) = val fmt (CharToken val _) = show val fmt (StrToken val _) = show val fmt (Err val _) = val upd :: Pos -> String -> Pos upd p s = foldl adv p s addSpacing :: Int -> Int -> Int -> String addSpacing l c1 c2 = replicate l '\n' ++ replicate c ' ' where c | l == 0 = c2 - c1 | otherwise = c2 - 1