on master help sign in
Added new (co)record syntax.
commit173703d2b7468f27da988b5576cf844c0b0f5d88 authorSune Alkærsig <sual@itu.dk> dateThu 19 Feb 2015, 11:57 (12 years ago) parente13e48d
8 files changed+197−39
src/Idris/AbsSyntax.hs+3−3 src/Idris/AbsSyntaxTree.hs+6−5 src/Idris/DeepSeq.hs+2−2 src/Idris/Elab/Record.hs+53−14 src/Idris/ElabDecls.hs+2−2 src/Idris/IBC.hs+4−2 src/Idris/ParseData.hs+125−9 src/Idris/ParseHelpers.hs+2−2
src/Idris/AbsSyntax.hs+3−3
@@ -1050,12 +1050,12 @@ expandParamsD rhs ist dec ps ns (PData doc argDocs syn fc co pd)
10501050 else PDatadecl n (expandParams dec ps ns [] ty) (map econ cons)
10511051 econ (doc, argDocs, n, t, fc, fs)
10521052 = (doc, argDocs, dec n, piBindp expl ps (expandParams dec ps ns [] t), fc, fs)
1053−expandParamsD rhs ist dec ps ns (PRecord doc syn fc tn tty opts cdoc cn cty)
1053+expandParamsD rhs ist dec ps ns (PRecord doc syn fc tn tty opts cdoc cn args cty)
10541054 = if tn `elem` ns
10551055 then PRecord doc syn fc (dec tn) (piBind ps (expandParams dec ps ns [] tty))
1056− opts cdoc (dec cn) conty
1056+ opts cdoc (liftM dec cn) args conty
10571057 else PRecord doc syn fc (dec tn) (expandParams dec ps ns [] tty)
1058− opts cdoc (dec cn) conty
1058+ opts cdoc (liftM dec cn) args conty
10591059 where conty = piBindp expl ps (expandParams dec ps ns [] cty)
10601060expandParamsD rhs ist dec ps ns (PParams f params pds)
10611061 = PParams f (ps ++ map (mapsnd (expandParams dec ps ns [])) params)
src/Idris/AbsSyntaxTree.hs+6−5
@@ -586,7 +586,7 @@ data PDecl' t
586586 | PData (Docstring (Either Err PTerm)) [(Name, Docstring (Either Err PTerm))] SyntaxInfo FC DataOpts (PData' t) -- ^ Data declaration.
587587 | PParams FC [(Name, t)] [PDecl' t] -- ^ Params block
588588 | PNamespace String [PDecl' t] -- ^ New namespace
589− | PRecord (Docstring (Either Err PTerm)) SyntaxInfo FC Name t DataOpts (Docstring (Either Err PTerm)) Name t -- ^ Record declaration
589+ | PRecord (Docstring (Either Err PTerm)) SyntaxInfo FC Name t DataOpts (Docstring (Either Err PTerm)) (Maybe Name) [(Name, Plicity)] t -- ^ Record declaration
590590 | PClass (Docstring (Either Err PTerm)) SyntaxInfo FC
591591 [(Name, t)] -- constraints
592592 Name
@@ -680,13 +680,14 @@ declared (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
680680declared (PData _ _ _ _ _ (PLaterdecl n _)) = [n]
681681declared (PParams _ _ ds) = concatMap declared ds
682682declared (PNamespace _ ds) = concatMap declared ds
683−declared (PRecord _ _ _ n _ _ _ c _) = [n, c]
683+declared (PRecord _ _ _ n _ _ _ (Just c) _ _) = [n, c]
684684declared (PClass _ _ _ _ n _ _ ms) = n : concatMap declared ms
685685declared (PInstance _ _ _ _ _ _ _ _) = []
686686declared (PDSL n _) = [n]
687687declared (PSyntax _ _) = []
688688declared (PMutual _ ds) = concatMap declared ds
689689declared (PDirective _) = []
690+declared _ = []
690691
691692-- get the names declared, not counting nested parameter blocks
692693tldeclared :: PDecl -> [Name]
@@ -694,7 +695,7 @@ tldeclared (PFix _ _ _) = []
694695tldeclared (PTy _ _ _ _ _ n t) = [n]
695696tldeclared (PPostulate _ _ _ _ n t) = [n]
696697tldeclared (PClauses _ _ n _) = [] -- not a declaration
697−tldeclared (PRecord _ _ _ n _ _ _ c _) = [n, c]
698+tldeclared (PRecord _ _ _ n _ _ _ (Just c) _ _) = [n, c]
698699tldeclared (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
699700 where fstt (_, _, a, _, _, _) = a
700701tldeclared (PParams _ _ ds) = []
@@ -715,14 +716,14 @@ defined (PData _ _ _ _ _ (PDatadecl n _ ts)) = n : map fstt ts
715716defined (PData _ _ _ _ _ (PLaterdecl n _)) = []
716717defined (PParams _ _ ds) = concatMap defined ds
717718defined (PNamespace _ ds) = concatMap defined ds
718−defined (PRecord _ _ _ n _ _ _ c _) = [n, c]
719+defined (PRecord _ _ _ n _ _ _ (Just c) _ _) = [n, c]
719720defined (PClass _ _ _ _ n _ _ ms) = n : concatMap defined ms
720721defined (PInstance _ _ _ _ _ _ _ _) = []
721722defined (PDSL n _) = [n]
722723defined (PSyntax _ _) = []
723724defined (PMutual _ ds) = concatMap defined ds
724725defined (PDirective _) = []
725−--defined _ = []
726+defined _ = []
726727
727728updateN :: [(Name, Name)] -> Name -> Name
728729updateN ns n | Just n' <- lookup n ns = n'
src/Idris/DeepSeq.hs+2−2
@@ -144,11 +144,11 @@ instance (NFData t) => NFData (PDecl' t) where
144144 rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` ()
145145 rnf (PParams x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
146146 rnf (PNamespace x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
147− rnf (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9)
147+ rnf (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9 x10)
148148 = rnf x1 `seq`
149149 rnf x2 `seq`
150150 rnf x3 `seq`
151− rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` rnf x9 `seq` ()
151+ rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` rnf x8 `seq` rnf x9 `seq` x10 `seq` ()
152152 rnf (PClass x1 x2 x3 x4 x5 x6 x8 x7)
153153 = rnf x1 `seq`
154154 rnf x2 `seq`
src/Idris/Elab/Record.hs+53−14
@@ -17,6 +17,7 @@ import Idris.PartialEval
1717import Idris.DeepSeq
1818import Idris.Output (iputStrLn, pshow, iWarn)
1919import IRTS.Lang
20+import Idris.ParseHelpers (opChars)
2021
2122import Idris.Elab.Type
2223import Idris.Elab.Data
@@ -51,9 +52,15 @@ import Data.List.Split (splitOn)
5152import Util.Pretty(pretty, text)
5253
5354elabRecord :: ElabInfo -> SyntaxInfo -> Docstring (Either Err PTerm) -> FC -> Name ->
54− PTerm -> DataOpts -> Docstring (Either Err PTerm) -> Name -> PTerm -> Idris ()
55−elabRecord info syn doc fc tyn ty opts cdoc cn cty_in
56− = do elabData info syn doc [] fc opts (PDatadecl tyn ty [(cdoc, [], cn, cty_in, fc, [])])
55+ PTerm -> DataOpts -> Docstring (Either Err PTerm) -> Maybe Name -> [(Name, Plicity)] -> PTerm -> Idris ()
56+elabRecord info syn doc fc tyn ty opts cdoc mcn args cty_in'
57+ = do cn <- liftM (expandNS syn) (case mcn of
58+ Just cn' -> return (nsroot cn')
59+ Nothing -> if isOp tyn
60+ then generateConsNameOp
61+ else generateConsName (sUN $ "Mk" ++ (show (nsroot tyn))))
62+ cty_in <- customizeConstructor args cty_in'
63+ elabData info syn doc [] fc opts (PDatadecl tyn ty [(cdoc, [], cn, cty_in, fc, [])])
5764 -- TODO think: something more in info?
5865 cty' <- implicit info syn cn cty_in
5966 i <- getIState
@@ -94,21 +101,53 @@ elabRecord info syn doc fc tyn ty opts cdoc cn cty_in
94101 ptys
95102
96103 -- Generate projection functions
97− proj_decls <- mapM (mkProj recty_in substs cimp) (zip ptys [0..])
104+ proj_decls <- mapM (mkProj recty_in substs cimp cn) (zip ptys [0..])
98105 logLvl 3 $ show proj_decls
99106 let nonImp = mapMaybe isNonImp (zip cimp ptys_u)
100107 let implBinds = getImplB id cty'
101−
102− -- Generate update functions
103− update_decls <- mapM (mkUpdate recty_u index_names_in extraImpls
104− (getFieldNames cty')
105− implBinds (length nonImp)) (zip nonImp [0..])
106108 mapM_ (rec_elabDecl info EAll info) (concat proj_decls)
107− logLvl 3 $ show update_decls
108− mapM_ (tryElabDecl info) (update_decls)
109+ -- Generate update functions
110+ when (Codata `notElem` opts)
111+ (do update_decls <- mapM (mkUpdate recty_u index_names_in extraImpls
112+ (getFieldNames cty')
113+ implBinds (length nonImp) cn) (zip nonImp [0..])
114+ logLvl 3 $ show update_decls
115+ mapM_ (tryElabDecl info) (update_decls))
109116 where
110117-- syn = syn_in { syn_namespace = show (nsroot tyn) : syn_namespace syn_in }
111−
118+ customizeConstructor :: [(Name, Plicity)] -> PTerm -> Idris PTerm
119+ customizeConstructor [] t = return t
120+ customizeConstructor ns t = cc ns t
121+ where
122+ cc names (PPi _ n t t')
123+ | Just p <- lookup n names = do r <- cc (deleteAssoc n names) t'
124+ return $ PPi p n t r
125+ | otherwise = tclift $ tfail (At fc (Elaborating recString tyn (Msg ("Argument " ++ show n ++ " missing."))))
126+ where
127+ deleteAssoc :: Eq a => a -> [(a, b)] -> [(a, b)]
128+ deleteAssoc y (x@(z,_) : xs)
129+ | z == y = xs
130+ | otherwise = x : (deleteAssoc y xs)
131+ deleteAssoc _ [] = []
132+ cc [] t = return t
133+ cc _ _ = tclift $ tfail (At fc (Elaborating recString tyn (Msg ("Not the right of arguments to constructor. You must mention either all or none."))))
134+
135+ recString = (if Codata `elem` opts then "co" else "") ++ "record "
136+
137+ generateConsNameOp :: Idris Name
138+ generateConsNameOp = generateConsName $ sUN "Mk_Operator_Record0"
139+
140+ generateConsName :: Name -> Idris Name
141+ generateConsName n = do i <- getIState
142+ case lookupTyNameExact (expandNS syn n) (tt_ctxt i) of
143+ Just _ -> generateConsName (nextName n)
144+ Nothing -> return n
145+
146+ isOp :: Name -> Bool
147+ isOp (UN t) = foldr (||) False (map (\x -> x `elem` opChars) (str t))
148+ isOp (NS n _) = isOp n
149+ isOp _ = True
150+
112151 isNonImp (PExp _ _ _ _, a) = Just a
113152 isNonImp _ = Nothing
114153
@@ -182,7 +221,7 @@ elabRecord info syn doc fc tyn ty opts cdoc cn cty_in
182221 mkType (MN i n) = sMN i ("set_" ++ str n)
183222 mkType (NS n s) = NS (mkType n) s
184223
185− mkProj recty substs cimp ((pn_in, pty), pos)
224+ mkProj recty substs cimp cn ((pn_in, pty), pos)
186225 = do let pn = expandNS syn pn_in -- projection name
187226 -- use pn_in in the indices, consistently, to avoid clash
188227 let pfnTy = PTy emptyDocstring [] defaultSyntax fc [] pn
@@ -204,7 +243,7 @@ elabRecord info syn doc fc tyn ty opts cdoc cn cty_in
204243 -- If the 'pty' we're updating includes anything in 'substs', we're
205244 -- updating the type as well, so use recty', otherwise just use
206245 -- recty
207− mkUpdate recty inames extras fnames k num ((pn, pty), pos)
246+ mkUpdate recty inames extras fnames k num cn ((pn, pty), pos)
208247 = do let setname = expandNS syn $ mkType pn
209248 let valname = sMN 0 "updateval"
210249 let pn_out = sMN 0 (show pn ++ "_out")
src/Idris/ElabDecls.hs+2−2
@@ -236,10 +236,10 @@ elabDecl' what info (PClass doc s f cs n ps pdocs ds)
236236elabDecl' what info (PInstance s f cs n ps t expn ds)
237237 = do iLOG $ "Elaborating instance " ++ show n
238238 elabInstance info s what f cs n ps t expn ds
239−elabDecl' what info (PRecord doc s f tyn ty opts cdoc cn cty)
239+elabDecl' what info (PRecord doc s f tyn ty opts cdoc cn args cty)
240240 | what /= ETypes
241241 = do iLOG $ "Elaborating record " ++ show tyn
242− elabRecord info s doc f tyn ty opts cdoc cn cty
242+ elabRecord info s doc f tyn ty opts cdoc cn args cty
243243 | otherwise
244244 = do iLOG $ "Elaborating [type of] " ++ show tyn
245245 elabData info s doc [] f [] (PLaterdecl tyn ty)
src/Idris/IBC.hs+4−2
@@ -1201,7 +1201,7 @@ instance (Binary t) => Binary (PDecl' t) where
12011201 PNamespace x1 x2 -> do putWord8 5
12021202 put x1
12031203 put x2
1204− PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9 ->
1204+ PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 ->
12051205 do putWord8 6
12061206 put x1
12071207 put x2
@@ -1212,6 +1212,7 @@ instance (Binary t) => Binary (PDecl' t) where
12121212 put x7
12131213 put x8
12141214 put x9
1215+ put x10
12151216 PClass x1 x2 x3 x4 x5 x6 x7 x8
12161217 -> do putWord8 7
12171218 put x1
@@ -1292,7 +1293,8 @@ instance (Binary t) => Binary (PDecl' t) where
12921293 x7 <- get
12931294 x8 <- get
12941295 x9 <- get
1295− return (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9)
1296+ x10 <- get
1297+ return (PRecord x1 x2 x3 x4 x5 x6 x7 x8 x9 x10)
12961298 7 -> do x1 <- get
12971299 x2 <- get
12981300 x3 <- get
src/Idris/ParseData.hs+125−9
@@ -37,6 +37,9 @@ import qualified Data.ByteString.UTF8 as UTF8
3737
3838import Debug.Trace
3939
40+type Docs = Docstring (Either Err PTerm)
41+type RecordConstructor = (Docs, [(Name, Docs)], Maybe Name, PTerm, [(Name, Plicity)])
42+
4043{- |Parses a record type declaration
4144Record ::=
4245 DocComment Accessibility? 'record' FnName TypeSig 'where' OpenBlock Constructor KeepTerminator CloseBlock;
@@ -50,23 +53,29 @@ record syn = do (doc, argDocs, acc, opts) <- try (do
5053 | (n, d) <- argDocs ]
5154 acc <- optional accessibility
5255 opts <- dataOpts []
53− reserved "record"
54− return (doc', argDocs', acc, opts))
56+ co <- recordI
57+ return (doc', argDocs', acc, opts ++ co))
5558 fc <- getFC
56− tyn_in <- fnName
57− lchar ':'
58− ty <- typeExpr (allowImp syn)
59+ tyn_in <- fnName
60+ tys <- manyTill (recordTypeParameter syn) (reserved "where")
61+ let ty = recordTypeConstructor tys
62+ let ty' = withoutNames ty
5963 let tyn = expandNS syn tyn_in
60− reserved "where"
61− (cdoc, cargDocs, cn, cty, _, _) <- indentedBlockS (constructor syn)
62− accData acc tyn [cn]
64+ (cdoc, cargDocs, cn, cty, args) <- indentedBlockS $ agdaStyleBody syn tyn ty
65+ case cn of
66+ Just cn' -> accData acc tyn [cn']
67+ Nothing -> return ()
6368 let rsyn = syn { syn_namespace = show (nsroot tyn) :
6469 syn_namespace syn }
6570 let fns = getRecNames rsyn cty
6671 mapM_ (\n -> addAcc n acc) fns
67− return $ PRecord doc rsyn fc tyn ty opts cdoc cn cty
72+ return $ PRecord doc rsyn fc tyn ty' opts cdoc cn args cty
6873 <?> "record type declaration"
6974 where
75+ withoutNames :: PTerm -> PTerm
76+ withoutNames (PPi p _ t sc) = PPi p (sUN "__pi_arg") t (withoutNames sc)
77+ withoutNames t = t
78+
7079 getRecNames :: SyntaxInfo -> PTerm -> [Name]
7180 getRecNames syn (PPi _ n _ sc) = [expandNS syn n, expandNS syn (mkType n)]
7281 ++ getRecNames syn sc
@@ -76,6 +85,109 @@ record syn = do (doc, argDocs, acc, opts) <- try (do
7685 toFreeze (Just Frozen) = Just Hidden
7786 toFreeze x = x
7887
88+ recordTypeConstructor :: [(Name, Plicity, PTerm)] -> PTerm
89+ recordTypeConstructor ((n, p, t) : rest) = PPi p n t (recordTypeConstructor rest)
90+ recordTypeConstructor [] = PType
91+
92+ -- Greatly inspired by ziman (https://github.com/ziman)
93+ agdaStyleBody :: SyntaxInfo -> Name -> PTerm -> IdrisParser RecordConstructor
94+ agdaStyleBody syn tyn tyc = do
95+ ist <- get
96+ fc <- getFC
97+
98+ fields <- many . indented $ field
99+
100+ let constructorDoc = parseDocstring . T.pack $ "Constructor of " ++ show tyn
101+ (constructorName, args) <- do c <- optional constructor
102+ let (n, args) = maybePair c
103+ return (n, mList args)
104+
105+ let constructorDoc' = annotate syn ist constructorDoc
106+ let fieldDocs = [(n, annotate syn ist doc) | (n, _, _, doc, _) <- fields]
107+ target = PApp fc (PRef fc tyn) (getParams fc tyc)
108+ constructorType = mkConstructorType [(n, t, p) | (n, t, p, _, _) <- fields] target
109+ constructorType' = replaceTarget constructorType (allImpl tyc)
110+
111+ return (constructorDoc', fieldDocs, constructorName, constructorType', args)
112+ where
113+ maybePair :: Maybe (a, b) -> (Maybe a, Maybe b)
114+ maybePair (Just(x, y)) = (Just x, Just y)
115+ maybePair Nothing = (Nothing, Nothing)
116+
117+ mList :: Maybe [a] -> [a]
118+ mList (Just xs) = xs
119+ mList Nothing = []
120+
121+ fieldsAndConstructor :: IdrisParser ([(Name, PTerm, Plicity, Docstring (), [(Name, Docstring ())])], (Maybe Name), [(Name, Plicity)])
122+ fieldsAndConstructor = do fields <- (indented field) `manyTill` (reserved "constructor")
123+ (cName, args) <- indented constructor
124+ return (fields, Just cName, args)
125+
126+ allImpl :: PTerm -> PTerm
127+ allImpl (PPi _ n t t') = PPi impl n t (allImpl t')
128+ allImpl t = t
129+
130+ field :: IdrisParser (Name, PTerm, Plicity, Docstring (), [(Name, Docstring ())])
131+ field = do (doc, argDocs) <- option noDocs docComment
132+ n <- fnName
133+ lchar ':'
134+ t <- typeExpr (allowImp syn)
135+ return (n, t, expl, doc, argDocs)
136+
137+ constructor :: IdrisParser (Name, [(Name, Plicity)])
138+ constructor = do n <- (reserved "constructor") *> fnName
139+ args <- option [] (do lchar '('
140+ args <- many (do p <- optional $ lchar '{'
141+ argName <- fnName
142+ plicity <- endPlicity p
143+ return (argName, plicity))
144+ lchar ')'
145+ return args)
146+ return (n, args)
147+
148+ endPlicity :: Maybe Char -> IdrisParser Plicity
149+ endPlicity (Just _) = do lchar '}'
150+ return impl
151+ endPlicity Nothing = return expl
152+
153+ mkConstructorType :: [(Name, PTerm, Plicity)] -> PTerm -> PTerm
154+ mkConstructorType ((n, t, p) : rest) t' = PPi p (nsroot n) t (mkConstructorType rest t')
155+ mkConstructorType [] t = t
156+
157+ getParams :: FC -> PTerm -> [PArg]
158+ getParams fc (PPi (Exp os _ _) n t ts) = (PExp 0 os n $ PRef fc n) : getParams fc ts
159+ getParams fc (PPi (Imp os _ _ _) n t ts) = (PImp 0 False os n $ PRef fc n) : getParams fc ts
160+ getParams _ _ = []
161+
162+ annotate :: SyntaxInfo -> IState -> Docstring () -> Docstring (Either Err PTerm)
163+ annotate syn ist = annotCode $ tryFullExpr syn ist
164+
165+ replaceTarget :: PTerm -> PTerm -> PTerm
166+ replaceTarget trg (PPi p n t ts) = PPi p n t (replaceTarget trg ts)
167+ replaceTarget trg _ = trg
168+
169+recordTypeParameter :: SyntaxInfo -> IdrisParser (Name, Plicity, PTerm)
170+recordTypeParameter syn =
171+ (do lchar '('
172+ (n, pt) <- (namedTy syn <|> onlyName syn)
173+ lchar ')'
174+ return (n, expl, pt))
175+ <|>
176+ (do (n, pt) <- onlyName syn
177+ return (n, expl, pt))
178+
179+ where
180+ namedTy :: SyntaxInfo -> IdrisParser (Name, PTerm)
181+ namedTy syn =
182+ do tyn <- fnName
183+ lchar ':'
184+ ty <- typeExpr (allowImp syn)
185+ return (tyn, ty)
186+ onlyName :: SyntaxInfo -> IdrisParser (Name, PTerm)
187+ onlyName syn =
188+ do n <- fnName
189+ return (n, PType)
190+
79191{- | Parses data declaration type (normal or codata)
80192DataI ::= 'data' | 'codata';
81193-}
@@ -83,6 +195,10 @@ dataI :: IdrisParser DataOpts
83195dataI = do reserved "data"; return []
84196 <|> do reserved "codata"; return [Codata]
85197
198+recordI :: IdrisParser DataOpts
199+recordI = do reserved "record"; return []
200+ <|> do reserved "corecord"; return [Codata]
201+
86202{- | Parses if a data should not have a default eliminator
87203DefaultEliminator ::= 'noelim'?
88204 -}
src/Idris/ParseHelpers.hs+2−2
@@ -226,14 +226,14 @@ idrisStyle = IdentifierStyle _styleName _styleStart _styleLetter _styleReserved
226226 where _styleName = "Idris"
227227 _styleStart = satisfy isAlpha
228228 _styleLetter = satisfy isAlphaNum <|> oneOf "_'."
229− _styleReserved = HS.fromList ["let", "in", "data", "codata", "record", "Type",
229+ _styleReserved = HS.fromList ["let", "in", "data", "codata", "record", "corecord", "Type",
230230 "do", "dsl", "import", "impossible",
231231 "case", "of", "total", "partial", "mutual",
232232 "infix", "infixl", "infixr", "rewrite",
233233 "where", "with", "syntax", "proof", "postulate",
234234 "using", "namespace", "class", "instance", "parameters",
235235 "public", "private", "abstract", "implicit",
236− "quoteGoal"]
236+ "quoteGoal", "constructor"]
237237
238238char :: MonadicParsing m => Char -> m Char
239239char = Chr.char