rc #13

Merged
crumbtoo merged 196 commits from dev into main 2024-02-13 13:22:23 -07:00
4 changed files with 119 additions and 35 deletions
Showing only changes of commit cae0939f0c - Show all commits

View File

@@ -18,6 +18,7 @@ import Data.Functor.Foldable
import Data.Text (Text) import Data.Text (Text)
import Data.Text qualified as T import Data.Text qualified as T
import Data.HashMap.Strict qualified as H import Data.HashMap.Strict qualified as H
import Data.Maybe (maybeToList)
import Data.List (foldl1') import Data.List (foldl1')
import Data.Char import Data.Char
import Data.Functor import Data.Functor
@@ -26,6 +27,7 @@ import Data.Fix hiding (cata)
import Lens.Micro import Lens.Micro
import Lens.Micro.Platform import Lens.Micro.Platform
import Rlp.Parse.Types import Rlp.Parse.Types
import Rlp.Parse.Utils
import Rlp.Syntax import Rlp.Syntax
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
@@ -39,6 +41,9 @@ parseTest' p s = case runState (runParserT p "test" s) init of
lexeme :: Parser a -> Parser a lexeme :: Parser a -> Parser a
lexeme = L.lexeme sc lexeme = L.lexeme sc
flexeme :: Parser a -> Parser a
flexeme p = L.lineFold scn $ \sc' -> L.lexeme sc' p
symbol :: Text -> Parser Text symbol :: Text -> Parser Text
symbol = L.symbol sc symbol = L.symbol sc
@@ -66,7 +71,16 @@ decl = choice
] ]
funD :: Parser PartialDecl' funD :: Parser PartialDecl'
funD = FunD <$> varid <*> many pat1 <*> (symbol "=" *> fmap Const partialExpr) funD = FunD <$> flexeme varid <*> params <*> (symbol "=" *> body) <*> whereClause
where
params = many pat1
body = fmap Const partialExpr
whereClause :: Parser Where'
whereClause = optionalList $
flexeme "where" *> pure
[ FunB "fixme" [] (VarE "fixme")
]
standalonePartialExpr :: Parser PartialExpr' standalonePartialExpr :: Parser PartialExpr'
standalonePartialExpr = standaloneOf partialExpr standalonePartialExpr = standaloneOf partialExpr
@@ -75,7 +89,7 @@ standaloneOf :: Parser a -> Parser a
standaloneOf = (<* eof) standaloneOf = (<* eof)
partialExpr :: Parser PartialExpr' partialExpr :: Parser PartialExpr'
partialExpr = (choice . fmap foldedLexeme) partialExpr = (choice . fmap flexeme)
[ try application [ try application
, Fix <$> infixExpr , Fix <$> infixExpr
] ]
@@ -87,17 +101,14 @@ partialExpr = (choice . fmap foldedLexeme)
mkB a f b = B f a b mkB a f b = B f a b
partialExpr1' = unFix <$> partialExpr1 partialExpr1' = unFix <$> partialExpr1
partialExpr' = unFix <$> partialExpr partialExpr' = unFix <$> partialExpr
infixOp' = foldedLexeme infixOp infixOp' = flexeme infixOp
mkApp :: PartialExpr' -> PartialExpr' -> PartialExpr' mkApp :: PartialExpr' -> PartialExpr' -> PartialExpr'
mkApp f x = Fix . E $ f `AppEF` x mkApp f x = Fix . E $ f `AppEF` x
foldedLexeme :: Parser a -> Parser a
foldedLexeme p = L.lineFold scn $ \sc' -> L.lexeme sc' p
partialExpr1 :: Parser PartialExpr' partialExpr1 :: Parser PartialExpr'
partialExpr1 = (choice . fmap foldedLexeme) partialExpr1 = (choice . fmap flexeme)
[ foldedLexeme "(" *> partialExpr' <* foldedLexeme ")" [ try $ flexeme "(" *> partialExpr' <* flexeme ")"
, Fix <$> varid' , Fix <$> varid'
, Fix <$> lit' , Fix <$> lit'
] ]
@@ -108,7 +119,7 @@ partialExpr1 = (choice . fmap foldedLexeme)
lit' = E . LitEF <$> lit lit' = E . LitEF <$> lit
infixOp :: Parser Name infixOp :: Parser Name
infixOp = symvar <|> symcon <?> "infix operator" infixOp = symvar <|> symcon <?> "operator"
symvar :: Parser Name symvar :: Parser Name
symvar = T.pack <$> symvar = T.pack <$>
@@ -119,18 +130,32 @@ symcon = T.pack <$>
liftA2 (:) (char ':') (many $ satisfy isSym) liftA2 (:) (char ':') (many $ satisfy isSym)
pat1 :: Parser Pat' pat1 :: Parser Pat'
pat1 = VarP <$> varid pat1 = VarP <$> flexeme varid
<?> "pattern" <?> "pattern"
conid :: Parser ConId
conid = NameCon <$> lexeme namecon
<|> SymCon <$> lexeme (char '(' *> symcon <* char ')')
<?> "constructor identifier"
namecon :: Parser Name
namecon = T.pack <$>
liftA2 (:) (satisfy isUpper)
(many $ satisfy isNameTail)
varid :: Parser VarId varid :: Parser VarId
varid = NameVar <$> lexeme namevar varid = NameVar <$> try (lexeme namevar)
<|> SymVar <$> lexeme (char '(' *> symvar <* char ')') <|> SymVar <$> lexeme (char '(' *> symvar <* char ')')
<?> "variable identifier" <?> "variable identifier"
where
namevar = T.pack <$> namevar :: Parser Name
namevar = try word
& withPredicate (`notElem` ["where"]) empty
where word = T.pack <$>
liftA2 (:) (satisfy isLower) (many $ satisfy isNameTail) liftA2 (:) (satisfy isLower) (many $ satisfy isNameTail)
isNameTail c = isAlphaNum c isNameTail :: Char -> Bool
isNameTail c = isAlphaNum c
|| c == '\'' || c == '\''
|| c == '_' || c == '_'
@@ -159,7 +184,7 @@ infixD = do
prec :: Parser Int prec :: Parser Int
prec = do prec = do
o <- getOffset o <- getOffset
n <- lexeme L.decimal n <- lexeme L.decimal <?> "precedence level (an integer)"
if 0 <= n && n <= 9 then if 0 <= n && n <= 9 then
pure n pure n
else else
@@ -173,10 +198,36 @@ infixD = do
psOpTable <~ H.alterF f op t psOpTable <~ H.alterF f op t
where where
f Nothing = pure (Just (a,p)) f Nothing = pure (Just (a,p))
f (Just _) = customFailure RlpParErrDuplicateInfixD f (Just x) = registerCustomFailure RlpParErrDuplicateInfixD
$> Just x
tySigD = undefined tySigD = undefined
dataD = undefined
dataD :: Parser (Decl' e)
dataD = DataD <$> (flexeme "data" *> conid) <*> many typaram
<*> optionalList (symbol "=" *> conalts)
where
typaram :: Parser Name
typaram = flexeme namevar
conalts :: Parser [ConAlt]
conalts = (:) <$> conalt <*> optionalList (symbol "|" *> conalts)
conalt :: Parser ConAlt
conalt = ConAlt <$> conid <*> many type1
type1 :: Parser Type
type1 = (choice . fmap flexeme)
[ flexeme "(" *> type_ <* flexeme ")"
, TyVar <$> namevar
, TyCon <$> namecon
]
type_ :: Parser Type
type_ = (choice . fmap flexeme)
[ try $ (:->) <$> type1 <*> (flexeme "->" *> type_)
, type1
]
lit :: Parser Lit' lit :: Parser Lit'
lit = int lit = int
@@ -184,9 +235,9 @@ lit = int
where where
int = IntL <$> L.decimal int = IntL <$> L.decimal
---------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- completing partial expressions
-- complete :: OpTable -> Fix Partial -> RlpExpr'
complete :: (?pt :: OpTable) => PartialExpr' -> RlpExpr' complete :: (?pt :: OpTable) => PartialExpr' -> RlpExpr'
complete = cata completePartial complete = cata completePartial

View File

@@ -22,9 +22,6 @@ module Rlp.Parse.Types
, RlpParseError(..) , RlpParseError(..)
, OpTable , OpTable
, OpInfo , OpInfo
-- * Extras
, registerCustomFailure
) )
where where
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
@@ -36,7 +33,6 @@ import Data.Functor.Const
import Data.Functor.Classes import Data.Functor.Classes
import Data.Void import Data.Void
import Data.Maybe import Data.Maybe
import Data.Set qualified as S
import Text.Megaparsec hiding (State) import Text.Megaparsec hiding (State)
import Text.Printf import Text.Printf
import Lens.Micro import Lens.Micro
@@ -121,6 +117,3 @@ type PartialExpr' = Fix Partial
makeLenses ''ParserState makeLenses ''ParserState
registerCustomFailure :: MonadParsec e s m => e -> m ()
registerCustomFailure = registerFancyFailure . S.singleton . ErrorCustom

30
src/RLP/Parse/Utils.hs Normal file
View File

@@ -0,0 +1,30 @@
module Rlp.Parse.Utils
( withPredicate
, registerCustomFailure
, optionalList
)
where
--------------------------------------------------------------------------------
import Text.Megaparsec
import Rlp.Parse.Types
import Data.Set qualified as S
import Data.Maybe
import Control.Monad
--------------------------------------------------------------------------------
-- TODO: generalise type sig
withPredicate :: (a -> Bool)
-> Parser a -- ^ action to run should the predicate fail
-> Parser a
-> Parser a
withPredicate f r p = do
o <- getOffset
a <- p
if f a then pure a else setOffset o *> r
registerCustomFailure :: MonadParsec e s m => e -> m ()
registerCustomFailure = registerFancyFailure . S.singleton . ErrorCustom
optionalList :: Parser [a] -> Parser [a]
optionalList = fmap (join . maybeToList) . optional

View File

@@ -2,7 +2,7 @@
{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-} {-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}
-- recursion-schemes -- recursion-schemes
{-# LANGUAGE TemplateHaskell, TypeFamilies #-} {-# LANGUAGE TemplateHaskell, TypeFamilies #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings, PatternSynonyms #-}
module Rlp.Syntax module Rlp.Syntax
( RlpExpr(..) ( RlpExpr(..)
, RlpExpr' , RlpExpr'
@@ -10,8 +10,15 @@ module Rlp.Syntax
, RlpExprF' , RlpExprF'
, Decl(..) , Decl(..)
, Decl' , Decl'
, Bind(..)
, Where
, Where'
, ConAlt(..)
, Type(..)
, pattern (:->)
, Assoc(..) , Assoc(..)
, VarId(..) , VarId(..)
, ConId(..)
, Pat(..) , Pat(..)
, Pat' , Pat'
, Lit(..) , Lit(..)
@@ -45,9 +52,9 @@ newtype RlpProgram b = RlpProgram [Decl RlpExpr b]
-- accounted for, we may complete the parsing task and get a proper @[Decl -- accounted for, we may complete the parsing task and get a proper @[Decl
-- RlpExpr Name]@. -- RlpExpr Name]@.
data Decl e b = FunD VarId [Pat b] (e b) data Decl e b = FunD VarId [Pat b] (e b) (Where b)
| TySigD [VarId] Type | TySigD [VarId] Type
| DataD ConId [ConId] [ConAlt] | DataD ConId [Name] [ConAlt]
| InfixD Assoc Int Name | InfixD Assoc Int Name
deriving Show deriving Show
@@ -58,14 +65,14 @@ data Assoc = InfixL
| Infix | Infix
deriving Show deriving Show
data ConAlt = ConAlt ConId [ConId] data ConAlt = ConAlt ConId [Type]
deriving Show deriving Show
data RlpExpr b = LetE [Bind b] (RlpExpr b) data RlpExpr b = LetE [Bind b] (RlpExpr b)
| VarE VarId | VarE VarId
| ConE ConId | ConE ConId
| LamE [Pat b] (RlpExpr b) | LamE [Pat b] (RlpExpr b)
| CaseE (RlpExpr b) [Alt b] | CaseE (RlpExpr b) [(Alt b, Where b)]
| IfE (RlpExpr b) (RlpExpr b) (RlpExpr b) | IfE (RlpExpr b) (RlpExpr b) (RlpExpr b)
| AppE (RlpExpr b) (RlpExpr b) | AppE (RlpExpr b) (RlpExpr b)
| LitE (Lit b) | LitE (Lit b)
@@ -73,6 +80,9 @@ data RlpExpr b = LetE [Bind b] (RlpExpr b)
type RlpExpr' = RlpExpr Name type RlpExpr' = RlpExpr Name
type Where b = [Bind b]
type Where' = [Bind Name]
-- do we want guards? -- do we want guards?
data Alt b = AltA (Pat b) (RlpExpr b) data Alt b = AltA (Pat b) (RlpExpr b)
deriving Show deriving Show