module SMR.Source.Expected where import SMR.Source.Parsec import SMR.Source.Token import SMR.Data.Located import SMR.Data.Bag (Bag) import Data.Text (Text) import qualified SMR.Data.Bag as Bag import qualified Data.Text as Text ------------------------------------------------------------------------------- -- | What we were expecting at the point there was a parse error. data Expected t s p -- | Expecting end of input. = ExBaseEnd -- | Expecting a name in the given namespace. | ExBaseNameOf Space -- | Expecting a name in any namespace. | ExBaseNameAny -- | Expecting a natural number. | ExBaseNat -- | Expecting a text string. | ExBaseText -- | Expecting a punctuation character. | ExBasePunc Char -- | Expecting something described by the given message. | ExBaseMsg String -- | Expecting something while parsing a declaration. | ExContextDecl Text (Bag (Blocker t (Expected t s p))) -- | Expecting something while parsing a binding. | ExContextBind Text (Bag (Blocker t (Expected t s p))) deriving Show -- | Pretty print an expected thing. pprExpected :: (Show s, Show p) => Expected (Located Token) s p -> String pprExpected bb = case bb of ExBaseEnd -> "expecting end of input" ExBaseNameOf s -> "expecting name " ++ show s ExBaseNat -> "expecting natural number" ExBaseText -> "expecting text string" ExBasePunc c -> "expecting " ++ show c ExBaseMsg t -> "expecting " ++ show t ExBaseNameAny -> "expecting name" ExContextDecl n es -> "in declaration @" ++ Text.unpack n ++ "\n" ++ (unlines $ map pprBlocker $ Bag.toList es) ExContextBind n esBag | e : _ <- Bag.toList esBag -> "in binding " ++ Text.unpack n ++ "\n" ++ pprBlocker e | otherwise -> "in binding " ++ Text.unpack n -- | Pretty print a blocker. pprBlocker :: (Show s, Show p) => Blocker (Located Token) (Expected (Located Token) s p) -> String pprBlocker (Blocker [] e) = pprExpected e pprBlocker (Blocker (t : _) e) = pprLocation (startOfLocated t) ++ " " ++ pprExpected e pprLocation :: Location -> String pprLocation (L l c) = show l ++ ":" ++ show c ------------------------------------------------------------------------------- -- | Parser error. data ParseError t e = ParseError [Blocker t e] deriving Show -- | Pretty print a parser error. pprParseError :: (Show s, Show p) => ParseError (Located Token) (Expected (Located Token) s p) -> String pprParseError (ParseError []) = "at end of input" pprParseError (ParseError (b : _bs)) = pprBlocker b