on master help sign in
Add %name directive for naming hints in editing.

Gives a list of preferred names for a particular type family. If none are available when generating names, just try adding a digit to each in turn. Also generate appropriate names for function arguments, and have a new set of invented names when nothing else is available.

commit4a0eba121c4fd36e26d8696891b5b82cc38c2c53 authorEdwin Brady <ecb10@st-andrews.ac.uk> dateSun 1 Dec 2013, 19:25 (13 years ago) parentcc9acda
11 files changed+139−57
libs/prelude/Prelude/List.idr+3 libs/prelude/Prelude/Nat.idr+3 libs/prelude/Prelude/Vect.idr+3 src/Core/TT.hs+5 src/Idris/AbsSyntax.hs+19 src/Idris/AbsSyntaxTree.hs+3 src/Idris/CaseSplit.hs+78−48 src/Idris/IBC.hs+14−5 src/Idris/ParseData.hs+1−1 src/Idris/Parser.hs+7 test/test032/expected+3−3
libs/prelude/Prelude/List.idr+3
@@ -19,6 +19,9 @@ infixl 8 ++
1919 = Nil
2020 | (::) a (List a)
2121
22+-- Name hints for interactive editing
23+%name List xs, ys, zs, ws
24+
2225--------------------------------------------------------------------------------
2326-- Syntactic tests
2427--------------------------------------------------------------------------------
libs/prelude/Prelude/Nat.idr+3
@@ -14,6 +14,9 @@ import Prelude.Classes
1414 = Z
1515 | S Nat
1616
17+-- name hints for interactive editing
18+%name Nat k,j,i,n,m
19+
1720--------------------------------------------------------------------------------
1821-- Syntactic tests
1922--------------------------------------------------------------------------------
libs/prelude/Prelude/Vect.idr+3
@@ -15,6 +15,9 @@ infixr 7 ::
1515 Nil : Vect Z a
1616 (::) : (x : a) -> (xs : Vect n a) -> Vect (S n) a
1717
18+-- Hints for interactive editing
19+%name Vect xs,ys,zs,ws
20+
1821--------------------------------------------------------------------------------
1922-- Indexing into vectors
2023--------------------------------------------------------------------------------
src/Core/TT.hs+5
@@ -834,6 +834,11 @@ getRetTy (Bind n (PVTy _) sc) = getRetTy sc
834834getRetTy (Bind n (Pi _) sc) = getRetTy sc
835835getRetTy sc = sc
836836
837+uniqueNameFrom :: [Name] -> [Name] -> Name
838+uniqueNameFrom (s : supply) hs
839+ | s `elem` hs = uniqueNameFrom supply hs
840+ | otherwise = s
841+
837842uniqueName :: Name -> [Name] -> Name
838843uniqueName n hs | n `elem` hs = uniqueName (nextName n) hs
839844 | otherwise = n
src/Idris/AbsSyntax.hs+19
@@ -167,6 +167,25 @@ addDocStr n doc
167167 = do i <- getIState
168168 putIState $ i { idris_docstrings = addDef n doc (idris_docstrings i) }
169169
170+addNameHint :: Name -> Name -> Idris ()
171+addNameHint ty n
172+ = do i <- getIState
173+ ty' <- case lookupCtxtName ty (idris_implicits i) of
174+ [(tyn, _)] -> return tyn
175+ [] -> throwError (NoSuchVariable ty)
176+ tyns -> throwError (CantResolveAlts (map show (map fst tyns)))
177+ let ns' = case lookupCtxt ty' (idris_namehints i) of
178+ [ns] -> ns ++ [n]
179+ _ -> [n]
180+ putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
181+
182+getNameHints :: IState -> Name -> [Name]
183+getNameHints i (UN "->") = [UN "f",UN "g"]
184+getNameHints i n =
185+ case lookupCtxt n (idris_namehints i) of
186+ [ns] -> ns
187+ _ -> []
188+
170189addToCalledG :: Name -> [Name] -> Idris ()
171190addToCalledG n ns = return () -- TODO
172191
src/Idris/AbsSyntaxTree.hs+3
@@ -92,6 +92,7 @@ data IState = IState {
9292 idris_dsls :: Ctxt DSL,
9393 idris_optimisation :: Ctxt OptInfo,
9494 idris_datatypes :: Ctxt TypeInfo,
95+ idris_namehints :: Ctxt [Name],
9596 idris_patdefs :: Ctxt ([([Name], Term, Term)], [PTerm]), -- not exported
9697 -- ^ list of lhs/rhs, and a list of missing clauses
9798 idris_flags :: Ctxt [FnOpt],
@@ -183,12 +184,14 @@ data IBCWrite = IBCFix FixDecl
183184 | IBCDoc Name
184185 | IBCCoercion Name
185186 | IBCDef Name -- i.e. main context
187+ | IBCNameHint (Name, Name)
186188 | IBCLineApp FilePath Int PTerm
187189 deriving Show
188190
189191idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
190192 emptyContext emptyContext emptyContext emptyContext
191193 emptyContext emptyContext emptyContext emptyContext
194+ emptyContext
192195 [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] []
193196 [] Nothing Nothing [] [] [] Hidden False [] Nothing [] [] RawOutput
194197 True defaultTheme stdout
src/Idris/CaseSplit.hs+78−48
@@ -71,7 +71,7 @@ split n t'
7171 logLvl 3 ("Split:\n" ++
7272 (showSep "\n" (map show (mapMaybe id newPats))))
7373 logLvl 3 "----"
74− let newPats' = mergeAllPats ctxt t (mapMaybe id newPats)
74+ let newPats' = mergeAllPats ist n t (mapMaybe id newPats)
7575 iLOG ("Name updates " ++ showSep "\n"
7676 (map (\ (p, u) -> show u ++ " " ++ show p) newPats'))
7777 return (map snd newPats')
@@ -84,47 +84,55 @@ data MergeState = MS { namemap :: [(Name, Name)],
8484addUpdate n tm = do ms <- get
8585 put (ms { updates = ((n, stripNS tm) : updates ms) } )
8686
87−inventName n =
87+inventName ist ty n =
8888 do ms <- get
89+ let supp = case ty of
90+ Nothing -> []
91+ Just t -> getNameHints ist t
92+ let nsupp = case n of
93+ MN i ('_':_) -> mkSupply (supp ++ varlist)
94+ MN i n -> mkSupply (UN n : supp ++ varlist)
95+ x -> mkSupply (x : supp)
8996 let badnames = map snd (namemap ms) ++ map snd (invented ms) ++
9097 explicit ms
9198 case lookup n (invented ms) of
9299 Just n' -> return n'
93100 Nothing ->
94− do let n' = case n of
95− MN i ('_':_) ->
96− uniqueName (UN "var") badnames
97− MN i n -> uniqueName (UN n) badnames
98− x -> x
101+ do let n' = uniqueNameFrom nsupp badnames
99102 put (ms { invented = (n, n') : invented ms })
100103 return n'
104+
105+mkSupply ns = mkSupply' ns (map nextName ns)
106+ where mkSupply' xs ns' = xs ++ mkSupply ns'
107+
108+varlist = map (UN . (:[])) "xyzwstuv" -- EB's personal preference :)
101109
102110stripNS tm = mapPT dens tm where
103111 dens (PRef fc n) = PRef fc (nsroot n)
104112 dens t = t
105113
106−mergeAllPats :: Context -> PTerm -> [PTerm] -> [(PTerm, [(Name, PTerm)])]
107−mergeAllPats ctxt t [] = []
108−mergeAllPats ctxt t (p : ps)
109− = let (p', MS _ _ _ u) = runState (mergePat ctxt t p)
110− (MS [] [] (patvars t) [])
111− ps' = mergeAllPats ctxt t ps in
114+mergeAllPats :: IState -> Name -> PTerm -> [PTerm] -> [(PTerm, [(Name, PTerm)])]
115+mergeAllPats ist cv t [] = []
116+mergeAllPats ist cv t (p : ps)
117+ = let (p', MS _ _ _ u) = runState (mergePat ist t p Nothing)
118+ (MS [] [] (filter (/=cv) (patvars t)) [])
119+ ps' = mergeAllPats ist cv t ps in
112120 ((p, u) : ps')
113121 where patvars (PRef _ n) = [n]
114122 patvars (PApp _ _ as) = concatMap (patvars . getTm) as
115123 patvars (PPatvar _ n) = [n]
116124 patvars _ = []
117125
118−mergePat :: Context -> PTerm -> PTerm -> State MergeState PTerm
126+mergePat :: IState -> PTerm -> PTerm -> Maybe Name -> State MergeState PTerm
119127-- If any names are unified, make sure they stay unified. Always prefer
120128-- user provided name (first pattern)
121−mergePat ctxt (PPatvar fc n) new
122− = mergePat ctxt (PRef fc n) new
123−mergePat ctxt old (PPatvar fc n)
124− = mergePat ctxt old (PRef fc n)
125−mergePat ctxt orig@(PRef fc n) new@(PRef _ n')
126− | isDConName n' ctxt = do addUpdate n new;
127− return new
129+mergePat ist (PPatvar fc n) new t
130+ = mergePat ist (PRef fc n) new t
131+mergePat ist old (PPatvar fc n) t
132+ = mergePat ist old (PRef fc n) t
133+mergePat ist orig@(PRef fc n) new@(PRef _ n') t
134+ | isDConName n' (tt_ctxt ist) = do addUpdate n new
135+ return new
128136 | otherwise
129137 = do ms <- get
130138 case lookup n' (namemap ms) of
@@ -132,37 +140,49 @@ mergePat ctxt orig@(PRef fc n) new@(PRef _ n')
132140 return (PRef fc x)
133141 Nothing -> do put (ms { namemap = ((n', n) : namemap ms) })
134142 return (PRef fc n)
135−mergePat ctxt (PApp _ _ args) (PApp fc f args')
136− = do newArgs <- zipWithM mergeArg args args'
143+mergePat ist (PApp _ _ args) (PApp fc f args') t
144+ = do newArgs <- zipWithM mergeArg args (zip args' (argTys ist f))
137145 return (PApp fc f newArgs)
138− where mergeArg x y = do tm' <- mergePat ctxt (getTm x) (getTm y)
139− case x of
140− (PImp _ _ _ _ _ _) ->
141− return (y { machine_inf = machine_inf x,
142− getTm = tm' })
143− _ -> return (y { getTm = tm' })
144−mergePat ctxt (PRef fc n) t = do tm <- tidy t
145− addUpdate n tm
146− return tm
147−mergePat ctxt x y = return y
146+ where mergeArg x (y, t)
147+ = do tm' <- mergePat ist (getTm x) (getTm y) t
148+ case x of
149+ (PImp _ _ _ _ _ _) ->
150+ return (y { machine_inf = machine_inf x,
151+ getTm = tm' })
152+ _ -> return (y { getTm = tm' })
153+mergePat ist (PRef fc n) tm ty = do tm <- tidy ist tm ty
154+ addUpdate n tm
155+ return tm
156+mergePat ist x y t = return y
148157
149158mergeUserImpl :: PTerm -> PTerm -> PTerm
150159mergeUserImpl x y = x
151160
152−tidy orig@(PRef fc n)
161+argTys :: IState -> PTerm -> [Maybe Name]
162+argTys ist (PRef fc n)
163+ = case lookupTy n (tt_ctxt ist) of
164+ [ty] -> map (tyName . snd) (getArgTys ty) ++ repeat Nothing
165+ _ -> repeat Nothing
166+ where tyName (Bind _ (Pi _) _) = Just (UN "->")
167+ tyName t | (P _ n _, _) <- unApply t = Just n
168+ | otherwise = Nothing
169+argTys _ _ = repeat Nothing
170+
171+tidy :: IState -> PTerm -> Maybe Name -> State MergeState PTerm
172+tidy ist orig@(PRef fc n) ty
153173 = do ms <- get
154174 case lookup n (namemap ms) of
155175 Just x -> return (PRef fc x)
156176 Nothing -> case n of
157177 (UN _) -> return orig
158− _ -> do n' <- inventName n
178+ _ -> do n' <- inventName ist ty n
159179 return (PRef fc n')
160−tidy (PApp fc f args)
161− = do args' <- mapM tidyArg args
180+tidy ist (PApp fc f args) ty
181+ = do args' <- zipWithM tidyArg args (argTys ist f)
162182 return (PApp fc f args')
163− where tidyArg x = do tm' <- tidy (getTm x)
164− return (x { getTm = tm' })
165−tidy tm = return tm
183+ where tidyArg x ty' = do tm' <- tidy ist (getTm x) ty'
184+ return (x { getTm = tm' })
185+tidy ist tm ty = return tm
166186
167187
168188-- mapPT tidyVar tm
@@ -291,15 +311,26 @@ getClause :: Int -- ^ line number that the type is declared on
291311 -> FilePath -- ^ Source file name
292312 -> Idris String
293313getClause l fn fp = do ty <- getInternalApp fp l
294− let ap = mkApp ty [1..]
314+ ist <- get
315+ let ap = mkApp ist ty []
295316 return (show fn ++ " " ++ ap ++
296317 "= ?" ++ show fn ++ "_rhs")
297− where mkApp (PPi (Exp _ _ _ False) (MN _ _) _ sc) (n : ns)
298− = "x" ++ show n ++ " " ++ mkApp sc ns
299− mkApp (PPi (Exp _ _ _ False) n _ sc) ns
300− = show n ++ " " ++ mkApp sc ns
301− mkApp (PPi _ _ _ sc) ns = mkApp sc ns
302− mkApp _ _ = ""
318+ where mkApp i (PPi (Exp _ _ _ False) (MN _ _) ty sc) used
319+ = let n = getNameFrom i used ty in
320+ show n ++ " " ++ mkApp i sc (n : used)
321+ mkApp i (PPi (Exp _ _ _ False) n _ sc) used
322+ = show n ++ " " ++ mkApp i sc (n : used)
323+ mkApp i (PPi _ _ _ sc) used = mkApp i sc used
324+ mkApp i _ _ = ""
325+
326+ getNameFrom i used (PPi _ _ _ _)
327+ = uniqueNameFrom (mkSupply [UN "f", UN "g"]) used
328+ getNameFrom i used (PApp fc f as) = getNameFrom i used f
329+ getNameFrom i used (PRef fc f)
330+ = case getNameHints i f of
331+ [] -> uniqueName (UN "x") used
332+ ns -> uniqueNameFrom (mkSupply ns) used
333+ getNameFrom i used _ = uniqueName (UN "x") used
303334
304335getProofClause :: Int -- ^ line number that the type is declared
305336 -> Name -- ^ Function name
@@ -326,4 +357,3 @@ mkWith str n = let str' = replaceRHS str "with (_)"
326357 | not ('=' `elem` rest) = str
327358 replaceRHS (x : rest) str = x : replaceRHS rest str
328359
329−
src/Idris/IBC.hs+14−5
@@ -23,7 +23,7 @@ import Debug.Trace
2323import Paths_idris
2424
2525ibcVersion :: Word8
26−ibcVersion = 45
26+ibcVersion = 46
2727
2828data IBCFile = IBCFile { ver :: Word8,
2929 sourcefile :: FilePath,
@@ -51,7 +51,8 @@ data IBCFile = IBCFile { ver :: Word8,
5151 ibc_docstrings :: [(Name, String)],
5252 ibc_transforms :: [(Term, Term)],
5353 ibc_coercions :: [Name],
54− ibc_lineapps :: [(FilePath, Int, PTerm)]
54+ ibc_lineapps :: [(FilePath, Int, PTerm)],
55+ ibc_namehints :: [(Name, Name)]
5556 }
5657 deriving Show
5758{-!
@@ -59,7 +60,7 @@ deriving instance Binary IBCFile
5960!-}
6061
6162initIBC :: IBCFile
62−initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
63+initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
6364
6465loadIBC :: FilePath -> Idris ()
6566loadIBC fp = do iLOG $ "Loading ibc " ++ fp
@@ -137,6 +138,8 @@ ibc i (IBCTotal n a) f = return f { ibc_total = (n,a) : ibc_total f }
137138ibc i (IBCTrans t) f = return f { ibc_transforms = t : ibc_transforms f }
138139ibc i (IBCLineApp fp l t) f
139140 = return f { ibc_lineapps = (fp,l,t) : ibc_lineapps f }
141+ibc i (IBCNameHint (n, ty)) f
142+ = return f { ibc_namehints = (n, ty) : ibc_namehints f }
140143
141144process :: IBCFile -> FilePath -> Idris ()
142145process i fn
@@ -172,6 +175,7 @@ process i fn
172175 pCoercions (ibc_coercions i)
173176 pTrans (ibc_transforms i)
174177 pLineApps (ibc_lineapps i)
178+ pNameHints (ibc_namehints i)
175179
176180timestampOlder :: FilePath -> FilePath -> IO ()
177181timestampOlder src ibc = do srct <- getModificationTime src
@@ -319,6 +323,9 @@ pTrans ts = mapM_ addTrans ts
319323pLineApps :: [(FilePath, Int, PTerm)] -> Idris ()
320324pLineApps ls = mapM_ (\ (f, i, t) -> addInternalApp f i t) ls
321325
326+pNameHints :: [(Name, Name)] -> Idris ()
327+pNameHints ns = mapM_ (\ (n, ty) -> addNameHint n ty) ns
328+
322329----- Generated by 'derive'
323330
324331instance Binary SizeChange where
@@ -873,7 +880,7 @@ instance Binary Totality where
873880 _ -> error "Corrupted binary data for Totality"
874881
875882instance Binary IBCFile where
876− put x@(IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27)
883+ put x@(IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28)
877884 = {-# SCC "putIBCFile" #-}
878885 do put x1
879886 put x2
@@ -902,6 +909,7 @@ instance Binary IBCFile where
902909 put x25
903910 put x26
904911 put x27
912+ put x28
905913 get
906914 = do x1 <- get
907915 if x1 == ibcVersion then
@@ -931,7 +939,8 @@ instance Binary IBCFile where
931939 x25 <- get
932940 x26 <- get
933941 x27 <- get
934− return (IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27)
942+ x28 <- get
943+ return (IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28)
935944 else return (initIBC { ver = x1 })
936945
937946instance Binary DataOpt where
src/Idris/ParseData.hs+1−1
@@ -144,7 +144,7 @@ data_ syn = do (doc, acc, dataOpts) <- try (do
144144 mkPApp fc t [] = t
145145 mkPApp fc t xs = PApp fc t (map pexp xs)
146146 bindArgs :: [PTerm] -> PTerm -> PTerm
147− bindArgs xs t = foldr (PPi expl (MN 0 "t")) t xs
147+ bindArgs xs t = foldr (PPi expl (MN 0 "_t")) t xs
148148 combineDataOpts :: DataOpts -> DataOpts
149149 combineDataOpts opts = if Codata `elem` opts then delete DefaultEliminator opts else opts
150150
src/Idris/Parser.hs+7
@@ -797,6 +797,7 @@ Directive' ::= 'lib' CodeGen String_t
797797 | 'default' Totality
798798 | 'logging' Natural
799799 | 'dynamic' StringList
800+ | 'name' Name NameList
800801 | 'language' 'TypeProviders'
801802 | 'language' 'ErrorReflection'
802803 ;
@@ -839,6 +840,12 @@ directive syn = do try (lchar '%' *> reserved "lib"); cgn <- codegen_; lib <- st
839840 Left lib -> addIBC (IBCDyLib (lib_name lib))
840841 Right msg ->
841842 fail $ msg)]
843+ <|> do try (lchar '%' *> reserved "name")
844+ ty <- iName []
845+ ns <- sepBy1 name (lchar ',')
846+ return [PDirective
847+ (do mapM_ (addNameHint ty) ns
848+ mapM_ (\n -> addIBC (IBCNameHint (ty, n))) ns)]
842849 <|> do try (lchar '%' *> reserved "language"); ext <- pLangExt;
843850 return [PDirective (addLangExt ext)]
844851 <?> "directive"
test/test032/expected+3−3
@@ -1,8 +1,8 @@
11Type checking ./test032.idr
22isElem x [] = ?isElem_rhs_1
3−isElem x (t :: t1) = ?isElem_rhs_3
3+isElem x (y :: xs) = ?isElem_rhs_3
44
5− localZipWith f (_ :: _) (x :: xs1) = ?localZipWith_rhs_1
5+ localZipWith f (_ :: _) (x :: ys) = ?localZipWith_rhs_1
66
77f x :: (map f xs)
88isElem2 x (y :: ys) with (_)
@@ -10,5 +10,5 @@ isElem2 x (y :: ys) with (_)
1010 isElem3 x (x :: ys) | (Yes refl) = ?isElem3_rhs_3
1111
1212 [] => ?bar_1
13− (t :: t1) => ?bar_2
13+ (x :: ys) => ?bar_2
1414