11{-# LANGUAGE LambdaCase #-}
22{-# LANGUAGE ScopedTypeVariables #-}
3+ {-# LANGUAGE TupleSections #-}
34{-# LANGUAGE TypeFamilies #-}
45
56module Telomare.Parser where
67
78import Control.Comonad.Cofree (Cofree (.. ), unwrap )
89import Control.Lens.Plated (Plated (.. ))
9- import Control.Monad (void , join )
10+ import Control.Monad (join , void )
1011import Control.Monad.State (State )
1112import Data.Bifunctor (Bifunctor (first , second ), bimap )
1213import Data.Functor (($>) )
@@ -29,7 +30,7 @@ import Text.Megaparsec.Char (alphaNumChar, char, letterChar, space1, string)
2930import qualified Text.Megaparsec.Char.Lexer as L
3031import Text.Megaparsec.Debug (dbg )
3132import Text.Megaparsec.Pos (Pos )
32- import Text.Read (readMaybe )
33+ import Text.Read (readMaybe , Lexeme ( String ) )
3334import Text.Show.Deriving (deriveShow1 )
3435
3536type AnnotatedUPT = Cofree UnprocessedParsedTermF LocTag
@@ -198,7 +199,7 @@ parseHash = do
198199parseBrand :: TelomareParser AnnotatedUPT
199200parseBrand = do
200201 x <- getLineColumn
201- brandElements :: [String ] <- brackets (commaSep (scn *> identifier <* scn))
202+ brandElements :: [String ] <- scn *> brackets (commaSep (scn *> identifier <* scn)) <* scn
202203 scn *> symbol " =" <?> " brand assignment ="
203204 expr <- scn *> parseLongExpr <* scn
204205 pure $ x :< BrandUPF brandElements expr
@@ -241,7 +242,13 @@ parsePatternString :: TelomareParser Pattern
241242parsePatternString = PatternString <$> (char ' "' >> manyTill L. charLiteral (char ' "' ))
242243
243244parsePatternVar :: TelomareParser Pattern
244- parsePatternVar = PatternVar <$> identifier
245+ parsePatternVar = do
246+ var <- identifier <* scn
247+ annotation <- optional . try $ parseRefinementCheck
248+ case annotation of
249+ Just annot -> pure $ PatternVarAnnotated (forget . annot $ DummyLoc :< VarUPF var) var
250+ _ -> pure $ PatternVar var
251+
245252
246253parsePatternIgnore :: TelomareParser Pattern
247254parsePatternIgnore = symbol " _" >> pure PatternIgnore
@@ -270,16 +277,44 @@ parseApplied = do
270277 pure $ foldl (\ a b -> x :< AppUPF a b) f args
271278 _ -> fail " expected expression"
272279
280+ -- parseLambdaArgs :: TelomareParser [Pattern]
281+ -- parseLambdaArgs = some parsePattern <* scn
282+
283+ makeLambda :: LocTag -> Pattern -> AnnotatedUPT -> AnnotatedUPT
284+ makeLambda lt p body =
285+ case p of
286+ PatternVar str -> lt :< LamUPF str body
287+ _ -> lt :< LamUPF varName
288+ (lt :< CaseUPF (lt :< VarUPF varName)
289+ [ (p, body)
290+ , (PatternIgnore , abort)
291+ ])
292+ where
293+ varName = genPatternVarName p
294+ abort = lt :< AppUPF
295+ (lt :< VarUPF " abort" )
296+ (lt :< StringUPF " makeLambda: pattern not reached" )
297+
298+ genPatternVarName :: Pattern -> String
299+ genPatternVarName = (" generatedVar" <> )
300+ . filter (\ x -> x /= ' \" '
301+ && x /= ' '
302+ && x /= ' ('
303+ && x /= ' )'
304+ && x /= ' ['
305+ && x /= ' ]' )
306+ . show
307+
273308-- | Parse lambda expression.
274309parseLambda :: TelomareParser AnnotatedUPT
275310parseLambda = do
276311 x <- getLineColumn
277312 symbol " \\ " <* scn
278- variables <- some identifier <* scn
313+ variables <- some parsePattern <* scn
314+ -- variables <- some identifier <* scn
279315 symbol " ->" <* scn
280- -- TODO make sure lambda names don't collide with bound names
281316 term1expr <- parseLongExpr <* scn
282- pure $ foldr (\ str upt -> x :< LamUPF str upt) term1expr variables
317+ pure $ foldr (\ p upt -> makeLambda x p upt) term1expr variables
283318
284319-- | Parser that fails if indent level is not `pos`.
285320parseSameLvl :: Pos -> TelomareParser a -> TelomareParser a
@@ -354,7 +389,7 @@ parseImportQualified = do
354389parseOneAssignmentOrBrand :: TelomareParser (String , AnnotatedUPT )
355390parseOneAssignmentOrBrand =
356391 parseAssignment
357- <|> ((\ exp -> ( " 8@$temp_label$@8" , exp ) ) <$> parseBrand)
392+ <|> ((" 8@$temp_label$@8" ,) <$> parseBrand)
358393
359394-- | Parse assignment or Brands, and add adding binding to ParserState.
360395parseAssignmentsAndBrands :: TelomareParser [(String , AnnotatedUPT )]
@@ -363,7 +398,7 @@ parseAssignmentsAndBrands = do
363398 let removeBrands = \ case
364399 (" 8@$temp_label$@8" , exp ) -> expandBrand exp
365400 x -> [x]
366- pure . join $ removeBrands <$> tempBindingList
401+ pure ( removeBrands =<< tempBindingList)
367402
368403-- | Parse top level expressions.
369404parseTopLevelWithExtraModuleBindings :: [(String , AnnotatedUPT )]
@@ -453,6 +488,40 @@ parseModule :: String -> Either String [Either AnnotatedUPT (String, AnnotatedUP
453488parseModule str = let result = runParser (scn *> many parseImportOrAssignment <* eof) " " str
454489 in first errorBundlePretty result
455490
491+ aux :: String
492+ aux = unlines
493+ [ " [Nat, toNat, nPlus, nMinus]"
494+ , " = let wrapper = \\ h ->"
495+ , " let N = \\ (hc, _) x -> assert (dEqual hc h) \" not Natural\" "
496+ , " in [ N"
497+ , " , \\ x -> (h, x)"
498+ , " , \\ ((_, aa) : N) ((_, bb) : N) -> (h, d2c aa succ bb)"
499+ , " , \\ ((_, aa) : N) ((_, bb) : N) ->"
500+ , " let sLeft = \\ x -> case x of"
501+ , " (l, _) -> l"
502+ , " y -> abort \" can't subtract larger number from smaller one\" "
503+ , " in (h, d2c bb sLeft aa)"
504+ , " ]"
505+ , " in wrapper (# wrapper)"
506+ ]
507+
508+ aux1 :: String
509+ aux1 = unlines
510+ [ " let wrapper = \\ h ->"
511+ , " let N = \\ (hc, _) x -> assert (dEqual hc h) \" not Natural\" "
512+ , " in [ N"
513+ , " , \\ x -> (h, x)"
514+ , " , \\ ((_, aa) : N) ((_, bb) : N) -> (h, d2c aa succ bb)"
515+ , " , \\ ((_, aa) : N) ((_, bb) : N) ->"
516+ , " let sLeft = \\ x -> case x of"
517+ , " (l, _) -> l"
518+ , " y -> abort \" can't subtract larger number from smaller one\" "
519+ , " in (h, d2c bb sLeft aa)"
520+ , " ]"
521+ , " in wrapper (# wrapper)"
522+ ]
523+
524+
456525-- | Parse either a single expression or top level definitions defaulting to the `main` definition.
457526-- This function was made for telomare-evaluare
458527parseOneExprOrTopLevelDefs :: [(String , AnnotatedUPT )] -> TelomareParser AnnotatedUPT
0 commit comments