Skip to content

Commit

Permalink
Use NonEmpty in lexer context stack
Browse files Browse the repository at this point in the history
  • Loading branch information
glguy committed Feb 24, 2024
1 parent 754d083 commit 4bcf07d
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/Toml/Schema/ToValue.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ Because the top-level TOML document is always a table,
the 'ToTable' class is for types that specifically support
conversion to a 'Table'.
"Toml.ToValue.Generic" can be used to derive instances of 'ToTable'
automatically for record types.
"Toml.Schema.Generic" can be used to derive instances of 'ToTable'
automatically for record types and 'ToValue' for array types.
-}
module Toml.Schema.ToValue (
Expand Down
18 changes: 10 additions & 8 deletions src/Toml/Syntax/ParserUtils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ module Toml.Syntax.ParserUtils (

import Data.Text (Text)
import Data.Time
import Data.List.NonEmpty (NonEmpty((:|)))
import Data.List.NonEmpty qualified as NonEmpty
import Toml.Pretty (prettyToken)
import Toml.Syntax.Lexer (scanToken, Context(..))
import Toml.Syntax.Position (Located(..), Position)
Expand All @@ -45,14 +47,14 @@ import Toml.Syntax.Token (Token(..))
-- continuation passing implementation of a state monad with errors
newtype Parser r a = P {
getP ::
[Context] -> Located Text ->
([Context] -> Located Text -> a -> Either (Located String) r) ->
NonEmpty Context -> Located Text ->
(NonEmpty Context -> Located Text -> a -> Either (Located String) r) ->
Either (Located String) r
}

-- | Run the top-level parser
runParser :: Parser r r -> Context -> Located Text -> Either (Located String) r
runParser (P k) ctx str = k [ctx] str \_ _ r -> Right r
runParser (P k) ctx str = k (ctx :| []) str \_ _ r -> Right r

-- | Bind implementation used in the happy-generated parser
thenP :: Parser r a -> (a -> Parser r b) -> Parser r b
Expand All @@ -66,16 +68,16 @@ pureP x = P \ctx str k -> k ctx str x

-- | Add a new context to the lexer context stack
push :: Context -> Parser r ()
push x = P \st str k -> k (x : st) str ()
push x = P \st str k -> k (NonEmpty.cons x st) str ()
{-# Inline push #-}

-- | Pop the top context off the lexer context stack. It is a program
-- error to pop without first pushing.
pop :: Parser r ()
pop = P \ctx str k ->
case ctx of
[] -> error "Toml.Parser.Utils.pop: PANIC! malformed production in parser"
_ : ctx' -> k ctx' str ()
case snd (NonEmpty.uncons ctx) of
Nothing -> error "toml-parser: PANIC! malformed production in parser"
Just ctx' -> k ctx' str ()
{-# Inline pop #-}

-- | Operation the parser generator uses when it reaches an unexpected token.
Expand All @@ -85,7 +87,7 @@ errorP e = P \_ _ _ -> Left (fmap (\t -> "parse error: unexpected " ++ prettyTok
-- | Operation the parser generator uses to request the next token.
lexerP :: (Located Token -> Parser r a) -> Parser r a
lexerP f = P \st str k ->
case scanToken (head st) str of
case scanToken (NonEmpty.head st) str of
Left le -> Left (("lexical error: " ++) <$> le)
Right (t, str') -> getP (f t) st str' k
{-# Inline lexerP #-}
Expand Down
2 changes: 1 addition & 1 deletion test/HieDemoSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Copyright : (c) Eric Mertens, 2023
License : ISC
Maintainer : [email protected]
This module demonstrates how "Toml.FromValue" can handle a real-world
This module demonstrates how "Toml.Schema" can handle a real-world
format as used in hie-bios. These types are copied from
<https://github.com/haskell/hie-bios/blob/master/src/HIE/Bios/Config/YAML.hs>
with slight alterations because the Other case is for YAML-specific extensibility.
Expand Down

0 comments on commit 4bcf07d

Please sign in to comment.