1module Idris.Parser where
8import Text.ParserCombinators.Parsec
9import Text.ParserCombinators.Parsec.Expr
10import Text.ParserCombinators.Parsec.Language
11import qualified Text.ParserCombinators.Parsec.Token as PTok
14import Control.Monad.State
17type TokenParser a = PTok.TokenParser a
19type IParser = GenParser Char IState
21lexer :: TokenParser IState
22lexer = PTok.makeTokenParser idrisDef
24whiteSpace= PTok.whiteSpace lexer
25lexeme = PTok.lexeme lexer
26symbol = PTok.symbol lexer
27natural = PTok.natural lexer
28parens = PTok.parens lexer
30comma = PTok.comma lexer
31identifier= PTok.identifier lexer
32reserved = PTok.reserved lexer
33operator = PTok.operator lexer
34reservedOp= PTok.reservedOp lexer
37parseExpr i = runParser pFullExpr i "(input)"
39parseProg :: String -> Idris [PDecl]
40parseProg fname = do file <- lift $ readFile fname
42 case (runParser (do ps <- many1 pDecl
45 return (ps, i')) i fname file) of
46 Left err -> fail (show err)
47 Right (x, i) -> do put i
50-- Collect PClauses with the same function name
51collect :: [PDecl] -> [PDecl]
52collect (PClauses _ [c@(PClause n l r)] : ds) = clauses n [c] ds
53 where clauses n acc (PClauses _ [c@(PClause n' l r)] : ds)
54 | n == n' = clauses n (c : acc) ds
55 clauses n acc xs = PClauses n (reverse acc) : collect xs
56collect (d : ds) = d : collect ds
59pFullExpr :: IParser PTerm
60pFullExpr = do x <- pExpr; eof;
68 return (fmap (addImpl i) d)
70--------- Top Level Declarations ---------
72pDecl' :: IParser PDecl
74 <|> try (do n <- pfName; ty <- pTSig
80--------- Fixity ---------
82pFixity :: IParser PDecl
83pFixity = do f <- fixity; i <- natural; ops <- sepBy1 operator (lchar ',')
84 let prec = fromInteger i
86 let fs = map (Fix (f prec)) ops
88 idris_infixes = sort (fs ++ idris_infixes istate) })
89 return (PFix (f prec) ops)
91fixity :: IParser (Int -> Fixity)
92fixity = try (do reserved "infixl"; return Infixl)
93 <|> try (do reserved "infixr"; return Infixr)
94 <|> try (do reserved "infix"; return InfixN)
96--------- Expressions ---------
98pExpr = do i <- getState
99 buildExpressionParser (table (idris_infixes i)) pExpr'
101pExpr' :: IParser PTerm
108 <|> do lchar '('; o <- operator; lchar ')'; return (UN [o])
111 try (do symbol "!["; t <- pTerm; lchar ']'
113 <|> try (do x <- pfName; return (PRef x))
114 <|> try (do lchar '_'; return Placeholder)
115 <|> try (do lchar '('; e <- pExpr; lchar ')'; return e)
116 <|> try (do reserved "Set"; return PSet)
118pHSimpleExpr = try pSimpleExpr
123pApp = do f <- pSimpleExpr
124 iargs <- many pImplicitArg
125 args <- many1 pSimpleExpr
126 return (PApp f iargs args)
128pImplicitArg = do lchar '{'; n <- iName
129 v <- option (PRef n) (do lchar '='; pExpr)
136pLambda = do lchar '\\'; x <- iName; t <- option Placeholder pTSig
141pPi = do lchar '('; x <- iName; t <- pTSig; lchar ')'
144 return (PPi Exp x t sc)
145 <|> do lchar '{'; x <- iName; t <- pTSig; lchar '}'
148 return (PPi Imp x t sc)
151 = toTable (reverse fixes) ++
152 [[binary "=" (\x y -> PApp (PRef (UN ["="])) [] [x,y]) AssocLeft],
153 [binary "->" (PPi Exp (MN 0 "X")) AssocRight]]
155toTable fs = map (map toBin)
156 (groupBy (\ (Fix x _) (Fix y _) -> prec x == prec y) fs)
157 where toBin (Fix f op) = binary op
158 (\x y -> PApp (PRef (UN [op])) [] [x,y]) (assoc f)
159 assoc (Infixl _) = AssocLeft
160 assoc (Infixr _) = AssocRight
161 assoc (InfixN _) = AssocNone
163binary name f assoc = Infix (do { reservedOp name; return f }) assoc
165--------- Data declarations ---------
167pData :: IParser PDecl
168pData = try (do reserved "data"; tyn <- pfName; ty <- pTSig
170 ty' <- implicit tyn ty
171 cons <- sepBy1 pConstructor (lchar '|')
172 return $ PData (PDatadecl tyn ty' cons))
173 <|> do reserved "data"; tyn <- pfName; args <- many iName
175 cons <- sepBy1 pSimpleCon (lchar '|')
176 let conty = mkPApp (PRef tyn) (map PRef args)
177 let ty = bindArgs (map (\a -> PSet) args) PSet
178 ty' <- implicit tyn ty
179 cons' <- mapM (\ (x, cargs) -> do let cty = bindArgs cargs conty
180 cty' <- implicit x cty
181 return (x, cty')) cons
182 return $ PData (PDatadecl tyn ty' cons')
185mkPApp t xs = PApp t [] xs
187bindArgs :: [PTerm] -> PTerm -> PTerm
189bindArgs (x:xs) t = PPi Exp (MN 0 "t") x (bindArgs xs t)
191pConstructor :: IParser (Name, PTerm)
193 = do cn <- pfName; ty <- pTSig
194 ty' <- implicit cn ty
197pSimpleCon :: IParser (Name, [PTerm])
198pSimpleCon = do cn <- pfName
199 args <- many pSimpleExpr
202--------- Pattern match clauses ---------
204pPattern :: IParser PDecl
205pPattern = do clause <- pClause
206 return (PClauses (MN 0 "_") [clause]) -- collect together later
208pClause :: IParser PClause
209pClause = try (do n <- pfName
210 iargs <- many pImplicitArg
211 args <- many pHSimpleExpr
214 return $ PClause n (PApp (PRef n) iargs args) rhs)
215 <|> do l <- pSimpleExpr
221 return $ PClause n (PApp (PRef n) [] [l,r]) rhs
223-- Dealing with implicit arguments
225implicit :: Name -> PTerm -> IParser PTerm
228 let (tm', name_arity) = implicitise i ptm
229 setState (i { idris_implicits = addDef n name_arity (idris_implicits i) })
232addImplicits :: PTerm -> IParser PTerm
235 return (addImpl i tm)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list