@@ -1,4 +1,4 @@
1−{-# LANGUAGE TypeSynonymInstances, TemplateHaskell #-}
1+{-# LANGUAGE TypeSynonymInstances #-}
3module Idris.IBC where
3module Idris.IBC where
@@ -7,17 +7,26 @@ import Core.TT
7import Core.CaseTree
7import Core.CaseTree
8import Idris.Compiler
8import Idris.Compiler
9import Idris.AbsSyntax
9import Idris.AbsSyntax
11import Data.Binary
12import Data.Binary
12import Data.List
13import Data.List
14+import Data.ByteString.Lazy as B hiding (length, elem)
13−import Data.DeriveTH
15+-- import Data.DeriveTH
14import Control.Monad
16import Control.Monad
17+import Control.Monad.State hiding (get, put)
18+import System.FilePath
19+import System.Posix.Files
16ibcVersion :: Word8
23ibcVersion :: Word8
17−ibcVersion = 1
24+ibcVersion = 3
19data IBCFile = IBCFile { ver :: Word8,
26data IBCFile = IBCFile { ver :: Word8,
27+ sourcefile :: FilePath,
20 ibc_imports :: [FilePath],
28 ibc_imports :: [FilePath],
29+ ibc_implicits :: [(Name, [PArg])],
21 ibc_fixes :: [FixDecl],
30 ibc_fixes :: [FixDecl],
22 ibc_statics :: [(Name, [Bool])],
31 ibc_statics :: [(Name, [Bool])],
23 ibc_classes :: [(Name, ClassInfo)],
32 ibc_classes :: [(Name, ClassInfo)],
@@ -27,59 +36,906 @@ data IBCFile = IBCFile { ver :: Word8,
27 ibc_libs :: [String],
36 ibc_libs :: [String],
28 ibc_hdrs :: [String],
37 ibc_hdrs :: [String],
29 ibc_defs :: [(Name, Def)] }
38 ibc_defs :: [(Name, Def)] }
40+deriving instance Binary IBCFile
31initIBC :: IBCFile
43initIBC :: IBCFile
32−initIBC = IBCFile ibcVersion [] [] [] [] [] [] [] [] [] []
44+initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] []
34loadIBC :: FilePath -> Idris ()
46loadIBC :: FilePath -> Idris ()
35−loadIBC fp = fail "Not implemented"
47+loadIBC fp = do iLOG $ "Loading ibc " ++ fp
48+ ibcf <- lift $ (decodeFile fp :: IO IBCFile)
37−writeIBC :: FilePath -> Idris ()
51+writeIBC :: FilePath -> FilePath -> Idris ()
38−writeIBC f
52+writeIBC src f
39 = do iLOG $ "Writing ibc " ++ show f
53 = do iLOG $ "Writing ibc " ++ show f
40 i <- getIState
54 i <- getIState
41 case idris_metavars i \\ primDefs of
55 case idris_metavars i \\ primDefs of
42 (_:_) -> fail "Can't write ibc when there are unsolve metavariables"
56 (_:_) -> fail "Can't write ibc when there are unsolve metavariables"
43 [] -> return ()
57 [] -> return ()
58+ ibcf <- mkIBC (ibc_write i) (initIBC { sourcefile = src })
59+ lift $ encodeFile f ibcf
46−$( derive makeBinary ''IBCFile )
63+mkIBC :: [IBCWrite] -> IBCFile -> Idris IBCFile
47−$( derive makeBinary ''PTerm )
64+mkIBC [] f = return f
48−$( derive makeBinary ''Raw )
65+mkIBC (i:is) f = do ist <- getIState
49−$( derive makeBinary ''PTactic' )
66+ logLvl 5 $ show i ++ " " ++ show (Data.List.length is)
50−$( derive makeBinary ''PDo' )
67+ f' <- ibc ist i f
51−$( derive makeBinary ''PArg' )
68+ mkIBC is f'
52−$( derive makeBinary ''ClassInfo )
69+
53−$( derive makeBinary ''Plicity )
70+ibc i (IBCFix d) f = return f { ibc_fixes = d : ibc_fixes f }
54−$( derive makeBinary ''FC )
71+ibc i (IBCImp n) f = case lookupCtxt Nothing n (idris_implicits i) of
55−$( derive makeBinary ''Syntax )
72+ [v] -> return f { ibc_implicits = (n,v): ibc_implicits f }
56−$( derive makeBinary ''SynContext )
73+ _ -> fail "IBC write failed"
57−$( derive makeBinary ''SSymbol )
74+ibc i (IBCStatic n) f
58−$( derive makeBinary ''Static )
75+ = case lookupCtxt Nothing n (idris_statics i) of
59−$( derive makeBinary ''Fixity )
76+ [v] -> return f { ibc_statics = (n,v): ibc_statics f }
60−$( derive makeBinary ''FixDecl )
77+ _ -> fail "IBC write failed"
61−
78+ibc i (IBCClass n) f
62−$( derive makeBinary ''Def )
79+ = case lookupCtxt Nothing n (idris_classes i) of
63−$( derive makeBinary ''SC )
80+ [v] -> return f { ibc_classes = (n,v): ibc_classes f }
64−$( derive makeBinary ''CaseAlt )
81+ _ -> fail "IBC write failed"
65−$( derive makeBinary ''NameType )
82+ibc i (IBCSyntax n) f = return f { ibc_syntax = n : ibc_syntax f }
66−$( derive makeBinary ''Name )
83+ibc i (IBCKeyword n) f = return f { ibc_keywords = n : ibc_keywords f }
67−$( derive makeBinary ''Binder )
84+ibc i (IBCImport n) f = return f { ibc_imports = n : ibc_imports f }
68−$( derive makeBinary ''TT )
85+ibc i (IBCObj n) f = return f { ibc_objs = n : ibc_objs f }
69−$( derive makeBinary ''Const )
86+ibc i (IBCLib n) f = return f { ibc_libs = n : ibc_libs f }
70−
87+ibc i (IBCHeader n) f = return f { ibc_hdrs = n : ibc_hdrs f }
71−-- We need this for serialising Def. Fortunately, it never gets used because
88+ibc i (IBCDef n) f = case lookupDef Nothing n (tt_ctxt i) of
72−-- we'll never serialise a primitive operator
89+ [v] -> return f { ibc_defs = (n,v): ibc_defs f }
73−
90+ _ -> fail "IBC write failed"
74−instance Binary (a -> b) where
91+
75− put x = return ()
92+process :: IBCFile -> FilePath -> Idris ()
76− get = undefined
93+process i fn
77−
94+ | ver i /= ibcVersion = do iLOG "ibc out of date"
78−-- We assume that universe levels have been checked, so anything external
95+ fail "Incorrect ibc version"
79−-- can just have the same universe variable and we won't get any new
96+ | otherwise =
80−-- cycles.
97+ do lift $ timestampOlder (sourcefile i) fn
81−
98+ pImports (ibc_imports i)
82−instance Binary UExp where
99+ pImps (ibc_implicits i)
83− put x = return ()
100+ pFixes (ibc_fixes i)
84− get = return (UVar (-1))
101+ pStatics (ibc_statics i)
102+ pClasses (ibc_classes i)
103+ pSyntax (ibc_syntax i)
104+ pKeywords (ibc_keywords i)
110+timestampOlder :: FilePath -> FilePath -> IO ()
111+timestampOlder src ibc = do srcs <- getFileStatus src
112+ ibcs <- getFileStatus ibc
113+ if (modificationTime srcs > modificationTime ibcs)
114+ then fail "Needs reloading"
117+pImports :: [FilePath] -> Idris ()
119+ = do datadir <- lift $ getDataDir
120+ mapM_ (\f -> do fp <- lift $ findImport [".", datadir] f
122+ if (f `elem` imported i)
123+ then iLOG $ "Already read " ++ f
124+ else do putIState (i { imported = f : imported i })
126+ IDR fn -> do iLOG $ "Failed at " ++ fn
127+ fail "Must be an ibc"
128+ IBC fn src -> loadIBC fn)
131+pImps :: [(Name, [PArg])] -> Idris ()
132+pImps imps = mapM_ (\ (n, imp) ->
134+ putIState (i { idris_implicits
135+ = addDef n imp (idris_implicits i) }))
138+pFixes :: [FixDecl] -> Idris ()
139+pFixes f = do i <- getIState
140+ putIState (i { idris_infixes = f ++ idris_infixes i })
142+pStatics :: [(Name, [Bool])] -> Idris ()
143+pStatics ss = mapM_ (\ (n, s) ->
145+ putIState (i { idris_statics
146+ = addDef n s (idris_statics i) }))
149+pClasses :: [(Name, ClassInfo)] -> Idris ()
150+pClasses cs = mapM_ (\ (n, c) ->
152+ putIState (i { idris_classes
153+ = addDef n c (idris_classes i) }))
156+pSyntax :: [Syntax] -> Idris ()
157+pSyntax s = do i <- getIState
158+ putIState (i { syntax_rules = s ++ syntax_rules i })
160+pKeywords :: [String] -> Idris ()
161+pKeywords k = do i <- getIState
162+ putIState (i { syntax_keywords = k ++ syntax_keywords i })
164+pObjs :: [FilePath] -> Idris ()
165+pObjs os = mapM_ addObjectFile os
167+pLibs :: [String] -> Idris ()
168+pLibs ls = mapM_ addLib ls
170+pHdrs :: [String] -> Idris ()
171+pHdrs hs = mapM_ addHdr hs
173+pDefs :: [(Name, Def)] -> Idris ()
174+pDefs ds = mapM_ (\ (n, d) ->
176+ putIState (i { tt_ctxt = addCtxtDef n d (tt_ctxt i) }))
180+----- Generated by 'derive'
183+instance Binary FC where
193+instance Binary Name where
196+ UN x1 -> do putWord8 0
198+ NS x1 x2 -> do putWord8 1
201+ MN x1 x2 -> do putWord8 2
215+ _ -> error "Corrupted binary data for Name"
218+instance Binary Const where
221+ I x1 -> do putWord8 0
223+ BI x1 -> do putWord8 1
225+ Fl x1 -> do putWord8 2
227+ Ch x1 -> do putWord8 3
229+ Str x1 -> do putWord8 4
232+ BIType -> putWord8 6
233+ FlType -> putWord8 7
234+ ChType -> putWord8 8
235+ StrType -> putWord8 9
236+ PtrType -> putWord8 10
255+ 10 -> return PtrType
256+ _ -> error "Corrupted binary data for Const"
259+instance Binary Raw where
262+ Var x1 -> do putWord8 0
264+ RBind x1 x2 x3 -> do putWord8 1
268+ RApp x1 x2 -> do putWord8 2
272+ RConstant x1 -> do putWord8 4
282+ return (RBind x1 x2 x3)
288+ return (RConstant x1)
289+ _ -> error "Corrupted binary data for Raw"
292+instance (Binary b) => Binary (Binder b) where
295+ Lam x1 -> do putWord8 0
297+ Pi x1 -> do putWord8 1
299+ Let x1 x2 -> do putWord8 2
302+ NLet x1 x2 -> do putWord8 3
305+ Hole x1 -> do putWord8 4
307+ GHole x1 -> do putWord8 5
309+ Guess x1 x2 -> do putWord8 6
312+ PVar x1 -> do putWord8 7
314+ PVTy x1 -> do putWord8 8
335+ return (Guess x1 x2)
340+ _ -> error "Corrupted binary data for Binder"
343+instance Binary NameType where
348+ DCon x1 x2 -> do putWord8 2
351+ TCon x1 x2 -> do putWord8 3
365+ _ -> error "Corrupted binary data for NameType"
368+instance (Binary n) => Binary (TT n) where
371+ P x1 x2 x3 -> do putWord8 0
375+ V x1 -> do putWord8 1
377+ Bind x1 x2 x3 -> do putWord8 2
381+ App x1 x2 -> do putWord8 3
384+ Constant x1 -> do putWord8 4
386+ Set x1 -> do putWord8 5
400+ return (Bind x1 x2 x3)
405+ return (Constant x1)
408+ _ -> error "Corrupted binary data for TT"
411+instance Binary SC where
414+ Case x1 x2 -> do putWord8 0
417+ STerm x1 -> do putWord8 1
419+ UnmatchedCase x1 -> do putWord8 2
430+ return (UnmatchedCase x1)
431+ _ -> error "Corrupted binary data for SC"
434+instance Binary CaseAlt where
437+ ConCase x1 x2 x3 x4 -> do putWord8 0
442+ ConstCase x1 x2 -> do putWord8 1
445+ DefaultCase x1 -> do putWord8 2
454+ return (ConCase x1 x2 x3 x4)
457+ return (ConstCase x1 x2)
459+ return (DefaultCase x1)
460+ _ -> error "Corrupted binary data for CaseAlt"
463+instance Binary Def where
466+ Function x1 x2 -> do putWord8 0
469+ TyDecl x1 x2 -> do putWord8 1
472+ Operator x1 x2 x3 -> do putWord8 2
476+ CaseOp x1 x2 x3 x4 x5 -> do putWord8 3
487+ return (Function x1 x2)
490+ return (TyDecl x1 x2)
494+ return (Operator x1 x2 x3)
500+ return (CaseOp x1 x2 x3 x4 x5)
501+ _ -> error "Corrupted binary data for Def"
504+instance Binary IBCFile where
505+ put (IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13)
521+ if x1 == ibcVersion then
534+ return (IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13)
535+ else return (initIBC { ver = x1 })
537+instance Binary Fixity where
540+ Infixl x1 -> do putWord8 0
542+ Infixr x1 -> do putWord8 1
544+ InfixN x1 -> do putWord8 2
546+ PrefixN x1 -> do putWord8 3
559+ _ -> error "Corrupted binary data for Fixity"
562+instance Binary FixDecl where
572+instance Binary Static where
575+ Static -> putWord8 0
576+ Dynamic -> putWord8 1
582+ _ -> error "Corrupted binary data for Static"
585+instance Binary Plicity where
588+ Imp x1 x2 -> do putWord8 0
591+ Exp x1 x2 -> do putWord8 1
594+ Constraint x1 x2 -> do putWord8 2
608+ return (Constraint x1 x2)
609+ _ -> error "Corrupted binary data for Plicity"
612+instance Binary PTerm where
615+ PQuote x1 -> do putWord8 0
617+ PRef x1 x2 -> do putWord8 1
620+ PLam x1 x2 x3 -> do putWord8 2
624+ PPi x1 x2 x3 x4 -> do putWord8 3
629+ PLet x1 x2 x3 x4 -> do putWord8 4
634+ PApp x1 x2 x3 -> do putWord8 5
638+ PTrue x1 -> do putWord8 6
640+ PFalse x1 -> do putWord8 7
642+ PRefl x1 -> do putWord8 8
644+ PResolveTC x1 -> do putWord8 9
646+ PEq x1 x2 x3 -> do putWord8 10
650+ PPair x1 x2 x3 -> do putWord8 11
654+ PDPair x1 x2 x3 x4 -> do putWord8 12
659+ PAlternative x1 -> do putWord8 13
661+ PHidden x1 -> do putWord8 14
664+ PConstant x1 -> do putWord8 16
666+ Placeholder -> putWord8 17
667+ PDoBlock x1 -> do putWord8 18
669+ PReturn x1 -> do putWord8 19
671+ PMetavar x1 -> do putWord8 20
673+ PProof x1 -> do putWord8 21
675+ PTactics x1 -> do putWord8 22
677+ PElabError x1 -> do putWord8 23
679+ PImpossible -> putWord8 24
691+ return (PLam x1 x2 x3)
696+ return (PPi x1 x2 x3 x4)
701+ return (PLet x1 x2 x3 x4)
705+ return (PApp x1 x2 x3)
713+ return (PResolveTC x1)
717+ return (PEq x1 x2 x3)
721+ return (PPair x1 x2 x3)
726+ return (PDPair x1 x2 x3 x4)
728+ return (PAlternative x1)
733+ return (PConstant x1)
734+ 17 -> return Placeholder
736+ return (PDoBlock x1)
740+ return (PMetavar x1)
744+ return (PTactics x1)
746+ return (PElabError x1)
747+ 24 -> return PImpossible
748+ _ -> error "Corrupted binary data for PTerm"
751+instance (Binary t) => Binary (PTactic' t) where
754+ Intro x1 -> do putWord8 0
756+ Focus x1 -> do putWord8 1
758+ Refine x1 x2 -> do putWord8 2
761+ Rewrite x1 -> do putWord8 3
763+ LetTac x1 x2 -> do putWord8 4
766+ Exact x1 -> do putWord8 5
768+ Compute -> putWord8 6
769+ Trivial -> putWord8 7
771+ Attack -> putWord8 9
772+ ProofState -> putWord8 10
773+ ProofTerm -> putWord8 11
775+ Try x1 x2 -> do putWord8 13
778+ TSeq x1 x2 -> do putWord8 14
791+ return (Refine x1 x2)
796+ return (LetTac x1 x2)
803+ 10 -> return ProofState
804+ 11 -> return ProofTerm
813+ _ -> error "Corrupted binary data for PTactic'"
816+instance (Binary t) => Binary (PDo' t) where
819+ DoExp x1 x2 -> do putWord8 0
822+ DoBind x1 x2 x3 -> do putWord8 1
826+ DoLet x1 x2 x3 -> do putWord8 2
835+ return (DoExp x1 x2)
839+ return (DoBind x1 x2 x3)
843+ return (DoLet x1 x2 x3)
844+ _ -> error "Corrupted binary data for PDo'"
847+instance (Binary t) => Binary (PArg' t) where
850+ PImp x1 x2 x3 x4 -> do putWord8 0
855+ PExp x1 x2 x3 -> do putWord8 1
859+ PConstraint x1 x2 x3 -> do putWord8 2
870+ return (PImp x1 x2 x3 x4)
874+ return (PExp x1 x2 x3)
878+ return (PConstraint x1 x2 x3)
879+ _ -> error "Corrupted binary data for PArg'"
882+instance Binary ClassInfo where
883+ put (CI x1 x2 x3 x4)
893+ return (CI x1 x2 x3 x4)
896+instance Binary SynContext where
899+ PatternSyntax -> putWord8 0
900+ TermSyntax -> putWord8 1
901+ AnySyntax -> putWord8 2
905+ 0 -> return PatternSyntax
906+ 1 -> return TermSyntax
907+ 2 -> return AnySyntax
908+ _ -> error "Corrupted binary data for SynContext"
911+instance Binary Syntax where
920+ return (Rule x1 x2 x3)
923+instance Binary SSymbol where
926+ Keyword x1 -> do putWord8 0
928+ Symbol x1 -> do putWord8 1
930+ Expr x1 -> do putWord8 2
941+ _ -> error "Corrupted binary data for SSymbol"