@@ -9,6 +9,7 @@ import Core.Evaluate
9import Control.Monad.State
9import Control.Monad.State
10import Data.List
10import Data.List
11import Data.Char
11import Data.Char
13data IOption = IOption { opt_logLevel :: Int }
14data IOption = IOption { opt_logLevel :: Int }
14 deriving (Show, Eq)
15 deriving (Show, Eq)
@@ -22,7 +23,7 @@ defaultOpts = IOption 0
23data IState = IState { tt_ctxt :: Context,
24data IState = IState { tt_ctxt :: Context,
24 idris_infixes :: [FixDecl],
25 idris_infixes :: [FixDecl],
25− idris_implicits :: Ctxt ([Name], Int), -- implicits, arity
26+ idris_implicits :: Ctxt [PArg],
26 idris_log :: String,
27 idris_log :: String,
27 idris_options :: IOption
28 idris_options :: IOption
@@ -99,7 +100,7 @@ data PDecl' t = PFix Fixity [String] -- fixity declaration
99 | PData (PData' t) -- data declaration
100 | PData (PData' t) -- data declaration
100 deriving Functor
101 deriving Functor
102−data PClause' t = PClause Name t t
103+data PClause' t = PClause Name t t [PDecl]
103 deriving Functor
104 deriving Functor
105data PData' t = PDatadecl { d_name :: Name,
106data PData' t = PDatadecl { d_name :: Name,
@@ -112,20 +113,27 @@ data PData' t = PDatadecl { d_name :: Name,
113type PDecl = PDecl' PTerm
114type PDecl = PDecl' PTerm
114type PData = PData' PTerm
115type PData = PData' PTerm
115−type PClause = PClause' PTerm
116+type PClause = PClause' PTerm
116−-- High level language terms
118+-- High level language terms
118data PTerm = PQuote Raw
120data PTerm = PQuote Raw
119 | PRef Name
121 | PRef Name
120 | PLam Name PTerm PTerm
122 | PLam Name PTerm PTerm
121 | PPi Plicity Name PTerm PTerm
123 | PPi Plicity Name PTerm PTerm
122 | PLet Name PTerm PTerm PTerm -- not implemented yet
124 | PLet Name PTerm PTerm PTerm -- not implemented yet
123− | PApp PTerm [(Name, PTerm)] [PTerm]
125+ | PApp PTerm [PArg]
124 | PHidden PTerm -- irrelevant or hidden pattern
126 | PHidden PTerm -- irrelevant or hidden pattern
126 | PConstant Const
128 | PConstant Const
127 | Placeholder
129 | Placeholder
131+data PArg' t = PImp { pname :: Name, getTm :: t }
132+ | PExp { getTm :: t }
133+ deriving (Show, Functor)
135+type PArg = PArg' PTerm
129-- Syntactic sugar info (TODO: namespaces, parameters, modules)
137-- Syntactic sugar info (TODO: namespaces, parameters, modules)
131data SyntaxInfo = Syn { using :: [(Name, PTerm)] }
139data SyntaxInfo = Syn { using :: [(Name, PTerm)] }
@@ -151,14 +159,27 @@ instance Show PData where
151 show d = showDImp False d
159 show d = showDImp False d
153showCImp :: Bool -> PClause -> String
161showCImp :: Bool -> PClause -> String
154−showCImp impl (PClause n l r) = showImp impl l ++ " = " ++ showImp impl r
162+showCImp impl (PClause n l r w) = showImp impl l ++ " = " ++ showImp impl r
155−
163+ ++ " where " ++ show w
156showDImp :: Bool -> PData -> String
164showDImp :: Bool -> PData -> String
157showDImp impl (PDatadecl n ty cons)
165showDImp impl (PDatadecl n ty cons)
158 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
166 = "data " ++ show n ++ " : " ++ showImp impl ty ++ " where\n\t"
159 ++ showSep "\n\t| "
167 ++ showSep "\n\t| "
160 (map (\ (n, t) -> show n ++ " : " ++ showImp impl t) cons)
168 (map (\ (n, t) -> show n ++ " : " ++ showImp impl t) cons)
170+getImps :: [PArg] -> [(Name, PTerm)]
172+getImps (PImp n tm : xs) = (n, tm) : getImps xs
173+getImps (_ : xs) = getImps xs
175+getExps :: [PArg] -> [PTerm]
177+getExps (PExp tm : xs) = tm : getExps xs
178+getExps (_ : xs) = getExps xs
180+getAll :: [PArg] -> [PTerm]
162showImp :: Bool -> PTerm -> String
183showImp :: Bool -> PTerm -> String
163showImp impl tm = se 10 tm where
184showImp impl tm = se 10 tm where
164 se p (PQuote r) = "![" ++ show r ++ "]"
185 se p (PQuote r) = "![" ++ show r ++ "]"
@@ -168,19 +189,21 @@ showImp impl tm = se 10 tm where
168 | n `elem` allNamesIn sc = bracket p 2 $
189 | n `elem` allNamesIn sc = bracket p 2 $
169 "(" ++ show n ++ " : " ++ se 10 ty ++
190 "(" ++ show n ++ " : " ++ se 10 ty ++
170 ") -> " ++ se 10 sc
191 ") -> " ++ se 10 sc
171− | otherwise = bracket p 2 $ se 10 ty ++ " -> " ++ se 10 sc
192+ | otherwise = bracket p 2 $ se 0 ty ++ " -> " ++ se 10 sc
172 se p (PPi Imp n ty sc)
193 se p (PPi Imp n ty sc)
173 | impl = bracket p 2 $ "{" ++ show n ++ " : " ++ se 10 ty ++
194 | impl = bracket p 2 $ "{" ++ show n ++ " : " ++ se 10 ty ++
174 "} -> " ++ se 10 sc
195 "} -> " ++ se 10 sc
175 | otherwise = se 10 sc
196 | otherwise = se 10 sc
176− se p (PApp (PRef f) _ [])
197+ se p (PApp (PRef f) [])
177 | not impl = show f
198 | not impl = show f
178− se p (PApp (PRef op@(UN [f:_])) _ [l, r])
199+ se p (PApp (PRef op@(UN [f:_])) args)
179− | not impl && not (isAlpha f)
200+ | length (getExps args) == 2 && not impl && not (isAlpha f)
201+ = let [l, r] = getExps args in
180− = bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
202+ bracket p 1 $ se 1 l ++ " " ++ show op ++ " " ++ se 0 r
181− se p (PApp f imps args)
203+ se p (PApp f as)
204+ = let (imps, args) = (getImps as, getExps as) in
182− = bracket p 1 $ se 1 f ++ (if impl then concatMap siArg imps else "")
205+ bracket p 1 $ se 1 f ++ (if impl then concatMap siArg imps else "")
183− ++ concatMap seArg args
206+ ++ concatMap seArg args
184 se p (PHidden tm) = "." ++ se 0 tm
207 se p (PHidden tm) = "." ++ se 0 tm
185 se p PSet = "Set"
208 se p PSet = "Set"
186 se p (PConstant c) = show c
209 se p (PConstant c) = show c
@@ -197,8 +220,7 @@ allNamesIn tm = nub $ ni [] tm
198 ni env (PRef n)
221 ni env (PRef n)
199 | not (n `elem` env) = [n]
222 | not (n `elem` env) = [n]
200− ni env (PApp f is es) = ni env f ++ concatMap (ni env) (map snd is) ++
223+ ni env (PApp f as) = ni env f ++ concatMap (ni env) (map getTm as)
201− concatMap (ni env) es
202 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
224 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
203 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
225 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
204 ni env (PHidden tm) = ni env tm
226 ni env (PHidden tm) = ni env tm
@@ -212,8 +234,7 @@ namesIn ist tm = nub $ ni [] tm
212 = case lookupCtxt n (idris_implicits ist) of
234 = case lookupCtxt n (idris_implicits ist) of
213 Nothing -> [n]
235 Nothing -> [n]
215− ni env (PApp f is es) = ni env f ++ concatMap (ni env) (map snd is) ++
237+ ni env (PApp f as) = ni env f ++ concatMap (ni env) (map getTm as)
216− concatMap (ni env) es
217 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
238 ni env (PLam n ty sc) = ni env ty ++ ni (n:env) sc
218 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
239 ni env (PPi _ n ty sc) = ni env ty ++ ni (n:env) sc
219 ni env (PHidden tm) = ni env tm
240 ni env (PHidden tm) = ni env tm
@@ -229,7 +250,7 @@ inferDecl = PDatadecl inferTy
229 PPi Exp (MN 0 "a") (PRef (MN 0 "A"))
250 PPi Exp (MN 0 "a") (PRef (MN 0 "A"))
230 (PRef inferTy)))]
251 (PRef inferTy)))]
232−infTerm t = PApp (PRef inferCon) [(MN 0 "A", Placeholder)] [t]
253+infTerm t = PApp (PRef inferCon) [PImp (MN 0 "A") Placeholder, PExp t]
233infP = P (TCon 0) inferTy (Set 0)
254infP = P (TCon 0) inferTy (Set 0)
235getInferTerm, getInferType :: Term -> Term
256getInferTerm, getInferType :: Term -> Term
@@ -246,52 +267,53 @@ getInferType (App (App _ ty) _) = ty
246-- Add implicit Pi bindings for any names in the term which appear in an
267-- Add implicit Pi bindings for any names in the term which appear in an
247-- argument position.
268-- argument position.
249−implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, ([Name], Int))
270+implicitise :: SyntaxInfo -> IState -> PTerm -> (PTerm, [PArg])
250implicitise syn ist tm
271implicitise syn ist tm
251 = let uvars = using syn
272 = let uvars = using syn
252− (declimps, a, ns) = execState (imps [] tm) ([], 0, []) in
273+ (declimps, ns) = execState (imps True [] tm) ([], []) in
253 if null ns
274 if null ns
254− then (tm, (reverse declimps, a))
275+ then (tm, reverse declimps)
255 else implicitise syn ist (pibind uvars ns tm)
276 else implicitise syn ist (pibind uvars ns tm)
257− imps env (PApp f is es)
278+ imps top env (PApp f as)
258− = do (decls, a, ns) <- get
279+ = do (decls, ns) <- get
259− let isn = concatMap (namesIn ist) (map snd is)
280+ let isn = concatMap (namesIn ist) (map getTm as)
260− let esn = concatMap (namesIn ist) es
261− put (decls, a, nub (ns ++ ((isn ++ esn) \\ (env ++ decls))))
281+ put (decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
262− imps env (PPi Imp n ty sc)
282+ imps top env (PPi Imp n ty sc)
263− = do imps env ty
283+ = do let isn = namesIn ist ty \\ [n]
264− (impdecls, a, ns) <- get
284+ (decls , ns) <- get
265− put (n:impdecls, a, ns)
285+ put (PImp n ty : decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
266− imps (n:env) sc
286+ imps True (n:env) sc
267− imps env (PPi Exp n ty sc)
287+ imps top env (PPi Exp n ty sc)
268− = do imps env ty
288+ = do let isn = (namesIn ist ty ++ case sc of
269− (impdecls, a, ns) <- get
289+ (PRef x) -> namesIn ist sc
270− put (impdecls, a+1, ns)
290+ _ -> []) \\ [n]
291+ (decls, ns) <- get -- ignore decls in HO types
292+ put (PExp ty : decls, nub (ns ++ (isn \\ (env ++ map fst (getImps decls)))))
271− imps (n:env) sc
293+ imps True (n:env) sc
272− imps env (PLam n ty sc)
294+ imps top env (PLam n ty sc)
273− = do imps env ty
295+ = do imps False env ty
274− imps (n:env) sc
296+ imps False (n:env) sc
275− imps env (PHidden tm) = imps env tm
297+ imps top env (PHidden tm) = imps False env tm
276− imps env _ = return ()
298+ imps top env _ = return ()
278 pibind using [] sc = sc
300 pibind using [] sc = sc
279 pibind using (n:ns) sc = case lookup n using of
301 pibind using (n:ns) sc = case lookup n using of
280 Just ty -> PPi Imp n ty (pibind using ns sc)
302 Just ty -> PPi Imp n ty (pibind using ns sc)
281 Nothing -> PPi Imp n Placeholder (pibind using ns sc)
303 Nothing -> PPi Imp n Placeholder (pibind using ns sc)
305+-- Add implicit arguments in function calls
283addImpl :: IState -> PTerm -> PTerm
307addImpl :: IState -> PTerm -> PTerm
284addImpl ist ptm = ai [] ptm
308addImpl ist ptm = ai [] ptm
286− ai env (PRef f) = aiFn env (PRef f) [] []
310+ ai env (PRef f) = aiFn env (PRef f) []
287− ai env (PApp (PRef f) is es)
311+ ai env (PApp (PRef f) as)
288− = let is' = map (\ (n, tm) -> (n, ai env tm)) is
312+ = let as' = map (fmap (ai env)) as in
289− es' = map (ai env) es in
290− aiFn env (PRef f) is' es'
313+ aiFn env (PRef f) as'
291− ai env (PApp f is es) = let f' = ai env f
314+ ai env (PApp f as) = let f' = ai env f
292− is' = map (\ (n, tm) -> (n, ai env tm)) is
315+ as' = map (fmap (ai env)) as in
293− es' = map (ai env) es in
294− aiFn env f' is' es'
316+ aiFn env f' as'
295 ai env (PLam n ty sc) = let ty' = ai env ty
317 ai env (PLam n ty sc) = let ty' = ai env ty
296 sc' = ai (n:env) sc in
318 sc' = ai (n:env) sc in
297 PLam n ty' sc'
319 PLam n ty' sc'
@@ -301,23 +323,31 @@ addImpl ist ptm = ai [] ptm
301 ai env (PHidden tm) = PHidden (ai env tm)
323 ai env (PHidden tm) = PHidden (ai env tm)
302 ai env tm = tm
324 ai env tm = tm
304− aiFn env (PRef f) is es | not (f `elem` env)
326+ aiFn env (PRef f) as | not (f `elem` env)
305 = case lookupCtxt f (idris_implicits ist) of
327 = case lookupCtxt f (idris_implicits ist) of
306− Just (ns, a) -> pApp a (PRef f) (insertImpl ns is) es
328+ Just ns -> pApp (length ns) (PRef f) (insertImpl ns as)
307− Nothing -> pApp 1 (PRef f) is es
329+ Nothing -> pApp 1 (PRef f) as
308− aiFn env f is es = pApp 1 f is es
330+ aiFn env f as = pApp 1 f as
310− pApp a f [] [] = f
332+ pApp a f [] = f
311− pApp a f is es = let rest = drop a es in
333+ pApp a f as = let rest = drop a as in
312− appRest (PApp f is (take a es)) rest
334+ appRest (PApp f (take a as)) rest
314 appRest f [] = f
336 appRest f [] = f
315− appRest f (a : as) = appRest (PApp f [] [a]) as
337+ appRest f (a : as) = appRest (PApp f [a]) as
317− insertImpl [] given = []
339+ insertImpl :: [PArg] -> [PArg] -> [PArg]
340+ insertImpl (PExp ty : ps) (PExp tm : given) =
341+ PExp tm : insertImpl ps given
318− insertImpl (n:ns) given
342+ insertImpl (PImp n ty : ps) given =
319− = case lookup n given of
343+ case find n given [] of
320− Just val -> (n, val) : insertImpl ns given
344+ Just (tm, given') -> PImp n ty : insertImpl ps given'
321− Nothing -> (n, Placeholder) : insertImpl ns given
345+ Nothing -> PImp n Placeholder : insertImpl ps given
322−
346+ insertImpl expected [] = []
347+ insertImpl [] given = given
349+ find n [] acc = Nothing
350+ find n (PImp n' t : gs) acc
351+ | n == n' = Just (t, reverse acc ++ gs)
352+ find n (g : gs) acc = find n gs (g : acc)