{-# LANGUAGE Safe #-}
module Config
(
parse
, Position(..)
, pretty
, Section(..)
, Value(..)
, Atom(..)
, valueAnn
, Number
, numberToInteger
, numberToRational
, integerToNumber
, rationalToNumber
, ParseError(..)
) where
import Config.Number (Number, numberToInteger, numberToRational, integerToNumber, rationalToNumber)
import Config.Value (Atom(..), Value(..), Section(..), valueAnn)
import Config.Parser (parseValue)
import Config.Pretty (pretty)
import Config.Lexer (scanTokens)
import Config.Tokens (Error(..), Position(..), Located(..), layoutPass, Token)
import qualified Config.Tokens as T
import Control.Exception (Exception(..))
import Numeric (showIntAtBase)
import Data.Char (intToDigit)
import Data.Text (Text)
import qualified Data.Text as Text
parse ::
Text ->
Either ParseError (Value Position)
parse :: Text -> Either ParseError (Value Position)
parse txt :: Text
txt =
case [Located Token] -> Either (Located Token) (Value Position)
parseValue ([Located Token] -> [Located Token]
layoutPass (Text -> [Located Token]
scanTokens Text
txt)) of
Right x :: Value Position
x -> Value Position -> Either ParseError (Value Position)
forall a b. b -> Either a b
Right Value Position
x
Left (Located posn :: Position
posn token :: Token
token) -> ParseError -> Either ParseError (Value Position)
forall a b. a -> Either a b
Left (Position -> String -> ParseError
ParseError Position
posn (Token -> String
explainToken Token
token))
data ParseError = ParseError Position String
deriving (ReadPrec [ParseError]
ReadPrec ParseError
Int -> ReadS ParseError
ReadS [ParseError]
(Int -> ReadS ParseError)
-> ReadS [ParseError]
-> ReadPrec ParseError
-> ReadPrec [ParseError]
-> Read ParseError
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ParseError]
$creadListPrec :: ReadPrec [ParseError]
readPrec :: ReadPrec ParseError
$creadPrec :: ReadPrec ParseError
readList :: ReadS [ParseError]
$creadList :: ReadS [ParseError]
readsPrec :: Int -> ReadS ParseError
$creadsPrec :: Int -> ReadS ParseError
Read, Int -> ParseError -> ShowS
[ParseError] -> ShowS
ParseError -> String
(Int -> ParseError -> ShowS)
-> (ParseError -> String)
-> ([ParseError] -> ShowS)
-> Show ParseError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ParseError] -> ShowS
$cshowList :: [ParseError] -> ShowS
show :: ParseError -> String
$cshow :: ParseError -> String
showsPrec :: Int -> ParseError -> ShowS
$cshowsPrec :: Int -> ParseError -> ShowS
Show, ParseError -> ParseError -> Bool
(ParseError -> ParseError -> Bool)
-> (ParseError -> ParseError -> Bool) -> Eq ParseError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ParseError -> ParseError -> Bool
$c/= :: ParseError -> ParseError -> Bool
== :: ParseError -> ParseError -> Bool
$c== :: ParseError -> ParseError -> Bool
Eq, Eq ParseError
Eq ParseError =>
(ParseError -> ParseError -> Ordering)
-> (ParseError -> ParseError -> Bool)
-> (ParseError -> ParseError -> Bool)
-> (ParseError -> ParseError -> Bool)
-> (ParseError -> ParseError -> Bool)
-> (ParseError -> ParseError -> ParseError)
-> (ParseError -> ParseError -> ParseError)
-> Ord ParseError
ParseError -> ParseError -> Bool
ParseError -> ParseError -> Ordering
ParseError -> ParseError -> ParseError
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ParseError -> ParseError -> ParseError
$cmin :: ParseError -> ParseError -> ParseError
max :: ParseError -> ParseError -> ParseError
$cmax :: ParseError -> ParseError -> ParseError
>= :: ParseError -> ParseError -> Bool
$c>= :: ParseError -> ParseError -> Bool
> :: ParseError -> ParseError -> Bool
$c> :: ParseError -> ParseError -> Bool
<= :: ParseError -> ParseError -> Bool
$c<= :: ParseError -> ParseError -> Bool
< :: ParseError -> ParseError -> Bool
$c< :: ParseError -> ParseError -> Bool
compare :: ParseError -> ParseError -> Ordering
$ccompare :: ParseError -> ParseError -> Ordering
$cp1Ord :: Eq ParseError
Ord)
instance Exception ParseError where
displayException :: ParseError -> String
displayException (ParseError posn :: Position
posn msg :: String
msg) =
"line " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Position -> Int
posLine Position
posn) String -> ShowS
forall a. [a] -> [a] -> [a]
++
" column " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Position -> Int
posColumn Position
posn) String -> ShowS
forall a. [a] -> [a] -> [a]
++
": " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg
explainToken :: Token -> String
explainToken :: Token -> String
explainToken token :: Token
token =
case Token
token of
T.Error e :: Error
e -> Error -> String
explainError Error
e
T.Atom atom :: Text
atom -> "parse error: unexpected atom: `" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
Text.unpack Text
atom String -> ShowS
forall a. [a] -> [a] -> [a]
++ "`"
T.String str :: Text
str -> "parse error: unexpected string: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show (Text -> String
Text.unpack Text
str)
T.Bullet -> "parse error: unexpected bullet '*'"
T.Comma -> "parse error: unexpected comma ','"
T.Section s :: Text
s -> "parse error: unexpected section: `" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
Text.unpack Text
s String -> ShowS
forall a. [a] -> [a] -> [a]
++ "`"
T.Number{} -> "parse error: unexpected number"
T.OpenList -> "parse error: unexpected start of list '['"
T.CloseList -> "parse error: unexpected end of list ']'"
T.OpenMap -> "parse error: unexpected start of section '{'"
T.CloseMap -> "parse error: unexpected end of section '}'"
T.LayoutSep -> "parse error: unexpected end of block"
T.LayoutEnd -> "parse error: unexpected end of block"
T.EOF -> "parse error: unexpected end of file"
showIntAtBase' :: (Show a, Integral a) => String -> a -> (Int -> Char) -> a -> ShowS
showIntAtBase' :: String -> a -> (Int -> Char) -> a -> ShowS
showIntAtBase' pfx :: String
pfx base :: a
base toDigit :: Int -> Char
toDigit n :: a
n
| a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = Char -> ShowS
showChar '-' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
pfx ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (Int -> Char) -> a -> ShowS
forall a. (Integral a, Show a) => a -> (Int -> Char) -> a -> ShowS
showIntAtBase a
base Int -> Char
toDigit (a -> a
forall a. Num a => a -> a
negate a
n)
| Bool
otherwise = String -> ShowS
showString String
pfx ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (Int -> Char) -> a -> ShowS
forall a. (Integral a, Show a) => a -> (Int -> Char) -> a -> ShowS
showIntAtBase a
base Int -> Char
toDigit a
n
explainError :: Error -> String
explainError :: Error -> String
explainError e :: Error
e =
case Error
e of
T.UntermComment -> "lexical error: unterminated comment"
T.UntermString -> "lexical error: unterminated string literal"
T.UntermSections -> "lexical error: unterminated sections"
T.UntermList -> "lexical error: unterminated list"
T.BadEscape c :: Text
c -> "lexical error: bad escape sequence: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
Text.unpack Text
c
T.NoMatch c :: Char
c -> "lexical error at character " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Char -> String
forall a. Show a => a -> String
show Char
c