1 ----------------------------------------------------------------
3 -- Copyright 2000, Jan-Willem Roorda and Daan Leijen
4 ----------------------------------------------------------------
5 module HenkParser where
7 import Text.ParserCombinators.Parsec.
8 import qualified Text.ParserCombinators.Parsec.Token as P
9 import Text.ParserCombinators.Parsec.Expr
10 import Text.ParserCombinators.Parsec.Language
14 ----------------------------------------------------------------
17 -- anonymous variables are any identifiers starting with "_"
19 -- unknown types (those that need to be inferred) can explicitly
22 -- instead of grammar: "var : aexpr" as in the henk paper,
23 -- we use "var : expr" instead. This means that variable
24 -- sequences as in \, |~|, \/ and /\ expressions need to
25 -- be comma seperated. Pattern variables are also comma
26 -- seperated. The case arrow (->) now needs to be (=>) in
27 -- order to distinguish the end of the pattern from function
29 ----------------------------------------------------------------
35 ; return $ Program ts vs
38 ----------------------------------------------------------------
40 ----------------------------------------------------------------
45 ; ts <- braces (semiSep1 tvar)
49 ----------------------------------------------------------------
51 ----------------------------------------------------------------
52 vdecl :: Parser ValueDecl
60 ; bs <- braces (semiSep1 bind)
72 ----------------------------------------------------------------
74 ----------------------------------------------------------------
79 , forallExpr -- forall before lambda! \/ vs. \
98 ; ts <- commaSep1 bindVar
101 ; return $ (foldr Lam e ts)
106 ; ts <- commaSep1 bindVar
109 ; return (foldr Pi e ts)
112 ----------------------------------------------------------------
114 ----------------------------------------------------------------
116 = do{ reserved "case"
119 ; as <- braces (semiSep1 alt)
120 ; es <- option [] (do{ reserved "at"
121 ; braces (semiSep expr)
123 ; return (Case e as es)
134 = do{ p <- atomPattern
135 ; vs <- commaSep boundVar
136 ; return (\e -> Alt p (foldr Lam e vs))
149 ----------------------------------------------------------------
150 -- Syntactic sugar: ->, \/, /\
151 ----------------------------------------------------------------
153 = chainr1 appExpr arrow
155 arrow = do{ symbol "->"
157 Pi (TVar anonymous x) y))
163 ; ts <- commaSep1 bindVar
166 ; return (foldr Lam e ts)
170 = do{ try (symbol "\\/") -- use "try" to try "\" (lambda) too.
171 ; ts <- commaSep1 bindVar
174 ; return (foldr Pi e ts)
177 ----------------------------------------------------------------
178 -- Simple expressions
179 ----------------------------------------------------------------
181 = do{ es <- many1 atomExpr
182 ; return (foldl1 App es)
187 <|> do{ v <- boundVar; return (Var v) }
188 <|> do{ l <- literal; return (Lit l)}
189 <|> do{ symbol "*"; return Star }
190 <|> do{ symbol "[]"; return Box }
191 <|> do{ symbol "?"; return Unknown }
192 <?> "simple expression"
195 ----------------------------------------------------------------
196 -- Variables & Literals
197 ----------------------------------------------------------------
204 ; cs <- many (identLetter henkDef)
209 = do{ i <- variable <|> anonymousVar
213 <|> return (TVar i Star)
222 <|> return (TVar i Unknown)
247 ----------------------------------------------------------------
249 ----------------------------------------------------------------
250 henk = P.makeTokenParser henkDef
252 lexeme = P.lexeme henk
253 parens = P.parens henk
254 braces = P.braces henk
255 semiSep = P.semiSep henk
256 semiSep1 = P.semiSep1 henk
257 commaSep = P.commaSep henk
258 commaSep1 = P.commaSep1 henk
259 whiteSpace = P.whiteSpace henk
260 symbol = P.symbol henk
261 identifier = P.identifier henk
262 reserved = P.reserved henk
263 natural = P.natural henk
268 { identStart = letter
269 , identLetter = alphaNum <|> oneOf "_'"
270 , opStart = opLetter henkDef
271 , opLetter = oneOf ":=\\->/|~.*[]"
272 , reservedOpNames = ["::","=","\\","->","=>","/\\","\\/"
273 ,"|~|",".",":","*","[]"]
274 , reservedNames = [ "case", "data", "letrec", "type"
275 , "import", "in", "let", "of", "at"