@@ -16,6 +16,7 @@ import Idris.Core.Evaluate
1616import Idris.Core.Unify
1717import Idris.Core.Typecheck (check)
1818import Idris.ErrReverse (errReverse)
19+import Idris.ElabQuasiquote (extractUnquotes)
1920
2021import Control.Applicative ((<$>))
2122import Control.Monad
@@ -123,7 +124,7 @@ elab ist info pattern opts fn tm
123124 = do let loglvl = opt_logLevel (idris_options ist)
124125 when (loglvl > 5) $ unifyLog True
125126 compute -- expand type synonyms, etc
126− elabE (False, False, False) tm -- (in argument, guarded, in type)
127+ elabE (False, False, False, False) tm -- (in argument, guarded, in type, in qquote)
127128 end_unify
128129 when pattern -- convert remaining holes to pattern vars
129130 (do update_term orderPats
@@ -133,7 +134,7 @@ elab ist info pattern opts fn tm
133134 mkPat)
134135 where
135136 tcgen = Dictionary `elem` opts
136− reflect = Reflection `elem` opts
137+ reflection = Reflection `elem` opts
137138
138139 isph arg = case getTm arg of
139140 Placeholder -> (True, priority arg)
@@ -153,8 +154,12 @@ elab ist info pattern opts fn tm
153154 (h: hs) -> do patvar h; mkPat
154155 [] -> return ()
155156
156− elabE :: (Bool, Bool, Bool) -> PTerm -> ElabD ()
157− elabE ina t =
157+ -- | elabE elaborates an expression, possibly wrapping implicit coercions
158+ -- and forces/delays. If you make a recursive call in elab', it is
159+ -- normally correct to call elabE - the ones that don't are desugarings
160+ -- typically
161+ elabE :: (Bool, Bool, Bool, Bool) -> PTerm -> ElabD ()
162+ elabE ina t =
158163 --do g <- goal
159164 --trace ("Elaborating " ++ show t ++ " : " ++ show g) $
160165 do ct <- insertCoerce ina t
@@ -203,13 +208,15 @@ elab ist info pattern opts fn tm
203208 constType VoidType = True
204209 constType _ = False
205210
206− elab' :: (Bool, Bool, Bool) -- ^ (in an argument, guarded, in a type)
211+ -- "guarded" means immediately under a constructor, to help find patvars
212+
213+ elab' :: (Bool, Bool, Bool, Bool) -- ^ (in an argument, guarded, in a type, in a quasiquote)
207214 -> PTerm -- ^ The term to elaborate
208215 -> ElabD ()
209216 elab' ina (PNoImplicits t) = elab' ina t -- skip elabE step
210217 elab' ina PType = do apply RType []; solve
211218-- elab' (_,_,inty) (PConstant c)
212−-- | constType c && pattern && not reflect && not inty
219+-- | constType c && pattern && not reflection && not inty
213220-- = lift $ tfail (Msg "Typecase is not allowed")
214221 elab' ina (PConstant c) = do apply (RConstant c) []; solve
215222 elab' ina (PQuote r) = do fill r; solve
@@ -232,16 +239,16 @@ elab ist info pattern opts fn tm
232239 [pimp (sMN 0 "A") Placeholder True,
233240 pimp (sMN 0 "B") Placeholder False,
234241 pexp l, pexp r])
235− elab' ina@(_, a, inty) (PPair fc _ l r)
242+ elab' ina@(_, a, inty, qq) (PPair fc _ l r)
236243 = do hnf_compute
237244 g <- goal
238245 case g of
239− TType _ -> elabE (True, a,inty) (PApp fc (PRef fc pairTy)
240− [pexp l,pexp r])
241− _ -> elabE (True, a, inty) (PApp fc (PRef fc pairCon)
242− [pimp (sMN 0 "A") Placeholder True,
243− pimp (sMN 0 "B") Placeholder True,
244− pexp l, pexp r])
246+ TType _ -> elabE (True, a,inty, qq) (PApp fc (PRef fc pairTy)
247+ [pexp l,pexp r])
248+ _ -> elabE (True, a, inty, qq) (PApp fc (PRef fc pairCon)
249+ [pimp (sMN 0 "A") Placeholder True,
250+ pimp (sMN 0 "B") Placeholder True,
251+ pexp l, pexp r])
245252 elab' ina (PDPair fc p l@(PRef _ n) t r)
246253 = case t of
247254 Placeholder ->
@@ -285,9 +292,9 @@ elab ist info pattern opts fn tm
285292 = try' (elab' ina x) (trySeq' deferr xs) True
286293 elab' ina (PPatvar fc n) | pattern = patvar n
287294-- elab' (_, _, inty) (PRef fc f)
288−-- | isTConName f (tt_ctxt ist) && pattern && not reflect && not inty
289−-- = lift $ tfail (Msg "Typecase is not allowed")
290− elab' (ina, guarded, inty) (PRef fc n) | pattern && not (inparamBlock n)
295+-- | isTConName f (tt_ctxt ist) && pattern && not reflection && not inty
296+-- = lift $ tfail (Msg "Typecase is not allowed")
297+ elab' (ina, guarded, inty, qq) (PRef fc n) | pattern && not (inparamBlock n) && not qq
291298 = do ctxt <- get_context
292299 let defined = case lookupTy n ctxt of
293300 [] -> False
@@ -304,7 +311,7 @@ elab ist info pattern opts fn tm
304311 _ -> True
305312 elab' ina f@(PInferRef fc n) = elab' ina (PApp fc f [])
306313 elab' ina (PRef fc n) = erun fc $ do apply (Var n) []; solve
307− elab' ina@(_, a, inty) (PLam n Placeholder sc)
314+ elab' ina@(_, a, inty, qq) (PLam n Placeholder sc)
308315 = do -- if n is a type constructor name, this makes no sense...
309316 ctxt <- get_context
310317 when (isTConName n ctxt) $
@@ -312,8 +319,8 @@ elab ist info pattern opts fn tm
312319 checkPiGoal n
313320 attack; intro (Just n);
314321 -- trace ("------ intro " ++ show n ++ " ---- \n" ++ show ptm)
315− elabE (True, a, inty) sc; solve
316− elab' ina@(_, a, inty) (PLam n ty sc)
322+ elabE (True, a, inty, qq) sc; solve
323+ elab' ina@(_, a, inty, qq) (PLam n ty sc)
317324 = do tyn <- getNameFrom (sMN 0 "lamty")
318325 -- if n is a type constructor name, this makes no sense...
319326 ctxt <- get_context
@@ -327,12 +334,12 @@ elab ist info pattern opts fn tm
327334 hs <- get_holes
328335 introTy (Var tyn) (Just n)
329336 focus tyn
330− elabE (True, a, True) ty
331− elabE (True, a, inty) sc
337+ elabE (True, a, True, qq) ty
338+ elabE (True, a, inty, qq) sc
332339 solve
333− elab' ina@(_, a, _) (PPi _ n Placeholder sc)
334− = do attack; arg n (sMN 0 "ty"); elabE (True, a, True) sc; solve
335− elab' ina@(_, a, _) (PPi _ n ty sc)
340+ elab' ina@(_, a, _, qq) (PPi _ n Placeholder sc)
341+ = do attack; arg n (sMN 0 "ty"); elabE (True, a, True, qq) sc; solve
342+ elab' ina@(_, a, _, qq) (PPi _ n ty sc)
336343 = do attack; tyn <- getNameFrom (sMN 0 "ty")
337344 claim tyn RType
338345 n' <- case n of
@@ -340,10 +347,10 @@ elab ist info pattern opts fn tm
340347 _ -> return n
341348 forall n' (Var tyn)
342349 focus tyn
343− elabE (True, a, True) ty
344− elabE (True, a, True) sc
350+ elabE (True, a, True, qq) ty
351+ elabE (True, a, True, qq) sc
345352 solve
346− elab' ina@(_, a, inty) (PLet n ty val sc)
353+ elab' ina@(_, a, inty, qq) (PLet n ty val sc)
347354 = do attack;
348355 tyn <- getNameFrom (sMN 0 "letty")
349356 claim tyn RType
@@ -355,17 +362,17 @@ elab ist info pattern opts fn tm
355362 Placeholder -> return ()
356363 _ -> do focus tyn
357364 explicit tyn
358− elabE (True, a, True) ty
365+ elabE (True, a, True, qq) ty
359366 focus valn
360− elabE (True, a, True) val
367+ elabE (True, a, True, qq) val
361368 env <- get_env
362− elabE (True, a, inty) sc
369+ elabE (True, a, inty, qq) sc
363370 -- HACK: If the name leaks into its type, it may leak out of
364371 -- scope outside, so substitute in the outer scope.
365372 expandLet n (case lookup n env of
366373 Just (Let t v) -> v)
367374 solve
368− elab' ina@(_, a, inty) (PGoal fc r n sc) = do
375+ elab' ina@(_, a, inty, qq) (PGoal fc r n sc) = do
369376 rty <- goal
370377 attack
371378 tyn <- getNameFrom (sMN 0 "letty")
@@ -374,10 +381,10 @@ elab ist info pattern opts fn tm
374381 claim valn (Var tyn)
375382 letbind n (Var tyn) (Var valn)
376383 focus valn
377− elabE (True, a, True) (PApp fc r [pexp (delab ist rty)])
384+ elabE (True, a, True, qq) (PApp fc r [pexp (delab ist rty)])
378385 env <- get_env
379386 computeLet n
380− elabE (True, a, inty) sc
387+ elabE (True, a, inty, qq) sc
381388 solve
382389-- elab' ina (PLet n Placeholder
383390-- (PApp fc r [pexp (delab ist rty)]) sc)
@@ -433,16 +440,16 @@ elab ist info pattern opts fn tm
433440 _ -> lift $ tfail (NoSuchVariable fn)
434441 ns <- match_apply (Var fn') (map (\x -> (x,0)) imps)
435442 solve
436− elab' (_, _, inty) (PApp fc (PRef _ f) args')
437− | isTConName f (tt_ctxt ist) && pattern && not reflect && not inty
443+ elab' (_, _, inty, qq) (PApp fc (PRef _ f) args')
444+ | isTConName f (tt_ctxt ist) && pattern && not reflection && not inty && not qq
438445 = lift $ tfail (Msg "Typecase is not allowed")
439446 -- if f is local, just do a simple_app
440− elab' (ina, g, inty) tm@(PApp fc (PRef _ f) args)
447+ elab' (ina, g, inty, qq) tm@(PApp fc (PRef _ f) args)
441448 = do env <- get_env
442449 if (f `elem` map fst env && length args == 1)
443450 then -- simple app, as below
444− do simple_app (elabE (ina, g, inty) (PRef fc f))
445− (elabE (True, g, inty) (getTm (head args)))
451+ do simple_app (elabE (ina, g, inty, qq) (PRef fc f))
452+ (elabE (True, g, inty, qq) (getTm (head args)))
446453 (show tm)
447454 solve
448455 else
@@ -468,7 +475,7 @@ elab ist info pattern opts fn tm
468475 -- Sort so that the implicit tactics and alternatives go last
469476 let (ns', eargs) = unzip $
470477 sortBy cmpArg (zip ns args)
471− elabArgs ist (ina || not isinf, guarded, inty)
478+ elabArgs ist (ina || not isinf, guarded, inty, qq)
472479 [] fc False f ns'
473480 (f == sUN "Force")
474481 (map (\x -> (False, getTm x)) eargs) -- TODO: remove this False arg
@@ -542,9 +549,9 @@ elab ist info pattern opts fn tm
542549 setInjective (PApp _ (PRef _ n) _) = setinj n
543550 setInjective _ = return ()
544551
545− elab' ina@(_, a, inty) tm@(PApp fc f [arg])
552+ elab' ina@(_, a, inty, qq) tm@(PApp fc f [arg])
546553 = erun fc $
547− do simple_app (elabE ina f) (elabE (True, a, inty) (getTm arg))
554+ do simple_app (elabE ina f) (elabE (True, a, inty, qq) (getTm arg))
548555 (show tm)
549556 solve
550557 elab' ina Placeholder = do (h : hs) <- get_holes
@@ -593,7 +600,7 @@ elab ist info pattern opts fn tm
593600 elab' ina sc
594601 elab' ina (PRef fc letn)
595602 solve
596− elab' ina@(_, a, inty) c@(PCase fc scr opts)
603+ elab' ina@(_, a, inty, qq) c@(PCase fc scr opts)
597604 = do attack
598605 tyn <- getNameFrom (sMN 0 "scty")
599606 claim tyn RType
@@ -602,7 +609,7 @@ elab ist info pattern opts fn tm
602609 claim valn (Var tyn)
603610 letbind scvn (Var tyn) (Var valn)
604611 focus valn
605− elabE (True, a, inty) scr
612+ elabE (True, a, inty, qq) scr
606613 args <- get_env
607614 cname <- unique_hole' True (mkCaseName fn)
608615 let cname' = mkN cname
@@ -629,6 +636,75 @@ elab ist info pattern opts fn tm
629636 elab' ina (PUnifyLog t) = do unifyLog True
630637 elab' ina t
631638 unifyLog False
639+ elab' (ina, g, inty, qq) (PQuasiquote t)
640+ = do -- First extract the unquoted subterms, replacing them with fresh
641+ -- names in the quasiquoted term. Claim their reflections to be
642+ -- of type TT.
643+ (t, unq) <- extractUnquotes t
644+ let unquoteNames = map fst unq
645+ mapM_ (flip claim (Var tt)) unquoteNames
646+
647+
648+ -- Save the old state - we need a fresh proof state to avoid
649+ -- capturing lexically available variables in the quoted term.
650+ ctxt <- get_context
651+ saveState
652+ updatePS (const .
653+ newProof (sMN 0 "q") ctxt $
654+ P Ref tt Erased)
655+
656+ -- Re-add the unquotes, letting Idris infer the (fictional)
657+ -- types. Here, they represent the real type rather than the type
658+ -- of their reflection.
659+ mapM_ (\n -> do ty <- getNameFrom (sMN 0 "unqTy")
660+ claim ty RType
661+ movelast ty
662+ claim n (Var ty)
663+ movelast n)
664+ unquoteNames
665+
666+ -- Establish holes for the type and value of the term to be
667+ -- quasiquoted
668+ qTy <- getNameFrom (sMN 0 "qquoteTy")
669+ claim qTy RType
670+ qTm <- getNameFrom (sMN 0 "qquoteTm")
671+ claim qTm (Var qTy)
672+ -- Let-bind the result of elaborating the contained term, so that
673+ -- the hole doesn't disappear
674+ nTm <- getNameFrom (sMN 0 "quotedTerm")
675+ letbind nTm (Var qTy) (Var qTm)
676+ -- We must solve the type later through unification
677+ movelast qTy
678+
679+
680+ -- Elaborate the quasiquoted term into the hole
681+ focus qTm
682+ elabE (ina, g, inty, True) t
683+ end_unify
684+
685+ -- We now have an elaborated term. Reflect it and solve the
686+ -- original goal in the original proof state.
687+ env <- get_env
688+ loadState
689+ case fmap (explicitNames . binderVal) $ lookup nTm env of
690+ Just q
691+ | pattern -> reflectQuotePattern unquoteNames q
692+ | otherwise -> do fill $ reflectQuote unquoteNames q
693+ solve
694+ Nothing -> fail "Broken elaboration of quasiquote"
695+
696+ -- Finally fill in the terms or patterns from the unquotes. This
697+ -- happens last so that their holes still exist while elaborating
698+ -- the main quotation.
699+ mapM_ elabUnquote unq
700+ where tt = sNS (sUN "TT") ["Reflection", "Language"]
701+
702+ elabUnquote (n, tm)
703+ = do focus n
704+ elabE (ina, g, inty, False) tm
705+
706+
707+ elab' ina (PUnquote t) = fail "Found unquote outside of quasiquote"
632708 elab' ina x = fail $ "Unelaboratable syntactic form " ++ showTmImpls x
633709
634710 isScr :: PTerm -> (Name, Binder Term) -> (Name, (Bool, Binder Term))
@@ -720,7 +796,7 @@ elab ist info pattern opts fn tm
720796
721797 -- | Elaborate the arguments to a function
722798 elabArgs :: IState -- ^ The current Idris state
723− -> (Bool, Bool, Bool) -- ^ (in an argument, guarded, in a type)
799+ -> (Bool, Bool, Bool, Bool) -- ^ (in an argument, guarded, in a type, in a qquote)
724800 -> [Bool]
725801 -> FC -- ^ Source location
726802 -> Bool
@@ -1441,21 +1517,159 @@ reflCall funName args
14411517
14421518-- | Lift a term into its Language.Reflection.TT representation
14431519reflect :: Term -> Raw
1444−reflect (P nt n t)
1445− = reflCall "P" [reflectNameType nt, reflectName n, reflect t]
1446−reflect (V n)
1520+reflect = reflectQuote []
1521+
1522+claimTT :: Name -> ElabD Name
1523+claimTT n = do n' <- getNameFrom n
1524+ claim n' (Var (sNS (sUN "TT") ["Reflection", "Language"]))
1525+ return n'
1526+
1527+-- | Convert a reflected term to a more suitable form for pattern-matching.
1528+-- In particular, the less-interesting bits are elaborated to _ patterns. This
1529+-- happens to NameTypes, universe levels, names that are bound but not used,
1530+-- and the type annotation field of the P constructor.
1531+reflectQuotePattern :: [Name] -> Term -> ElabD ()
1532+reflectQuotePattern unq (P _ n _)
1533+ | n `elem` unq = -- the unquoted names have been claimed as TT already - just use them
1534+ do fill (Var n) ; solve
1535+ | otherwise =
1536+ do tyannot <- claimTT (sMN 0 "pTyAnnot")
1537+ movelast tyannot -- use a _ pattern here
1538+ nt <- getNameFrom (sMN 0 "nt")
1539+ claim nt (Var (reflm "NameType"))
1540+ movelast nt -- use a _ pattern here
1541+ n' <- getNameFrom (sMN 0 "n")
1542+ claim n' (Var (reflm "TTName"))
1543+ fill $ reflCall "P" [Var nt, Var n', Var tyannot]
1544+ solve
1545+ focus n'; reflectNameQuotePattern n
1546+reflectQuotePattern unq (V n)
1547+ = do fill $ reflCall "V" [RConstant (I n)]
1548+ solve
1549+reflectQuotePattern unq (Bind n b x)
1550+ = do x' <- claimTT (sMN 0 "sc")
1551+ movelast x'
1552+ b' <- getNameFrom (sMN 0 "binder")
1553+ claim b' (RApp (Var (sNS (sUN "Binder") ["Reflection", "Language"]))
1554+ (Var (sNS (sUN "TT") ["Reflection", "Language"])))
1555+ if n `elem` freeNames x
1556+ then do fill $ reflCall "Bind"
1557+ [reflectName n,
1558+ Var b',
1559+ Var x']
1560+ solve
1561+ else do any <- getNameFrom (sMN 0 "anyName")
1562+ claim any (Var (reflm "TTName"))
1563+ movelast any
1564+ fill $ reflCall "Bind"
1565+ [Var any,
1566+ Var b',
1567+ Var x']
1568+ solve
1569+ focus x'; reflectQuotePattern unq x
1570+ focus b'; reflectBinderQuotePattern unq b
1571+
1572+ where
1573+ reflectBinderQuotePattern :: [Name] -> Binder Term -> ElabD ()
1574+ reflectBinderQuotePattern unq (Lam t)
1575+ = do t' <- claimTT (sMN 0 "ty"); movelast t'
1576+ fill $ reflCall "Lam" [Var (reflm "TT"), Var t']
1577+ solve
1578+ focus t'; reflectQuotePattern unq t
1579+ reflectBinderQuotePattern unq (Pi t)
1580+ = do t' <- claimTT (sMN 0 "ty") ; movelast t'
1581+ fill $ reflCall "Pi" [Var (reflm "TT"), Var t']
1582+ solve
1583+ focus t'; reflectQuotePattern unq t
1584+ reflectBinderQuotePattern unq (Let x y)
1585+ = do x' <- claimTT (sMN 0 "ty"); movelast x';
1586+ y' <- claimTT (sMN 0 "v"); movelast y';
1587+ fill $ reflCall "Let" [Var (reflm "TT"), Var x', Var y']
1588+ solve
1589+ focus x'; reflectQuotePattern unq x
1590+ focus y'; reflectQuotePattern unq y
1591+ reflectBinderQuotePattern unq (NLet x y)
1592+ = do x' <- claimTT (sMN 0 "ty"); movelast x'
1593+ y' <- claimTT (sMN 0 "v"); movelast y'
1594+ fill $ reflCall "NLet" [Var (reflm "TT"), Var x', Var y']
1595+ solve
1596+ focus x'; reflectQuotePattern unq x
1597+ focus y'; reflectQuotePattern unq y
1598+ reflectBinderQuotePattern unq (Hole t)
1599+ = do t' <- claimTT (sMN 0 "ty"); movelast t'
1600+ fill $ reflCall "Hole" [Var (reflm "TT"), Var t']
1601+ solve
1602+ focus t'; reflectQuotePattern unq t
1603+ reflectBinderQuotePattern unq (GHole _ t)
1604+ = do t' <- claimTT (sMN 0 "ty"); movelast t'
1605+ fill $ reflCall "GHole" [Var (reflm "TT"), Var t']
1606+ solve
1607+ focus t'; reflectQuotePattern unq t
1608+ reflectBinderQuotePattern unq (Guess x y)
1609+ = do x' <- claimTT (sMN 0 "ty"); movelast x'
1610+ y' <- claimTT (sMN 0 "v"); movelast y'
1611+ fill $ reflCall "Guess" [Var (reflm "TT"), Var x', Var y']
1612+ solve
1613+ focus x'; reflectQuotePattern unq x
1614+ focus y'; reflectQuotePattern unq y
1615+ reflectBinderQuotePattern unq (PVar t)
1616+ = do t' <- claimTT (sMN 0 "ty"); movelast t'
1617+ fill $ reflCall "PVar" [Var (reflm "TT"), Var t']
1618+ solve
1619+ focus t'; reflectQuotePattern unq t
1620+ reflectBinderQuotePattern unq (PVTy t)
1621+ = do t' <- claimTT (sMN 0 "ty"); movelast t'
1622+ fill $ reflCall "PVTy" [Var (reflm "TT"), Var t']
1623+ solve
1624+ focus t'; reflectQuotePattern unq t
1625+reflectQuotePattern unq (App f x)
1626+ = do f' <- claimTT (sMN 0 "f"); movelast f'
1627+ x' <- claimTT (sMN 0 "x"); movelast x'
1628+ fill $ reflCall "App" [Var f', Var x']
1629+ solve
1630+ focus f'; reflectQuotePattern unq f
1631+ focus x'; reflectQuotePattern unq x
1632+reflectQuotePattern unq (Constant c)
1633+ = do fill $ reflCall "TConst" [reflectConstant c]
1634+ solve
1635+reflectQuotePattern unq (Proj t i)
1636+ = do t' <- claimTT (sMN 0 "t"); movelast t'
1637+ fill $ reflCall "Proj" [Var t', RConstant (I i)]
1638+ solve
1639+ focus t'; reflectQuotePattern unq t
1640+reflectQuotePattern unq (Erased)
1641+ = do erased <- claimTT (sMN 0 "erased")
1642+ movelast erased
1643+ fill $ (Var erased)
1644+ solve
1645+reflectQuotePattern unq (Impossible)
1646+ = do fill $ Var (reflm "Impossible")
1647+ solve
1648+reflectQuotePattern unq (TType exp)
1649+ = do ue <- getNameFrom (sMN 0 "uexp")
1650+ claim ue (Var (sNS (sUN "TTUExp") ["Reflection", "Language"]))
1651+ movelast ue
1652+ fill $ reflCall "TType" [Var ue]
1653+ solve
1654+
1655+-- | Create a reflected term, but leave refs to the provided name intact
1656+reflectQuote :: [Name] -> Term -> Raw
1657+reflectQuote unq (P nt n t)
1658+ | n `elem` unq = Var n
1659+ | otherwise = reflCall "P" [reflectNameType nt, reflectName n, reflectQuote unq t]
1660+reflectQuote unq (V n)
14471661 = reflCall "V" [RConstant (I n)]
1448−reflect (Bind n b x)
1449− = reflCall "Bind" [reflectName n, reflectBinder b, reflect x]
1450−reflect (App f x)
1451− = reflCall "App" [reflect f, reflect x]
1452−reflect (Constant c)
1662+reflectQuote unq (Bind n b x)
1663+ = reflCall "Bind" [reflectName n, reflectBinderQuote unq b, reflectQuote unq x]
1664+reflectQuote unq (App f x)
1665+ = reflCall "App" [reflectQuote unq f, reflectQuote unq x]
1666+reflectQuote unq (Constant c)
14531667 = reflCall "TConst" [reflectConstant c]
1454−reflect (Proj t i)
1455− = reflCall "Proj" [reflect t, RConstant (I i)]
1456−reflect (Erased) = Var (reflm "Erased")
1457−reflect (Impossible) = Var (reflm "Impossible")
1458−reflect (TType exp) = reflCall "TType" [reflectUExp exp]
1668+reflectQuote unq (Proj t i)
1669+ = reflCall "Proj" [reflectQuote unq t, RConstant (I i)]
1670+reflectQuote unq (Erased) = Var (reflm "Erased")
1671+reflectQuote unq (Impossible) = Var (reflm "Impossible")
1672+reflectQuote unq (TType exp) = reflCall "TType" [reflectUExp exp]
14591673
14601674reflectNameType :: NameType -> Raw
14611675reflectNameType (Bound) = Var (reflm "Bound")
@@ -1482,25 +1696,44 @@ reflectName (MN i n)
14821696reflectName (NErased) = Var (reflm "NErased")
14831697reflectName n = Var (reflm "NErased") -- special name, not yet implemented
14841698
1699+-- | Elaborate a name to a pattern. This means that NS and UN will be intact,
1700+-- while all others become _
1701+reflectNameQuotePattern :: Name -> ElabD ()
1702+reflectNameQuotePattern n@(UN s)
1703+ = do fill $ reflectName n
1704+ solve
1705+reflectNameQuotePattern n@(NS _ _)
1706+ = do fill $ reflectName n
1707+ solve
1708+reflectNameQuotePattern _ -- for all other names, match any
1709+ = do nameHole <- getNameFrom (sMN 0 "name")
1710+ claim nameHole (Var (reflm "TTName"))
1711+ movelast nameHole
1712+ fill (Var nameHole)
1713+ solve
1714+
14851715reflectBinder :: Binder Term -> Raw
1486−reflectBinder (Lam t)
1487− = reflCall "Lam" [Var (reflm "TT"), reflect t]
1488−reflectBinder (Pi t)
1489− = reflCall "Pi" [Var (reflm "TT"), reflect t]
1490−reflectBinder (Let x y)
1491− = reflCall "Let" [Var (reflm "TT"), reflect x, reflect y]
1492−reflectBinder (NLet x y)
1493− = reflCall "NLet" [Var (reflm "TT"), reflect x, reflect y]
1494−reflectBinder (Hole t)
1495− = reflCall "Hole" [Var (reflm "TT"), reflect t]
1496−reflectBinder (GHole _ t)
1497− = reflCall "GHole" [Var (reflm "TT"), reflect t]
1498−reflectBinder (Guess x y)
1499− = reflCall "Guess" [Var (reflm "TT"), reflect x, reflect y]
1500−reflectBinder (PVar t)
1501− = reflCall "PVar" [Var (reflm "TT"), reflect t]
1502−reflectBinder (PVTy t)
1503− = reflCall "PVTy" [Var (reflm "TT"), reflect t]
1716+reflectBinder = reflectBinderQuote []
1717+
1718+reflectBinderQuote :: [Name] -> Binder Term -> Raw
1719+reflectBinderQuote unq (Lam t)
1720+ = reflCall "Lam" [Var (reflm "TT"), reflectQuote unq t]
1721+reflectBinderQuote unq (Pi t)
1722+ = reflCall "Pi" [Var (reflm "TT"), reflectQuote unq t]
1723+reflectBinderQuote unq (Let x y)
1724+ = reflCall "Let" [Var (reflm "TT"), reflectQuote unq x, reflectQuote unq y]
1725+reflectBinderQuote unq (NLet x y)
1726+ = reflCall "NLet" [Var (reflm "TT"), reflectQuote unq x, reflectQuote unq y]
1727+reflectBinderQuote unq (Hole t)
1728+ = reflCall "Hole" [Var (reflm "TT"), reflectQuote unq t]
1729+reflectBinderQuote unq (GHole _ t)
1730+ = reflCall "GHole" [Var (reflm "TT"), reflectQuote unq t]
1731+reflectBinderQuote unq (Guess x y)
1732+ = reflCall "Guess" [Var (reflm "TT"), reflectQuote unq x, reflectQuote unq y]
1733+reflectBinderQuote unq (PVar t)
1734+ = reflCall "PVar" [Var (reflm "TT"), reflectQuote unq t]
1735+reflectBinderQuote unq (PVTy t)
1736+ = reflCall "PVTy" [Var (reflm "TT"), reflectQuote unq t]
15041737
15051738reflectConstant :: Const -> Raw
15061739reflectConstant c@(I _) = reflCall "I" [RConstant c]