less prototype, less bad code implementation of CCHM type theory
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

64 lines
2.1 KiB

  1. {-# LANGUAGE BlockArguments #-}
  2. {-# LANGUAGE OverloadedStrings #-}
  3. {-# LANGUAGE ScopedTypeVariables #-}
  4. module Main where
  5. import Control.Exception
  6. import qualified Data.ByteString.Lazy as Bsl
  7. import qualified Data.Text.Encoding as T
  8. import qualified Data.Map.Strict as Map
  9. import qualified Data.Text.IO as T
  10. import qualified Data.Text as T
  11. import Data.Text ( Text )
  12. import Data.Foldable
  13. import Elab.Monad
  14. import Elab.Eval
  15. import Elab
  16. import Presyntax.Presyntax (Posn(Posn))
  17. import Presyntax.Parser
  18. import Presyntax.Tokens
  19. import Presyntax.Lexer
  20. import System.Exit
  21. import Syntax.Pretty
  22. main :: IO ()
  23. main = do
  24. t <- Bsl.readFile "test.tt"
  25. let Right tks = runAlex t parseProg
  26. env <- runElab (checkProgram tks) emptyEnv `catch` \e -> displayAndDie (T.decodeUtf8 (Bsl.toStrict t)) (e :: SomeException)
  27. for_ (Map.toList (getEnv env)) $ \(n, x) -> putStrLn $ show n ++ " : " ++ showValue (zonk (fst x))
  28. displayAndDie :: Exception e => Text -> e -> IO a
  29. displayAndDie lines e = do
  30. () <- throwIO e `catches` displayExceptions lines
  31. exitFailure
  32. displayExceptions :: Text -> [Handler ()]
  33. displayExceptions lines =
  34. [ Handler \(WhileChecking a b e) -> do
  35. T.putStrLn $ squiggleUnder a b lines
  36. displayExceptions' lines e
  37. , Handler \(NotEqual ta tb) -> do
  38. putStrLn . unlines $
  39. [ "\x1b[1;31merror\x1b[0m: Mismatch between actual and expected types:"
  40. , " * \x1b[1mActual\x1b[0m: " ++ showValue (zonk ta)
  41. , " * \x1b[1mExpected\x1b[0m: " ++ showValue (zonk tb)
  42. ]
  43. ]
  44. displayExceptions' :: Exception e => Text -> e -> IO ()
  45. displayExceptions' lines e = displayAndDie lines e `catch` \(_ :: ExitCode) -> pure ()
  46. squiggleUnder :: Posn -> Posn -> Text -> Text
  47. squiggleUnder (Posn l c) (Posn l' c') file
  48. | l == l' =
  49. let
  50. line = T.pack (show l) <> " | " <> T.lines file !! (l - 1)
  51. padding = T.replicate (length (show l)) (T.singleton ' ') <> " |"
  52. squiggle = T.replicate c " " <> T.pack "\x1b[1;31m" <> T.replicate (c' - c) "~" <> T.pack "\x1b[0m"
  53. in T.unlines [ padding, line, padding <> squiggle ]
  54. | otherwise = T.pack (show (Posn l c, Posn l' c'))