{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE DerivingVia, OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-missing-import-lists #-}
module Text.Gigaparsec.Errors.DefaultErrorBuilder (module Text.Gigaparsec.Errors.DefaultErrorBuilder) where
import Prelude hiding (lines)
import Data.Monoid (Endo(Endo))
import Data.String (IsString(fromString))
import Data.List (intersperse, sortBy)
import Data.Maybe (mapMaybe)
import Data.Foldable (toList)
import Data.Ord (comparing, Down (Down))
type StringBuilder :: *
newtype StringBuilder = StringBuilder (String -> String)
deriving (NonEmpty StringBuilder -> StringBuilder
StringBuilder -> StringBuilder -> StringBuilder
(StringBuilder -> StringBuilder -> StringBuilder)
-> (NonEmpty StringBuilder -> StringBuilder)
-> (forall b. Integral b => b -> StringBuilder -> StringBuilder)
-> Semigroup StringBuilder
forall b. Integral b => b -> StringBuilder -> StringBuilder
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: StringBuilder -> StringBuilder -> StringBuilder
<> :: StringBuilder -> StringBuilder -> StringBuilder
$csconcat :: NonEmpty StringBuilder -> StringBuilder
sconcat :: NonEmpty StringBuilder -> StringBuilder
$cstimes :: forall b. Integral b => b -> StringBuilder -> StringBuilder
stimes :: forall b. Integral b => b -> StringBuilder -> StringBuilder
Semigroup, Semigroup StringBuilder
StringBuilder
Semigroup StringBuilder =>
StringBuilder
-> (StringBuilder -> StringBuilder -> StringBuilder)
-> ([StringBuilder] -> StringBuilder)
-> Monoid StringBuilder
[StringBuilder] -> StringBuilder
StringBuilder -> StringBuilder -> StringBuilder
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: StringBuilder
mempty :: StringBuilder
$cmappend :: StringBuilder -> StringBuilder -> StringBuilder
mappend :: StringBuilder -> StringBuilder -> StringBuilder
$cmconcat :: [StringBuilder] -> StringBuilder
mconcat :: [StringBuilder] -> StringBuilder
Monoid) via Endo String
instance IsString StringBuilder where
{-# INLINE fromString #-}
fromString :: String -> StringBuilder
fromString :: [Char] -> StringBuilder
fromString [Char]
str = ([Char] -> [Char]) -> StringBuilder
StringBuilder ([Char]
str [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++)
{-# INLINE toString #-}
toString :: StringBuilder -> String
toString :: StringBuilder -> [Char]
toString (StringBuilder [Char] -> [Char]
build) = [Char] -> [Char]
build [Char]
forall a. Monoid a => a
mempty
{-# INLINE from #-}
from :: Show a => a -> StringBuilder
from :: forall a. Show a => a -> StringBuilder
from = ([Char] -> [Char]) -> StringBuilder
StringBuilder (([Char] -> [Char]) -> StringBuilder)
-> (a -> [Char] -> [Char]) -> a -> StringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [Char] -> [Char]
forall a. Show a => a -> [Char] -> [Char]
shows
{-# INLINABLE buildDefault #-}
buildDefault :: StringBuilder -> Maybe StringBuilder -> [StringBuilder] -> String
buildDefault :: StringBuilder -> Maybe StringBuilder -> [StringBuilder] -> [Char]
buildDefault StringBuilder
pos Maybe StringBuilder
source [StringBuilder]
lines = StringBuilder -> [Char]
toString (StringBuilder -> [StringBuilder] -> Int -> StringBuilder
blockError StringBuilder
header [StringBuilder]
lines Int
2)
where header :: StringBuilder
header = StringBuilder
-> (StringBuilder -> StringBuilder)
-> Maybe StringBuilder
-> StringBuilder
forall b a. b -> (a -> b) -> Maybe a -> b
maybe StringBuilder
forall a. Monoid a => a
mempty (\StringBuilder
src -> StringBuilder
"In " StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
src StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
" ") Maybe StringBuilder
source StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
pos
{-# INLINABLE vanillaErrorDefault #-}
vanillaErrorDefault :: Foldable t => Maybe StringBuilder -> Maybe StringBuilder -> t StringBuilder -> [StringBuilder] -> [StringBuilder]
vanillaErrorDefault :: forall (t :: * -> *).
Foldable t =>
Maybe StringBuilder
-> Maybe StringBuilder
-> t StringBuilder
-> [StringBuilder]
-> [StringBuilder]
vanillaErrorDefault Maybe StringBuilder
unexpected Maybe StringBuilder
expected t StringBuilder
reasons =
[StringBuilder] -> [StringBuilder] -> [StringBuilder]
combineInfoWithLines (([StringBuilder] -> [StringBuilder])
-> (StringBuilder -> [StringBuilder] -> [StringBuilder])
-> Maybe StringBuilder
-> [StringBuilder]
-> [StringBuilder]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [StringBuilder] -> [StringBuilder]
forall a. a -> a
id (:) Maybe StringBuilder
unexpected (([StringBuilder] -> [StringBuilder])
-> (StringBuilder -> [StringBuilder] -> [StringBuilder])
-> Maybe StringBuilder
-> [StringBuilder]
-> [StringBuilder]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [StringBuilder] -> [StringBuilder]
forall a. a -> a
id (:) Maybe StringBuilder
expected (t StringBuilder -> [StringBuilder]
forall a. t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList t StringBuilder
reasons)))
{-# INLINABLE specialisedErrorDefault #-}
specialisedErrorDefault :: [StringBuilder] -> [StringBuilder] -> [StringBuilder]
specialisedErrorDefault :: [StringBuilder] -> [StringBuilder] -> [StringBuilder]
specialisedErrorDefault = [StringBuilder] -> [StringBuilder] -> [StringBuilder]
combineInfoWithLines
{-# INLINABLE combineInfoWithLines #-}
combineInfoWithLines :: [StringBuilder] -> [StringBuilder] -> [StringBuilder]
combineInfoWithLines :: [StringBuilder] -> [StringBuilder] -> [StringBuilder]
combineInfoWithLines [] [StringBuilder]
lines = StringBuilder
"unknown parse error" StringBuilder -> [StringBuilder] -> [StringBuilder]
forall a. a -> [a] -> [a]
: [StringBuilder]
lines
combineInfoWithLines [StringBuilder]
info [StringBuilder]
lines = [StringBuilder]
info [StringBuilder] -> [StringBuilder] -> [StringBuilder]
forall a. [a] -> [a] -> [a]
++ [StringBuilder]
lines
{-# INLINABLE rawDefault #-}
rawDefault :: String -> String
rawDefault :: [Char] -> [Char]
rawDefault [Char]
n = [Char]
"\"" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
n [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"\""
{-# INLINABLE namedDefault #-}
namedDefault :: String -> String
namedDefault :: [Char] -> [Char]
namedDefault = [Char] -> [Char]
forall a. a -> a
id
{-# INLINABLE endOfInputDefault #-}
endOfInputDefault :: String
endOfInputDefault :: [Char]
endOfInputDefault = [Char]
"end of input"
{-# INLINABLE messageDefault #-}
messageDefault :: String -> String
messageDefault :: [Char] -> [Char]
messageDefault = [Char] -> [Char]
forall a. a -> a
id
{-# INLINABLE expectedDefault #-}
expectedDefault :: Maybe StringBuilder -> Maybe StringBuilder
expectedDefault :: Maybe StringBuilder -> Maybe StringBuilder
expectedDefault = (StringBuilder -> StringBuilder)
-> Maybe StringBuilder -> Maybe StringBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (StringBuilder
"expected " StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<>)
{-# INLINABLE unexpectedDefault #-}
unexpectedDefault :: Maybe String -> Maybe StringBuilder
unexpectedDefault :: Maybe [Char] -> Maybe StringBuilder
unexpectedDefault = ([Char] -> StringBuilder) -> Maybe [Char] -> Maybe StringBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((StringBuilder
"unexpected " StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<>) (StringBuilder -> StringBuilder)
-> ([Char] -> StringBuilder) -> [Char] -> StringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString)
{-# INLINABLE disjunct #-}
disjunct :: Bool -> [String] -> Maybe StringBuilder
disjunct :: Bool -> [[Char]] -> Maybe StringBuilder
disjunct Bool
oxford [[Char]]
elems = Bool -> [[Char]] -> [Char] -> Maybe StringBuilder
junct Bool
oxford [[Char]]
elems [Char]
"or"
{-# INLINABLE junct #-}
junct :: Bool -> [String] -> String -> Maybe StringBuilder
junct :: Bool -> [[Char]] -> [Char] -> Maybe StringBuilder
junct Bool
oxford [[Char]]
elems [Char]
junction = [[Char]] -> Maybe StringBuilder
junct' (([Char] -> [Char] -> Ordering) -> [[Char]] -> [[Char]]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (([Char] -> Down [Char]) -> [Char] -> [Char] -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing [Char] -> Down [Char]
forall a. a -> Down a
Down) [[Char]]
elems)
where
j :: StringBuilder
j :: StringBuilder
j = [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
junction
junct' :: [[Char]] -> Maybe StringBuilder
junct' [] = Maybe StringBuilder
forall a. Maybe a
Nothing
junct' [[Char]
alt] = StringBuilder -> Maybe StringBuilder
forall a. a -> Maybe a
Just ([Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
alt)
junct' [[Char]
alt1, [Char]
alt2] = StringBuilder -> Maybe StringBuilder
forall a. a -> Maybe a
Just ([Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
alt2 StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
" " StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
junction StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
" " StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
alt1)
junct' as :: [[Char]]
as@([Char]
alt:[[Char]]
alts)
| ([Char] -> Bool) -> [[Char]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem Char
',') [[Char]]
as = StringBuilder -> Maybe StringBuilder
forall a. a -> Maybe a
Just ([[Char]] -> [Char] -> [Char] -> StringBuilder
junct'' ([[Char]] -> [[Char]]
forall a. [a] -> [a]
reverse [[Char]]
alts) [Char]
alt [Char]
"; ")
| Bool
otherwise = StringBuilder -> Maybe StringBuilder
forall a. a -> Maybe a
Just ([[Char]] -> [Char] -> [Char] -> StringBuilder
junct'' ([[Char]] -> [[Char]]
forall a. [a] -> [a]
reverse [[Char]]
alts) [Char]
alt [Char]
", ")
junct'' :: [[Char]] -> [Char] -> [Char] -> StringBuilder
junct'' [[Char]]
is [Char]
l [Char]
delim = StringBuilder
front StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
back
where front :: StringBuilder
front = StringBuilder -> [StringBuilder] -> StringBuilder
forall m. Monoid m => m -> [m] -> m
intercalate ([Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
delim) (([Char] -> StringBuilder) -> [[Char]] -> [StringBuilder]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [[Char]]
is) :: StringBuilder
back :: StringBuilder
back
| Bool
oxford = [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
delim StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
j StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
" " StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
l
| Bool
otherwise = StringBuilder
" " StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
j StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
" " StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
l
{-# INLINABLE combineMessagesDefault #-}
combineMessagesDefault :: Foldable t => t String -> [StringBuilder]
combineMessagesDefault :: forall (t :: * -> *). Foldable t => t [Char] -> [StringBuilder]
combineMessagesDefault = ([Char] -> Maybe StringBuilder) -> [[Char]] -> [StringBuilder]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\[Char]
msg -> if [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
msg then Maybe StringBuilder
forall a. Maybe a
Nothing else StringBuilder -> Maybe StringBuilder
forall a. a -> Maybe a
Just ([Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
msg)) ([[Char]] -> [StringBuilder])
-> (t [Char] -> [[Char]]) -> t [Char] -> [StringBuilder]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t [Char] -> [[Char]]
forall a. t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
{-# INLINABLE blockError #-}
blockError :: StringBuilder -> [StringBuilder] -> Int -> StringBuilder
blockError :: StringBuilder -> [StringBuilder] -> Int -> StringBuilder
blockError StringBuilder
header [StringBuilder]
lines Int
indent = StringBuilder
header StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
":\n" StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> [StringBuilder] -> Int -> StringBuilder
indentAndUnlines [StringBuilder]
lines Int
indent
{-# INLINABLE indentAndUnlines #-}
indentAndUnlines :: [StringBuilder] -> Int -> StringBuilder
indentAndUnlines :: [StringBuilder] -> Int -> StringBuilder
indentAndUnlines [StringBuilder]
lines Int
indent = [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString [Char]
pre StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder -> [StringBuilder] -> StringBuilder
forall m. Monoid m => m -> [m] -> m
intercalate ([Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString (Char
'\n' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char]
pre)) [StringBuilder]
lines
where pre :: [Char]
pre = Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate Int
indent Char
' '
{-# INLINABLE lineInfoDefault #-}
lineInfoDefault :: String -> [String] -> [String] -> Word -> Word -> Word -> [StringBuilder]
lineInfoDefault :: [Char]
-> [[Char]] -> [[Char]] -> Word -> Word -> Word -> [StringBuilder]
lineInfoDefault [Char]
curLine [[Char]]
beforeLines [[Char]]
afterLines Word
_line Word
pointsAt Word
width =
[[StringBuilder]] -> [StringBuilder]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [([Char] -> StringBuilder) -> [[Char]] -> [StringBuilder]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> StringBuilder
inputLine [[Char]]
beforeLines, [[Char] -> StringBuilder
inputLine [Char]
curLine, StringBuilder
caretLine], ([Char] -> StringBuilder) -> [[Char]] -> [StringBuilder]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> StringBuilder
inputLine [[Char]]
afterLines]
where inputLine :: String -> StringBuilder
inputLine :: [Char] -> StringBuilder
inputLine = [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString ([Char] -> StringBuilder)
-> ([Char] -> [Char]) -> [Char] -> StringBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char
'>' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:)
caretLine :: StringBuilder
caretLine :: StringBuilder
caretLine = [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString (Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word
pointsAt Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
1)) Char
' ') StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> [Char] -> StringBuilder
forall a. IsString a => [Char] -> a
fromString (Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
width) Char
'^')
{-# INLINABLE posDefault #-}
posDefault :: Word -> Word -> StringBuilder
posDefault :: Word -> Word -> StringBuilder
posDefault Word
line Word
col = StringBuilder
"(line "
StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> Word -> StringBuilder
forall a. Show a => a -> StringBuilder
from Word
line
StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
", column "
StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> Word -> StringBuilder
forall a. Show a => a -> StringBuilder
from Word
col
StringBuilder -> StringBuilder -> StringBuilder
forall a. Semigroup a => a -> a -> a
<> StringBuilder
")"
{-# INLINABLE intercalate #-}
intercalate :: Monoid m => m -> [m] -> m
intercalate :: forall m. Monoid m => m -> [m] -> m
intercalate m
x [m]
xs = [m] -> m
forall a. Monoid a => [a] -> a
mconcat (m -> [m] -> [m]
forall a. a -> [a] -> [a]
intersperse m
x [m]
xs)