-
Notifications
You must be signed in to change notification settings - Fork 0
/
Main.lean
80 lines (65 loc) · 2.11 KB
/
Main.lean
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
import Wasm
import Cli
def version := "24.06.0"
open Cli
inductive Wasm.Output
| wat
| wasm
deriving Inhabited
def Wasm.outputText (p : Parsed) (msg : String) : IO UInt32 := do
match p.flag? "output" with
| .some file =>
let output := file.as! String
IO.FS.writeFile output msg
return 0
| .none =>
IO.println msg
return 0
def Wasm.outputBin (p : Parsed)
(input : System.FilePath)
(data : Wasm.Binary.ByteSeq)
: IO UInt32 := do
let output :=
match p.flag? "output" with
| .some file => file.as! String
| .none => input.withExtension "wasm"
IO.FS.writeBinFile output ⟨data.toArray⟩
return 0
def run (p : Parsed) : IO UInt32 := do
if !p.hasPositionalArg "input" then
panic! "Missing file argument"
let input : System.FilePath :=
p.positionalArg! "input" |>.as! String
if !(← input.pathExists) then
panic! s!"Input file does not exist: {input}"
if ← input.isDir then
panic! s!"Input path is a directory: {input}"
let emit : Wasm.Output :=
match p.flag? "emit" |>.map (·.as! String |>.toLower) with
| .some "wasm" => .wasm
| .some "wat" => .wat
| .some x => panic! s!"Unknown emit target '{x}'!"
| .none => .wat
-- must be a WASM file for now :)
let contents ← IO.FS.readBinFile input
let init := Wasm.Binary.Bytecode.State.new contents
match (Wasm.Binary.Module.ofOpcode).run init with
| (.error e, s) =>
IO.println s!"ERROR:\n\n{e}\n---"
IO.println s!"{String.intercalate "\n" s.log.reverse}\n"
return 1
| (.ok mod, s) =>
match emit with
| .wat => Wasm.outputText p (Wasm.Text.Module.toString mod)
| .wasm => Wasm.outputBin p input (Wasm.Binary.Module.toOpcode mod)
return 0
def topCmd : Cmd := `[Cli|
wasm VIA run; [version]
"A verified (WIP) implementation of WebAssembly"
FLAGS:
e, emit : String; "Specify the output format (either WAT or WASM)"
o, output : String; "Specify output file"
ARGS:
input : String; "The input file"
]
def main (args : List String) : IO UInt32 := topCmd.validate args