@@ -1,7 +1,7 @@
1{-# LANGUAGE PatternGuards #-}
1{-# LANGUAGE PatternGuards #-}
3module Idris.Interactive(caseSplitAt, addClauseFrom, addProofClauseFrom,
3module Idris.Interactive(caseSplitAt, addClauseFrom, addProofClauseFrom,
4− addMissing, makeWith, doProofSearch,
4+ addMissing, makeWith, makeCase, doProofSearch,
5 makeLemma) where
5 makeLemma) where
7{- Bits and pieces for editing source files interactively, called from
7{- Bits and pieces for editing source files interactively, called from
@@ -158,6 +158,47 @@ makeWith fn updatefile l n
158 else iPrintResult with
158 else iPrintResult with
159 where getIndent s = length (takeWhile isSpace s)
159 where getIndent s = length (takeWhile isSpace s)
161+-- Replace the given metavariable on the given line with a 'case'
162+-- block, using a _ for the scrutinee
163+makeCase :: FilePath -> Bool -> Int -> Name -> Idris ()
164+makeCase fn updatefile l n
165+ = do src <- runIO $ readSource fn
166+ let (before, tyline : later) = splitAt (l-1) (lines src)
167+ let newcase = addCaseSkel (show n) tyline
170+ do let fb = fn ++ "~"
171+ runIO $ writeSource fb (unlines (before ++ newcase ++ later))
172+ runIO $ copyFile fb fn
173+ else iPrintResult (unlines newcase)
174+ where addCaseSkel n line =
175+ let b = brackets False line in
176+ case findSubstr ('?':n) line of
177+ Just (before, pos, after) ->
178+ [before ++ (if b then "(" else "") ++ "case _ of",
179+ take (pos + (if b then 6 else 5)) (repeat ' ') ++
180+ "case_val => ?" ++ n ++ if b then ")" else "",
182+ Nothing -> fail "No such metavariable"
184+ -- Assume case needs to be bracketed unless the metavariable is
185+ -- on its own after an =
186+ brackets eq line | line == '?' : show n = not eq
187+ brackets eq ('=':ls) = brackets True ls
188+ brackets eq (' ':ls) = brackets eq ls
189+ brackets eq (l : ls) = brackets False ls
190+ brackets eq [] = True
192+ findSubstr n xs = findSubstr' [] 0 n xs
194+ findSubstr' acc i n xs | take (length n) xs == n
195+ = Just (reverse acc, i, drop (length n) xs)
196+ findSubstr' acc i n [] = Nothing
197+ findSubstr' acc i n (x : xs) = findSubstr' (x : acc) (i + 1) n xs
162doProofSearch :: FilePath -> Bool -> Bool ->
203doProofSearch :: FilePath -> Bool -> Bool ->
163 Int -> Name -> [Name] -> Maybe Int -> Idris ()
204 Int -> Name -> [Name] -> Maybe Int -> Idris ()