@@ -5,15 +5,18 @@ module Idris.ElabTerm where
5import Idris.AbsSyntax
5import Idris.AbsSyntax
6import Idris.DSL
6import Idris.DSL
7import Idris.Delaborate
7import Idris.Delaborate
8import Idris.ProofSearch
9import Idris.ProofSearch
10import Idris.Core.Elaborate hiding (Tactic(..))
11import Idris.Core.Elaborate hiding (Tactic(..))
11import Idris.Core.TT
12import Idris.Core.TT
12import Idris.Core.Evaluate
13import Idris.Core.Evaluate
14+import Idris.Core.Typecheck (check)
14import Control.Monad
16import Control.Monad
15import Control.Monad.State
17import Control.Monad.State
16import Data.List
18import Data.List
19+import Data.Maybe (mapMaybe)
18import Debug.Trace
21import Debug.Trace
@@ -1031,7 +1034,7 @@ runTac autoSolve ist tac
1031 runReflected t = do t' <- reify ist t
1034 runReflected t = do t' <- reify ist t
1032 runTac autoSolve ist t'
1035 runTac autoSolve ist t'
1034−-- | Prefix a name with the "Reflection.Language" namespace
1037+-- | Prefix a name with the "Language.Reflection" namespace
1035reflm :: String -> Name
1038reflm :: String -> Name
1036reflm n = NS (UN n) ["Reflection", "Language"]
1039reflm n = NS (UN n) ["Reflection", "Language"]
@@ -1370,10 +1373,172 @@ reflectEnv = foldr consToEnvList emptyEnvList
1370 [envTupleType]
1373 [envTupleType]
1372-- | Reflect an error into the internal datatype of Idris -- TODO
1375-- | Reflect an error into the internal datatype of Idris -- TODO
1376+rawBool :: Bool -> Raw
1377+rawBool True = Var (NS (UN "True") ["Bool", "Prelude"])
1378+rawBool False = Var (NS (UN "False") ["Bool", "Prelude"])
1380+rawNil :: Raw -> Raw
1381+rawNil ty = raw_apply (Var (NS (UN "Nil") ["List", "Prelude"])) [ty]
1383+rawCons :: Raw -> Raw -> Raw -> Raw
1384+rawCons ty hd tl = raw_apply (Var (NS (UN "::") ["List", "Prelude"])) [ty, hd, tl]
1386+rawList :: Raw -> [Raw] -> Raw
1387+rawList ty = foldr (rawCons ty) (rawNil ty)
1389+rawPairTy :: Raw -> Raw -> Raw
1390+rawPairTy t1 t2 = raw_apply (Var pairTy) [t1, t2]
1392+rawPair :: (Raw, Raw) -> (Raw, Raw) -> Raw
1393+rawPair (a, b) (x, y) = raw_apply (Var pairCon) [a, b, x, y]
1395+reflectCtxt :: [(Name, Type)] -> Raw
1396+reflectCtxt ctxt = rawList (rawPairTy (Var $ reflm "TTName") (Var $ reflm "TT"))
1397+ (map (\ (n, t) -> (rawPair (Var $ reflm "TTName", Var $ reflm "TT")
1398+ (reflectName n, reflect t)))
1373reflectErr :: Err -> Raw
1401reflectErr :: Err -> Raw
1374−reflectErr (Msg msg) = raw_apply (Var (NS (UN "Msg") ["Reflection", "Language"])) [reflectConstant (Str msg)]
1402+reflectErr (Msg msg) = raw_apply (Var $ reflErrName "Msg") [RConstant (Str msg)]
1375−reflectErr (InternalMsg msg) = raw_apply (Var (NS (UN "InternalMsg") ["Reflection", "Language"])) [reflectConstant (Str msg)]
1403+reflectErr (InternalMsg msg) = raw_apply (Var $ reflErrName "InternalMsg") [RConstant (Str msg)]
1376−reflectErr x = trace ("Couldn't reflect error " ++ show x) raw_apply (Var (NS (UN "Msg") ["Reflection", "Language"])) [reflectConstant (Str $ show x)]
1404+reflectErr (CantUnify b t1 t2 e ctxt i) =
1405+ raw_apply (Var $ reflErrName "CantUnify")
1412+reflectErr (InfiniteUnify n tm ctxt) =
1413+ raw_apply (Var $ reflErrName "InfiniteUnify")
1418+reflectErr (CantConvert t t' ctxt) =
1419+ raw_apply (Var $ reflErrName "CantConvert")
1424+reflectErr (UnifyScope n n' t ctxt) =
1425+ raw_apply (Var $ reflErrName "UnifyScope")
1431+reflectErr (CantInferType str) =
1432+ raw_apply (Var $ reflErrName "CantInferType") [RConstant (Str str)]
1433+reflectErr (NonFunctionType t t') =
1434+ raw_apply (Var $ reflErrName "NonFunctionType") [reflect t, reflect t']
1435+reflectErr (NotEquality t t') =
1436+ raw_apply (Var $ reflErrName "NotEquality") [reflect t, reflect t']
1437+reflectErr (TooManyArguments n) = raw_apply (Var $ reflErrName "TooManyArguments") [reflectName n]
1438+reflectErr (CantIntroduce t) = raw_apply (Var $ reflErrName "CantIntroduce") [reflect t]
1439+reflectErr (NoSuchVariable n) = raw_apply (Var $ reflErrName "NoSuchVariable") [reflectName n]
1440+reflectErr (NoTypeDecl n) = raw_apply (Var $ reflErrName "NoTypeDecl") [reflectName n]
1441+reflectErr (NotInjective t1 t2 t3) =
1442+ raw_apply (Var $ reflErrName "NotInjective")
1447+reflectErr (CantResolve t) = raw_apply (Var $ reflErrName "CantResolve") [reflect t]
1448+reflectErr (CantResolveAlts ss) =
1449+ raw_apply (Var $ reflErrName "CantResolve")
1450+ [rawList (Var $ (UN "String")) (map (RConstant . Str) ss)]
1451+reflectErr (IncompleteTerm t) = raw_apply (Var $ reflErrName "IncompleteTerm") [reflect t]
1452+reflectErr UniverseError = Var $ reflErrName "UniverseError"
1453+reflectErr ProgramLineComment = Var $ reflErrName "ProgramLineComment"
1454+reflectErr (Inaccessible n) = raw_apply (Var $ reflErrName "Inaccessible") [reflectName n]
1455+reflectErr (NonCollapsiblePostulate n) = raw_apply (Var $ reflErrName "NonCollabsiblePostulate") [reflectName n]
1456+reflectErr (AlreadyDefined n) = raw_apply (Var $ reflErrName "AlreadyDefined") [reflectName n]
1457+reflectErr (ProofSearchFail e) = raw_apply (Var $ reflErrName "ProofSearchFail") [reflectErr e]
1458+reflectErr (NoRewriting tm) = raw_apply (Var $ reflErrName "NoRewriting") [reflect tm]
1459+reflectErr (At fc err) = raw_apply (Var $ reflErrName "At") [reflectFC fc, reflectErr err]
1460+ where reflectFC (FC source line col) = raw_apply (Var $ reflErrName "FileLoc")
1461+ [ RConstant (Str source)
1462+ , RConstant (I line)
1463+ , RConstant (I col)
1465+reflectErr (Elaborating str n e) =
1466+ raw_apply (Var $ reflErrName "Elaborating")
1467+ [ RConstant (Str str)
1471+reflectErr (ProviderError str) =
1472+ raw_apply (Var $ reflErrName "ProviderError") [RConstant (Str str)]
1473+reflectErr (LoadingFailed str err) =
1474+ raw_apply (Var $ reflErrName "LoadingFailed") [RConstant (Str str)]
1475+reflectErr x = raw_apply (Var (NS (UN "Msg") ["Errors", "Reflection", "Language"])) [RConstant . Str $ "Default reflection: " ++ show x]
1477+withErrorReflection :: Idris a -> Idris a
1478+withErrorReflection x = idrisCatch x (\ e -> handle e >>= ierror)
1479+ where handle :: Err -> Idris Err
1480+ handle e@(ReflectionError _ _) = do logLvl 3 "Skipping reflection of error reflection result"
1481+ return e -- Don't do meta-reflection of errors
1482+ handle e@(ReflectionFailed _ _) = do logLvl 3 "Skipping reflection of reflection failure"
1484+ handle e = do ist <- getIState
1485+ logLvl 2 "Starting error reflection"
1486+ let handlers = idris_errorhandlers ist
1487+ logLvl 3 $ "Using reflection handlers " ++ concat (intersperse ", " (map show handlers))
1488+ let reports = map (\n -> RApp (Var n) (reflectErr e)) handlers
1490+ -- Typecheck error handlers - if this fails, then something else was wrong earlier!
1491+ handlers <- case mapM (check (tt_ctxt ist) []) reports of
1492+ Error e -> ierror $ ReflectionFailed "Type error while constructing reflected error" e
1495+ -- Normalize error handler terms to produce the new messages
1497+ let results = map (normalise ctxt []) (map fst handlers)
1498+ logLvl 3 $ "New error message info: " ++ concat (intersperse " and " (map show results))
1500+ -- For each handler term output, either discard it if it is Nothing or reify it the Haskell equivalent
1501+ let errorpartsTT = mapMaybe unList (mapMaybe fromTTMaybe results)
1502+ errorparts <- mapM (mapM reifyReportPart) errorpartsTT
1504+ return $ case errorparts of
1506+ parts -> ReflectionError errorparts e
1508+ fromTTMaybe :: Term -> Maybe Term -- WARNING: Assumes the term has type Maybe a
1509+ fromTTMaybe (App (App (P (DCon _ _) (NS (UN "Just") _) _) ty) tm) = Just tm
1510+ fromTTMaybe x = Nothing
1512+reflErrName :: String -> Name
1513+reflErrName n = NS (UN n) ["Errors", "Reflection", "Language"]
1515+reifyReportPart :: Term -> Idris ErrorReportPart
1516+reifyReportPart (App (P (DCon _ _) n _) (Constant (Str msg))) | n == reflErrName "TextPart" =
1517+ return (TextPart msg)
1518+reifyReportPart (App (P (DCon _ _) n _) ttn)
1519+ | n == reflErrName "NamePart" =
1520+ case runElab [] (reifyTTName ttn) (initElaborator NErased initContext Erased) of
1521+ Error e -> ierror . InternalMsg $
1522+ "could not reify name term " ++
1524+ " when reflecting an error"
1525+ OK (n', _)-> return $ NamePart n'
1526+reifyReportPart (App (P (DCon _ _) n _) tm)
1527+ | n == reflErrName "TermPart" =
1528+ do ist <- getIState
1529+ case runElab [] (reifyTT tm) (initElaborator NErased initContext Erased) of
1530+ Error e -> ierror . InternalMsg $
1531+ "could not reify reflected term " ++
1533+ " when reflecting an error"
1534+ OK (tm', _) -> return $ TermPart tm'
1535+reifyReportPart (App (P (DCon _ _) n _) tm)
1536+ | n == reflErrName "SubReport" =
1538+ Just xs -> do subParts <- mapM reifyReportPart xs
1539+ return (SubReport subParts)
1540+ Nothing -> ierror . InternalMsg $ "could not reify subreport " ++ show tm
1541+reifyReportPart x = ierror . InternalMsg $ "could not reify " ++ show x
1378envTupleType :: Raw
1543envTupleType :: Raw
1379envTupleType
1544envTupleType