summaryrefslogtreecommitdiff
path: root/src/LambdaCube
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-02-13 13:11:21 +0100
committerPéter Diviánszky <divipp@gmail.com>2016-02-13 13:11:38 +0100
commit32abd090f36c19cdeef4ad0c475a22d715d9bee3 (patch)
treef0916f10dbee548039677b0d56c5ee924800fc9b /src/LambdaCube
parent5a2116c429a9762d17440e30b88572dc5d0cbadd (diff)
add structure to error messages
Diffstat (limited to 'src/LambdaCube')
-rw-r--r--src/LambdaCube/Compiler.hs37
-rw-r--r--src/LambdaCube/Compiler/Infer.hs72
-rw-r--r--src/LambdaCube/Compiler/Lexer.hs20
-rw-r--r--src/LambdaCube/Compiler/Parser.hs14
4 files changed, 73 insertions, 70 deletions
diff --git a/src/LambdaCube/Compiler.hs b/src/LambdaCube/Compiler.hs
index f6e2ccd3..cb93928a 100644
--- a/src/LambdaCube/Compiler.hs
+++ b/src/LambdaCube/Compiler.hs
@@ -10,7 +10,6 @@ module LambdaCube.Compiler
10 ( Backend(..) 10 ( Backend(..)
11 , Pipeline 11 , Pipeline
12 , Infos, listInfos, Range(..) 12 , Infos, listInfos, Range(..)
13 , ErrorMsg(..)
14 , Exp, outputType, boolType, trueExp 13 , Exp, outputType, boolType, trueExp
15 14
16 , MMT, runMMT, mapMMT 15 , MMT, runMMT, mapMMT
@@ -46,7 +45,7 @@ import qualified Data.Text.IO as TIO
46 45
47import LambdaCube.IR as IR 46import LambdaCube.IR as IR
48import LambdaCube.Compiler.Pretty hiding ((</>)) 47import LambdaCube.Compiler.Pretty hiding ((</>))
49import LambdaCube.Compiler.Infer (Infos, listInfos, ErrorMsg(..), PolyEnv(..), Export(..), Module(..), ErrorT, throwErrorTCM, parseLC, joinPolyEnvs, filterPolyEnv, inference_, ImportItems (..), Range(..), Exp, outputType, boolType, trueExp) 48import LambdaCube.Compiler.Infer (Infos, listInfos, PolyEnv(..), Export(..), Module(..), showError, parseLC, joinPolyEnvs, filterPolyEnv, inference_, ImportItems (..), Range(..), Exp, outputType, boolType, trueExp)
50import LambdaCube.Compiler.CoreToIR 49import LambdaCube.Compiler.CoreToIR
51 50
52-- inlcude path for: Builtins, Internals and Prelude 51-- inlcude path for: Builtins, Internals and Prelude
@@ -55,11 +54,11 @@ import Paths_lambdacube_compiler (getDataDir)
55type EName = String 54type EName = String
56type MName = String 55type MName = String
57 56
58type Modules = Map FilePath (Either Doc PolyEnv) 57type Modules = Map FilePath (Either Doc (PolyEnv, String))
59type ModuleFetcher m = Maybe FilePath -> MName -> m (FilePath, String) 58type ModuleFetcher m = Maybe FilePath -> MName -> m (FilePath, String)
60 59
61newtype MMT m a = MMT { runMMT :: ReaderT (ModuleFetcher (MMT m)) (ErrorT (StateT Modules (WriterT Infos m))) a } 60newtype MMT m a = MMT { runMMT :: ReaderT (ModuleFetcher (MMT m)) (ExceptT String (StateT Modules (WriterT Infos m))) a }
62 deriving (Functor, Applicative, Monad, MonadReader (ModuleFetcher (MMT m)), MonadState Modules, MonadError ErrorMsg, MonadIO, MonadThrow, MonadCatch, MonadMask) 61 deriving (Functor, Applicative, Monad, MonadReader (ModuleFetcher (MMT m)), MonadState Modules, MonadError String, MonadIO, MonadThrow, MonadCatch, MonadMask)
63type MM = MMT IO 62type MM = MMT IO
64 63
65instance MonadMask m => MonadMask (ExceptT e m) where 64instance MonadMask m => MonadMask (ExceptT e m) where
@@ -68,7 +67,7 @@ instance MonadMask m => MonadMask (ExceptT e m) where
68 67
69mapMMT f (MMT m) = MMT $ f m 68mapMMT f (MMT m) = MMT $ f m
70 69
71type Err a = (Either ErrorMsg a, Infos) 70type Err a = (Either String a, Infos)
72 71
73runMM :: Monad m => ModuleFetcher (MMT m) -> MMT m a -> m (Err a) 72runMM :: Monad m => ModuleFetcher (MMT m) -> MMT m a -> m (Err a)
74runMM fetcher 73runMM fetcher
@@ -84,7 +83,7 @@ catchErr er m = (force <$> m >>= liftIO . evaluate) `catch` getErr `catch` getPM
84 getErr (e :: ErrorCall) = catchErr er $ er $ show e 83 getErr (e :: ErrorCall) = catchErr er $ er $ show e
85 getPMatchFail (e :: PatternMatchFail) = catchErr er $ er $ show e 84 getPMatchFail (e :: PatternMatchFail) = catchErr er $ er $ show e
86 85
87catchMM :: Monad m => MMT m a -> (ErrorMsg -> MMT m a) -> MMT m a 86catchMM :: Monad m => MMT m a -> (String -> MMT m a) -> MMT m a
88catchMM m e = mapMMT (mapReaderT $ lift . runExceptT) m >>= either e return 87catchMM m e = mapMMT (mapReaderT $ lift . runExceptT) m >>= either e return
89 88
90-- TODO: remove dependent modules from cache too 89-- TODO: remove dependent modules from cache too
@@ -103,7 +102,7 @@ ioFetch :: MonadIO m => [FilePath] -> ModuleFetcher (MMT m)
103ioFetch paths imp n = do 102ioFetch paths imp n = do
104 preludePath <- (</> "lc") <$> liftIO getDataDir 103 preludePath <- (</> "lc") <$> liftIO getDataDir
105 let 104 let
106 f [] = throwErrorTCM $ "can't find module" <+> hsep (map text fnames) 105 f [] = throwError $ show $ "can't find module" <+> hsep (map text fnames)
107 f (x:xs) = liftIO (readFile' x) >>= \case 106 f (x:xs) = liftIO (readFile' x) >>= \case
108 Nothing -> f xs 107 Nothing -> f xs
109 Just src -> do 108 Just src -> do
@@ -133,10 +132,10 @@ loadModule imp mname = do
133 (fname, src) <- fetch imp mname 132 (fname, src) <- fetch imp mname
134 c <- gets $ Map.lookup fname 133 c <- gets $ Map.lookup fname
135 case c of 134 case c of
136 Just (Right m) -> return (fname, m) 135 Just (Right (m, _)) -> return (fname, m)
137 Just (Left e) -> throwErrorTCM $ "cycles in module imports:" <+> pShow mname <+> e 136 Just (Left e) -> throwError $ show $ "cycles in module imports:" <+> pShow mname <+> e
138 _ -> do 137 _ -> do
139 e <- MMT $ lift $ mapExceptT (lift . lift) $ parseLC fname src 138 e <- either (throwError . show) return $ parseLC fname src
140 modify $ Map.insert fname $ Left $ pShow $ map fst $ moduleImports e 139 modify $ Map.insert fname $ Left $ pShow $ map fst $ moduleImports e
141 let 140 let
142 loadModuleImports (m, is) = do 141 loadModuleImports (m, is) = do
@@ -145,7 +144,8 @@ loadModule imp mname = do
145 ms <- mapM loadModuleImports $ moduleImports e 144 ms <- mapM loadModuleImports $ moduleImports e
146 x' <- {-trace ("loading " ++ fname) $-} do 145 x' <- {-trace ("loading " ++ fname) $-} do
147 env <- joinPolyEnvs False ms 146 env <- joinPolyEnvs False ms
148 x <- MMT $ lift $ mapExceptT (lift . mapWriterT (return . runIdentity)) $ inference_ env e src 147 srcs <- gets $ Map.mapMaybe (either (const Nothing) (Just . snd))
148 x <- MMT $ lift $ mapExceptT (lift . mapWriterT (return . first (showError (Map.insert fname src srcs) +++ id) . runIdentity)) $ inference_ env e
149 case moduleExports e of 149 case moduleExports e of
150 Nothing -> return x 150 Nothing -> return x
151 Just es -> joinPolyEnvs False $ flip map es $ \exp -> case exp of 151 Just es -> joinPolyEnvs False $ flip map es $ \exp -> case exp of
@@ -158,9 +158,8 @@ loadModule imp mname = do
158 [PolyEnv x infos] -> PolyEnv x mempty -- TODO 158 [PolyEnv x infos] -> PolyEnv x mempty -- TODO
159 [] -> error "empty export list" 159 [] -> error "empty export list"
160 _ -> error "export list: internal error" 160 _ -> error "export list: internal error"
161 modify $ Map.insert fname $ Right x' 161 modify $ Map.insert fname $ Right (x', src)
162 return (fname, x') 162 return (fname, x')
163-- `finally` modify (Map.delete fname)
164 `catchMM` (\e -> modify (Map.delete fname) >> throwError e) 163 `catchMM` (\e -> modify (Map.delete fname) >> throwError e)
165 164
166filterImports (ImportAllBut ns) = not . (`elem` ns) 165filterImports (ImportAllBut ns) = not . (`elem` ns)
@@ -180,26 +179,26 @@ getDef m d ty = do
180 , infos pe 179 , infos pe
181 ) 180 )
182 181
183parseAndToCoreMain m = either (throwErrorTCM . text) return . (\(_, e, i) -> flip (,) i <$> e) =<< getDef m "main" (Just outputType) 182parseAndToCoreMain m = either throwError return . (\(_, e, i) -> flip (,) i <$> e) =<< getDef m "main" (Just outputType)
184 183
185-- | most commonly used interface for end users 184-- | most commonly used interface for end users
186compileMain :: [FilePath] -> IR.Backend -> MName -> IO (Either String IR.Pipeline) 185compileMain :: [FilePath] -> IR.Backend -> MName -> IO (Either String IR.Pipeline)
187compileMain path backend fname 186compileMain path backend fname
188 = fmap ((show +++ fst) . fst) $ runMM (ioFetch path) $ first (compilePipeline backend) <$> parseAndToCoreMain fname 187 = fmap ((id +++ fst) . fst) $ runMM (ioFetch path) $ first (compilePipeline backend) <$> parseAndToCoreMain fname
189 188
190-- | Removes the escaping characters from the error message 189-- | Removes the escaping characters from the error message
191removeEscapes = first ((\(ErrorMsg e) -> ErrorMsg (removeEscs e)) +++ id) 190removeEscapes = first (removeEscs +++ id)
192 191
193-- used by the compiler-service of the online editor 192-- used by the compiler-service of the online editor
194preCompile :: (MonadMask m, MonadIO m) => [FilePath] -> [FilePath] -> Backend -> String -> IO (String -> m (Err (IR.Pipeline, Infos))) 193preCompile :: (MonadMask m, MonadIO m) => [FilePath] -> [FilePath] -> Backend -> String -> IO (String -> m (Err (IR.Pipeline, Infos)))
195preCompile paths paths' backend mod = do 194preCompile paths paths' backend mod = do
196 res <- runMM (ioFetch paths) $ loadModule Nothing mod 195 res <- runMM (ioFetch paths) $ loadModule Nothing mod
197 case res of 196 case res of
198 (Left err, i) -> error $ "Prelude could not compiled: " ++ show err 197 (Left err, i) -> error $ "Prelude could not compiled: " ++ err
199 (Right (_, prelude), _) -> return compile 198 (Right (_, prelude), _) -> return compile
200 where 199 where
201 compile src = fmap removeEscapes . runMM fetch $ do 200 compile src = fmap removeEscapes . runMM fetch $ do
202 modify $ Map.insert ("." </> "Prelude.lc") $ Right prelude 201 modify $ Map.insert ("." </> "Prelude.lc") $ Right (prelude, "<<TODO>>")
203 first (compilePipeline backend) <$> parseAndToCoreMain "Main" 202 first (compilePipeline backend) <$> parseAndToCoreMain "Main"
204 where 203 where
205 fetch imp = \case 204 fetch imp = \case
diff --git a/src/LambdaCube/Compiler/Infer.hs b/src/LambdaCube/Compiler/Infer.hs
index 181a686b..3a2bbe77 100644
--- a/src/LambdaCube/Compiler/Infer.hs
+++ b/src/LambdaCube/Compiler/Infer.hs
@@ -23,11 +23,12 @@ module LambdaCube.Compiler.Infer
23 , down, Subst (..), free 23 , down, Subst (..), free
24 , litType 24 , litType
25 , initEnv, Env(..), pattern EBind2 25 , initEnv, Env(..), pattern EBind2
26 , Infos(..), listInfos, ErrorMsg(..), PolyEnv(..), ErrorT, throwErrorTCM, parseLC, joinPolyEnvs, filterPolyEnv, inference_ 26 , Infos(..), listInfos, PolyEnv(..), parseLC, joinPolyEnvs, filterPolyEnv, inference_
27 , ImportItems (..) 27 , ImportItems (..)
28 , SI(..), Range(..) 28 , SI(..), Range(..)
29 , nType, conType, neutType, neutType', appTy, mkConPars, makeCaseFunPars, makeCaseFunPars' 29 , nType, conType, neutType, neutType', appTy, mkConPars, makeCaseFunPars, makeCaseFunPars'
30 , MaxDB(..), unfixlabel 30 , MaxDB(..), unfixlabel
31 , ErrorMsg, showError
31 ) where 32 ) where
32import Data.Monoid 33import Data.Monoid
33import Data.Maybe 34import Data.Maybe
@@ -750,10 +751,26 @@ mkExpTypes t@(Pi _ a _) (x: xs) = (x, t): mkExpTypes (appTy t x) xs
750appTy (Pi _ a b) x = subst 0 x b 751appTy (Pi _ a b) x = subst 0 x b
751appTy t x = error $ "appTy: " ++ show t 752appTy t x = error $ "appTy: " ++ show t
752 753
754-------------------------------------------------------------------------------- error messages
755
756data ErrorMsg
757 = ErrorMsg String
758 | ECantFind SName SI
759 | ETypeError String SI
760 | ERedefined SName SI SI
761
762showError :: Map.Map FilePath String -> ErrorMsg -> String
763showError srcs = \case
764 ErrorMsg s -> s
765 ECantFind s si -> "can't find: " ++ s ++ " in " ++ showSI srcs si
766 ETypeError msg si -> "type error: " ++ msg ++ "\nin " ++ showSI srcs si ++ "\n"
767 ERedefined s si si' -> "already defined " ++ s ++ " at " ++ showSI srcs si ++ "\n and at " ++ showSI srcs si'
768
769
753-------------------------------------------------------------------------------- inference 770-------------------------------------------------------------------------------- inference
754 771
755-- inference monad 772-- inference monad
756type IM m = ExceptT String (ReaderT (Extensions, String{-full source-}, GlobalEnv) (WriterT Infos m)) 773type IM m = ExceptT ErrorMsg (ReaderT (Extensions, GlobalEnv) (WriterT Infos m))
757 774
758expAndType s (e, t, si) = (e, t) 775expAndType s (e, t, si) = (e, t)
759 776
@@ -763,12 +780,9 @@ lookupName s m = expAndType s <$> Map.lookup s m
763--elemIndex' s@('\'':s') m = elemIndex s m `mplus` elemIndex s' m 780--elemIndex' s@('\'':s') m = elemIndex s m `mplus` elemIndex s' m
764--elemIndex' s m = elemIndex s m 781--elemIndex' s m = elemIndex s m
765 782
766getSource = asks $ \(_, s, _) -> s
767
768getDef te si s = do 783getDef te si s = do
769 src <- getSource 784 nv <- asks snd
770 nv <- asks $ \(_, _, s) -> s 785 maybe (throwError $ ECantFind s si) return (lookupName s nv)
771 maybe (throwError $ "can't find: " ++ s ++ " in " ++ showSI_ src si {- ++ "\nitems:\n" ++ intercalate ", " (take' "..." 10 $ Map.keys $ snd $ extractEnv te)-}) return (lookupName s nv)
772{- 786{-
773take' e n xs = case splitAt n xs of 787take' e n xs = case splitAt n xs of
774 (as, []) -> as 788 (as, []) -> as
@@ -825,7 +839,7 @@ inferN tracelevel = infer where
825 notHiddenLam = \case 839 notHiddenLam = \case
826 SLam Visible _ _ -> return True 840 SLam Visible _ _ -> return True
827 SGlobal (si,s) -> do 841 SGlobal (si,s) -> do
828 nv <- asks $ \(_,_,s) -> s 842 nv <- asks snd
829 case fromMaybe (error $ "infer: can't find: " ++ s) $ lookupName s nv of 843 case fromMaybe (error $ "infer: can't find: " ++ s) $ lookupName s nv of
830 (Lam _, Pi Hidden _ _) -> return False 844 (Lam _, Pi Hidden _ _) -> return False
831 _ -> return True 845 _ -> return True
@@ -884,7 +898,7 @@ inferN tracelevel = infer where
884 ELet1 le te b{-in-} -> infer (ELet2 le (replaceMetas' eet{-let-}) te) b{-in-} 898 ELet1 le te b{-in-} -> infer (ELet2 le (replaceMetas' eet{-let-}) te) b{-in-}
885 EBind2_ si BMeta tt te 899 EBind2_ si BMeta tt te
886 | Unit <- tt -> refocus te $ subst 0 TT eet 900 | Unit <- tt -> refocus te $ subst 0 TT eet
887 | Empty msg <- tt -> getSource >>= \src -> throwError $ "type error: " ++ msg ++ "\nin " ++ showSI_ src si ++ "\n"-- todo: better error msg 901 | Empty msg <- tt -> throwError $ ETypeError msg si
888 | T2 x y <- tt, let te' = EBind2_ si BMeta (up 1 y) $ EBind2_ si BMeta x te 902 | T2 x y <- tt, let te' = EBind2_ si BMeta (up 1 y) $ EBind2_ si BMeta x te
889 -> refocus te' $ subst 2 (t2C (Var 1) (Var 0)) $ up 2 eet 903 -> refocus te' $ subst 2 (t2C (Var 1) (Var 0)) $ up 2 eet
890 | CstrT t a b <- tt, Just r <- cst (a, t) b -> r 904 | CstrT t a b <- tt, Just r <- cst (a, t) b -> r
@@ -941,8 +955,8 @@ inferN tracelevel = infer where
941 955
942 EGlobal{} -> return eet 956 EGlobal{} -> return eet
943 _ -> case eet of 957 _ -> case eet of
944 MEnd x -> throwError_ $ "focus todo: " ++ ppShow x 958 MEnd x -> throwError $ ErrorMsg $ "focus todo: " ++ ppShow x
945 _ -> throwError_ $ "focus checkMetas: " ++ ppShow env ++ "\n" ++ ppShow (fst <$> eet) 959 _ -> throwError $ ErrorMsg $ "focus checkMetas: " ++ ppShow env ++ "\n" ++ ppShow (fst <$> eet)
946 where 960 where
947 refocus_ :: (Env -> CEnv ExpType -> IM m ExpType') -> Env -> CEnv ExpType -> IM m ExpType' 961 refocus_ :: (Env -> CEnv ExpType -> IM m ExpType') -> Env -> CEnv ExpType -> IM m ExpType'
948 refocus_ _ e (MEnd at) = focus_ e at 962 refocus_ _ e (MEnd at) = focus_ e at
@@ -1132,7 +1146,7 @@ handleStmt defs = \case
1132-} 1146-}
1133 PrecDef{} -> return mempty 1147 PrecDef{} -> return mempty
1134 Data s (map (second trSExp') -> ps) (trSExp' -> t_) addfa (map (second trSExp') -> cs) -> do 1148 Data s (map (second trSExp') -> ps) (trSExp' -> t_) addfa (map (second trSExp') -> cs) -> do
1135 af <- if addfa then asks $ \(exs, _, ge) -> addForalls exs . (snd s:) . defined' $ ge else return id 1149 af <- if addfa then asks $ \(exs, ge) -> addForalls exs . (snd s:) . defined' $ ge else return id
1136 vty <- inferType tr $ addParamsS ps t_ 1150 vty <- inferType tr $ addParamsS ps t_
1137 tellStmtType (fst s) vty 1151 tellStmtType (fst s) vty
1138 let 1152 let
@@ -1153,7 +1167,7 @@ handleStmt defs = \case
1153 , addParamsS pars 1167 , addParamsS pars
1154 $ foldl SAppV (SVar (debugSI "22", ".cs") $ j + length pars) $ drop pnum' xs ++ [apps' (SGlobal cn) (zip acts $ downToS ("a4 " ++ snd cn ++ " " ++ show (length ps)) (j+1+length pars) (length ps) ++ downToS "a5" 0 (act- length ps))] 1168 $ foldl SAppV (SVar (debugSI "22", ".cs") $ j + length pars) $ drop pnum' xs ++ [apps' (SGlobal cn) (zip acts $ downToS ("a4 " ++ snd cn ++ " " ++ show (length ps)) (j+1+length pars) (length ps) ++ downToS "a5" 0 (act- length ps))]
1155 )) 1169 ))
1156 | otherwise = throwError "illegal data definition (parameters are not uniform)" -- ++ show (c, cn, take pnum' xs, act) 1170 | otherwise = throwError $ ErrorMsg "illegal data definition (parameters are not uniform)" -- ++ show (c, cn, take pnum' xs, act)
1157 where 1171 where
1158 (c, map snd -> xs) = getApps $ snd $ getParamsS ct 1172 (c, map snd -> xs) = getApps $ snd $ getParamsS ct
1159 1173
@@ -1189,7 +1203,7 @@ handleStmt defs = \case
1189 1203
1190 stmt -> error $ "handleStmt: " ++ show stmt 1204 stmt -> error $ "handleStmt: " ++ show stmt
1191 1205
1192withEnv e = local (\(a,b,c) -> (a,b,c <> e)) 1206withEnv e = local $ second (<> e)
1193 1207
1194mkELet (False, n) x xt = x 1208mkELet (False, n) x xt = x
1195mkELet (True, n) x t{-type of x-} 1209mkELet (True, n) x t{-type of x-}
@@ -1229,22 +1243,20 @@ getLams (Lam b) = getLams b
1229getLams x = x 1243getLams x = x
1230 1244
1231inferTerm :: Monad m => String -> Bool -> SExp2 -> IM m ExpType 1245inferTerm :: Monad m => String -> Bool -> SExp2 -> IM m ExpType
1232inferTerm msg tr t = ask >>= \(exs, _, _) -> smartTrace exs $ \tr -> 1246inferTerm msg tr t = ask >>= \(exs, _) -> smartTrace exs $ \tr ->
1233 fmap ((closedExp *** closedExp) . recheck msg EGlobal . replaceMetas (lamPi Hidden)) $ inferN (if tr then traceLevel exs else 0) EGlobal t 1247 fmap ((closedExp *** closedExp) . recheck msg EGlobal . replaceMetas (lamPi Hidden)) $ inferN (if tr then traceLevel exs else 0) EGlobal t
1234inferType :: Monad m => Bool -> SExp2 -> IM m Type 1248inferType :: Monad m => Bool -> SExp2 -> IM m Type
1235inferType tr t = ask >>= \(exs, _, _) -> fmap (closedExp . fst . recheck "inferType" EGlobal . flip (,) TType . replaceMetas (Pi Hidden) . fmap fst) $ inferN (if tr then traceLevel exs else 0) (CheckType_ (debugSI "inferType CheckType_") TType EGlobal) t 1249inferType tr t = ask >>= \(exs, _) -> fmap (closedExp . fst . recheck "inferType" EGlobal . flip (,) TType . replaceMetas (Pi Hidden) . fmap fst) $ inferN (if tr then traceLevel exs else 0) (CheckType_ (debugSI "inferType CheckType_") TType EGlobal) t
1236 1250
1237addToEnv :: Monad m => SIName -> MFixity -> ExpType -> IM m GlobalEnv 1251addToEnv :: Monad m => SIName -> MFixity -> ExpType -> IM m GlobalEnv
1238addToEnv (si, s) mf (x, t) = do 1252addToEnv (si, s) mf (x, t) = do
1239-- maybe (pure ()) throwError_ $ ambiguityCheck s t -- TODO 1253-- maybe (pure ()) throwError_ $ ambiguityCheck s t -- TODO
1240 exs <- asks $ \(exs, _, _) -> exs 1254 exs <- asks fst
1241 when (trLight exs) $ mtrace (s ++ " :: " ++ ppShow t) 1255 when (trLight exs) $ mtrace (s ++ " :: " ++ ppShow t)
1242 v <- asks $ \(_, _, ge) -> Map.lookup s ge 1256 v <- asks $ Map.lookup s . snd
1243 case v of 1257 case v of
1244 Nothing -> return $ Map.singleton s (closedExp x, closedExp t, (si, mf)) 1258 Nothing -> return $ Map.singleton s (closedExp x, closedExp t, (si, mf))
1245 Just (_, _, (si', _)) 1259 Just (_, _, (si', _)) -> throwError $ ERedefined s si si'
1246 | sameSource si si' -> getSource >>= \ge -> throwError $ "already defined " ++ s ++ " at " ++ showSI_ ge si ++ "\n and at " ++ showSI_ ge si'
1247 | otherwise -> getSource >>= \ge -> throwError $ "already defined " ++ s ++ " at " ++ showSI_ ge si ++ "\n and at " ++ showSourcePosSI si'
1248{- 1260{-
1249joinEnv :: Monad m => GlobalEnv -> GlobalEnv -> IM m GlobalEnv 1261joinEnv :: Monad m => GlobalEnv -> GlobalEnv -> IM m GlobalEnv
1250joinEnv e1 e2 = do 1262joinEnv e1 e2 = do
@@ -1254,7 +1266,7 @@ downTo n m = map Var [n+m-1, n+m-2..n]
1254 1266
1255defined' = Map.keys 1267defined' = Map.keys
1256 1268
1257addF = asks $ \(exs, _, ge) -> addForalls exs $ defined' ge 1269addF = asks $ \(exs, ge) -> addForalls exs $ defined' ge
1258 1270
1259tellType si t = tell $ mkInfoItem (sourceInfo si) $ removeEscs $ showDoc $ mkDoc True (t, TType) 1271tellType si t = tell $ mkInfoItem (sourceInfo si) $ removeEscs $ showDoc $ mkDoc True (t, TType)
1260tellStmtType si t = tellType si t 1272tellStmtType si t = tellType si t
@@ -1269,7 +1281,7 @@ data PolyEnv = PolyEnv
1269 1281
1270filterPolyEnv p pe = pe { getPolyEnv = Map.filterWithKey (\k _ -> p k) $ getPolyEnv pe } 1282filterPolyEnv p pe = pe { getPolyEnv = Map.filterWithKey (\k _ -> p k) $ getPolyEnv pe }
1271 1283
1272joinPolyEnvs :: MonadError ErrorMsg m => Bool -> [PolyEnv] -> m PolyEnv 1284joinPolyEnvs :: MonadError String m => Bool -> [PolyEnv] -> m PolyEnv
1273joinPolyEnvs _ = return . foldr mappend' mempty' -- todo 1285joinPolyEnvs _ = return . foldr mappend' mempty' -- todo
1274 where 1286 where
1275 mempty' = PolyEnv mempty mempty 1287 mempty' = PolyEnv mempty mempty
@@ -1401,13 +1413,13 @@ instance MkDoc (CEnv Exp) where
1401 1413
1402-------------------------------------------------------------------------------- main 1414-------------------------------------------------------------------------------- main
1403 1415
1404smartTrace :: MonadError String m => Extensions -> (Bool -> m a) -> m a 1416smartTrace :: MonadError ErrorMsg m => Extensions -> (Bool -> m a) -> m a
1405smartTrace exs f | traceLevel exs >= 2 = f True 1417smartTrace exs f | traceLevel exs >= 2 = f True
1406smartTrace exs f | traceLevel exs == 0 = f False 1418smartTrace exs f | traceLevel exs == 0 = f False
1407smartTrace exs f = catchError (f False) $ \err -> 1419smartTrace exs f = catchError (f False) $ \err ->
1408 trace_ (unlines 1420 trace_ (unlines
1409 [ "---------------------------------" 1421 [ "---------------------------------"
1410 , err 1422 , showError mempty err
1411 , "try again with trace" 1423 , "try again with trace"
1412 , "---------------------------------" 1424 , "---------------------------------"
1413 ]) $ f True 1425 ]) $ f True
@@ -1420,8 +1432,8 @@ trLight exs = traceLevel exs >= 1
1420mfix' f = ExceptT (mfix (runExceptT . f . either bomb id)) 1432mfix' f = ExceptT (mfix (runExceptT . f . either bomb id))
1421 where bomb e = error $ "mfix (ExceptT): inner computation returned Left value:\n" ++ show e 1433 where bomb e = error $ "mfix (ExceptT): inner computation returned Left value:\n" ++ show e
1422 1434
1423inference_ :: PolyEnv -> Module -> String -> ErrorT (WriterT Infos Identity) PolyEnv 1435inference_ :: PolyEnv -> Module -> ExceptT ErrorMsg (WriterT Infos Identity) PolyEnv
1424inference_ (PolyEnv pe is) m src = do 1436inference_ (PolyEnv pe is) m = do
1425 1437
1426 ((defs, dns), ds) <- mfix $ \ff -> do 1438 ((defs, dns), ds) <- mfix $ \ff -> do
1427 let ds = snd ff 1439 let ds = snd ff
@@ -1430,13 +1442,13 @@ inference_ (PolyEnv pe is) m src = do
1430 let ds' = mkDesugarInfo defs `joinDesugarInfo` extractDesugarInfo pe 1442 let ds' = mkDesugarInfo defs `joinDesugarInfo` extractDesugarInfo pe
1431 return ((defs, dns), ds') 1443 return ((defs, dns), ds')
1432 1444
1433 mapM_ (maybe (return ()) (throwErrorTCM . text)) dns 1445 mapM_ (maybe (return ()) (throwError . ErrorMsg)) dns
1434 mapExceptT (ff . runWriter . flip runReaderT (extensions m, src, mempty)) $ gg (handleStmt defs) (initEnv <> pe) $ sortDefs ds defs 1446 mapExceptT (ff . runWriter . flip runReaderT (extensions m, mempty)) $ gg (handleStmt defs) (initEnv <> pe) $ sortDefs ds defs
1435 1447
1436 where 1448 where
1437 ff (Left e, is) = do 1449 ff (Left e, is) = do
1438 tell is 1450 tell is
1439 return $ Left $ ErrorMsg e 1451 return $ Left e
1440 ff (Right ge, is) = do 1452 ff (Right ge, is) = do
1441 return $ Right $ PolyEnv ge is 1453 return $ Right $ PolyEnv ge is
1442 1454
diff --git a/src/LambdaCube/Compiler/Lexer.hs b/src/LambdaCube/Compiler/Lexer.hs
index bd845368..eee1e293 100644
--- a/src/LambdaCube/Compiler/Lexer.hs
+++ b/src/LambdaCube/Compiler/Lexer.hs
@@ -134,15 +134,17 @@ instance PShow SI where
134 pShowPrec _ (NoSI ds) = hsep $ map pShow $ Set.toList ds 134 pShowPrec _ (NoSI ds) = hsep $ map pShow $ Set.toList ds
135 pShowPrec _ (RangeSI r) = pShow r 135 pShowPrec _ (RangeSI r) = pShow r
136 136
137showSI_ _ (NoSI ds) = unwords $ Set.toList ds 137showSI _ (NoSI ds) = unwords $ Set.toList ds
138showSI_ source (RangeSI (Range s e)) = show str 138showSI srcs si@(RangeSI (Range s e)) = case Map.lookup (sourceName s) srcs of
139 where 139 Just source -> show str
140 startLine = sourceLine s - 1 140 where
141 endline = sourceLine e - if sourceColumn e == 1 then 1 else 0 141 startLine = sourceLine s - 1
142 len = endline - startLine 142 endline = sourceLine e - if sourceColumn e == 1 then 1 else 0
143 str = vcat $ text (show s <> ":"){- <+> "-" <+> text (show e)-}: 143 len = endline - startLine
144 map text (take len $ drop startLine $ lines source) 144 str = vcat $ text (show s <> ":"){- <+> "-" <+> text (show e)-}:
145 ++ [text $ replicate (sourceColumn s - 1) ' ' ++ replicate (sourceColumn e - sourceColumn s) '^' | len == 1] 145 map text (take len $ drop startLine $ lines source)
146 ++ [text $ replicate (sourceColumn s - 1) ' ' ++ replicate (sourceColumn e - sourceColumn s) '^' | len == 1]
147 Nothing -> showSourcePosSI si
146 148
147showSourcePosSI (NoSI ds) = unwords $ Set.toList ds 149showSourcePosSI (NoSI ds) = unwords $ Set.toList ds
148showSourcePosSI (RangeSI (Range s _)) = show s 150showSourcePosSI (RangeSI (Range s _)) = show s
diff --git a/src/LambdaCube/Compiler/Parser.hs b/src/LambdaCube/Compiler/Parser.hs
index d643b746..0c728b4e 100644
--- a/src/LambdaCube/Compiler/Parser.hs
+++ b/src/LambdaCube/Compiler/Parser.hs
@@ -18,7 +18,6 @@ module LambdaCube.Compiler.Parser
18 , debug, LI, isPi, varDB, lowerDB, justDB, upDB, cmpDB, MaxDB (..), iterateN, traceD, parseLC 18 , debug, LI, isPi, varDB, lowerDB, justDB, upDB, cmpDB, MaxDB (..), iterateN, traceD, parseLC
19 , getParamsS, addParamsS, getApps, apps', downToS, addForalls 19 , getParamsS, addParamsS, getApps, apps', downToS, addForalls
20 , mkDesugarInfo, joinDesugarInfo 20 , mkDesugarInfo, joinDesugarInfo
21 , throwErrorTCM, ErrorMsg(..), ErrorT
22 , Up (..), up1, up 21 , Up (..), up1, up
23 , Doc, shLam, shApp, shLet, shLet_, shAtom, shAnn, shVar, epar, showDoc, showDoc_, sExpDoc, shCstr 22 , Doc, shLam, shApp, shLet, shLet_, shAtom, shAnn, shVar, epar, showDoc, showDoc_, sExpDoc, shCstr
24 , mtrace, sortDefs 23 , mtrace, sortDefs
@@ -59,14 +58,6 @@ instance Show (SData a) where show _ = "SData"
59instance Eq (SData a) where _ == _ = True 58instance Eq (SData a) where _ == _ = True
60instance Ord (SData a) where _ `compare` _ = EQ 59instance Ord (SData a) where _ `compare` _ = EQ
61 60
62newtype ErrorMsg = ErrorMsg String
63instance Show ErrorMsg where show (ErrorMsg s) = s
64
65type ErrorT = ExceptT ErrorMsg
66
67throwErrorTCM :: MonadError ErrorMsg m => P.Doc -> m a
68throwErrorTCM d = throwError $ ErrorMsg $ show d
69
70traceD x = if debug then trace_ x else id 61traceD x = if debug then trace_ x else id
71 62
72debug = False--True--tr 63debug = False--True--tr
@@ -1087,10 +1078,9 @@ parseModule f str = do
1087 , definitions = \ge -> first ((show +++ id) . snd) $ runP' (ge, ns) f (parseDefs SLabelEnd <* eof) st 1078 , definitions = \ge -> first ((show +++ id) . snd) $ runP' (ge, ns) f (parseDefs SLabelEnd <* eof) st
1088 } 1079 }
1089 1080
1090parseLC :: MonadError ErrorMsg m => FilePath -> String -> m Module 1081parseLC :: FilePath -> String -> Either ParseError Module
1091parseLC f str 1082parseLC f str
1092 = either (throwError . ErrorMsg . show) return 1083 = fst
1093 . fst
1094 . runP (error "globalenv used", Namespace (Just ExpLevel) True) f (parseModule f str) 1084 . runP (error "globalenv used", Namespace (Just ExpLevel) True) f (parseModule f str)
1095 $ str 1085 $ str
1096 1086