-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathTy.hs
74 lines (64 loc) · 2.13 KB
/
Ty.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
{-# LANGUAGE TypeFamilies, FlexibleContexts #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE OverloadedStrings, RecordWildCards, TupleSections #-}
module Toy.Language.Parser.Ty
( ty
, baseRT
) where
import Control.Monad
import Data.List.Extra
import Data.String
import Text.Megaparsec
import Text.Megaparsec.Char.Lexer
import Toy.Language.Syntax
import Toy.Language.Syntax.Terms.Sugar
import Toy.Language.Parser.Common
import Toy.Language.Parser.Util
ty :: ToyMonad e s m => m Ty
ty = TyArrow <$> try arrow
<|> arrowLHS
arrowLHS :: ToyMonad e s m => m Ty
arrowLHS = parens ty <|> TyBase <$> baseRT
arrow :: ToyMonad e s m => m ArrowTy
arrow = do
(piVarName, domTy) <- boundLHS <|> unboundLHS
void $ lstring "->"
codTy <- ty
pure $ ArrowTy { .. }
where
unboundLHS = (Nothing,) <$> arrowLHS
boundLHS = try $ parens $ do
piVarName <- Just <$> varName <* lstring ":"
domTy <- ty
pure (piVarName, domTy)
baseRT :: ToyMonad e s m => m RefinedBaseTy
baseRT = try refinedTy <|> implicitTrue
where
implicitTrue = RefinedBaseTy <$> baseTy <*> pure trueRefinement
refinedTy = do
void $ lstring "{"
void $ lstring "v"
void $ lstring ":"
baseType <- baseTy
void $ lstring "|"
baseTyRefinement <- Just <$> refinement
void $ lstring "}"
pure $ RefinedBaseTy { .. }
-- TODO support custom refinement vars
refinement :: ToyMonad e s m => m Refinement
refinement = Refinement "v" <$> atomicRefinement `sepBy1` lstring "&"
atomicRefinement :: ToyMonad e s m => m AtomicRefinement
atomicRefinement = do
void $ lstring "v"
(\op arg -> AR $ TBinOp () v op arg) <$> parseTable ops <*> args
where
ops = [ ("<=", BinOpLeq), ("<", BinOpLt), ("=", BinOpEq), ("/=", BinOpNEq), (">=", BinOpGeq), (">", BinOpGt) ]
args = choice [ TInteger () <$> lexeme' decimal
, lstringSpace "len" >> TApp () "len" . TName () <$> varName
, TName () <$> varName
]
baseTy :: ToyMonad e s m => m BaseTy
baseTy = parseTable [ (fromString str, bty)
| bty <- enumerate
, let str = tail $ show bty
]