@@ -15,7 +15,7 @@ import Data.Maybe
15import Data.List
15import Data.List
16import Control.Monad
16import Control.Monad
18−elabRecord :: ElabInfo ->
18+elabRecord :: ElabInfo ->
19 (Docstring (Either Err PTerm)) ->
19 (Docstring (Either Err PTerm)) ->
20 SyntaxInfo ->
20 SyntaxInfo ->
@@ -23,13 +23,12 @@ elabRecord :: ElabInfo ->
23 Name -> -- ^ Record Type Name
23 Name -> -- ^ Record Type Name
24 [(Name, Plicity, PTerm)] -> -- ^ Parameters
24 [(Name, Plicity, PTerm)] -> -- ^ Parameters
25 [(Name, Docstring (Either Err PTerm))] -> -- ^ Parameter Docs
25 [(Name, Docstring (Either Err PTerm))] -> -- ^ Parameter Docs
26− [(Name, Plicity, PTerm)] -> -- ^ Fields
27− [(Name, Docstring (Either Err PTerm))] -> -- ^ Field Docs
26+ [((Maybe Name), Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))] -> -- ^ Fields
28 Maybe Name -> -- ^ Constructor Name
27 Maybe Name -> -- ^ Constructor Name
29 (Docstring (Either Err PTerm)) -> -- ^ Constructor Doc
28 (Docstring (Either Err PTerm)) -> -- ^ Constructor Doc
30 SyntaxInfo -> -- ^ Constructor SyntaxInfo
29 SyntaxInfo -> -- ^ Constructor SyntaxInfo
32−elabRecord info doc rsyn fc opts tyn params paramDocs fields fieldDocs cname cdoc csyn
31+elabRecord info doc rsyn fc opts tyn params paramDocs fields cname cdoc csyn
33 = do logLvl 1 $ "Building data declaration for " ++ show tyn
32 = do logLvl 1 $ "Building data declaration for " ++ show tyn
34 -- Type constructor
33 -- Type constructor
35 let tycon = generateTyConType params
34 let tycon = generateTyConType params
@@ -37,16 +36,105 @@ elabRecord info doc rsyn fc opts tyn params paramDocs fields fieldDocs cname cdo
38 -- Data constructor
37 -- Data constructor
39 dconName <- generateDConName cname
38 dconName <- generateDConName cname
40− let dconTy = generateDConType params fields
39+ let dconTy = generateDConType params fieldsWithNameAndDoc
41 logLvl 1 $ "Data constructor: " ++ showTmImpls dconTy
40 logLvl 1 $ "Data constructor: " ++ showTmImpls dconTy
43 -- Build data declaration for elaboration
42 -- Build data declaration for elaboration
44− let datadecl = PDatadecl tyn tycon [(cdoc, [], dconName, dconTy, fc, [])]
43+ let datadecl = PDatadecl tyn tycon [(cdoc, dconsArgDocs, dconName, dconTy, fc, [])]
45− elabData info rsyn doc [] fc opts datadecl
44+ elabData info rsyn doc paramDocs fc opts datadecl
46+ iLOG $ "fieldsWithName " ++ show fieldsWithName
47+ iLOG $ "fieldsWIthNameAndDoc " ++ show fieldsWithNameAndDoc
48+ elabRecordFunctions info rsyn fc tyn paramsAndDoc fieldsWithNameAndDoc dconName target
50+ -- | Generates a type constructor.
51+ generateTyConType :: [(Name, Plicity, PTerm)] -> PTerm
52+ generateTyConType ((n, p, t) : rest) = PPi p (nsroot n) t (generateTyConType rest)
53+ generateTyConType [] = PType
55+ -- | Generates a name for the data constructor if none was specified.
56+ generateDConName :: Maybe Name -> Idris Name
57+ generateDConName (Just n) = return $ expandNS csyn n
58+ generateDConName Nothing = uniqueName (expandNS csyn $ sMN 0 ("Mk" ++ (show (nsroot tyn))))
60+ uniqueName :: Name -> Idris Name
47− i <- getIState
61+ uniqueName n = do i <- getIState
62+ case lookupTyNameExact n (tt_ctxt i) of
63+ Just _ -> uniqueName (nextName n)
66+ -- | Generates the data constructor type.
67+ generateDConType :: [(Name, Plicity, PTerm)] -> [(Name, Plicity, PTerm, a)] -> PTerm
68+ generateDConType ((n, _, t) : ps) as = PPi impl (nsroot n) t (generateDConType ps as)
69+ generateDConType [] ((n, p, t, _) : as) = PPi p (nsroot n) t (generateDConType [] as)
70+ generateDConType [] [] = target
72+ -- | The target for the constructor and projection functions. Also the source of the update functions.
74+ target = PApp fc (PRef fc tyn) $ map (uncurry asPRefArg) [(p, n) | (n, p, _) <- params]
76+ paramsAndDoc :: [(Name, Plicity, PTerm, Docstring (Either Err PTerm))]
77+ paramsAndDoc = pad params paramDocs
79+ pad :: [(Name, Plicity, PTerm)] -> [(Name, Docstring (Either Err PTerm))] -> [(Name, Plicity, PTerm, Docstring (Either Err PTerm))]
80+ pad ((n, p, t) : rest) docs
81+ = let d = case lookup n docs of
83+ Nothing -> emptyDocstring
84+ in (n, p, t, d) : (pad rest docs)
87+ dconsArgDocs :: [(Name, Docstring (Either Err PTerm))]
88+ dconsArgDocs = paramDocs ++ (dcad fieldsWithName)
90+ dcad :: [(Name, Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))] -> [(Name, Docstring (Either Err PTerm))]
91+ dcad ((n, _, _, (Just d)) : rest) = (n, d) : (dcad rest)
92+ dcad (_ : rest) = dcad rest
95+ fieldsWithName :: [(Name, Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))]
96+ fieldsWithName = fwn [] fields
98+ fwn :: [Name] -> [(Maybe Name, Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))] -> [(Name, Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))]
99+ fwn ns ((n, p, t, d) : rest)
100+ = let nn = case n of
102+ Nothing -> newName ns baseName
103+ in (expandNS rsyn $ nn, p, t, d) : (fwn (nn : ns) rest)
106+ baseName = sUN "__pi_arg"
108+ newName :: [Name] -> Name -> Name
110+ | n `elem` ns = newName ns (nextName n)
113+ fieldsWithNameAndDoc :: [(Name, Plicity, PTerm, Docstring (Either Err PTerm))]
114+ fieldsWithNameAndDoc = fwnad fieldsWithName
116+ fwnad :: [(Name, Plicity, PTerm, Maybe (Docstring (Either Err PTerm)))] -> [(Name, Plicity, PTerm, Docstring (Either Err PTerm))]
117+ fwnad ((n, p, t, d) : rest)
118+ = let doc = fromMaybe emptyDocstring d
119+ in (n, p, t, doc) : (fwnad rest)
122+elabRecordFunctions :: ElabInfo ->
125+ Name -> -- ^ Record Type Name
126+ [(Name, Plicity, PTerm, Docstring (Either Err PTerm))] -> -- ^ Parameters
127+ [(Name, Plicity, PTerm, Docstring (Either Err PTerm))]-> -- ^ Fields
128+ Name -> -- ^ Constructor Name
129+ PTerm -> -- ^ Target Type
131+elabRecordFunctions info rsyn fc tyn params fields dconName target
132+ = do logLvl 1 $ "Elaborating helper functions for record " ++ show tyn
134+ iLOG $ "Fields: " ++ show fieldNames
135+ iLOG $ "Params: " ++ show paramNames
49 -- The elaborated constructor type for the data declaration
136 -- The elaborated constructor type for the data declaration
50 ttConsTy <-
138 ttConsTy <-
51 case lookupTyExact dconName (tt_ctxt i) of
139 case lookupTyExact dconName (tt_ctxt i) of
52 Just as -> return as
140 Just as -> return as
@@ -54,15 +142,17 @@ elabRecord info doc rsyn fc opts tyn params paramDocs fields fieldDocs cname cdo
55 -- The arguments to the constructor
143 -- The arguments to the constructor
56 let constructorArgs = getArgTys ttConsTy
144 let constructorArgs = getArgTys ttConsTy
145+ iLOG $ "Cons args: " ++ show constructorArgs
146+ iLOG $ "Free fields: " ++ show (filter (not . isFieldOrParam') constructorArgs)
57 -- If elaborating the constructor has resulted in some new implicit fields we make projection functions for them.
147 -- If elaborating the constructor has resulted in some new implicit fields we make projection functions for them.
58 let freeFieldsForElab = map (freeField i) (filter (not . isFieldOrParam') constructorArgs)
148 let freeFieldsForElab = map (freeField i) (filter (not . isFieldOrParam') constructorArgs)
60 -- The parameters for elaboration with their documentation
150 -- The parameters for elaboration with their documentation
61 -- Parameter functions are all prefixed with "param_".
151 -- Parameter functions are all prefixed with "param_".
62− let paramsForElab = [((nsroot n), (paramName n), impl, t, d) | (n, t, d) <- zipParams i params paramDocs]
152+ let paramsForElab = [((nsroot n), (paramName n), impl, t, d) | (n, _, t, d) <- params] -- zipParams i params paramDocs]
64 -- The fields (written by the user) with their documentation.
154 -- The fields (written by the user) with their documentation.
65− let userFieldsForElab = [((nsroot n), n, p, t, d) | ((n, p, t), (_, d)) <- zip fields fieldDocs]
155+ let userFieldsForElab = [((nsroot n), n, p, t, d) | (n, p, t, d) <- fields]
67 -- All things we need to elaborate projection functions for, together with a number denoting their position in the constructor.
157 -- All things we need to elaborate projection functions for, together with a number denoting their position in the constructor.
68 let projectors = [(n, n', p, t, d, i) | ((n, n', p, t, d), i) <- zip (freeFieldsForElab ++ paramsForElab ++ userFieldsForElab) [0..]]
158 let projectors = [(n, n', p, t, d, i) | ((n, n', p, t, d), i) <- zip (freeFieldsForElab ++ paramsForElab ++ userFieldsForElab) [0..]]
@@ -78,46 +168,16 @@ elabRecord info doc rsyn fc opts tyn params paramDocs fields fieldDocs cname cdo
78 -- Build and elaborate update functions
168 -- Build and elaborate update functions
79 elabUp dconName updaters
169 elabUp dconName updaters
81− -- | Generates a type constructor.
82− generateTyConType :: [(Name, Plicity, PTerm)] -> PTerm
83− generateTyConType ((n, p, t) : rest) = PPi p (nsroot n) t (generateTyConType rest)
84− generateTyConType [] = PType
86− -- | Generates a name for the data constructor if none was specified.
87− generateDConName :: Maybe Name -> Idris Name
88− generateDConName (Just n) = return $ expandNS csyn n
89− generateDConName Nothing = uniqueName (expandNS csyn $ sMN 0 ("Mk" ++ (show (nsroot tyn))))
91− uniqueName :: Name -> Idris Name
92− uniqueName n = do i <- getIState
93− case lookupTyNameExact n (tt_ctxt i) of
94− Just _ -> uniqueName (nextName n)
97− -- | Generates the data constructor type.
98− generateDConType :: [(Name, Plicity, PTerm)] -> [(Name, Plicity, PTerm)] -> PTerm
99− generateDConType ((n, _, t) : ps) as = PPi impl (nsroot n) t (generateDConType ps as)
100− generateDConType [] ((n, p, t) : as) = PPi p (nsroot n) t (generateDConType [] as)
101− generateDConType [] [] = target
103− -- | Creates an PArg from a plicity and a name where the term is a PRef.
104− asPRefArg :: Plicity -> Name -> PArg
105− asPRefArg p n = asArg p (nsroot n) $ PRef fc (nsroot n)
107− -- | The target for the constructor and projection functions. Also the source of the update functions.
109− target = PApp fc (PRef fc tyn) $ map (uncurry asPRefArg) [(p, n) | (n, p, t) <- params]
111 -- | Creates a PArg from a plicity and a name where the term is a Placeholder.
171 -- | Creates a PArg from a plicity and a name where the term is a Placeholder.
112 placeholderArg :: Plicity -> Name -> PArg
172 placeholderArg :: Plicity -> Name -> PArg
113 placeholderArg p n = asArg p (nsroot n) Placeholder
173 placeholderArg p n = asArg p (nsroot n) Placeholder
115 -- | Root names of all fields in the current record declarations
175 -- | Root names of all fields in the current record declarations
116 fieldNames :: [Name]
176 fieldNames :: [Name]
117− fieldNames = [nsroot n | (n, _, _) <- fields]
177+ fieldNames = [nsroot n | (n, _, _, _) <- fields]
119 paramNames :: [Name]
179 paramNames :: [Name]
120− paramNames = [nsroot n | (n, _, _) <- params]
180+ paramNames = [nsroot n | (n, _, _, _) <- params]
122 isFieldOrParam :: Name -> Bool
182 isFieldOrParam :: Name -> Bool
123 isFieldOrParam n = n `elem` (fieldNames ++ paramNames)
183 isFieldOrParam n = n `elem` (fieldNames ++ paramNames)
@@ -132,7 +192,7 @@ elabRecord info doc rsyn fc opts tyn params paramDocs fields fieldDocs cname cdo
132 isField' (n, _, _, _, _, _) = isField n
192 isField' (n, _, _, _, _, _) = isField n
134 fieldTerms :: [PTerm]
194 fieldTerms :: [PTerm]
135− fieldTerms = [t | (_, _, t) <- fields]
195+ fieldTerms = [t | (_, _, t, _) <- fields]
137 -- Delabs the TT to PTerm
197 -- Delabs the TT to PTerm
138 -- This is not good.
198 -- This is not good.
@@ -186,7 +246,7 @@ elabRecord info doc rsyn fc opts tyn params paramDocs fields fieldDocs cname cdo
187 -- | A map from a field name to the other fields it depends on.
247 -- | A map from a field name to the other fields it depends on.
188 fieldDependencies :: [(Name, [Name])]
248 fieldDependencies :: [(Name, [Name])]
189− fieldDependencies = map (uncurry fieldDep) [(n, t) | (n, _, t) <- fields ++ params]
249+ fieldDependencies = map (uncurry fieldDep) [(n, t) | (n, _, t, _) <- fields ++ params]
191 fieldDep :: Name -> PTerm -> (Name, [Name])
251 fieldDep :: Name -> PTerm -> (Name, [Name])
192 fieldDep n t = ((nsroot n), paramNames ++ fieldNames `intersect` allNamesIn t)
252 fieldDep n t = ((nsroot n), paramNames ++ fieldNames `intersect` allNamesIn t)
@@ -363,3 +423,7 @@ projectInType xs = mapPT st
363 st (PRef fc n)
423 st (PRef fc n)
364 | Just pn <- lookup n xs = PApp fc (PRef fc pn) [pexp recRef]
424 | Just pn <- lookup n xs = PApp fc (PRef fc pn) [pexp recRef]
427+-- | Creates an PArg from a plicity and a name where the term is a PRef.
428+asPRefArg :: Plicity -> Name -> PArg
429+asPRefArg p n = asArg p (nsroot n) $ PRef emptyFC (nsroot n)