Skip to content

Commit 2bb8b07

Browse files
authored
extract codegen & introduce optparse-applicative (#73)
- introduce `optparse-applicative` to parse CLI input - extract `codegen` to simplify program With optparse, user can get CLI helps ```shell $ witc-exe -h instance Usage: witc-exe instance COMMAND Generate code for instance (wasm) Available commands: import Generate import code for instance (wasm) export Generate export code for instance (wasm) ```
2 parents 4630af2 + c25bff5 commit 2bb8b07

File tree

5 files changed

+93
-41
lines changed

5 files changed

+93
-41
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ and this project adheres to the
88

99
## Unreleased
1010

11+
- command line interface get improved (with `--help` and subcommand)
12+
- check imports existed, e.g. `use {a, b, c} from m` will ensure `m` does have type definition `a`, `b`, and `c`
13+
1114
## 0.1.0.0
1215

1316
- wasm interface types supporting

app/Main.hs

Lines changed: 82 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,59 +8,101 @@ cli design
88
-}
99
module Main (main) where
1010

11+
import Control.Monad
1112
import Data.Functor
1213
import Data.List (isSuffixOf)
14+
import Options.Applicative
1315
import Prettyprinter
1416
import Prettyprinter.Render.Terminal
1517
import System.Directory
16-
import System.Environment
1718
import Wit
1819

19-
handle :: [String] -> IO ()
20-
handle ["version"] = putStrLn "0.2.0"
21-
handle ["check", file] = checkFileWithDoneHint file
22-
handle ["check"] = do
20+
main :: IO ()
21+
main = do
22+
join $
23+
execParser
24+
( info
25+
(helper <*> versionOption <*> programOptions)
26+
( fullDesc
27+
<> progDesc "compiler for wit"
28+
<> header
29+
"witc - compiler for wit, a language for describing wasm interface types"
30+
)
31+
)
32+
where
33+
versionOption :: Parser (a -> a)
34+
versionOption = infoOption "0.2.0" (long "version" <> help "Show version")
35+
programOptions :: Parser (IO ())
36+
programOptions =
37+
subparser
38+
( command
39+
"check"
40+
( info
41+
(check <$> optional (strArgument (metavar "FILE" <> help "Name of the thing to create")))
42+
(progDesc "Validate wit file")
43+
)
44+
<> command
45+
"instance"
46+
( info
47+
( subparser
48+
( command
49+
"import"
50+
( info
51+
( codegen Import Instance
52+
<$> strArgument (metavar "FILE" <> help "Wit file")
53+
<*> strArgument (value "wasmedge" <> help "Name of import")
54+
)
55+
(progDesc "Generate import code for instance (wasm)")
56+
)
57+
<> command
58+
"export"
59+
( info
60+
((\f -> codegen Export Instance f "wasmedge") <$> strArgument (metavar "FILE" <> help "Wit file"))
61+
(progDesc "Generate export code for instance (wasm)")
62+
)
63+
)
64+
)
65+
(progDesc "Generate code for instance (wasm)")
66+
)
67+
<> command
68+
"runtime"
69+
( info
70+
( subparser
71+
( command
72+
"import"
73+
( info
74+
( codegen Import Runtime
75+
<$> strArgument (metavar "FILE" <> help "Wit file")
76+
<*> strArgument (value "wasmedge" <> help "Name of import")
77+
)
78+
(progDesc "Generate import code for runtime (WasmEdge)")
79+
)
80+
<> command
81+
"export"
82+
( info
83+
((\f -> codegen Export Runtime f "wasmedge") <$> strArgument (metavar "FILE" <> help "Wit file"))
84+
(progDesc "Generate export code for runtime (WasmEdge)")
85+
)
86+
)
87+
)
88+
(progDesc "Generate code for runtime (WasmEdge)")
89+
)
90+
)
91+
92+
check :: Maybe FilePath -> IO ()
93+
check (Just file) = checkFileWithDoneHint file
94+
check Nothing = do
2395
dir <- getCurrentDirectory
2496
witFileList <- filter (".wit" `isSuffixOf`) <$> listDirectory dir
2597
mapM_ checkFileWithDoneHint witFileList
26-
handle ["instance", "import", file, importName] =
27-
parseFile file
28-
>>= eitherIO check0
29-
>>= eitherIO (putDoc . prettyFile Config {language = Rust, direction = Import, side = Instance} importName)
30-
handle ["runtime", "import", file, importName] =
31-
parseFile file
32-
>>= eitherIO check0
33-
>>= eitherIO (putDoc . prettyFile Config {language = Rust, direction = Import, side = Runtime} importName)
34-
handle ["instance", mode, file] = do
35-
case mode of
36-
"import" ->
37-
parseFile file
38-
>>= eitherIO check0
39-
>>= eitherIO (putDoc . prettyFile Config {language = Rust, direction = Import, side = Instance} "wasmedge")
40-
"export" ->
41-
parseFile file
42-
>>= eitherIO check0
43-
>>= eitherIO (putDoc . prettyFile Config {language = Rust, direction = Export, side = Instance} "wasmedge")
44-
bad -> putStrLn $ "unknown option: " ++ bad
45-
handle ["runtime", mode, file] =
46-
case mode of
47-
"import" ->
48-
parseFile file
49-
>>= eitherIO check0
50-
>>= eitherIO (putDoc . prettyFile Config {language = Rust, direction = Import, side = Runtime} "wasmedge")
51-
"export" ->
52-
parseFile file
53-
>>= eitherIO check0
54-
>>= eitherIO (putDoc . prettyFile Config {language = Rust, direction = Export, side = Runtime} "wasmedge")
55-
bad -> putStrLn $ "unknown option: " ++ bad
56-
handle _ = putStrLn "bad usage"
5798

5899
checkFileWithDoneHint :: FilePath -> IO ()
59100
checkFileWithDoneHint file = do
60101
checkFile file $> ()
61102
putDoc $ pretty file <+> annotate (color Green) (pretty "OK") <+> line
62103

63-
main :: IO ()
64-
main = do
65-
args <- getArgs
66-
handle args
104+
codegen :: Direction -> Side -> FilePath -> String -> IO ()
105+
codegen d s file importName =
106+
parseFile file
107+
>>= eitherIO check0
108+
>>= eitherIO (putDoc . prettyFile Config {language = Rust, direction = d, side = s} importName)

bindings/rust/invoke-witc/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ fn name_value_meta(meta: &Meta) -> (String, String) {
1919
}
2020

2121
fn check_version() {
22-
let ver_output = Command::new("witc-exe").args(["version"]).output().unwrap();
22+
let ver_output = Command::new("witc-exe")
23+
.args(["--version"])
24+
.output()
25+
.unwrap();
2326
let ver = String::from_utf8(ver_output.stdout).unwrap();
2427
if ver != "0.2.0\n" {
2528
panic!("witc-exe version mismatch: expected 0.2.0, got {}", ver);

package.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies:
3232
- prettyprinter
3333
- prettyprinter-ansi-terminal
3434
- template-haskell
35+
- optparse-applicative
3536

3637
ghc-options:
3738
- -Wall

witc.cabal

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ library
5353
, directory
5454
, megaparsec
5555
, mtl
56+
, optparse-applicative
5657
, prettyprinter
5758
, prettyprinter-ansi-terminal
5859
, primitive
@@ -79,6 +80,7 @@ executable witc-exe
7980
, directory
8081
, megaparsec
8182
, mtl
83+
, optparse-applicative
8284
, prettyprinter
8385
, prettyprinter-ansi-terminal
8486
, primitive
@@ -111,6 +113,7 @@ test-suite witc-test
111113
, hspec-megaparsec
112114
, megaparsec
113115
, mtl
116+
, optparse-applicative
114117
, prettyprinter
115118
, prettyprinter-ansi-terminal
116119
, primitive

0 commit comments

Comments
 (0)