wasmer_interface_types/decoders/
wat.rs

1//! Parse the WIT textual representation into an [AST](crate::ast).
2
3use 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    // New keywords.
14    custom_keyword!(implement);
15    custom_keyword!(r#type = "type");
16    custom_keyword!(record);
17    custom_keyword!(field);
18
19    // New types.
20    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    // Instructions.
31    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
585/// Parse a WIT definition in its textual format, and produces an
586/// [AST](crate::ast) with the [`Interfaces`](crate::ast::Interfaces)
587/// structure upon succesful.
588///
589/// # Examples
590///
591/// ```rust
592/// use wasmer_interface_types::{
593///     ast::{Adapter, Export, Implementation, Import, Interfaces, Type},
594///     decoders::wat::{parse, Buffer},
595///     interpreter::Instruction,
596///     types::InterfaceType,
597/// };
598///
599/// let input = Buffer::new(
600///     r#"(@interface type (func (param i32) (result s8)))
601///
602/// (@interface import "ns" "foo" (func (type 0)))
603///
604/// (@interface func (type 0) arg.get 42)
605///
606/// (@interface export "bar" (func 0))
607///
608/// (@interface implement (func 0) (func 1))"#,
609/// )
610/// .unwrap();
611/// let output = Interfaces {
612///     types: vec![Type::Function {
613///         inputs: vec![InterfaceType::I32],
614///         outputs: vec![InterfaceType::S8],
615///     }],
616///     imports: vec![Import {
617///         namespace: "ns",
618///         name: "foo",
619///         signature_type: 0,
620///     }],
621///     adapters: vec![Adapter {
622///         function_type: 0,
623///         instructions: vec![Instruction::ArgumentGet { index: 42 }],
624///     }],
625///     exports: vec![Export {
626///         name: "bar",
627///         function_type: 0,
628///     }],
629///     implementations: vec![Implementation {
630///         core_function_type: 0,
631///         adapter_function_type: 1,
632///     }],
633/// };
634///
635/// assert_eq!(parse(&input).unwrap(), output);
636/// ```
637pub 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}