@@ -293,8 +293,8 @@ elab ist info pattern opts fn tm
293293 elab' ina (PPatvar fc n) | pattern = patvar n
294294-- elab' (_, _, inty) (PRef fc f)
295295-- | 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)
296+-- = lift $ tfail (Msg "Typecase is not allowed")
297+ elab' (ina, guarded, inty, qq) (PRef fc n) | pattern && not (inparamBlock n) && not qq
298298 = do ctxt <- get_context
299299 let defined = case lookupTy n ctxt of
300300 [] -> False
@@ -640,8 +640,9 @@ elab ist info pattern opts fn tm
640640 = do -- First elaborate the unquoted subterms, replacing them with
641641 -- fresh names in the quasiquoted term
642642 (t, unq) <- extractUnquotes t
643− mapM_ (flip claim (Var tt) . fst) unq
644643 let unquoteNames = map fst unq
644+ mapM_ (flip claim (Var tt)) unquoteNames
645+
645646
646647 -- Save the old state - we need a fresh proof state for this to
647648 -- avoid capture
@@ -676,17 +677,18 @@ elab ist info pattern opts fn tm
676677 focus qTm
677678 elabE (ina, g, inty, True) t
678679 end_unify
680+
679681 -- We now have an elaborated term. Reflect it and solve the
680682 -- original goal
681683 env <- get_env
682− let qTerm = fmap (reflectQuote unquoteNames . binderVal) $ lookup nTm env
683−
684− case qTerm of
685− Just q -> do loadState
686− fill q
687− solve
688− mapM_ elabUnquote unq
684+ loadState
685+ case fmap (explicitNames . binderVal) $ lookup nTm env of
686+ Just q
687+ | pattern -> reflectQuotePattern unquoteNames q
688+ | otherwise -> do fill $ reflectQuote unquoteNames q
689+ solve
689690 Nothing -> fail "Broken elaboration of quasiquote"
691+ mapM_ elabUnquote unq
690692 where tt = sNS (sUN "TT") ["Reflection", "Language"]
691693
692694 elabUnquote (n, tm)
@@ -1509,6 +1511,138 @@ reflCall funName args
15091511reflect :: Term -> Raw
15101512reflect = reflectQuote []
15111513
1514+claimTT :: Name -> ElabD Name
1515+claimTT n = do n' <- getNameFrom n
1516+ claim n' (Var (sNS (sUN "TT") ["Reflection", "Language"]))
1517+ return n'
1518+
1519+-- | Convert a reflected term to a more suitable form for pattern-matching.
1520+-- In particular, the less-interesting bits are elaborated to _ patterns. This
1521+-- happens to NameTypes, universe levels, names that are bound but not used,
1522+-- and the type annotation field of the P constructor.
1523+reflectQuotePattern :: [Name] -> Term -> ElabD ()
1524+reflectQuotePattern unq (P _ n _)
1525+ | n `elem` unq = -- the unquoted names have been claimed as TT already - just use them
1526+ do fill (Var n) ; solve
1527+ | otherwise =
1528+ do tyannot <- claimTT (sMN 0 "pTyAnnot")
1529+ movelast tyannot -- use a _ pattern here
1530+ nt <- getNameFrom (sMN 0 "nt")
1531+ claim nt (Var (reflm "NameType"))
1532+ movelast nt -- use a _ pattern here
1533+ n' <- getNameFrom (sMN 0 "n")
1534+ claim n' (Var (reflm "TTName"))
1535+ fill $ reflCall "P" [Var nt, Var n', Var tyannot]
1536+ solve
1537+ focus n'; reflectNameQuotePattern n
1538+reflectQuotePattern unq (V n)
1539+ = do fill $ reflCall "V" [RConstant (I n)]
1540+ solve
1541+reflectQuotePattern unq (Bind n b x)
1542+ = do x' <- claimTT (sMN 0 "sc")
1543+ movelast x'
1544+ b' <- getNameFrom (sMN 0 "binder")
1545+ claim b' (RApp (Var (sNS (sUN "Binder") ["Reflection", "Language"]))
1546+ (Var (sNS (sUN "TT") ["Reflection", "Language"])))
1547+ if n `elem` freeNames x
1548+ then do fill $ reflCall "Bind"
1549+ [reflectName n,
1550+ Var b',
1551+ Var x']
1552+ solve
1553+ else do any <- claimTT (sMN 0 "any")
1554+ movelast any
1555+ fill $ reflCall "Bind"
1556+ [Var any,
1557+ Var b',
1558+ Var x']
1559+ solve
1560+ focus x'; reflectQuotePattern unq x
1561+ focus b'; reflectBinderQuotePattern unq b
1562+
1563+ where
1564+ reflectBinderQuotePattern :: [Name] -> Binder Term -> ElabD ()
1565+ reflectBinderQuotePattern unq (Lam t)
1566+ = do t' <- claimTT (sMN 0 "ty"); movelast t'
1567+ fill $ reflCall "Lam" [Var (reflm "TT"), Var t']
1568+ solve
1569+ focus t'; reflectQuotePattern unq t
1570+ reflectBinderQuotePattern unq (Pi t)
1571+ = do t' <- claimTT (sMN 0 "ty") ; movelast t'
1572+ fill $ reflCall "Pi" [Var (reflm "TT"), Var t']
1573+ solve
1574+ focus t'; reflectQuotePattern unq t
1575+ reflectBinderQuotePattern unq (Let x y)
1576+ = do x' <- claimTT (sMN 0 "ty"); movelast x';
1577+ y' <- claimTT (sMN 0 "v"); movelast y';
1578+ fill $ reflCall "Let" [Var (reflm "TT"), Var x', Var y']
1579+ solve
1580+ focus x'; reflectQuotePattern unq x
1581+ focus y'; reflectQuotePattern unq y
1582+ reflectBinderQuotePattern unq (NLet x y)
1583+ = do x' <- claimTT (sMN 0 "ty"); movelast x'
1584+ y' <- claimTT (sMN 0 "v"); movelast y'
1585+ fill $ reflCall "NLet" [Var (reflm "TT"), Var x', Var y']
1586+ solve
1587+ focus x'; reflectQuotePattern unq x
1588+ focus y'; reflectQuotePattern unq y
1589+ reflectBinderQuotePattern unq (Hole t)
1590+ = do t' <- claimTT (sMN 0 "ty"); movelast t'
1591+ fill $ reflCall "Hole" [Var (reflm "TT"), Var t']
1592+ solve
1593+ focus t'; reflectQuotePattern unq t
1594+ reflectBinderQuotePattern unq (GHole _ t)
1595+ = do t' <- claimTT (sMN 0 "ty"); movelast t'
1596+ fill $ reflCall "GHole" [Var (reflm "TT"), Var t']
1597+ solve
1598+ focus t'; reflectQuotePattern unq t
1599+ reflectBinderQuotePattern unq (Guess x y)
1600+ = do x' <- claimTT (sMN 0 "ty"); movelast x'
1601+ y' <- claimTT (sMN 0 "v"); movelast y'
1602+ fill $ reflCall "Guess" [Var (reflm "TT"), Var x', Var y']
1603+ solve
1604+ focus x'; reflectQuotePattern unq x
1605+ focus y'; reflectQuotePattern unq y
1606+ reflectBinderQuotePattern unq (PVar t)
1607+ = do t' <- claimTT (sMN 0 "ty"); movelast t'
1608+ fill $ reflCall "PVar" [Var (reflm "TT"), Var t']
1609+ solve
1610+ focus t'; reflectQuotePattern unq t
1611+ reflectBinderQuotePattern unq (PVTy t)
1612+ = do t' <- claimTT (sMN 0 "ty"); movelast t'
1613+ fill $ reflCall "PVTy" [Var (reflm "TT"), Var t']
1614+ solve
1615+ focus t'; reflectQuotePattern unq t
1616+reflectQuotePattern unq (App f x)
1617+ = do f' <- claimTT (sMN 0 "f"); movelast f'
1618+ x' <- claimTT (sMN 0 "x"); movelast x'
1619+ fill $ reflCall "App" [Var f', Var x']
1620+ solve
1621+ focus f'; reflectQuotePattern unq f
1622+ focus x'; reflectQuotePattern unq x
1623+reflectQuotePattern unq (Constant c)
1624+ = do fill $ reflCall "TConst" [reflectConstant c]
1625+ solve
1626+reflectQuotePattern unq (Proj t i)
1627+ = do t' <- claimTT (sMN 0 "t"); movelast t'
1628+ fill $ reflCall "Proj" [Var t', RConstant (I i)]
1629+ solve
1630+ focus t'; reflectQuotePattern unq t
1631+reflectQuotePattern unq (Erased)
1632+ = do erased <- claimTT (sMN 0 "erased")
1633+ movelast erased
1634+ fill $ (Var erased)
1635+ solve
1636+reflectQuotePattern unq (Impossible)
1637+ = do fill $ Var (reflm "Impossible")
1638+ solve
1639+reflectQuotePattern unq (TType exp)
1640+ = do ue <- getNameFrom (sMN 0 "uexp")
1641+ claim ue (Var (sNS (sUN "TTUExp") ["Reflection", "Language"]))
1642+ movelast ue
1643+ fill $ reflCall "TType" [Var ue]
1644+ solve
1645+
15121646-- | Create a reflected term, but leave refs to the provided name intact
15131647reflectQuote :: [Name] -> Term -> Raw
15141648reflectQuote unq (P nt n t)
@@ -1517,7 +1651,7 @@ reflectQuote unq (P nt n t)
15171651reflectQuote unq (V n)
15181652 = reflCall "V" [RConstant (I n)]
15191653reflectQuote unq (Bind n b x)
1520− = reflCall "Bind" [reflectName n, reflectBinder b, reflectQuote unq x]
1654+ = reflCall "Bind" [reflectName n, reflectBinderQuote unq b, reflectQuote unq x]
15211655reflectQuote unq (App f x)
15221656 = reflCall "App" [reflectQuote unq f, reflectQuote unq x]
15231657reflectQuote unq (Constant c)
@@ -1553,6 +1687,22 @@ reflectName (MN i n)
15531687reflectName (NErased) = Var (reflm "NErased")
15541688reflectName n = Var (reflm "NErased") -- special name, not yet implemented
15551689
1690+-- | Elaborate a name to a pattern. This means that NS and UN will be intact,
1691+-- while all others become _
1692+reflectNameQuotePattern :: Name -> ElabD ()
1693+reflectNameQuotePattern n@(UN s)
1694+ = do fill $ reflectName n
1695+ solve
1696+reflectNameQuotePattern n@(NS _ _)
1697+ = do fill $ reflectName n
1698+ solve
1699+reflectNameQuotePattern _ -- for all other names, match any
1700+ = do nameHole <- getNameFrom (sMN 0 "name")
1701+ claim nameHole (Var (reflm "TTName"))
1702+ movelast nameHole
1703+ fill (Var nameHole)
1704+ solve
1705+
15561706reflectBinder :: Binder Term -> Raw
15571707reflectBinder = reflectBinderQuote []
15581708