@@ -1,5 +1,6 @@
11module Idris.Interactive(caseSplitAt, addClauseFrom, addProofClauseFrom,
2− addMissing, makeWith, doProofSearch) where
2+ addMissing, makeWith, doProofSearch,
3+ makeLemma) where
34
45{- Bits and pieces for editing source files interactively, called from
56 the REPL -}
@@ -195,26 +196,67 @@ doProofSearch h fn updatefile rec l n hints
195196 nsroot (SN (WhereN _ _ n)) = nsroot n
196197 nsroot n = n
197198
198− updateMeta brack ('?':cs) n new
199− | length cs >= length n
200− = case splitAt (length n) cs of
201− (mv, c:cs) ->
202− if ((isSpace c || c == ')' || c == '}') && mv == n)
203− then addBracket brack new ++ (c : cs)
204− else '?' : mv ++ c : updateMeta True cs n new
205− (mv, []) -> if (mv == n) then addBracket brack new else '?' : mv
206− updateMeta brack ('=':cs) n new = '=':updateMeta False cs n new
207− updateMeta brack (c:cs) n new
208− = c : updateMeta (brack || not (isSpace c)) cs n new
209− updateMeta brack [] n new = ""
199+updateMeta brack ('?':cs) n new
200+ | length cs >= length n
201+ = case splitAt (length n) cs of
202+ (mv, c:cs) ->
203+ if ((isSpace c || c == ')' || c == '}') && mv == n)
204+ then addBracket brack new ++ (c : cs)
205+ else '?' : mv ++ c : updateMeta True cs n new
206+ (mv, []) -> if (mv == n) then addBracket brack new else '?' : mv
207+updateMeta brack ('=':cs) n new = '=':updateMeta False cs n new
208+updateMeta brack (c:cs) n new
209+ = c : updateMeta (brack || not (isSpace c)) cs n new
210+updateMeta brack [] n new = ""
210211
211− addBracket False new = new
212− addBracket True new@('(':xs) | last xs == ')' = new
213− addBracket True new | any isSpace new = '(' : new ++ ")"
214− | otherwise = new
212+addBracket False new = new
213+addBracket True new@('(':xs) | last xs == ')' = new
214+addBracket True new | any isSpace new = '(' : new ++ ")"
215+ | otherwise = new
215216
216217
218+makeLemma :: Handle -> FilePath -> Bool -> Int -> Name -> Idris ()
219+makeLemma h fn updatefile l n
220+ = do src <- runIO $ readFile fn
221+ let (before, tyline : later) = splitAt (l-1) (lines src)
222+
223+ ctxt <- getContext
224+ mty <- case lookupTy n ctxt of
225+ [t] -> return t
226+ [] -> ierror (NoSuchVariable n)
227+ ns -> ierror (CantResolveAlts (map show ns))
228+
229+ i <- getIState
230+ let lem = show n ++ " : " ++ show (stripMNBind (delab i mty))
231+ let lem_app = show n ++ appArgs mty
232+
233+ if updatefile then
234+ do let fb = fn ++ "~"
235+ runIO $ writeFile fb (addLem before tyline lem lem_app later)
236+ runIO $ copyFile fb fn
237+ else ihPrintResult h $ lem ++ "\n" ++ lem_app
238+
239+ where getIndent s = length (takeWhile isSpace s)
240+
241+ appArgs (Bind n@(UN c) (Pi _) sc)
242+ | thead c /= '_' = " " ++ show n ++ appArgs sc
243+ appArgs (Bind _ (Pi _) sc) = " " ++ appArgs sc
244+ appArgs _ = ""
245+
246+ stripMNBind (PPi b n@(UN c) ty sc)
247+ | thead c /= '_' = PPi b n ty (stripMNBind sc)
248+ stripMNBind (PPi b _ ty sc) = stripMNBind sc
249+ stripMNBind t = t
250+
251+ blank = all isSpace
217252
253+ addLem before tyline lem lem_app later
254+ = let (bef_end, blankline : bef_start)
255+ = span (not . blank) (reverse before)
256+ mvline = updateMeta False tyline (show n) lem_app in
257+ unlines $ reverse bef_start ++
258+ [blankline, lem, blankline] ++
259+ reverse bef_end ++ mvline : later
218260
219261
220262