{-# LANGUAGE Safe #-}
module Config
( Section(..)
, Value(..)
, Atom(..)
, parse
, pretty
) where
import Config.Value (Atom(..), Value(..), Section(..))
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 Numeric (showIntAtBase)
import Data.Char (intToDigit)
import Data.Text (Text)
import qualified Data.Text as Text
parse ::
Text ->
Either String Value
parse txt =
case parseValue (layoutPass (scanTokens txt)) of
Right x -> Right x
Left (Located posn token) -> Left (explain posn token)
explain :: Position -> Token -> String
explain posn token
= show (posLine posn) ++ ":"
++ show (posColumn posn) ++ ": "
++ case token of
T.Error e -> explainError e
T.Atom atom -> "parse error: unexpected atom: " ++ Text.unpack atom
T.String str -> "parse error: unexpected string: " ++ show (Text.unpack str)
T.Bullet -> "parse error: unexpected bullet '*'"
T.Comma -> "parse error: unexpected comma ','"
T.Section s -> "parse error: unexpected section: " ++ Text.unpack s
T.Number 2 n -> "parse error: unexpected number: 0b" ++ showIntAtBase 2 intToDigit n ""
T.Number 8 n -> "parse error: unexpected number: 0o" ++ showIntAtBase 8 intToDigit n ""
T.Number 16 n -> "parse error: unexpected number: 0x" ++ showIntAtBase 16 intToDigit n ""
T.Number _ n -> "parse error: unexpected number: " ++ showIntAtBase 10 intToDigit n ""
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"
explainError :: Error -> String
explainError e =
case e of
T.UntermComment -> "lexical error: unterminated comment"
T.UntermCommentString -> "lexical error: unterminated string literal in comment"
T.UntermString -> "lexical error: unterminated string literal"
T.UntermFile -> "lexical error: unterminated line"
T.BadEscape c -> "lexical error: bad escape sequence: " ++ Text.unpack c
T.NoMatch c -> "lexical error at character " ++ show c