ref: c6a6f85900770fd7f140ef273d63a14d86fa853b
parent: 8ca938fdab80f32b770ce009c2fdb441a41a0109
author: Lennart Augustsson <lennart.augustsson@epicgames.com>
date: Thu Sep 21 08:51:21 EDT 2023
Use catch in Interactive.hs
--- a/Makefile
+++ b/Makefile
@@ -69,6 +69,7 @@
$(GHCC) -c lib/Control/Monad/State/Strict.hs
# $(GHCC) -c lib/Debug/Trace.hs
$(GHCC) -c lib/System/Console/SimpleReadline.hs
+ $(GHCC) -c lib/Control/Exception.hs
$(GHCC) -c src/Text/ParserComb.hs
$(GHCC) -c src/MicroHs/Ident.hs
$(GHCC) -c src/MicroHs/Expr.hs
--- a/TODO
+++ b/TODO
@@ -8,7 +8,6 @@
- Add SHA checksumming to the C code
- Use filename as the cache lookup key and SHA for validation
* make an interactive version
- - implement catch (and maybe throw) using setjmp & longjmp
- make the runtime system catch ^C and stop execution
* use pointer stack during GC instead of recursion.
* add Double primitive type
--- a/comb/mhs.comb
+++ b/comb/mhs.comb
@@ -1,3 +1,3 @@
v3.4
-874
-(($A :0 ((_664 _613) (($B ((($S' ($C (($C (($C $S') _3)) ((($C' ($C' $P)) ((($C' $B) _1) _596)) ($K ($K (_809 "Usage: mhs [-v] [-r] [-iPATH] [-oFILE] [ModuleName]"))))))) (($S (($S ((($S' _21) (($B _718) (_705 (_656 "-v")))) ((_734 _656) "-r"))) (($B (_699 (($O 46) $K))) (($B _763) (_704 ((_723 _785) "-i")))))) (($B (_764 _730)) ((($C' _701) (($B _763) (_704 ((_723 _785) "-o")))) (($O "out.comb") $K))))) (_705 ((_765 _805) ((_765 (_656 (($O 45) $K))) (_716 1)))))) (_726 ((_765 _805) (_656 "--")))))) (($A :1 ((($S' ($S' _664)) _30) (($B ($B ($B (_664 _695)))) ((($C' ($C' ($C' $C))) ((($C' $B) (($B ($C' $C)) ((($C' ($S' ($C' $C'))) (($B ($B ($B $C))) ((($C' ($C' ($C' $C))) ((($C' ($C' ($C' ($C' $S')))) (($B ($B ($B ($B $C)))) ((($C' ($C' ($C' ($C' $C)))) ((($C' ($C' ($C' ($S' ($C' $S'))))) ((($C' ($C' ($C' ($C' ($C' $C'))))) ((($C' ($S' ($C' ($C' ($C' $C'))))) (($B ($B ($B ($B $B')))) ((($C' ($S' ($C' $B))) (($B ($B ($B $C))) ((($S' $B) ($B' (($B ($S' $C')) (($B $B') (($B ($B _665)) ((($C' $B) (($B _764) (($B _685) ((($C' _800) _22) 0)))) (($B (_764 _688)) (($B (_701 "top level defns: ")) _644)))))))) ((($S' ($C' $B)) (($B $B') (($B $B') (($B $B') (($B ($B _665)) ((($C' $B) (($B _764) (($B _685) ((($C' _800) _22) 1)))) (_684 ($T (($B ($B (_764 _688))) ((($C' $B) (($B _701) ((($C' _701) _602) " = "))) (($C _422) $K))))))))))) ((($C' ($C' ($C' ($C' $B)))) ((($S' $B) ($B' ($B' _23))) ((($S' $B) (($B ($C' ($C' _665))) ((($C' $B) ($B' (($B _764) (($B _690) _25)))) (($B _701) ((($C' _701) (($B (_701 _2)) _644)) (($O 10) $K)))))) (($B ($B (_664 _695))) ((($C' $B) ($B' (($B _764) (($B _685) ((($C' _800) _22) 0))))) (($B ($B (_764 _688))) ((($C' ($C' _701)) (($B ($B (_701 "final pass "))) (($B ($B (_658 6))) (($B ($B _644)) _794)))) "ms"))))))) _16))))) ($C $P)))) ((($C' ($C' $C)) (($B (($C' $C) (($B ($C _706)) _422))) (($C _719) (_735 0)))) $K))) (($B ($C $B)) (($B ($B ($C $B))) (($B ($B $BK)) (($B ($B (($C' $B) (($B _765) (($B _701) ((($C' _701) (($B (_701 "(($A :")) _644)) (($O 32) $K))))))) ((($C' $B) (($B ($C' _765)) ($B _422))) (($B (_765 (_701 ") "))) (($C _765) (_701 (($O 41) $K))))))))))) $T)) (($B $Y) ((($C' ($C' $S)) ((($C' ($C' $S)) ((($C' $B) $P) ((($S' ($C' $B)) ($B _397)) $I))) ($BK $K))) $K))))) (($B (($S' _764) (($B _761) (($B (_764 _809)) (($B (_701 "main: findIdent: ")) _602))))) (($C' _632) _599)))) _639))) (($B ($B _636)) (($B (($C' _703) (($B $T) (($B ($C $B)) (($B ($B $BK)) ((($C' ($C' ($C' $O))) ($B (($C' $P) _599))) $K)))))) (($C _719) (_735 0))))))) (($C _605) (_596 "main")))) (($B (_764 _396)) (($B (_764 _596)) (($B (_701 (($O 95) $K))) _644))))))) (($A :2 "v3.4\10&") (($A :3 (($B (_665 (_688 "Type ':quit' to quit"))) ((($C' _664) (($B (_570 _5)) ($P _4))) ($K (_666 _811))))) (($A :4 ((_701 ((_701 ((_701 ((_701 "module ") _6)) "(module ")) _6)) ") where\10&import Prelude\10&import Unsafe.Coerce\10&")) (($A :5 ((_571 ((_764 _580) ((_13 ".mhsi") "> "))) (($P _5) (($C (($S (($C $equal) ":quit")) ((($C' _572) _9) _5))) ((_764 _580) (_688 "Bye")))))) (($A :6 "Interactive") (($A :7 "_it") (($A :8 ((($C' _701) (_701 ((_701 ((_701 ((_701 _7) " :: Any\10&")) _7)) " = unsafeCoerce ("))) ")\10&")) (($A :9 (($B (_571 _579)) (($B $T) ((($S' ($S' $B)) (($B ($B _571)) (($B ($B _10)) (($B (($C' _701) (($C _701) (($O 10) $K)))) _8)))) ((($C' ($C' ($C' $P))) (($B ($B $BK)) (($B ($B (($C' (($S' _571) _10)) (($B ($B ($P (($B (_764 _580)) _688)))) (($B $BK) (($B ($B _578)) ($C $P))))))) ((($C' ($C' _701)) ($C _701)) (($O 10) $K))))) _11))))) (($A :10 ((($C' _572) (($B (_764 _580)) (_690 ((_701 _6) ".hs")))) ((_571 (_575 _773)) ((($C' _571) (($B (_764 _580)) (($C _30) (_596 _6)))) (($B _573) _776))))) (($A :11 (($B (($B (_764 _580)) (($S (($S _870) (($S (($C _871) (_688 "Type must be Int or IO"))) _20))) (($B (_764 _688)) (($B (_764 _644)) _20))))) (($B _17) ($P (_596 ((_701 ((_701 _6) (($O 46) $K))) _7)))))) (($A :12 ((($C' _665) _686) ((_664 (((_15 (($P _698) _698)) $K) $K)) ($T ($K _666))))) (($A :13 ((($S' $B) (($B _664) (($C _678) _660))) (($B ($B (($C' _664) (($P (_666 _698)) ((($C' _664) _692) (($B ((($S' _6\ No newline at end of file
+878
+(($A :0 ((_668 _617) (($B ((($S' ($C (($C (($C $S') _3)) ((($C' ($C' $P)) ((($C' $B) _1) _600)) ($K ($K (_813 "Usage: mhs [-v] [-r] [-iPATH] [-oFILE] [ModuleName]"))))))) (($S (($S ((($S' _25) (($B _722) (_709 (_660 "-v")))) ((_738 _660) "-r"))) (($B (_703 (($O 46) $K))) (($B _767) (_708 ((_727 _789) "-i")))))) (($B (_768 _734)) ((($C' _705) (($B _767) (_708 ((_727 _789) "-o")))) (($O "out.comb") $K))))) (_709 ((_769 _809) ((_769 (_660 (($O 45) $K))) (_720 1)))))) (_730 ((_769 _809) (_660 "--")))))) (($A :1 ((($S' ($S' _668)) _34) (($B ($B ($B (_668 _699)))) ((($C' ($C' ($C' $C))) ((($C' $B) (($B ($C' $C)) ((($C' ($S' ($C' $C'))) (($B ($B ($B $C))) ((($C' ($C' ($C' $C))) ((($C' ($C' ($C' ($C' $S')))) (($B ($B ($B ($B $C)))) ((($C' ($C' ($C' ($C' $C)))) ((($C' ($C' ($C' ($S' ($C' $S'))))) ((($C' ($C' ($C' ($C' ($C' $C'))))) ((($C' ($S' ($C' ($C' ($C' $C'))))) (($B ($B ($B ($B $B')))) ((($C' ($S' ($C' $B))) (($B ($B ($B $C))) ((($S' $B) ($B' (($B ($S' $C')) (($B $B') (($B ($B _669)) ((($C' $B) (($B _768) (($B _689) ((($C' _804) _26) 0)))) (($B (_768 _692)) (($B (_705 "top level defns: ")) _648)))))))) ((($S' ($C' $B)) (($B $B') (($B $B') (($B $B') (($B ($B _669)) ((($C' $B) (($B _768) (($B _689) ((($C' _804) _26) 1)))) (_688 ($T (($B ($B (_768 _692))) ((($C' $B) (($B _705) ((($C' _705) _606) " = "))) (($C _426) $K))))))))))) ((($C' ($C' ($C' ($C' $B)))) ((($S' $B) ($B' ($B' _27))) ((($S' $B) (($B ($C' ($C' _669))) ((($C' $B) ($B' (($B _768) (($B _694) _29)))) (($B _705) ((($C' _705) (($B (_705 _2)) _648)) (($O 10) $K)))))) (($B ($B (_668 _699))) ((($C' $B) ($B' (($B _768) (($B _689) ((($C' _804) _26) 0))))) (($B ($B (_768 _692))) ((($C' ($C' _705)) (($B ($B (_705 "final pass "))) (($B ($B (_662 6))) (($B ($B _648)) _798)))) "ms"))))))) _20))))) ($C $P)))) ((($C' ($C' $C)) (($B (($C' $C) (($B ($C _710)) _426))) (($C _723) (_739 0)))) $K))) (($B ($C $B)) (($B ($B ($C $B))) (($B ($B $BK)) (($B ($B (($C' $B) (($B _769) (($B _705) ((($C' _705) (($B (_705 "(($A :")) _648)) (($O 32) $K))))))) ((($C' $B) (($B ($C' _769)) ($B _426))) (($B (_769 (_705 ") "))) (($C _769) (_705 (($O 41) $K))))))))))) $T)) (($B $Y) ((($C' ($C' $S)) ((($C' ($C' $S)) ((($C' $B) $P) ((($S' ($C' $B)) ($B _401)) $I))) ($BK $K))) $K))))) (($B (($S' _768) (($B _765) (($B (_768 _813)) (($B (_705 "main: findIdent: ")) _606))))) (($C' _636) _603)))) _643))) (($B ($B _640)) (($B (($C' _707) (($B $T) (($B ($C $B)) (($B ($B $BK)) ((($C' ($C' ($C' $O))) ($B (($C' $P) _603))) $K)))))) (($C _723) (_739 0))))))) (($C _609) (_600 "main")))) (($B (_768 _400)) (($B (_768 _600)) (($B (_705 (($O 95) $K))) _648))))))) (($A :2 "v3.4\10&") (($A :3 (($B (_669 (_692 "Type ':quit' to quit"))) ((($C' _668) (($B (_574 _5)) ($P _4))) ($K (_670 _815))))) (($A :4 ((_705 ((_705 ((_705 ((_705 "module ") _6)) "(module ")) _6)) ") where\10&import Prelude\10&import Unsafe.Coerce\10&")) (($A :5 ((_575 ((_768 _584) ((_13 ".mhsi") "> "))) (($P _5) (($C (($S (($C $equal) ":quit")) ((($C' _576) _9) _5))) ((_768 _584) (_692 "Bye")))))) (($A :6 "Interactive") (($A :7 "_it") (($A :8 ((($C' _705) (_705 ((_705 ((_705 ((_705 _7) " :: Any\10&")) _7)) " = unsafeCoerce ("))) ")\10&")) (($A :9 (($B (_575 _583)) (($B $T) ((($S' ($S' $B)) (($B ($B _575)) (($B ($B _10)) (($B (($C' _705) (($C _705) (($O 10) $K)))) _8)))) ((($C' ($C' ($C' $P))) (($B ($B $BK)) (($B ($B (($C' (($S' _575) _10)) (($B ($B ($P (($B (_768 _584)) _692)))) (($B $BK) (($B ($B _582)) ($C $P))))))) ((($C' ($C' _705)) ($C _705)) (($O 10) $K))))) _11))))) (($A :10 ((($C' _576) (($B (_768 _584)) (_694 ((_705 _6) ".hs")))) ((_575 (_579 _777)) (($B (_768 _584)) (($B (_768 _18)) (($C _34) (_600 _6))))))) (($A :11 (($B (($C ((($C' $B) (($B _575) (($B (_768 _584)) (($B _18) (($S _701) _670))))) (($B ($B (_768 _584))) (($S $P) ((($C' $S) (($B ($S _874)) (($B ($S (($C _875) (_692 "Type must be Int or IO")))) (($B (($C' _668) (($B _18) _24))) (($C $P) ($K (_670 _815))))))) (($B (_768 _692)) (($B (_768 _648)) _24))))))) (($B (_768 _692)) (_705 "Error: ")))) (($B _21) ($P (_600 ((_705 ((_705 _6) (($O 46) $K))) _7)))))) (($A :12 ((($C' _66\ No newline at end of file
--- a/src/Compat.hs
+++ b/src/Compat.hs
@@ -2,6 +2,7 @@
-- See LICENSE file for full license.
-- Functions for GHC that are defined in the UHS libs.
module Compat(module Compat) where
+--import Control.Exception
import qualified Data.Function as F
import Data.Time
import Data.Time.Clock.POSIX
@@ -181,3 +182,7 @@
primIsInt = error "isInt"
primIsIO :: Any -> Bool
primIsIO = error "isIO"
+
+newtype Exn = Exn String
+ deriving (Show)
+instance Exception Exn
--- a/src/MicroHs/Interactive.hs
+++ b/src/MicroHs/Interactive.hs
@@ -1,5 +1,6 @@
module MicroHs.Interactive(module MicroHs.Interactive) where
import Prelude
+import Control.Exception
import qualified MicroHs.StateIO as S
import MicroHs.Compile
import MicroHs.Exp(Exp)
@@ -17,6 +18,7 @@
mainInteractive :: Flags -> IO ()
mainInteractive flags = do
+ putStrLn "Welcome to interactive MicroHs!"
putStrLn "Type ':quit' to quit"
_ <- S.runStateIO repl (preamble, flags)
return ()
@@ -53,23 +55,30 @@
let lls = ls ++ line ++ "\n"
defTest <- tryCompile lls
case defTest of
- Right _ -> S.put (lls, flgs)
- Left s -> S.liftIO $ putStrLn s
+ Right _ -> S.put (lls, flgs)
+ Left (Exn s) -> S.liftIO $ putStrLn s
-tryCompile :: String -> I (Either String [LDef])
+tryCompile :: String -> I (Either Exn [LDef])
tryCompile file = S.do
S.liftIO $ writeFile (interactiveName ++ ".hs") file
flgs <- S.gets snd
- cmdl <- S.liftIO $ compileTop flgs (mkIdent interactiveName)
- S.return (Right cmdl)
+ S.liftIO $ try $ compileTop flgs (mkIdent interactiveName)
evalExpr :: [LDef] -> I ()
evalExpr cmdl = S.do
- let val = translate (mkIdent (interactiveName ++ "." ++ itName), cmdl)
+ let res = translate (mkIdent (interactiveName ++ "." ++ itName), cmdl)
+ err s = putStrLn $ "Error: " ++ s
+ mval <- S.liftIO $ try (seq res (return res))
S.liftIO $
- if primIsInt val then
- putStrLn $ showInt $ unsafeCoerce val
- else if primIsIO val then
- unsafeCoerce val
- else
- putStrLn "Type must be Int or IO"
+ case mval of
+ Left (Exn s) -> err s
+ Right val ->
+ if primIsInt val then
+ putStrLn $ showInt $ unsafeCoerce val
+ else if primIsIO val then do
+ mio <- try (unsafeCoerce val)
+ case mio of
+ Left (Exn s) -> err s
+ Right _ -> return ()
+ else
+ putStrLn "Type must be Int or IO"
--
⑨