forked from rhysd/wain
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wat.rs
135 lines (130 loc) · 3.06 KB
/
wat.rs
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
extern crate wain_exec;
extern crate wain_syntax_text;
extern crate wain_validate;
use futures::executor::block_on;
use std::process::exit;
use wain_exec::execute;
use wain_syntax_text::parse;
use wain_validate::validate;
// examples/hello/hello.wat
const HELLO_WORLD: &str = r#"
(module
(type (;0;) (func (param i32) (result i32)))
(type (;1;) (func (param i32)))
(type (;2;) (func))
(import "env" "putchar" (func $putchar (type 0)))
(func $print (type 1) (param i32)
(local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32)
global.get 0
local.set 1
i32.const 16
local.set 2
local.get 1
local.get 2
i32.sub
local.set 3
local.get 3
global.set 0
local.get 3
local.get 0
i32.store offset=12
block ;; label = @1
loop ;; label = @2
local.get 3
i32.load offset=12
local.set 4
local.get 4
i32.load8_u
local.set 5
i32.const 24
local.set 6
local.get 5
local.get 6
i32.shl
local.set 7
local.get 7
local.get 6
i32.shr_s
local.set 8
local.get 8
i32.eqz
br_if 1 (;@1;)
local.get 3
i32.load offset=12
local.set 9
local.get 9
i32.load8_u
local.set 10
i32.const 24
local.set 11
local.get 10
local.get 11
i32.shl
local.set 12
local.get 12
local.get 11
i32.shr_s
local.set 13
local.get 13
call $putchar
drop
local.get 3
i32.load offset=12
local.set 14
i32.const 1
local.set 15
local.get 14
local.get 15
i32.add
local.set 16
local.get 3
local.get 16
i32.store offset=12
br 0 (;@2;)
end
end
i32.const 16
local.set 17
local.get 3
local.get 17
i32.add
local.set 18
local.get 18
global.set 0
return)
(func $_start (type 2)
(local i32)
i32.const 1024
local.set 0
local.get 0
call $print
return)
(table (;0;) 1 1 funcref)
(memory (;0;) 2)
(global (;0;) (mut i32) (i32.const 66576))
(export "memory" (memory 0))
(export "_start" (func $_start))
(data (;0;) (i32.const 1024) "Hello, world\0a\00"))
"#;
fn main() {
block_on(async {
// Parse WAT text into syntax tree
let tree = match parse(HELLO_WORLD) {
Ok(tree) => tree,
Err(err) => {
eprintln!("Parse failed: {}", err);
exit(1);
}
};
// Validate module
if let Err(err) = validate(&tree) {
eprintln!("This .wat file is invalid: {}", err);
exit(1);
}
// Execute module
if let Err(trap) = execute(&tree.module).await {
eprintln!("Execution was trapped: {}", trap);
exit(1);
}
});
}