-
Notifications
You must be signed in to change notification settings - Fork 0
/
Main.hs
82 lines (72 loc) · 2.52 KB
/
Main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
{-
Main.hs
- http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/
- http://lxr.mozilla.org/mozilla/source/js/src/
-}
module Main where
import System.IO.Error hiding (try)
import Data.List
import System.Environment hiding (getEnv)
import System.Console.GetOpt
import System.Exit
import Control.Monad.State
import Control.Monad.Cont
import Parser
import ParserUtil
import DataTypes
import Context
import Eval
import Repl
import Init
run :: [Flag] -> Evaluate a -> IO ()
run flags thunk =
do nullEnv <- nullEnv flags
(withCC CExit $ setupEnv >> thunk >> return Void) `runContT` (const $ return Void) `evalStateT` nullEnv
return ()
runRepl :: [Flag] -> IO ()
runRepl flags =
run flags runReplWithTry
evalText :: String -> Evaluate Value
evalText input =
case parse input of
Left err -> liftIO $ do
printParseError input err
exitFailure -- XXX
Right program -> evalProgram program
evalFile :: [Flag] -> String -> IO ()
evalFile flags filename =
do content <- readFile filename
run flags $ try $ do
evalText content
when (EnterRepl `elem` flags)
(runReplWithTry)
options :: [OptDescr Flag]
options = [
Option ['d'] ["debug"] (NoArg Debug) "debug mode",
Option ['w'] ["warn"] (NoArg Warn) "turn on warnings",
Option ['p'] ["parse"] (NoArg ParseOnly) "only parse text (do not evaluate)",
Option ['e'] [] (ReqArg EvalStr "") "evaluate string",
Option ['r'] ["repl"] (NoArg EnterRepl) "enter repl (after reading file)",
Option ['V'] ["version"] (NoArg Version) "show version"
]
parseOpts :: [String] -> IO ([Flag], [String])
parseOpts argv =
case getOpt Permute options argv of
(o, n, []) -> return (o, n)
(_, _, errs) -> do progName <- getProgName
ioError $ userError $ concat errs ++ usageInfo ("Usage: " ++ progName ++ " [OPTION...] [file]") options
printVersion :: IO ()
printVersion =
putStrLn $ unwords $ words "jusk $Id$" \\ ["$Id:", "Main.hs", "motemen", "$"]
main :: IO ()
main =
do args <- getArgs
(flags, rest) <- parseOpts args
when (Version `elem` flags) printVersion
maybe (case length rest of
0 -> runRepl flags
_ -> evalFile flags $ rest !! 0)
(\(EvalStr string) -> run flags $ try $ evalText string)
(find isEvalStr flags)
where isEvalStr (EvalStr _) = True
isEvalStr _ = False