somehow
This commit is contained in:
parent
b1f2c94eb8
commit
1e95e53d3b
|
@ -1,4 +1,10 @@
|
||||||
|
{-# Language ConstraintKinds #-}
|
||||||
module Data.Config.Suckless.Parse.Megaparsec
|
module Data.Config.Suckless.Parse.Megaparsec
|
||||||
|
( parseSyntax
|
||||||
|
, parseTop
|
||||||
|
, MegaParsec
|
||||||
|
, MegaContext
|
||||||
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Data.Config.Suckless.Syntax
|
import Data.Config.Suckless.Syntax
|
||||||
|
@ -8,13 +14,27 @@ import Control.Applicative()
|
||||||
import Data.Char (showLitChar)
|
import Data.Char (showLitChar)
|
||||||
import Data.Text qualified as Text
|
import Data.Text qualified as Text
|
||||||
|
|
||||||
|
import Control.Monad
|
||||||
import Text.Megaparsec
|
import Text.Megaparsec
|
||||||
import Text.Megaparsec.Char (space1,char,letterChar,digitChar)
|
import Text.Megaparsec.Char (hspace1,space1,char,letterChar,digitChar,eol)
|
||||||
import Text.Megaparsec.Char.Lexer qualified as L
|
import Text.Megaparsec.Char.Lexer qualified as L
|
||||||
import Text.Megaparsec.Char.Lexer ( signed )
|
import Text.Megaparsec.Char.Lexer ( signed )
|
||||||
import Data.String(IsString(..))
|
import Data.String(IsString(..))
|
||||||
|
import GHC.Generics
|
||||||
|
import Data.Data
|
||||||
|
|
||||||
import Debug.Trace
|
data MegaParsec =
|
||||||
|
MegaParsec
|
||||||
|
deriving (Data,Typeable,Generic)
|
||||||
|
|
||||||
|
newtype instance Context MegaParsec = MegaContext (Maybe Int)
|
||||||
|
|
||||||
|
instance IsContext MegaParsec where
|
||||||
|
noContext = MegaContext Nothing
|
||||||
|
|
||||||
|
type MegaContext = Context MegaParsec
|
||||||
|
|
||||||
|
type MegaConstraints c = ( c ~ MegaParsec, IsContext c )
|
||||||
|
|
||||||
type Parser r = Parsec () [Char] r
|
type Parser r = Parsec () [Char] r
|
||||||
|
|
||||||
|
@ -26,24 +46,34 @@ sc = do
|
||||||
where
|
where
|
||||||
lineComment = L.skipLineComment ";"
|
lineComment = L.skipLineComment ";"
|
||||||
|
|
||||||
|
scTop :: Parser ()
|
||||||
|
scTop = do
|
||||||
|
L.space hspace1 lineComment empty
|
||||||
|
where
|
||||||
|
lineComment = L.skipLineComment ";"
|
||||||
|
|
||||||
dquot :: Parser Char
|
dquot :: Parser Char
|
||||||
dquot = char '"'
|
dquot = char '"'
|
||||||
|
|
||||||
-- FIXME: position!
|
-- FIXME: position!
|
||||||
stringLit :: Monoid (Context c) => Parser (Syntax c)
|
stringLit :: forall c . MegaConstraints c
|
||||||
stringLit = L.lexeme sc $
|
=> Parser () -> Parser (Syntax c)
|
||||||
Literal mempty . LitStr <$> str
|
|
||||||
|
stringLit sp = L.lexeme sp $ do
|
||||||
|
co <- MegaContext . Just <$> getOffset
|
||||||
|
Literal co . LitStr <$> str
|
||||||
where
|
where
|
||||||
str = do
|
str = do
|
||||||
s <- dquot >> manyTill L.charLiteral dquot
|
s <- dquot >> manyTill L.charLiteral dquot
|
||||||
pure $ Text.pack (mconcat [ showLitChar c "" | c <- s ])
|
pure $ Text.pack (mconcat [ showLitChar c "" | c <- s ])
|
||||||
|
|
||||||
{-
|
|
||||||
|
|
||||||
-- FIXME: position!
|
-- FIXME: position!
|
||||||
intLit :: Parser Syntax
|
intLit :: forall c . MegaConstraints c
|
||||||
intLit = L.lexeme sc $
|
=> Parser () -> Parser (Syntax c)
|
||||||
Literal . LitInt <$> choice [hex, oct, bin, dec, dec']
|
|
||||||
|
intLit sp = L.lexeme sp $ do
|
||||||
|
co <- MegaContext . Just <$> getOffset
|
||||||
|
Literal co . LitInt <$> choice [hex, oct, bin, dec, dec']
|
||||||
where
|
where
|
||||||
hex = L.symbol sc "0x" >> L.hexadecimal
|
hex = L.symbol sc "0x" >> L.hexadecimal
|
||||||
oct = L.symbol sc "0o" >> L.octal
|
oct = L.symbol sc "0o" >> L.octal
|
||||||
|
@ -58,18 +88,20 @@ symbolChar :: Parser Char
|
||||||
symbolChar = oneOf symbolChars
|
symbolChar = oneOf symbolChars
|
||||||
|
|
||||||
-- FIXME: position!
|
-- FIXME: position!
|
||||||
symbol :: Parser Syntax
|
symbol :: forall c . MegaConstraints c
|
||||||
symbol = L.lexeme sc $ do
|
=> Parser () -> Parser (Syntax c)
|
||||||
co <- Context . Just <$> getOffset
|
symbol sp = L.lexeme sp $ do
|
||||||
|
co <- MegaContext . Just <$> getOffset
|
||||||
h <- letterChar <|> symbolChar
|
h <- letterChar <|> symbolChar
|
||||||
t <- many (letterChar <|> digitChar <|> symbolChar)
|
t <- many (letterChar <|> digitChar <|> symbolChar)
|
||||||
case Symbol (fromString (h:t)) of
|
case h:t of
|
||||||
SymbolVal "#t" -> pure $ Literal (mkLit True)
|
"#t" -> pure $ Literal co (mkLit True)
|
||||||
SymbolVal "#f" -> pure $ Literal (mkLit False)
|
"#f" -> pure $ Literal co (mkLit False)
|
||||||
SymbolVal other -> pure (Symbol_ co other)
|
other -> pure $ Symbol co (fromString other)
|
||||||
|
|
||||||
|
|
||||||
skipChar :: Char -> Parser ()
|
skipChar :: Char -> Parser ()
|
||||||
skipChar c = void $ char c
|
skipChar c = void (char c)
|
||||||
|
|
||||||
oParen :: Parser ()
|
oParen :: Parser ()
|
||||||
oParen = skipChar '('
|
oParen = skipChar '('
|
||||||
|
@ -97,51 +129,54 @@ someEnclosedBy :: Parser ()
|
||||||
someEnclosedBy o i c = do
|
someEnclosedBy o i c = do
|
||||||
between o c (many (sc >> i)) -- <|> parseError (error (show ("WTF!", ctx))) -- (ParseError (ListParseError ctx))
|
between o c (many (sc >> i)) -- <|> parseError (error (show ("WTF!", ctx))) -- (ParseError (ListParseError ctx))
|
||||||
|
|
||||||
list :: Parser Syntax
|
list :: forall c . MegaConstraints c
|
||||||
list = L.lexeme sc $ do
|
=> Parser() -> Parser (Syntax c)
|
||||||
co <- Context . Just <$> getOffset
|
|
||||||
-- traceShowM ("List", co)
|
|
||||||
List_ co <$> choice [ someEnclosedBy oParen syntax cParen
|
|
||||||
, someEnclosedBy oBrace syntax cBrace
|
|
||||||
, someEnclosedBy oBracket syntax cBracket
|
|
||||||
]
|
|
||||||
|
|
||||||
syntax :: Parser Syntax
|
list sp = L.lexeme sp $ do
|
||||||
syntax = choice [ symbol
|
co <- MegaContext . Just <$> getOffset
|
||||||
, stringLit
|
List co <$> choice [ someEnclosedBy oParen (syntax sp) cParen
|
||||||
, intLit
|
, someEnclosedBy oBrace (syntax sp) cBrace
|
||||||
, list
|
, someEnclosedBy oBracket (syntax sp) cBracket
|
||||||
]
|
]
|
||||||
|
|
||||||
-- top :: Parser (AST (Core S))
|
syntax :: forall c . MegaConstraints c
|
||||||
-- top = sc >> many syntaxWithPos >>= toAST
|
=> Parser () -> Parser (Syntax c)
|
||||||
-- where
|
syntax sp = choice [ symbol sp
|
||||||
-- -- FIXME: push real position here
|
, stringLit sp
|
||||||
-- syntaxWithPos = do
|
, intLit sp
|
||||||
-- pos <- getOffset
|
, list sp
|
||||||
-- node <- (pos,) <$> syntax
|
]
|
||||||
-- pure node
|
|
||||||
|
|
||||||
-- toAST xs = go xs
|
merely :: Parser a -> Parser a
|
||||||
|
merely f = do
|
||||||
|
sc
|
||||||
|
r <- f
|
||||||
|
sc
|
||||||
|
eof
|
||||||
|
pure r
|
||||||
|
|
||||||
-- go :: [(Int, Syntax)] -> Parser (AST (Core S))
|
parseSyntax :: forall c . MegaConstraints c
|
||||||
-- go ( (p, syn) : rest ) = do
|
=> String -> Either ParseFail (Syntax c)
|
||||||
-- let c = Context (Just p)
|
|
||||||
-- mkExpr c . Seq syn <$> go rest
|
|
||||||
|
|
||||||
-- go [] = pure $ mkLeaf0 ()
|
parseSyntax = parse (merely (syntax sc)) "input"
|
||||||
|
|
||||||
-- merely :: Parser a -> Parser a
|
top :: forall c . MegaConstraints c => Parser [Syntax c]
|
||||||
-- merely f = do
|
top = sc >> many (topStmt <|> syntax scTop)
|
||||||
-- sc
|
|
||||||
-- r <- f
|
|
||||||
-- sc
|
|
||||||
-- eof
|
|
||||||
-- pure r
|
|
||||||
|
|
||||||
-- parseSyntax :: String -> Either ParseFail Syntax
|
topStmt :: forall c . MegaConstraints c => Parser (Syntax c)
|
||||||
-- parseSyntax = parse (merely syntax) "input"
|
topStmt = do
|
||||||
|
scTop
|
||||||
|
|
||||||
|
co <- MegaContext . Just <$> getOffset
|
||||||
|
|
||||||
|
s0 <- symbol scTop
|
||||||
|
ss <- many (syntax scTop)
|
||||||
|
|
||||||
|
void eol <|> eof
|
||||||
|
pure $ List co (s0:ss)
|
||||||
|
|
||||||
|
parseTop :: forall c . MegaConstraints c
|
||||||
|
=> String -> Either ParseFail [Syntax c]
|
||||||
|
|
||||||
|
parseTop = parse top "input"
|
||||||
|
|
||||||
-- parseTop :: String -> Either ParseFail (AST (Core S))
|
|
||||||
-- parseTop = parse top "input"
|
|
||||||
-}
|
|
||||||
|
|
|
@ -1,33 +1,51 @@
|
||||||
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||||
{-# LANGUAGE UndecidableInstances #-}
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
|
{-# LANGUAGE AllowAmbiguousTypes #-}
|
||||||
{-# LANGUAGE PatternSynonyms #-}
|
{-# LANGUAGE PatternSynonyms #-}
|
||||||
module Data.Config.Suckless.Syntax
|
module Data.Config.Suckless.Syntax
|
||||||
( Syntax(..)
|
( Syntax(..)
|
||||||
, Context(..)
|
|
||||||
, Id(..)
|
, Id(..)
|
||||||
, Literal(..)
|
, Literal(..)
|
||||||
|
, Context
|
||||||
, HasContext(..)
|
, HasContext(..)
|
||||||
|
, IsContext(..)
|
||||||
|
, IsLiteral(..)
|
||||||
, pattern SymbolVal
|
, pattern SymbolVal
|
||||||
|
, pattern ListVal
|
||||||
|
, pattern LitVal
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
import GHC.Generics
|
|
||||||
import Data.Text (Text)
|
|
||||||
import Data.Data
|
import Data.Data
|
||||||
import Data.String
|
|
||||||
import Data.Kind
|
import Data.Kind
|
||||||
|
import Data.String
|
||||||
|
import Data.Text (Text)
|
||||||
|
import GHC.Generics
|
||||||
|
|
||||||
import Prettyprinter
|
import Prettyprinter
|
||||||
|
|
||||||
pattern SymbolVal :: Id -> Syntax c
|
pattern SymbolVal :: Id -> Syntax c
|
||||||
pattern SymbolVal v <- Symbol _ v
|
pattern SymbolVal v <- Symbol _ v
|
||||||
|
|
||||||
data family Context c :: Type
|
pattern LitVal :: forall {c}. Id -> Syntax c
|
||||||
|
pattern LitVal v <- Symbol _ v
|
||||||
|
|
||||||
|
pattern ListVal :: forall {c}. [Syntax c] -> Syntax c
|
||||||
|
pattern ListVal v <- List _ v
|
||||||
|
|
||||||
|
|
||||||
|
data family Context c :: Type
|
||||||
|
|
||||||
|
class IsContext c where
|
||||||
|
noContext :: Context c
|
||||||
|
|
||||||
class HasContext c a where
|
class HasContext c a where
|
||||||
setContext :: Context c -> a -> a
|
setContext :: Context c -> a -> a
|
||||||
getContext :: a -> Context c
|
getContext :: a -> Context c
|
||||||
|
|
||||||
|
class IsLiteral a where
|
||||||
|
mkLit :: a -> Literal
|
||||||
|
|
||||||
newtype Id =
|
newtype Id =
|
||||||
Id Text
|
Id Text
|
||||||
deriving newtype (IsString,Pretty)
|
deriving newtype (IsString,Pretty)
|
||||||
|
@ -39,6 +57,15 @@ data Literal =
|
||||||
| LitBool Bool
|
| LitBool Bool
|
||||||
deriving stock (Eq,Ord,Data,Generic,Show)
|
deriving stock (Eq,Ord,Data,Generic,Show)
|
||||||
|
|
||||||
|
instance IsLiteral Text where
|
||||||
|
mkLit = LitStr
|
||||||
|
|
||||||
|
instance IsLiteral Bool where
|
||||||
|
mkLit = LitBool
|
||||||
|
|
||||||
|
instance IsLiteral Integer where
|
||||||
|
mkLit = LitInt
|
||||||
|
|
||||||
data Syntax c
|
data Syntax c
|
||||||
= List (Context c) [Syntax c]
|
= List (Context c) [Syntax c]
|
||||||
| Symbol (Context c) Id
|
| Symbol (Context c) Id
|
||||||
|
@ -71,3 +98,9 @@ instance Pretty Literal where
|
||||||
| otherwise -> "#f"
|
| otherwise -> "#f"
|
||||||
|
|
||||||
|
|
||||||
|
deriving instance ( Data c
|
||||||
|
, Data (Context c)
|
||||||
|
, Typeable c
|
||||||
|
) => Data (Syntax c)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
module MyLib (someFunc) where
|
|
||||||
|
|
||||||
someFunc :: IO ()
|
|
||||||
someFunc = putStrLn "someFunc"
|
|
Loading…
Reference in New Issue