1#![doc = include_str!("readme.md")]
2use oak_core::source::{SourceBuffer, ToSource};
3
4#[derive(Clone, Debug)]
6pub struct WatRoot {
7 pub items: Vec<WatItem>,
9}
10
11impl ToSource for WatRoot {
12 fn to_source(&self, buffer: &mut SourceBuffer) {
13 for item in &self.items {
14 item.to_source(buffer);
15 buffer.push("\n")
16 }
17 }
18}
19
20#[derive(Clone, Debug)]
22pub enum WatItem {
23 Module(WatModule),
25}
26
27impl ToSource for WatItem {
28 fn to_source(&self, buffer: &mut SourceBuffer) {
29 match self {
30 WatItem::Module(m) => m.to_source(buffer),
31 }
32 }
33}
34
35#[derive(Clone, Debug)]
37pub struct WatModule {
38 pub name: Option<String>,
40 pub items: Vec<WatModuleField>,
42}
43
44impl ToSource for WatModule {
45 fn to_source(&self, buffer: &mut SourceBuffer) {
46 buffer.push("(module");
47 if let Some(name) = &self.name {
48 buffer.push(" ");
49 buffer.push(name)
50 }
51 for item in &self.items {
52 buffer.push("\n ");
53 item.to_source(buffer)
54 }
55 buffer.push(")")
56 }
57}
58
59#[derive(Clone, Debug)]
61pub enum WatModuleField {
62 Func(WatFunc),
64 Import(WatImport),
66 Export(WatExport),
68 Type(WatType),
70 Table(WatTable),
72 Memory(WatMemory),
74 Global(WatGlobal),
76}
77
78impl ToSource for WatModuleField {
79 fn to_source(&self, buffer: &mut SourceBuffer) {
80 match self {
81 WatModuleField::Func(f) => f.to_source(buffer),
82 WatModuleField::Import(i) => i.to_source(buffer),
83 WatModuleField::Export(e) => e.to_source(buffer),
84 WatModuleField::Type(t) => t.to_source(buffer),
85 WatModuleField::Table(t) => t.to_source(buffer),
86 WatModuleField::Memory(m) => m.to_source(buffer),
87 WatModuleField::Global(g) => g.to_source(buffer),
88 }
89 }
90}
91
92#[derive(Clone, Debug)]
94pub struct WatFunc {
95 pub name: Option<String>,
97 pub params: Vec<WatParam>,
99 pub results: Vec<WatResult>,
101 pub locals: Vec<WatLocal>,
103 pub body: Vec<WatInstruction>,
105}
106
107impl ToSource for WatFunc {
108 fn to_source(&self, buffer: &mut SourceBuffer) {
109 buffer.push("(func");
110 if let Some(name) = &self.name {
111 buffer.push(" ");
112 buffer.push(name)
113 }
114 for param in &self.params {
115 buffer.push(" ");
116 param.to_source(buffer)
117 }
118 for result in &self.results {
119 buffer.push(" ");
120 result.to_source(buffer)
121 }
122 for local in &self.locals {
123 buffer.push(" ");
124 local.to_source(buffer)
125 }
126 for instr in &self.body {
127 buffer.push("\n ");
128 instr.to_source(buffer)
129 }
130 buffer.push(")")
131 }
132}
133
134#[derive(Clone, Debug)]
136pub struct WatParam {
137 pub name: Option<String>,
139 pub ty: WatTypeKind,
141}
142
143impl ToSource for WatParam {
144 fn to_source(&self, buffer: &mut SourceBuffer) {
145 buffer.push("(param");
146 if let Some(name) = &self.name {
147 buffer.push(" ");
148 buffer.push(name)
149 }
150 buffer.push(" ");
151 self.ty.to_source(buffer);
152 buffer.push(")")
153 }
154}
155
156#[derive(Clone, Debug)]
158pub struct WatResult {
159 pub ty: WatTypeKind,
161}
162
163impl ToSource for WatResult {
164 fn to_source(&self, buffer: &mut SourceBuffer) {
165 buffer.push("(result ");
166 self.ty.to_source(buffer);
167 buffer.push(")")
168 }
169}
170
171#[derive(Clone, Debug)]
173pub struct WatLocal {
174 pub name: Option<String>,
176 pub ty: WatTypeKind,
178}
179
180impl ToSource for WatLocal {
181 fn to_source(&self, buffer: &mut SourceBuffer) {
182 buffer.push("(local");
183 if let Some(name) = &self.name {
184 buffer.push(" ");
185 buffer.push(name)
186 }
187 buffer.push(" ");
188 self.ty.to_source(buffer);
189 buffer.push(")")
190 }
191}
192
193#[derive(Clone, Debug)]
195pub enum WatTypeKind {
196 I32,
198 I64,
200 F32,
202 F64,
204}
205
206impl ToSource for WatTypeKind {
207 fn to_source(&self, buffer: &mut SourceBuffer) {
208 match self {
209 WatTypeKind::I32 => buffer.push("i32"),
210 WatTypeKind::I64 => buffer.push("i64"),
211 WatTypeKind::F32 => buffer.push("f32"),
212 WatTypeKind::F64 => buffer.push("f64"),
213 }
214 }
215}
216
217#[derive(Clone, Debug)]
219pub enum WatInstruction {
220 Unreachable,
222 Nop,
224 Drop,
226 Select,
228 Return,
230 LocalGet(String),
232 LocalSet(String),
234 LocalTee(String),
236 GlobalGet(String),
238 GlobalSet(String),
240 I32Const(i32),
242 I64Const(i64),
244 F32Const(f32),
246 F64Const(f64),
248 I32Add,
250 I32Sub,
252 I32Mul,
254 I64Add,
256 I64Sub,
258 I64Mul,
260 Other(String, Vec<String>),
262}
263
264impl ToSource for WatInstruction {
265 fn to_source(&self, buffer: &mut SourceBuffer) {
266 match self {
267 WatInstruction::Unreachable => buffer.push("unreachable"),
268 WatInstruction::Nop => buffer.push("nop"),
269 WatInstruction::Drop => buffer.push("drop"),
270 WatInstruction::Select => buffer.push("select"),
271 WatInstruction::Return => buffer.push("return"),
272 WatInstruction::LocalGet(id) => {
273 buffer.push("local.get ");
274 buffer.push(id);
275 }
276 WatInstruction::LocalSet(id) => {
277 buffer.push("local.set ");
278 buffer.push(id);
279 }
280 WatInstruction::LocalTee(id) => {
281 buffer.push("local.tee ");
282 buffer.push(id);
283 }
284 WatInstruction::GlobalGet(id) => {
285 buffer.push("global.get ");
286 buffer.push(id);
287 }
288 WatInstruction::GlobalSet(id) => {
289 buffer.push("global.set ");
290 buffer.push(id);
291 }
292 WatInstruction::I32Const(val) => {
293 buffer.push("i32.const ");
294 buffer.push(&val.to_string());
295 }
296 WatInstruction::I64Const(val) => {
297 buffer.push("i64.const ");
298 buffer.push(&val.to_string());
299 }
300 WatInstruction::F32Const(val) => {
301 buffer.push("f32.const ");
302 buffer.push(&val.to_string());
303 }
304 WatInstruction::F64Const(val) => {
305 buffer.push("f64.const ");
306 buffer.push(&val.to_string());
307 }
308 WatInstruction::I32Add => buffer.push("i32.add"),
309 WatInstruction::I32Sub => buffer.push("i32.sub"),
310 WatInstruction::I32Mul => buffer.push("i32.mul"),
311 WatInstruction::I64Add => buffer.push("i64.add"),
312 WatInstruction::I64Sub => buffer.push("i64.sub"),
313 WatInstruction::I64Mul => buffer.push("i64.mul"),
314 WatInstruction::Other(name, args) => {
315 buffer.push(name);
316 for arg in args {
317 buffer.push(" ");
318 buffer.push(arg);
319 }
320 }
321 }
322 }
323}
324
325#[derive(Clone, Debug)]
327pub struct WatImport {
328 pub module: String,
330 pub name: String,
332 pub kind: String,
334}
335
336impl ToSource for WatImport {
337 fn to_source(&self, buffer: &mut SourceBuffer) {
338 buffer.push("(import \"");
339 buffer.push(&self.module);
340 buffer.push("\" \"");
341 buffer.push(&self.name);
342 buffer.push("\" (");
343 buffer.push(&self.kind);
344 buffer.push("))")
345 }
346}
347
348#[derive(Clone, Debug)]
350pub struct WatExport {
351 pub name: String,
353 pub kind: String,
355 pub id: String,
357}
358
359impl ToSource for WatExport {
360 fn to_source(&self, buffer: &mut SourceBuffer) {
361 buffer.push("(export \"");
362 buffer.push(&self.name);
363 buffer.push("\" (");
364 buffer.push(&self.kind);
365 buffer.push(" ");
366 buffer.push(&self.id);
367 buffer.push("))")
368 }
369}
370
371#[derive(Clone, Debug)]
373pub struct WatType {
374 pub id: Option<String>,
376}
377
378impl ToSource for WatType {
379 fn to_source(&self, buffer: &mut SourceBuffer) {
380 buffer.push("(type");
381 if let Some(id) = &self.id {
382 buffer.push(" ");
383 buffer.push(id)
384 }
385 buffer.push(")")
386 }
387}
388
389#[derive(Clone, Debug)]
391pub struct WatTable {
392 pub id: Option<String>,
394 pub span: oak_core::Range<usize>,
396}
397
398impl ToSource for WatTable {
399 fn to_source(&self, buffer: &mut SourceBuffer) {
400 buffer.push("(table");
401 if let Some(id) = &self.id {
402 buffer.push(" ");
403 buffer.push(id)
404 }
405 buffer.push(")")
406 }
407}
408
409#[derive(Clone, Debug)]
411pub struct WatMemory {
412 pub id: Option<String>,
414 pub span: oak_core::Range<usize>,
416}
417
418impl ToSource for WatMemory {
419 fn to_source(&self, buffer: &mut SourceBuffer) {
420 buffer.push("(memory");
421 if let Some(id) = &self.id {
422 buffer.push(" ");
423 buffer.push(id)
424 }
425 buffer.push(")")
426 }
427}
428
429#[derive(Clone, Debug)]
431pub struct WatGlobal {
432 pub id: Option<String>,
434 pub ty: WatTypeKind,
436 pub mutable: bool,
438}
439
440impl ToSource for WatGlobal {
441 fn to_source(&self, buffer: &mut SourceBuffer) {
442 buffer.push("(global");
443 if let Some(id) = &self.id {
444 buffer.push(" ");
445 buffer.push(id)
446 }
447 buffer.push(" ");
448 if self.mutable {
449 buffer.push("(mut ");
450 self.ty.to_source(buffer);
451 buffer.push(")");
452 }
453 else {
454 self.ty.to_source(buffer);
455 }
456 buffer.push(")")
457 }
458}