Skip to content

Commit 8c05ad2

Browse files
committed
New lambdas don't break everything now
1 parent e98c3f2 commit 8c05ad2

4 files changed

Lines changed: 113 additions & 23 deletions

File tree

app/Evaluare.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{-# LANGUAGE RecursiveDo #-}
2+
13
module Main where
24

35
import Control.Comonad.Cofree (Cofree ((:<)))

examples.tel

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,40 @@ import Prelude
77
-- -- main = \input -> (aux, 0)
88
-- main = \input -> ("Hello", 0)
99

10-
-- -- refinement fail
10+
-- refinement fail
1111
-- main : (\x -> if x then "fail" else 0) = 1
12+
main : (\x -> assert 1 "fail") = 1
13+
-- main : (\x -> assert (not (left x)) "fail") = 1
14+
15+
-- main : (\x -> assert (not x) "fail") = 1
1216

1317
-- Ad hoc user defined types example:
1418

15-
MyInt = let wrapper = \h -> ( \i -> if not i
16-
then abort "MyInt cannot be 0"
17-
else i
18-
, \i -> if dEqual (left i) h
19-
then 0
20-
else abort "Not a MyInt"
21-
)
22-
in wrapper (# wrapper)
23-
24-
aux = \x -> if dEqual x 0 then "Success" else "Failure"
25-
main = \i -> (aux ((left MyInt) 0), 0)
19+
-- MyInt = let wrapper = \h -> ( \i -> if not i
20+
-- then abort "MyInt cannot be 0"
21+
-- else i
22+
-- , \i -> if dEqual (left i) h
23+
-- then 0
24+
-- else abort "Not a MyInt"
25+
-- )
26+
-- in wrapper (# wrapper)
27+
28+
-- aux = \x -> if dEqual x 8 then "Success" else "Failure"
29+
-- main = \i -> (aux ((left MyInt) 8), 0)
30+
31+
-- [Nat, toNat, nPlus, nMinus]
32+
-- = let wrapper = \h ->
33+
-- let N = \(hc, _) x -> assert (dEqual hc h) "not Natural"
34+
-- in [ N
35+
-- , \x -> (h, x)
36+
-- , \((_, aa) : N) ((_, bb) : N) -> (h, d2c aa succ bb)
37+
-- , \((_, aa) : N) ((_, bb) : N) ->
38+
-- let sLeft = \x -> case x of
39+
-- (l, _) -> l
40+
-- y -> abort "can't subtract larger number from smaller one"
41+
-- in (h, d2c bb sLeft aa)
42+
-- ]
43+
-- in wrapper (# wrapper)
2644

2745
-- something
2846
-- main =

src/Telomare.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,12 +1000,12 @@ convertAbortMessage = \case
10001000
-- |AST for patterns in `case` expressions
10011001
data Pattern
10021002
= PatternVar String
1003+
| PatternVarAnnotated UnprocessedParsedTerm String
10031004
| PatternInt Int
10041005
| PatternString String
10051006
| PatternIgnore
10061007
| PatternPair Pattern Pattern
10071008
deriving (Show, Eq, Ord)
1008-
makeBaseFunctor ''Pattern
10091009

10101010
-- |Firstly parsed AST sans location annotations
10111011
data UnprocessedParsedTerm
@@ -1034,6 +1034,8 @@ data UnprocessedParsedTerm
10341034
makeBaseFunctor ''UnprocessedParsedTerm -- Functorial version UnprocessedParsedTerm
10351035
makePrisms ''UnprocessedParsedTerm
10361036

1037+
makeBaseFunctor ''Pattern
1038+
10371039
instance Eq a => Eq (UnprocessedParsedTermF a) where
10381040
(==) = eq1
10391041

@@ -1078,7 +1080,6 @@ instance Eq1 UnprocessedParsedTermF where
10781080
mod1 == mod2
10791081
liftEq _ _ _ = False
10801082

1081-
10821083
instance (Show a) => Show (UnprocessedParsedTermF a) where
10831084
show (VarUPF s) = "VarUPF " <> show s
10841085
show (ITEUPF c t e) = "ITEUPF " <> show c <> " " <> show t <> " " <> show e

src/Telomare/Parser.hs

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
{-# LANGUAGE LambdaCase #-}
22
{-# LANGUAGE ScopedTypeVariables #-}
3+
{-# LANGUAGE TupleSections #-}
34
{-# LANGUAGE TypeFamilies #-}
45

56
module Telomare.Parser where
67

78
import Control.Comonad.Cofree (Cofree (..), unwrap)
89
import Control.Lens.Plated (Plated (..))
9-
import Control.Monad (void, join)
10+
import Control.Monad (join, void)
1011
import Control.Monad.State (State)
1112
import Data.Bifunctor (Bifunctor (first, second), bimap)
1213
import Data.Functor (($>))
@@ -29,7 +30,7 @@ import Text.Megaparsec.Char (alphaNumChar, char, letterChar, space1, string)
2930
import qualified Text.Megaparsec.Char.Lexer as L
3031
import Text.Megaparsec.Debug (dbg)
3132
import Text.Megaparsec.Pos (Pos)
32-
import Text.Read (readMaybe)
33+
import Text.Read (readMaybe, Lexeme (String))
3334
import Text.Show.Deriving (deriveShow1)
3435

3536
type AnnotatedUPT = Cofree UnprocessedParsedTermF LocTag
@@ -198,7 +199,7 @@ parseHash = do
198199
parseBrand :: TelomareParser AnnotatedUPT
199200
parseBrand = 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
241242
parsePatternString = PatternString <$> (char '"' >> manyTill L.charLiteral (char '"'))
242243

243244
parsePatternVar :: 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

246253
parsePatternIgnore :: TelomareParser Pattern
247254
parsePatternIgnore = 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.
274309
parseLambda :: TelomareParser AnnotatedUPT
275310
parseLambda = 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`.
285320
parseSameLvl :: Pos -> TelomareParser a -> TelomareParser a
@@ -354,7 +389,7 @@ parseImportQualified = do
354389
parseOneAssignmentOrBrand :: TelomareParser (String, AnnotatedUPT)
355390
parseOneAssignmentOrBrand =
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.
360395
parseAssignmentsAndBrands :: 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.
369404
parseTopLevelWithExtraModuleBindings :: [(String, AnnotatedUPT)]
@@ -453,6 +488,40 @@ parseModule :: String -> Either String [Either AnnotatedUPT (String, AnnotatedUP
453488
parseModule 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
458527
parseOneExprOrTopLevelDefs :: [(String, AnnotatedUPT)] -> TelomareParser AnnotatedUPT

0 commit comments

Comments
 (0)