@@ -18,6 +18,7 @@ import Idris.Core.Typecheck (check, recheck)
18import Idris.ErrReverse (errReverse)
18import Idris.ErrReverse (errReverse)
19import Idris.ElabQuasiquote (extractUnquotes)
19import Idris.ElabQuasiquote (extractUnquotes)
20import Idris.Elab.Utils
20import Idris.Elab.Utils
21+import Idris.Reflection
21import qualified Util.Pretty as U
22import qualified Util.Pretty as U
23import Control.Applicative ((<$>))
24import Control.Applicative ((<$>))
@@ -36,6 +37,32 @@ import Debug.Trace
36data ElabMode = ETyDecl | ELHS | ERHS
37data ElabMode = ETyDecl | ELHS | ERHS
37 deriving Eq
38 deriving Eq
41+ ElabResult { resultTerm :: Term -- ^ The term resulting from elaboration
42+ , resultMetavars :: [(Name, (Int, Maybe Name, Type))]
43+ -- ^ Information about new metavariables
44+ , resultCaseDecls :: [PDecl]
45+ -- ^ Deferred declarations as the meaning of case blocks
46+ , resultContext :: Context
47+ -- ^ The potentially extended context from new definitions
48+ , resultTyDecls :: [(Name, FC, [PArg], Type)]
49+ -- ^ Meta-info about the new type declarations
52+processTacticDecls :: [(Name, FC, [PArg], Type)] -> Idris ()
53+processTacticDecls info =
54+ forM_ info $ \(n, fc, impls, ty) ->
55+ do logLvl 3 $ "Declaration from tactics: " ++ show n ++ " : " ++ show ty
56+ logLvl 3 $ " It has impls " ++ show impls
57+ updateIState $ \i -> i { idris_implicits =
58+ addDef n impls (idris_implicits i) }
60+ ds <- checkDef fc [(n, (-1, Nothing, ty))]
62+ let ds' = map (\(n, (i, top, t)) -> (n, (i, top, t, True))) ds
39-- Using the elaborator, convert a term in raw syntax to a fully
66-- Using the elaborator, convert a term in raw syntax to a fully
40-- elaborated, typechecked term.
67-- elaborated, typechecked term.
@@ -45,7 +72,7 @@ data ElabMode = ETyDecl | ELHS | ERHS
45-- Also find deferred names in the term and their types
72-- Also find deferred names in the term and their types
47build :: IState -> ElabInfo -> ElabMode -> FnOpts -> Name -> PTerm ->
74build :: IState -> ElabInfo -> ElabMode -> FnOpts -> Name -> PTerm ->
48− ElabD (Term, [(Name, (Int, Maybe Name, Type))], [PDecl])
75+ ElabD ElabResult
49build ist info emode opts fn tm
76build ist info emode opts fn tm
50 = do elab ist info emode opts fn tm
77 = do elab ist info emode opts fn tm
51 let tmIn = tm
78 let tmIn = tm
@@ -94,12 +121,13 @@ build ist info emode opts fn tm
94 when tydecl (do update_term orderPats
121 when tydecl (do update_term orderPats
96-- update_term liftPats)
123-- update_term liftPats)
97− EState is _ <- getAux
124+ EState is _ impls <- getAux
98 tt <- get_term
125 tt <- get_term
99 let (tm, ds) = runState (collectDeferred (Just fn) tt) []
126 let (tm, ds) = runState (collectDeferred (Just fn) tt) []
100 log <- getLog
127 log <- getLog
101− if (log /= "") then trace log $ return (tm, ds, is)
129+ if (log /= "") then trace log $ return (ElabResult tm ds is ctxt impls)
102− else return (tm, ds, is)
130+ else return (ElabResult tm ds is ctxt impls)
103 where pattern = emode == ELHS
131 where pattern = emode == ELHS
104 tydecl = emode == ETyDecl
132 tydecl = emode == ETyDecl
@@ -114,7 +142,7 @@ build ist info emode opts fn tm
114-- know about yet on the LHS of a pattern def)
142-- know about yet on the LHS of a pattern def)
116buildTC :: IState -> ElabInfo -> ElabMode -> FnOpts -> Name -> PTerm ->
144buildTC :: IState -> ElabInfo -> ElabMode -> FnOpts -> Name -> PTerm ->
117− ElabD (Term, [(Name, (Int, Maybe Name, Type))], [PDecl])
145+ ElabD ElabResult
118buildTC ist info emode opts fn tm
146buildTC ist info emode opts fn tm
119 = do -- set name supply to begin after highest index in tm
147 = do -- set name supply to begin after highest index in tm
120 let ns = allNamesIn tm
148 let ns = allNamesIn tm
@@ -135,12 +163,13 @@ buildTC ist info emode opts fn tm
135 -- unification
163 -- unification
136 when (not (null dots)) $
164 when (not (null dots)) $
137 lift (Error (CantMatch (getInferTerm tm)))
165 lift (Error (CantMatch (getInferTerm tm)))
138− EState is _ <- getAux
166+ EState is _ impls <- getAux
139 tt <- get_term
167 tt <- get_term
140 let (tm, ds) = runState (collectDeferred (Just fn) tt) []
168 let (tm, ds) = runState (collectDeferred (Just fn) tt) []
141 log <- getLog
169 log <- getLog
142− if (log /= "") then trace log $ return (tm, ds, is)
171+ if (log /= "") then trace log $ return (ElabResult tm ds is ctxt impls)
143− else return (tm, ds, is)
172+ else return (ElabResult tm ds is ctxt impls)
144 where pattern = emode == ELHS
173 where pattern = emode == ELHS
146-- return whether arguments of the given constructor name can be
175-- return whether arguments of the given constructor name can be
@@ -183,9 +212,9 @@ goal_polymorphic =
183 _ -> return True
212 _ -> return True
184 _ -> return False
213 _ -> return False
186−-- Returns the set of declarations we need to add to complete the definition
215+-- | Returns the set of declarations we need to add to complete the
187−-- (most likely case blocks to elaborate)
216+-- definition (most likely case blocks to elaborate) as well as
188−
217+-- declarations resulting from user tactic scripts (%runTactics)
189elab :: IState -> ElabInfo -> ElabMode -> FnOpts -> Name -> PTerm ->
218elab :: IState -> ElabInfo -> ElabMode -> FnOpts -> Name -> PTerm ->
191elab ist info emode opts fn tm
220elab ist info emode opts fn tm
@@ -1077,8 +1106,8 @@ elab ist info emode opts fn tm
1078 elab' ina (Just fc') tm
1107 elab' ina (Just fc') tm
1079 env <- get_env
1108 env <- get_env
1080− ctxt <- get_context
1081− runTactical (maybe fc' id fc) ctxt env (P Bound n' Erased)
1109+ runTactical (maybe fc' id fc) env (P Bound n' Erased)
1110+ EState _ _ todo <- getAux
1083 elab' ina fc x = fail $ "Unelaboratable syntactic form " ++ showTmImpls x
1112 elab' ina fc x = fail $ "Unelaboratable syntactic form " ++ showTmImpls x
@@ -1505,11 +1534,17 @@ case_ ind autoSolve ist fn tm = do
1505 else casetac (forget val)
1534 else casetac (forget val)
1506 when autoSolve solveAll
1535 when autoSolve solveAll
1537+tacN :: String -> Name
1538+tacN str = sNS (sUN str) ["Tactical", "Reflection", "Language"]
1508−runTactical :: FC -> Context -> Env -> Term -> ElabD ()
1540+runTactical :: FC -> Env -> Term -> ElabD ()
1509−runTactical fc ctxt env tm = runTacTm (eval tm) >> return ()
1541+runTactical fc env tm = do tm' <- eval tm
1545+ eval tm = do ctxt <- get_context
1511− eval = normaliseAll ctxt env . finalise
1546+ return $ normaliseAll ctxt env (finalise tm)
1512− tacN str = sNS (sUN str) ["Tactical", "Reflection", "Language"]
1547+
1513 returnUnit = fmap fst $ get_type_val (Var unitCon)
1548 returnUnit = fmap fst $ get_type_val (Var unitCon)
1515 -- | Do a step in the reflected elaborator monad. The input is the
1550 -- | Do a step in the reflected elaborator monad. The input is the
@@ -1547,26 +1582,31 @@ runTactical fc ctxt env tm = runTacTm (eval tm) >> return ()
1547 = do env <- get_env
1582 = do env <- get_env
1548 fmap fst . get_type_val $ reflectEnv env
1583 fmap fst . get_type_val $ reflectEnv env
1549 | n == tacN "prim__Fail", [_a, errs] <- args
1584 | n == tacN "prim__Fail", [_a, errs] <- args
1585+ = do errs' <- eval errs
1550− = do parts <- reifyReportParts (eval errs)
1586+ parts <- reifyReportParts errs'
1551 lift . tfail $ ReflectionError [parts] (Msg "")
1587 lift . tfail $ ReflectionError [parts] (Msg "")
1552 | n == tacN "prim__PureTactical", [_a, tm] <- args
1588 | n == tacN "prim__PureTactical", [_a, tm] <- args
1553 = return tm
1589 = return tm
1554 | n == tacN "prim__BindTactical", [_a, _b, first, andThen] <- args
1590 | n == tacN "prim__BindTactical", [_a, _b, first, andThen] <- args
1555− = do let first' = eval first
1591+ = do first' <- eval first
1556 res <- runTacTm first'
1592 res <- runTacTm first'
1557− let next = eval (App andThen res)
1593+ next <- eval (App andThen res)
1558 runTacTm next
1594 runTacTm next
1559 | n == tacN "prim__Try", [_a, first, alt] <- args
1595 | n == tacN "prim__Try", [_a, first, alt] <- args
1560− = do let first' = eval first
1596+ = do first' <- eval first
1561− let alt' = eval alt
1597+ alt' <- eval alt
1562 try' (runTacTm first') (runTacTm alt') True
1598 try' (runTacTm first') (runTacTm alt') True
1563 | n == tacN "prim__Fill", [raw] <- args
1599 | n == tacN "prim__Fill", [raw] <- args
1564 = do raw' <- reifyRaw raw
1600 = do raw' <- reifyRaw raw
1565 apply raw' []
1601 apply raw' []
1566 returnUnit
1602 returnUnit
1567− | n == tacN "prim__Gensym", [eval -> Constant (Str hint)] <- args
1603+ | n == tacN "prim__Gensym", [hint] <- args
1604+ = do hintStr <- eval hint
1606+ Constant (Str h) -> do
1568− = do n <- getNameFrom (sMN 0 hint)
1607+ n <- getNameFrom (sMN 0 h)
1569− fmap fst $ get_type_val (reflectName n)
1608+ fmap fst $ get_type_val (reflectName n)
1609+ _ -> fail "no hint"
1570 | n == tacN "prim__Claim", [n, ty] <- args
1610 | n == tacN "prim__Claim", [n, ty] <- args
1571 = do n' <- reifyTTName n
1611 = do n' <- reifyTTName n
1572 ty' <- reifyRaw ty
1612 ty' <- reifyRaw ty
@@ -1596,6 +1636,29 @@ runTactical fc ctxt env tm = runTacTm (eval tm) >> return ()
1596 Just name -> fmap Just $ reifyTTName name
1636 Just name -> fmap Just $ reifyTTName name
1598 returnUnit
1638 returnUnit
1639+ | n == tacN "prim__DeclareType", [decl] <- args
1640+ = do (RDeclare n args res) <- reifyTyDecl decl
1641+ ctxt <- get_context
1642+ let mkPi arg res = RBind (argName arg)
1643+ (Pi Nothing (argTy arg) (RUType AllTypes))
1645+ rty = foldr mkPi res args
1646+ (checked, ty') <- lift $ check ctxt [] rty
1647+ case normaliseAll ctxt [] (finalise ty') of
1648+ TType _ -> lift . tfail . InternalMsg $
1649+ show checked ++ " is not a type: it's " ++ show ty'
1651+ case lookupDefExact n ctxt of
1652+ Just _ -> lift . tfail . InternalMsg $
1653+ show n ++ " is already defined."
1654+ Nothing -> return ()
1655+ let decl = TyDecl Ref checked
1656+ ctxt' = addCtxtDef n decl ctxt
1658+ updateAux $ \e -> e { new_tyDecls = (n, fc, map rArgToPArg args, checked) :
1599 | n == tacN "prim__Debug", [ty, msg] <- args
1662 | n == tacN "prim__Debug", [ty, msg] <- args
1600 = do let msg' = fromTTMaybe msg
1663 = do let msg' = fromTTMaybe msg
1601 case msg' of
1664 case msg' of
@@ -2749,6 +2812,28 @@ reifyReportPart (App (P (DCon _ _ _) n _) tm)
2749 Nothing -> Left . InternalMsg $ "could not reify subreport " ++ show tm
2812 Nothing -> Left . InternalMsg $ "could not reify subreport " ++ show tm
2750reifyReportPart x = Left . InternalMsg $ "could not reify " ++ show x
2813reifyReportPart x = Left . InternalMsg $ "could not reify " ++ show x
2815+reifyTyDecl :: Term -> ElabD RTyDecl
2816+reifyTyDecl (App (App (App (P (DCon _ _ _) n _) tyN) args) ret)
2817+ | n == tacN "Declare" =
2818+ do tyN' <- reifyTTName tyN
2819+ args' <- case unList args of
2820+ Nothing -> fail $ "Couldn't reify " ++ show args ++ " as an arglist."
2821+ Just xs -> mapM reifyRArg xs
2822+ ret' <- reifyRaw ret
2823+ return $ RDeclare tyN' args' ret'
2824+ where reifyRArg :: Term -> ElabD RArg
2825+ reifyRArg (App (App (P (DCon _ _ _) n _) argN) argTy)
2826+ | n == tacN "Explicit" = liftM2 RExplicit
2829+ | n == tacN "Implicit" = liftM2 RImplicit
2831+ (reifyRaw argTy) | n == tacN "Constraint" = liftM2 RConstraint
2834+ reifyRArg aTm = fail $ "Couldn't reify " ++ show aTm ++ " as an RArg."
2835+reifyTyDecl tm = fail $ "Couldn't reify " ++ show tm ++ " as a type declaration."
2752envTupleType :: Raw
2837envTupleType :: Raw
2753envTupleType
2838envTupleType
2754 = raw_apply (Var pairTy) [ (Var $ reflm "TTName")
2839 = raw_apply (Var pairTy) [ (Var $ reflm "TTName")