diff options
author | Péter Diviánszky <divipp@gmail.com> | 2016-02-13 13:11:21 +0100 |
---|---|---|
committer | Péter Diviánszky <divipp@gmail.com> | 2016-02-13 13:11:38 +0100 |
commit | 32abd090f36c19cdeef4ad0c475a22d715d9bee3 (patch) | |
tree | f0916f10dbee548039677b0d56c5ee924800fc9b /src/LambdaCube | |
parent | 5a2116c429a9762d17440e30b88572dc5d0cbadd (diff) |
add structure to error messages
Diffstat (limited to 'src/LambdaCube')
-rw-r--r-- | src/LambdaCube/Compiler.hs | 37 | ||||
-rw-r--r-- | src/LambdaCube/Compiler/Infer.hs | 72 | ||||
-rw-r--r-- | src/LambdaCube/Compiler/Lexer.hs | 20 | ||||
-rw-r--r-- | src/LambdaCube/Compiler/Parser.hs | 14 |
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 | ||
47 | import LambdaCube.IR as IR | 46 | import LambdaCube.IR as IR |
48 | import LambdaCube.Compiler.Pretty hiding ((</>)) | 47 | import LambdaCube.Compiler.Pretty hiding ((</>)) |
49 | import LambdaCube.Compiler.Infer (Infos, listInfos, ErrorMsg(..), PolyEnv(..), Export(..), Module(..), ErrorT, throwErrorTCM, parseLC, joinPolyEnvs, filterPolyEnv, inference_, ImportItems (..), Range(..), Exp, outputType, boolType, trueExp) | 48 | import LambdaCube.Compiler.Infer (Infos, listInfos, PolyEnv(..), Export(..), Module(..), showError, parseLC, joinPolyEnvs, filterPolyEnv, inference_, ImportItems (..), Range(..), Exp, outputType, boolType, trueExp) |
50 | import LambdaCube.Compiler.CoreToIR | 49 | import 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) | |||
55 | type EName = String | 54 | type EName = String |
56 | type MName = String | 55 | type MName = String |
57 | 56 | ||
58 | type Modules = Map FilePath (Either Doc PolyEnv) | 57 | type Modules = Map FilePath (Either Doc (PolyEnv, String)) |
59 | type ModuleFetcher m = Maybe FilePath -> MName -> m (FilePath, String) | 58 | type ModuleFetcher m = Maybe FilePath -> MName -> m (FilePath, String) |
60 | 59 | ||
61 | newtype MMT m a = MMT { runMMT :: ReaderT (ModuleFetcher (MMT m)) (ErrorT (StateT Modules (WriterT Infos m))) a } | 60 | newtype 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) |
63 | type MM = MMT IO | 62 | type MM = MMT IO |
64 | 63 | ||
65 | instance MonadMask m => MonadMask (ExceptT e m) where | 64 | instance MonadMask m => MonadMask (ExceptT e m) where |
@@ -68,7 +67,7 @@ instance MonadMask m => MonadMask (ExceptT e m) where | |||
68 | 67 | ||
69 | mapMMT f (MMT m) = MMT $ f m | 68 | mapMMT f (MMT m) = MMT $ f m |
70 | 69 | ||
71 | type Err a = (Either ErrorMsg a, Infos) | 70 | type Err a = (Either String a, Infos) |
72 | 71 | ||
73 | runMM :: Monad m => ModuleFetcher (MMT m) -> MMT m a -> m (Err a) | 72 | runMM :: Monad m => ModuleFetcher (MMT m) -> MMT m a -> m (Err a) |
74 | runMM fetcher | 73 | runMM 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 | ||
87 | catchMM :: Monad m => MMT m a -> (ErrorMsg -> MMT m a) -> MMT m a | 86 | catchMM :: Monad m => MMT m a -> (String -> MMT m a) -> MMT m a |
88 | catchMM m e = mapMMT (mapReaderT $ lift . runExceptT) m >>= either e return | 87 | catchMM 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) | |||
103 | ioFetch paths imp n = do | 102 | ioFetch 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 | ||
166 | filterImports (ImportAllBut ns) = not . (`elem` ns) | 165 | filterImports (ImportAllBut ns) = not . (`elem` ns) |
@@ -180,26 +179,26 @@ getDef m d ty = do | |||
180 | , infos pe | 179 | , infos pe |
181 | ) | 180 | ) |
182 | 181 | ||
183 | parseAndToCoreMain m = either (throwErrorTCM . text) return . (\(_, e, i) -> flip (,) i <$> e) =<< getDef m "main" (Just outputType) | 182 | parseAndToCoreMain 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 |
186 | compileMain :: [FilePath] -> IR.Backend -> MName -> IO (Either String IR.Pipeline) | 185 | compileMain :: [FilePath] -> IR.Backend -> MName -> IO (Either String IR.Pipeline) |
187 | compileMain path backend fname | 186 | compileMain 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 |
191 | removeEscapes = first ((\(ErrorMsg e) -> ErrorMsg (removeEscs e)) +++ id) | 190 | removeEscapes = 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 |
194 | preCompile :: (MonadMask m, MonadIO m) => [FilePath] -> [FilePath] -> Backend -> String -> IO (String -> m (Err (IR.Pipeline, Infos))) | 193 | preCompile :: (MonadMask m, MonadIO m) => [FilePath] -> [FilePath] -> Backend -> String -> IO (String -> m (Err (IR.Pipeline, Infos))) |
195 | preCompile paths paths' backend mod = do | 194 | preCompile 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 |
32 | import Data.Monoid | 33 | import Data.Monoid |
33 | import Data.Maybe | 34 | import Data.Maybe |
@@ -750,10 +751,26 @@ mkExpTypes t@(Pi _ a _) (x: xs) = (x, t): mkExpTypes (appTy t x) xs | |||
750 | appTy (Pi _ a b) x = subst 0 x b | 751 | appTy (Pi _ a b) x = subst 0 x b |
751 | appTy t x = error $ "appTy: " ++ show t | 752 | appTy t x = error $ "appTy: " ++ show t |
752 | 753 | ||
754 | -------------------------------------------------------------------------------- error messages | ||
755 | |||
756 | data ErrorMsg | ||
757 | = ErrorMsg String | ||
758 | | ECantFind SName SI | ||
759 | | ETypeError String SI | ||
760 | | ERedefined SName SI SI | ||
761 | |||
762 | showError :: Map.Map FilePath String -> ErrorMsg -> String | ||
763 | showError 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 |
756 | type IM m = ExceptT String (ReaderT (Extensions, String{-full source-}, GlobalEnv) (WriterT Infos m)) | 773 | type IM m = ExceptT ErrorMsg (ReaderT (Extensions, GlobalEnv) (WriterT Infos m)) |
757 | 774 | ||
758 | expAndType s (e, t, si) = (e, t) | 775 | expAndType 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 | ||
766 | getSource = asks $ \(_, s, _) -> s | ||
767 | |||
768 | getDef te si s = do | 783 | getDef 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 | {- |
773 | take' e n xs = case splitAt n xs of | 787 | take' 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 | ||
1192 | withEnv e = local (\(a,b,c) -> (a,b,c <> e)) | 1206 | withEnv e = local $ second (<> e) |
1193 | 1207 | ||
1194 | mkELet (False, n) x xt = x | 1208 | mkELet (False, n) x xt = x |
1195 | mkELet (True, n) x t{-type of x-} | 1209 | mkELet (True, n) x t{-type of x-} |
@@ -1229,22 +1243,20 @@ getLams (Lam b) = getLams b | |||
1229 | getLams x = x | 1243 | getLams x = x |
1230 | 1244 | ||
1231 | inferTerm :: Monad m => String -> Bool -> SExp2 -> IM m ExpType | 1245 | inferTerm :: Monad m => String -> Bool -> SExp2 -> IM m ExpType |
1232 | inferTerm msg tr t = ask >>= \(exs, _, _) -> smartTrace exs $ \tr -> | 1246 | inferTerm 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 |
1234 | inferType :: Monad m => Bool -> SExp2 -> IM m Type | 1248 | inferType :: Monad m => Bool -> SExp2 -> IM m Type |
1235 | inferType 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 | 1249 | inferType 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 | ||
1237 | addToEnv :: Monad m => SIName -> MFixity -> ExpType -> IM m GlobalEnv | 1251 | addToEnv :: Monad m => SIName -> MFixity -> ExpType -> IM m GlobalEnv |
1238 | addToEnv (si, s) mf (x, t) = do | 1252 | addToEnv (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 | {- |
1249 | joinEnv :: Monad m => GlobalEnv -> GlobalEnv -> IM m GlobalEnv | 1261 | joinEnv :: Monad m => GlobalEnv -> GlobalEnv -> IM m GlobalEnv |
1250 | joinEnv e1 e2 = do | 1262 | joinEnv e1 e2 = do |
@@ -1254,7 +1266,7 @@ downTo n m = map Var [n+m-1, n+m-2..n] | |||
1254 | 1266 | ||
1255 | defined' = Map.keys | 1267 | defined' = Map.keys |
1256 | 1268 | ||
1257 | addF = asks $ \(exs, _, ge) -> addForalls exs $ defined' ge | 1269 | addF = asks $ \(exs, ge) -> addForalls exs $ defined' ge |
1258 | 1270 | ||
1259 | tellType si t = tell $ mkInfoItem (sourceInfo si) $ removeEscs $ showDoc $ mkDoc True (t, TType) | 1271 | tellType si t = tell $ mkInfoItem (sourceInfo si) $ removeEscs $ showDoc $ mkDoc True (t, TType) |
1260 | tellStmtType si t = tellType si t | 1272 | tellStmtType si t = tellType si t |
@@ -1269,7 +1281,7 @@ data PolyEnv = PolyEnv | |||
1269 | 1281 | ||
1270 | filterPolyEnv p pe = pe { getPolyEnv = Map.filterWithKey (\k _ -> p k) $ getPolyEnv pe } | 1282 | filterPolyEnv p pe = pe { getPolyEnv = Map.filterWithKey (\k _ -> p k) $ getPolyEnv pe } |
1271 | 1283 | ||
1272 | joinPolyEnvs :: MonadError ErrorMsg m => Bool -> [PolyEnv] -> m PolyEnv | 1284 | joinPolyEnvs :: MonadError String m => Bool -> [PolyEnv] -> m PolyEnv |
1273 | joinPolyEnvs _ = return . foldr mappend' mempty' -- todo | 1285 | joinPolyEnvs _ = 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 | ||
1404 | smartTrace :: MonadError String m => Extensions -> (Bool -> m a) -> m a | 1416 | smartTrace :: MonadError ErrorMsg m => Extensions -> (Bool -> m a) -> m a |
1405 | smartTrace exs f | traceLevel exs >= 2 = f True | 1417 | smartTrace exs f | traceLevel exs >= 2 = f True |
1406 | smartTrace exs f | traceLevel exs == 0 = f False | 1418 | smartTrace exs f | traceLevel exs == 0 = f False |
1407 | smartTrace exs f = catchError (f False) $ \err -> | 1419 | smartTrace 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 | |||
1420 | mfix' f = ExceptT (mfix (runExceptT . f . either bomb id)) | 1432 | mfix' 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 | ||
1423 | inference_ :: PolyEnv -> Module -> String -> ErrorT (WriterT Infos Identity) PolyEnv | 1435 | inference_ :: PolyEnv -> Module -> ExceptT ErrorMsg (WriterT Infos Identity) PolyEnv |
1424 | inference_ (PolyEnv pe is) m src = do | 1436 | inference_ (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 | ||
137 | showSI_ _ (NoSI ds) = unwords $ Set.toList ds | 137 | showSI _ (NoSI ds) = unwords $ Set.toList ds |
138 | showSI_ source (RangeSI (Range s e)) = show str | 138 | showSI 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 | ||
147 | showSourcePosSI (NoSI ds) = unwords $ Set.toList ds | 149 | showSourcePosSI (NoSI ds) = unwords $ Set.toList ds |
148 | showSourcePosSI (RangeSI (Range s _)) = show s | 150 | showSourcePosSI (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" | |||
59 | instance Eq (SData a) where _ == _ = True | 58 | instance Eq (SData a) where _ == _ = True |
60 | instance Ord (SData a) where _ `compare` _ = EQ | 59 | instance Ord (SData a) where _ `compare` _ = EQ |
61 | 60 | ||
62 | newtype ErrorMsg = ErrorMsg String | ||
63 | instance Show ErrorMsg where show (ErrorMsg s) = s | ||
64 | |||
65 | type ErrorT = ExceptT ErrorMsg | ||
66 | |||
67 | throwErrorTCM :: MonadError ErrorMsg m => P.Doc -> m a | ||
68 | throwErrorTCM d = throwError $ ErrorMsg $ show d | ||
69 | |||
70 | traceD x = if debug then trace_ x else id | 61 | traceD x = if debug then trace_ x else id |
71 | 62 | ||
72 | debug = False--True--tr | 63 | debug = 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 | ||
1090 | parseLC :: MonadError ErrorMsg m => FilePath -> String -> m Module | 1081 | parseLC :: FilePath -> String -> Either ParseError Module |
1091 | parseLC f str | 1082 | parseLC 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 | ||