1use crate::{ast::*, interpreter::Instruction, types::*, vec1::Vec1};
4pub use wast::parser::ParseBuffer as Buffer;
5use wast::parser::{self, Cursor, Parse, Parser, Peek, Result};
6
7mod keyword {
8 pub use wast::{
9 custom_keyword,
10 kw::{anyref, export, f32, f64, func, i32, i64, import, param, result},
11 };
12
13 custom_keyword!(implement);
15 custom_keyword!(r#type = "type");
16 custom_keyword!(record);
17 custom_keyword!(field);
18
19 custom_keyword!(s8);
21 custom_keyword!(s16);
22 custom_keyword!(s32);
23 custom_keyword!(s64);
24 custom_keyword!(u8);
25 custom_keyword!(u16);
26 custom_keyword!(u32);
27 custom_keyword!(u64);
28 custom_keyword!(string);
29
30 custom_keyword!(argument_get = "arg.get");
32 custom_keyword!(call_core = "call-core");
33 custom_keyword!(s8_from_i32 = "s8.from_i32");
34 custom_keyword!(s8_from_i64 = "s8.from_i64");
35 custom_keyword!(s16_from_i32 = "s16.from_i32");
36 custom_keyword!(s16_from_i64 = "s16.from_i64");
37 custom_keyword!(s32_from_i32 = "s32.from_i32");
38 custom_keyword!(s32_from_i64 = "s32.from_i64");
39 custom_keyword!(s64_from_i32 = "s64.from_i32");
40 custom_keyword!(s64_from_i64 = "s64.from_i64");
41 custom_keyword!(i32_from_s8 = "i32.from_s8");
42 custom_keyword!(i32_from_s16 = "i32.from_s16");
43 custom_keyword!(i32_from_s32 = "i32.from_s32");
44 custom_keyword!(i32_from_s64 = "i32.from_s64");
45 custom_keyword!(i64_from_s8 = "i64.from_s8");
46 custom_keyword!(i64_from_s16 = "i64.from_s16");
47 custom_keyword!(i64_from_s32 = "i64.from_s32");
48 custom_keyword!(i64_from_s64 = "i64.from_s64");
49 custom_keyword!(u8_from_i32 = "u8.from_i32");
50 custom_keyword!(u8_from_i64 = "u8.from_i64");
51 custom_keyword!(u16_from_i32 = "u16.from_i32");
52 custom_keyword!(u16_from_i64 = "u16.from_i64");
53 custom_keyword!(u32_from_i32 = "u32.from_i32");
54 custom_keyword!(u32_from_i64 = "u32.from_i64");
55 custom_keyword!(u64_from_i32 = "u64.from_i32");
56 custom_keyword!(u64_from_i64 = "u64.from_i64");
57 custom_keyword!(i32_from_u8 = "i32.from_u8");
58 custom_keyword!(i32_from_u16 = "i32.from_u16");
59 custom_keyword!(i32_from_u32 = "i32.from_u32");
60 custom_keyword!(i32_from_u64 = "i32.from_u64");
61 custom_keyword!(i64_from_u8 = "i64.from_u8");
62 custom_keyword!(i64_from_u16 = "i64.from_u16");
63 custom_keyword!(i64_from_u32 = "i64.from_u32");
64 custom_keyword!(i64_from_u64 = "i64.from_u64");
65 custom_keyword!(string_lift_memory = "string.lift_memory");
66 custom_keyword!(string_lower_memory = "string.lower_memory");
67 custom_keyword!(string_size = "string.size");
68 custom_keyword!(record_lift = "record.lift");
69 custom_keyword!(record_lower = "record.lower");
70}
71
72impl Parse<'_> for InterfaceType {
73 fn parse(parser: Parser<'_>) -> Result<Self> {
74 let mut lookahead = parser.lookahead1();
75
76 if lookahead.peek::<keyword::s8>() {
77 parser.parse::<keyword::s8>()?;
78
79 Ok(InterfaceType::S8)
80 } else if lookahead.peek::<keyword::s16>() {
81 parser.parse::<keyword::s16>()?;
82
83 Ok(InterfaceType::S16)
84 } else if lookahead.peek::<keyword::s32>() {
85 parser.parse::<keyword::s32>()?;
86
87 Ok(InterfaceType::S32)
88 } else if lookahead.peek::<keyword::s64>() {
89 parser.parse::<keyword::s64>()?;
90
91 Ok(InterfaceType::S64)
92 } else if lookahead.peek::<keyword::u8>() {
93 parser.parse::<keyword::u8>()?;
94
95 Ok(InterfaceType::U8)
96 } else if lookahead.peek::<keyword::u16>() {
97 parser.parse::<keyword::u16>()?;
98
99 Ok(InterfaceType::U16)
100 } else if lookahead.peek::<keyword::u32>() {
101 parser.parse::<keyword::u32>()?;
102
103 Ok(InterfaceType::U32)
104 } else if lookahead.peek::<keyword::u64>() {
105 parser.parse::<keyword::u64>()?;
106
107 Ok(InterfaceType::U64)
108 } else if lookahead.peek::<keyword::f32>() {
109 parser.parse::<keyword::f32>()?;
110
111 Ok(InterfaceType::F32)
112 } else if lookahead.peek::<keyword::f64>() {
113 parser.parse::<keyword::f64>()?;
114
115 Ok(InterfaceType::F64)
116 } else if lookahead.peek::<keyword::string>() {
117 parser.parse::<keyword::string>()?;
118
119 Ok(InterfaceType::String)
120 } else if lookahead.peek::<keyword::anyref>() {
121 parser.parse::<keyword::anyref>()?;
122
123 Ok(InterfaceType::Anyref)
124 } else if lookahead.peek::<keyword::i32>() {
125 parser.parse::<keyword::i32>()?;
126
127 Ok(InterfaceType::I32)
128 } else if lookahead.peek::<keyword::i64>() {
129 parser.parse::<keyword::i64>()?;
130
131 Ok(InterfaceType::I64)
132 } else if lookahead.peek::<keyword::record>() {
133 Ok(InterfaceType::Record(parser.parse()?))
134 } else {
135 Err(lookahead.error())
136 }
137 }
138}
139
140impl Parse<'_> for RecordType {
141 fn parse(parser: Parser<'_>) -> Result<Self> {
142 parser.parse::<keyword::record>()?;
143
144 let mut fields = vec![];
145
146 while !parser.is_empty() {
147 fields.push(parser.parens(|parser| {
148 parser.parse::<keyword::field>()?;
149
150 parser.parse()
151 })?);
152 }
153
154 Ok(RecordType {
155 fields: Vec1::new(fields).expect("Record must have at least one field, zero given."),
156 })
157 }
158}
159
160impl<'a> Parse<'a> for Instruction {
161 #[allow(clippy::cognitive_complexity)]
162 fn parse(parser: Parser<'a>) -> Result<Self> {
163 let mut lookahead = parser.lookahead1();
164
165 if lookahead.peek::<keyword::argument_get>() {
166 parser.parse::<keyword::argument_get>()?;
167
168 Ok(Instruction::ArgumentGet {
169 index: parser.parse()?,
170 })
171 } else if lookahead.peek::<keyword::call_core>() {
172 parser.parse::<keyword::call_core>()?;
173
174 Ok(Instruction::CallCore {
175 function_index: parser.parse::<u32>()?,
176 })
177 } else if lookahead.peek::<keyword::s8_from_i32>() {
178 parser.parse::<keyword::s8_from_i32>()?;
179
180 Ok(Instruction::S8FromI32)
181 } else if lookahead.peek::<keyword::s8_from_i64>() {
182 parser.parse::<keyword::s8_from_i64>()?;
183
184 Ok(Instruction::S8FromI64)
185 } else if lookahead.peek::<keyword::s16_from_i32>() {
186 parser.parse::<keyword::s16_from_i32>()?;
187
188 Ok(Instruction::S16FromI32)
189 } else if lookahead.peek::<keyword::s16_from_i64>() {
190 parser.parse::<keyword::s16_from_i64>()?;
191
192 Ok(Instruction::S16FromI64)
193 } else if lookahead.peek::<keyword::s32_from_i32>() {
194 parser.parse::<keyword::s32_from_i32>()?;
195
196 Ok(Instruction::S32FromI32)
197 } else if lookahead.peek::<keyword::s32_from_i64>() {
198 parser.parse::<keyword::s32_from_i64>()?;
199
200 Ok(Instruction::S32FromI64)
201 } else if lookahead.peek::<keyword::s64_from_i32>() {
202 parser.parse::<keyword::s64_from_i32>()?;
203
204 Ok(Instruction::S64FromI32)
205 } else if lookahead.peek::<keyword::s64_from_i64>() {
206 parser.parse::<keyword::s64_from_i64>()?;
207
208 Ok(Instruction::S64FromI64)
209 } else if lookahead.peek::<keyword::i32_from_s8>() {
210 parser.parse::<keyword::i32_from_s8>()?;
211
212 Ok(Instruction::I32FromS8)
213 } else if lookahead.peek::<keyword::i32_from_s16>() {
214 parser.parse::<keyword::i32_from_s16>()?;
215
216 Ok(Instruction::I32FromS16)
217 } else if lookahead.peek::<keyword::i32_from_s32>() {
218 parser.parse::<keyword::i32_from_s32>()?;
219
220 Ok(Instruction::I32FromS32)
221 } else if lookahead.peek::<keyword::i32_from_s64>() {
222 parser.parse::<keyword::i32_from_s64>()?;
223
224 Ok(Instruction::I32FromS64)
225 } else if lookahead.peek::<keyword::i64_from_s8>() {
226 parser.parse::<keyword::i64_from_s8>()?;
227
228 Ok(Instruction::I64FromS8)
229 } else if lookahead.peek::<keyword::i64_from_s16>() {
230 parser.parse::<keyword::i64_from_s16>()?;
231
232 Ok(Instruction::I64FromS16)
233 } else if lookahead.peek::<keyword::i64_from_s32>() {
234 parser.parse::<keyword::i64_from_s32>()?;
235
236 Ok(Instruction::I64FromS32)
237 } else if lookahead.peek::<keyword::i64_from_s64>() {
238 parser.parse::<keyword::i64_from_s64>()?;
239
240 Ok(Instruction::I64FromS64)
241 } else if lookahead.peek::<keyword::u8_from_i32>() {
242 parser.parse::<keyword::u8_from_i32>()?;
243
244 Ok(Instruction::U8FromI32)
245 } else if lookahead.peek::<keyword::u8_from_i64>() {
246 parser.parse::<keyword::u8_from_i64>()?;
247
248 Ok(Instruction::U8FromI64)
249 } else if lookahead.peek::<keyword::u16_from_i32>() {
250 parser.parse::<keyword::u16_from_i32>()?;
251
252 Ok(Instruction::U16FromI32)
253 } else if lookahead.peek::<keyword::u16_from_i64>() {
254 parser.parse::<keyword::u16_from_i64>()?;
255
256 Ok(Instruction::U16FromI64)
257 } else if lookahead.peek::<keyword::u32_from_i32>() {
258 parser.parse::<keyword::u32_from_i32>()?;
259
260 Ok(Instruction::U32FromI32)
261 } else if lookahead.peek::<keyword::u32_from_i64>() {
262 parser.parse::<keyword::u32_from_i64>()?;
263
264 Ok(Instruction::U32FromI64)
265 } else if lookahead.peek::<keyword::u64_from_i32>() {
266 parser.parse::<keyword::u64_from_i32>()?;
267
268 Ok(Instruction::U64FromI32)
269 } else if lookahead.peek::<keyword::u64_from_i64>() {
270 parser.parse::<keyword::u64_from_i64>()?;
271
272 Ok(Instruction::U64FromI64)
273 } else if lookahead.peek::<keyword::i32_from_u8>() {
274 parser.parse::<keyword::i32_from_u8>()?;
275
276 Ok(Instruction::I32FromU8)
277 } else if lookahead.peek::<keyword::i32_from_u16>() {
278 parser.parse::<keyword::i32_from_u16>()?;
279
280 Ok(Instruction::I32FromU16)
281 } else if lookahead.peek::<keyword::i32_from_u32>() {
282 parser.parse::<keyword::i32_from_u32>()?;
283
284 Ok(Instruction::I32FromU32)
285 } else if lookahead.peek::<keyword::i32_from_u64>() {
286 parser.parse::<keyword::i32_from_u64>()?;
287
288 Ok(Instruction::I32FromU64)
289 } else if lookahead.peek::<keyword::i64_from_u8>() {
290 parser.parse::<keyword::i64_from_u8>()?;
291
292 Ok(Instruction::I64FromU8)
293 } else if lookahead.peek::<keyword::i64_from_u16>() {
294 parser.parse::<keyword::i64_from_u16>()?;
295
296 Ok(Instruction::I64FromU16)
297 } else if lookahead.peek::<keyword::i64_from_u32>() {
298 parser.parse::<keyword::i64_from_u32>()?;
299
300 Ok(Instruction::I64FromU32)
301 } else if lookahead.peek::<keyword::i64_from_u64>() {
302 parser.parse::<keyword::i64_from_u64>()?;
303
304 Ok(Instruction::I64FromU64)
305 } else if lookahead.peek::<keyword::string_lift_memory>() {
306 parser.parse::<keyword::string_lift_memory>()?;
307
308 Ok(Instruction::StringLiftMemory)
309 } else if lookahead.peek::<keyword::string_lower_memory>() {
310 parser.parse::<keyword::string_lower_memory>()?;
311
312 Ok(Instruction::StringLowerMemory)
313 } else if lookahead.peek::<keyword::string_size>() {
314 parser.parse::<keyword::string_size>()?;
315
316 Ok(Instruction::StringSize)
317 } else if lookahead.peek::<keyword::record_lift>() {
318 parser.parse::<keyword::record_lift>()?;
319
320 Ok(Instruction::RecordLift {
321 type_index: parser.parse()?,
322 })
323 } else if lookahead.peek::<keyword::record_lower>() {
324 parser.parse::<keyword::record_lower>()?;
325
326 Ok(Instruction::RecordLower {
327 type_index: parser.parse()?,
328 })
329 } else {
330 Err(lookahead.error())
331 }
332 }
333}
334
335struct AtInterface;
336
337impl Peek for AtInterface {
338 fn peek(cursor: Cursor<'_>) -> bool {
339 cursor.reserved().map(|(string, _)| string) == Some("@interface")
340 }
341
342 fn display() -> &'static str {
343 "`@interface`"
344 }
345}
346
347impl Parse<'_> for AtInterface {
348 fn parse(parser: Parser<'_>) -> Result<Self> {
349 parser.step(|cursor| {
350 if let Some(("@interface", rest)) = cursor.reserved() {
351 return Ok((AtInterface, rest));
352 }
353
354 Err(cursor.error("expected `@interface`"))
355 })
356 }
357}
358
359#[derive(PartialEq, Debug)]
360enum FunctionType {
361 Input(Vec<InterfaceType>),
362 Output(Vec<InterfaceType>),
363}
364
365impl Parse<'_> for FunctionType {
366 fn parse(parser: Parser<'_>) -> Result<Self> {
367 parser.parens(|parser| {
368 let mut lookahead = parser.lookahead1();
369
370 if lookahead.peek::<keyword::param>() {
371 parser.parse::<keyword::param>()?;
372
373 let mut inputs = vec![];
374
375 while !parser.is_empty() {
376 inputs.push(parser.parse()?);
377 }
378
379 Ok(FunctionType::Input(inputs))
380 } else if lookahead.peek::<keyword::result>() {
381 parser.parse::<keyword::result>()?;
382
383 let mut outputs = vec![];
384
385 while !parser.is_empty() {
386 outputs.push(parser.parse()?);
387 }
388
389 Ok(FunctionType::Output(outputs))
390 } else {
391 Err(lookahead.error())
392 }
393 })
394 }
395}
396
397#[derive(PartialEq, Debug)]
398enum Interface<'a> {
399 Type(Type),
400 Import(Import<'a>),
401 Adapter(Adapter),
402 Export(Export<'a>),
403 Implementation(Implementation),
404}
405
406impl<'a> Parse<'a> for Interface<'a> {
407 fn parse(parser: Parser<'a>) -> Result<Self> {
408 parser.parens(|parser| {
409 let mut lookahead = parser.lookahead1();
410
411 if lookahead.peek::<AtInterface>() {
412 parser.parse::<AtInterface>()?;
413
414 let mut lookahead = parser.lookahead1();
415
416 if lookahead.peek::<keyword::r#type>() {
417 Ok(Interface::Type(parser.parse()?))
418 } else if lookahead.peek::<keyword::import>() {
419 Ok(Interface::Import(parser.parse()?))
420 } else if lookahead.peek::<keyword::func>() {
421 Ok(Interface::Adapter(parser.parse()?))
422 } else if lookahead.peek::<keyword::export>() {
423 Ok(Interface::Export(parser.parse()?))
424 } else if lookahead.peek::<keyword::implement>() {
425 Ok(Interface::Implementation(parser.parse()?))
426 } else {
427 Err(lookahead.error())
428 }
429 } else {
430 Err(lookahead.error())
431 }
432 })
433 }
434}
435
436impl<'a> Parse<'a> for Type {
437 fn parse(parser: Parser<'a>) -> Result<Self> {
438 parser.parse::<keyword::r#type>()?;
439
440 let ty = parser.parens(|parser| {
441 let mut lookahead = parser.lookahead1();
442
443 if lookahead.peek::<keyword::func>() {
444 parser.parse::<keyword::func>()?;
445
446 let mut input_types = vec![];
447 let mut output_types = vec![];
448
449 while !parser.is_empty() {
450 let function_type = parser.parse::<FunctionType>()?;
451
452 match function_type {
453 FunctionType::Input(mut inputs) => input_types.append(&mut inputs),
454 FunctionType::Output(mut outputs) => output_types.append(&mut outputs),
455 }
456 }
457
458 Ok(Type::Function {
459 inputs: input_types,
460 outputs: output_types,
461 })
462 } else if lookahead.peek::<keyword::record>() {
463 Ok(Type::Record(parser.parse()?))
464 } else {
465 Err(lookahead.error())
466 }
467 })?;
468
469 Ok(ty)
470 }
471}
472
473impl<'a> Parse<'a> for Import<'a> {
474 fn parse(parser: Parser<'a>) -> Result<Self> {
475 parser.parse::<keyword::import>()?;
476
477 let namespace = parser.parse()?;
478 let name = parser.parse()?;
479
480 let signature_type = parser.parens(|parser| {
481 parser.parse::<keyword::func>()?;
482
483 parser.parens(|parser| {
484 parser.parse::<keyword::r#type>()?;
485
486 parser.parse()
487 })
488 })?;
489
490 Ok(Import {
491 namespace,
492 name,
493 signature_type,
494 })
495 }
496}
497
498impl<'a> Parse<'a> for Export<'a> {
499 fn parse(parser: Parser<'a>) -> Result<Self> {
500 parser.parse::<keyword::export>()?;
501
502 let name = parser.parse()?;
503
504 let function_type = parser.parens(|parser| {
505 parser.parse::<keyword::func>()?;
506
507 parser.parse()
508 })?;
509
510 Ok(Export {
511 name,
512 function_type,
513 })
514 }
515}
516
517impl<'a> Parse<'a> for Implementation {
518 fn parse(parser: Parser<'a>) -> Result<Self> {
519 parser.parse::<keyword::implement>()?;
520
521 let core_function_type = parser.parens(|parser| {
522 parser.parse::<keyword::func>()?;
523
524 parser.parse()
525 })?;
526
527 let adapter_function_type = parser.parens(|parser| {
528 parser.parse::<keyword::func>()?;
529
530 parser.parse()
531 })?;
532
533 Ok(Implementation {
534 core_function_type,
535 adapter_function_type,
536 })
537 }
538}
539
540impl<'a> Parse<'a> for Adapter {
541 fn parse(parser: Parser<'a>) -> Result<Self> {
542 parser.parse::<keyword::func>()?;
543
544 let function_type = parser.parens(|parser| {
545 parser.parse::<keyword::r#type>()?;
546
547 parser.parse()
548 })?;
549
550 let mut instructions = vec![];
551
552 while !parser.is_empty() {
553 instructions.push(parser.parse()?);
554 }
555
556 Ok(Adapter {
557 function_type,
558 instructions,
559 })
560 }
561}
562
563impl<'a> Parse<'a> for Interfaces<'a> {
564 fn parse(parser: Parser<'a>) -> Result<Self> {
565 let mut interfaces: Interfaces = Default::default();
566
567 while !parser.is_empty() {
568 let interface = parser.parse::<Interface>()?;
569
570 match interface {
571 Interface::Type(ty) => interfaces.types.push(ty),
572 Interface::Import(import) => interfaces.imports.push(import),
573 Interface::Adapter(adapter) => interfaces.adapters.push(adapter),
574 Interface::Export(export) => interfaces.exports.push(export),
575 Interface::Implementation(implementation) => {
576 interfaces.implementations.push(implementation)
577 }
578 }
579 }
580
581 Ok(interfaces)
582 }
583}
584
585pub fn parse<'input>(input: &'input Buffer) -> Result<Interfaces<'input>> {
638 parser::parse::<Interfaces>(&input)
639}
640
641#[cfg(test)]
642mod tests {
643 use super::*;
644 use wast::parser;
645
646 fn buffer(input: &str) -> Buffer {
647 Buffer::new(input).expect("Failed to build the parser buffer.")
648 }
649
650 #[test]
651 fn test_interface_type() {
652 let inputs = vec![
653 "s8",
654 "s16",
655 "s32",
656 "s64",
657 "u8",
658 "u16",
659 "u32",
660 "u64",
661 "f32",
662 "f64",
663 "string",
664 "anyref",
665 "i32",
666 "i64",
667 "record (field string)",
668 ];
669 let outputs = vec![
670 InterfaceType::S8,
671 InterfaceType::S16,
672 InterfaceType::S32,
673 InterfaceType::S64,
674 InterfaceType::U8,
675 InterfaceType::U16,
676 InterfaceType::U32,
677 InterfaceType::U64,
678 InterfaceType::F32,
679 InterfaceType::F64,
680 InterfaceType::String,
681 InterfaceType::Anyref,
682 InterfaceType::I32,
683 InterfaceType::I64,
684 InterfaceType::Record(RecordType {
685 fields: vec1![InterfaceType::String],
686 }),
687 ];
688
689 assert_eq!(inputs.len(), outputs.len());
690
691 for (input, output) in inputs.iter().zip(outputs.iter()) {
692 assert_eq!(
693 &parser::parse::<InterfaceType>(&buffer(input)).unwrap(),
694 output
695 );
696 }
697 }
698
699 #[test]
700 fn test_record_type() {
701 let inputs = vec![
702 "record (field string)",
703 "record (field string) (field i32)",
704 "record (field string) (field record (field i32) (field i32)) (field f64)",
705 ];
706 let outputs = vec![
707 RecordType {
708 fields: vec1![InterfaceType::String],
709 },
710 RecordType {
711 fields: vec1![InterfaceType::String, InterfaceType::I32],
712 },
713 RecordType {
714 fields: vec1![
715 InterfaceType::String,
716 InterfaceType::Record(RecordType {
717 fields: vec1![InterfaceType::I32, InterfaceType::I32],
718 }),
719 InterfaceType::F64,
720 ],
721 },
722 ];
723
724 assert_eq!(inputs.len(), outputs.len());
725
726 for (input, output) in inputs.iter().zip(outputs.iter()) {
727 assert_eq!(
728 &parser::parse::<RecordType>(&buffer(input)).unwrap(),
729 output
730 );
731 }
732 }
733
734 #[test]
735 fn test_instructions() {
736 let inputs = vec![
737 "arg.get 7",
738 "call-core 7",
739 "s8.from_i32",
740 "s8.from_i64",
741 "s16.from_i32",
742 "s16.from_i64",
743 "s32.from_i32",
744 "s32.from_i64",
745 "s64.from_i32",
746 "s64.from_i64",
747 "i32.from_s8",
748 "i32.from_s16",
749 "i32.from_s32",
750 "i32.from_s64",
751 "i64.from_s8",
752 "i64.from_s16",
753 "i64.from_s32",
754 "i64.from_s64",
755 "u8.from_i32",
756 "u8.from_i64",
757 "u16.from_i32",
758 "u16.from_i64",
759 "u32.from_i32",
760 "u32.from_i64",
761 "u64.from_i32",
762 "u64.from_i64",
763 "i32.from_u8",
764 "i32.from_u16",
765 "i32.from_u32",
766 "i32.from_u64",
767 "i64.from_u8",
768 "i64.from_u16",
769 "i64.from_u32",
770 "i64.from_u64",
771 "string.lift_memory",
772 "string.lower_memory",
773 "string.size",
774 "record.lift 42",
775 "record.lower 42",
776 ];
777 let outputs = vec![
778 Instruction::ArgumentGet { index: 7 },
779 Instruction::CallCore { function_index: 7 },
780 Instruction::S8FromI32,
781 Instruction::S8FromI64,
782 Instruction::S16FromI32,
783 Instruction::S16FromI64,
784 Instruction::S32FromI32,
785 Instruction::S32FromI64,
786 Instruction::S64FromI32,
787 Instruction::S64FromI64,
788 Instruction::I32FromS8,
789 Instruction::I32FromS16,
790 Instruction::I32FromS32,
791 Instruction::I32FromS64,
792 Instruction::I64FromS8,
793 Instruction::I64FromS16,
794 Instruction::I64FromS32,
795 Instruction::I64FromS64,
796 Instruction::U8FromI32,
797 Instruction::U8FromI64,
798 Instruction::U16FromI32,
799 Instruction::U16FromI64,
800 Instruction::U32FromI32,
801 Instruction::U32FromI64,
802 Instruction::U64FromI32,
803 Instruction::U64FromI64,
804 Instruction::I32FromU8,
805 Instruction::I32FromU16,
806 Instruction::I32FromU32,
807 Instruction::I32FromU64,
808 Instruction::I64FromU8,
809 Instruction::I64FromU16,
810 Instruction::I64FromU32,
811 Instruction::I64FromU64,
812 Instruction::StringLiftMemory,
813 Instruction::StringLowerMemory,
814 Instruction::StringSize,
815 Instruction::RecordLift { type_index: 42 },
816 Instruction::RecordLower { type_index: 42 },
817 ];
818
819 assert_eq!(inputs.len(), outputs.len());
820
821 for (input, output) in inputs.iter().zip(outputs.iter()) {
822 assert_eq!(
823 &parser::parse::<Instruction>(&buffer(input)).unwrap(),
824 output
825 );
826 }
827 }
828
829 #[test]
830 fn test_param_empty() {
831 let input = buffer("(param)");
832 let output = FunctionType::Input(vec![]);
833
834 assert_eq!(parser::parse::<FunctionType>(&input).unwrap(), output);
835 }
836
837 #[test]
838 fn test_param() {
839 let input = buffer("(param i32 string)");
840 let output = FunctionType::Input(vec![InterfaceType::I32, InterfaceType::String]);
841
842 assert_eq!(parser::parse::<FunctionType>(&input).unwrap(), output);
843 }
844
845 #[test]
846 fn test_result_empty() {
847 let input = buffer("(result)");
848 let output = FunctionType::Output(vec![]);
849
850 assert_eq!(parser::parse::<FunctionType>(&input).unwrap(), output);
851 }
852
853 #[test]
854 fn test_result() {
855 let input = buffer("(result i32 string)");
856 let output = FunctionType::Output(vec![InterfaceType::I32, InterfaceType::String]);
857
858 assert_eq!(parser::parse::<FunctionType>(&input).unwrap(), output);
859 }
860
861 #[test]
862 fn test_type_function() {
863 let input = buffer(r#"(@interface type (func (param i32 i32) (result i32)))"#);
864 let output = Interface::Type(Type::Function {
865 inputs: vec![InterfaceType::I32, InterfaceType::I32],
866 outputs: vec![InterfaceType::I32],
867 });
868
869 assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
870 }
871
872 #[test]
873 fn test_type_record() {
874 let input = buffer(r#"(@interface type (record (field string) (field i32)))"#);
875 let output = Interface::Type(Type::Record(RecordType {
876 fields: vec1![InterfaceType::String, InterfaceType::I32],
877 }));
878
879 assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
880 }
881
882 #[test]
883 fn test_export() {
884 let input = buffer(r#"(@interface export "foo" (func 0))"#);
885 let output = Interface::Export(Export {
886 name: "foo",
887 function_type: 0,
888 });
889
890 assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
891 }
892
893 #[test]
894 fn test_export_escaped_name() {
895 let input = buffer(r#"(@interface export "fo\"o" (func 0))"#);
896 let output = Interface::Export(Export {
897 name: r#"fo"o"#,
898 function_type: 0,
899 });
900
901 assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
902 }
903
904 #[test]
905 fn test_import() {
906 let input = buffer(r#"(@interface import "ns" "foo" (func (type 0)))"#);
907 let output = Interface::Import(Import {
908 namespace: "ns",
909 name: "foo",
910 signature_type: 0,
911 });
912
913 assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
914 }
915
916 #[test]
917 fn test_adapter() {
918 let input = buffer(r#"(@interface func (type 0) arg.get 42)"#);
919 let output = Interface::Adapter(Adapter {
920 function_type: 0,
921 instructions: vec![Instruction::ArgumentGet { index: 42 }],
922 });
923
924 assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
925 }
926
927 #[test]
928 fn test_implementation() {
929 let input = buffer(r#"(@interface implement (func 0) (func 1))"#);
930 let output = Interface::Implementation(Implementation {
931 core_function_type: 0,
932 adapter_function_type: 1,
933 });
934
935 assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
936 }
937
938 #[test]
939 fn test_interfaces() {
940 let input = buffer(
941 r#"(@interface type (func (param i32) (result s8)))
942
943(@interface import "ns" "foo" (func (type 0)))
944
945(@interface func (type 0) arg.get 42)
946
947(@interface export "bar" (func 0))
948
949(@interface implement (func 0) (func 1))"#,
950 );
951 let output = Interfaces {
952 types: vec![Type::Function {
953 inputs: vec![InterfaceType::I32],
954 outputs: vec![InterfaceType::S8],
955 }],
956 imports: vec![Import {
957 namespace: "ns",
958 name: "foo",
959 signature_type: 0,
960 }],
961 adapters: vec![Adapter {
962 function_type: 0,
963 instructions: vec![Instruction::ArgumentGet { index: 42 }],
964 }],
965 exports: vec![Export {
966 name: "bar",
967 function_type: 0,
968 }],
969 implementations: vec![Implementation {
970 core_function_type: 0,
971 adapter_function_type: 1,
972 }],
973 };
974
975 assert_eq!(parser::parse::<Interfaces>(&input).unwrap(), output);
976 }
977}