blob: 8846c81e08fafd7a40f80065b3c20933eadf9dee (
plain)
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
83
84
|
import Minilang.REPL (evaluatorFromEnv, withIO, withTerminal)
import Minilang.REPL.Types (Evaluator (..))
import Minilang.Server (startServer, waitServer)
import Options.Applicative
import System.IO (stdin, stdout)
import System.Posix.IO (stdInput)
import System.Posix.Terminal (queryTerminal)
import Text.Read (readMaybe)
data RunMode
= Local
| Server
deriving (Eq, Show)
data Options = Options
{ serverPort :: Int,
runMode :: RunMode,
-- | 'Nothing' means "read from MINILANG_EVAL env var".
evalOpt :: Maybe Evaluator
}
deriving (Eq, Show)
optionsParser :: ParserInfo Options
optionsParser =
info
(helper <*> minilangOptions)
( header "Minilang"
<> fullDesc
)
minilangOptions :: Parser Options
minilangOptions =
Options <$> portOption <*> runModeOption <*> evalOption
portOption :: Parser Int
portOption =
option
auto
( long "port"
<> short 'p'
<> value 7890
<> metavar "INT"
<> help "port to listen on (default: 7890)"
)
runModeOption :: Parser RunMode
runModeOption =
flag
Local
Server
( long "server"
<> short 'S'
<> help "run in server mode, listening for client REPLs over HTTP"
)
evalOption :: Parser (Maybe Evaluator)
evalOption =
optional $
option
(eitherReader parseEvaluator)
( long "eval"
<> short 'E'
<> metavar "EVALUATOR"
<> help "reduction strategy: DeBruijn (default) or NbE. \
\Falls back to the MINILANG_EVAL environment variable."
)
parseEvaluator :: String -> Either String Evaluator
parseEvaluator s = case readMaybe s of
Just ev -> Right ev
Nothing -> Left $ "Unknown evaluator: " <> show s <> ". Valid values: DeBruijn, NbE"
main :: IO ()
main = do
Options {..} <- execParser optionsParser
-- CLI flag takes precedence; fall back to env var.
ev <- maybe evaluatorFromEnv pure evalOpt
case runMode of
Local -> do
hasTty <- queryTerminal stdInput
if hasTty
then withTerminal ev
else withIO ev stdin stdout
Server -> startServer serverPort ev >>= waitServer
|