From eee13eed78863a85ff67a8fd188d36612b4d5902 Mon Sep 17 00:00:00 2001 From: vms Date: Wed, 16 Sep 2020 00:20:47 +0300 Subject: [PATCH] improve parsing --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/decoders/wat.rs | 23 ++++++++++++-- src/encoders/wat.rs | 47 +++++++++++++---------------- src/interpreter/instructions/mod.rs | 34 ++++++++++++++++++--- 5 files changed, 73 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b94511e..9b35e64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,7 +195,7 @@ checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" [[package]] name = "wasmer-interface-types-fl" -version = "0.17.4" +version = "0.17.5" dependencies = [ "log", "nom", diff --git a/Cargo.toml b/Cargo.toml index 2deb218..10109f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasmer-interface-types-fl" -version = "0.17.4" +version = "0.17.5" description = "WebAssembly Interface Types library for Wasmer" license = "MIT" authors = ["The Wasmer Engineering Team "] diff --git a/src/decoders/wat.rs b/src/decoders/wat.rs index 37b70a2..876b222 100644 --- a/src/decoders/wat.rs +++ b/src/decoders/wat.rs @@ -17,6 +17,10 @@ mod keyword { custom_keyword!(record); custom_keyword!(field); + // Special symbols + custom_keyword!(comma = ","); + custom_keyword!(colon = ":"); + // New types. custom_keyword!(s8); custom_keyword!(s16); @@ -431,10 +435,25 @@ impl Parse<'_> for FunctionType { let mut arguments = vec![]; while !parser.is_empty() { - let arg_name: String = parser.parse()?; + let arg_name = parser.step(|cursor| { + cursor + .id() + .ok_or_else(|| cursor.error("expecting argument identifier")) + })?; + + if !arg_name.ends_with(':') { + parser.step(|cursor| { + if let Some((":", rest)) = cursor.reserved() { + return Ok(("", rest)); + } + Err(cursor.error("expected : between an argument and a type")) + })?; + } + let arg_type: InterfaceType = parser.parse()?; + arguments.push(FunctionArg { - name: arg_name, + name: arg_name.trim_end_matches(':').to_string(), ty: arg_type, }); } diff --git a/src/encoders/wat.rs b/src/encoders/wat.rs index 2baa28c..9c3d5a4 100644 --- a/src/encoders/wat.rs +++ b/src/encoders/wat.rs @@ -93,7 +93,7 @@ impl ToString for &RecordType { .fold(String::new(), |mut accumulator, field_type| { accumulator.push(' '); accumulator.push_str(&format!( - "{}: {},\n", + "{}: {}\n", field_type.name, (&field_type.ty).to_string() )); @@ -172,23 +172,16 @@ fn encode_function_arguments(arguments: &[FunctionArg]) -> String { } else { format!( "\n (param{})", - arguments - .iter() - .fold( - (String::new(), true), - |(mut accumulator, is_first), FunctionArg { name, ty }| { - if !is_first { - accumulator.push(','); - } - - accumulator.push(' '); - accumulator.push_str(name); - accumulator.push_str(": "); - accumulator.push_str(&ty.to_string()); - (accumulator, false) - } - ) - .0 + arguments.iter().fold( + String::new(), + |mut accumulator, FunctionArg { name, ty }| { + accumulator.push_str(" $"); + accumulator.push_str(name); + accumulator.push_str(": "); + accumulator.push_str(&ty.to_string()); + accumulator + } + ) ) } } @@ -290,14 +283,16 @@ impl<'input> ToString for &Interfaces<'input> { fn to_string(&self) -> String { let mut output = String::new(); - let types = self - .types - .iter() - .fold(String::new(), |mut accumulator, ty| { - accumulator.push('\n'); - accumulator.push_str(&ty.to_string()); - accumulator - }); + let types = + self.types + .iter() + .enumerate() + .fold(String::new(), |mut accumulator, (id, ty)| { + accumulator.push('\n'); + accumulator.push_str(&ty.to_string()); + accumulator.push_str(&format!(" ;; {}", id)); + accumulator + }); let imports = self .imports diff --git a/src/interpreter/instructions/mod.rs b/src/interpreter/instructions/mod.rs index 4ba9575..518850b 100644 --- a/src/interpreter/instructions/mod.rs +++ b/src/interpreter/instructions/mod.rs @@ -495,12 +495,32 @@ pub(crate) mod tests { }, memory: Memory::new(vec![Cell::new(0); 128]), wit_types: vec![Type::Record(RecordType { + name: String::from("RecordType0"), fields: vec1![ - InterfaceType::I32, - InterfaceType::Record(RecordType { - fields: vec1![InterfaceType::String, InterfaceType::F32], - }), - InterfaceType::I64, + RecordFieldType { + name: String::from("field_0"), + ty: InterfaceType::I32, + }, + RecordFieldType { + name: String::from("field_1"), + ty: InterfaceType::Record(RecordType { + name: String::from("RecordType1"), + fields: vec1![ + RecordFieldType { + name: String::from("field_0"), + ty: InterfaceType::String, + }, + RecordFieldType { + name: String::from("field1"), + ty: InterfaceType::F32 + } + ], + }), + }, + RecordFieldType { + name: String::from("field_2"), + ty: InterfaceType::I64, + } ], })], } @@ -526,5 +546,9 @@ pub(crate) mod tests { fn wit_type_by_id(&self, index: u32) -> Option<&Type> { self.wit_types.get(index as usize) } + + fn wit_record_by_id(&self, index: u64) -> Option<&RecordType> { + self.wit_types.get(index as _) + } } }