mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-01 23:41:03 +00:00
feat(interface-types) Parse Import
in the WAT decoders.
This commit is contained in:
parent
c97122899d
commit
2e78cf1fc0
@ -7,11 +7,11 @@ use nom::{
|
|||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::{escaped, tag, take_while1},
|
bytes::complete::{escaped, tag, take_while1},
|
||||||
character::complete::{alphanumeric1, char, one_of},
|
character::complete::{alphanumeric1, char, one_of},
|
||||||
combinator::{cut, opt, value},
|
combinator::{cut, map, opt, value},
|
||||||
error::ParseError,
|
error::ParseError,
|
||||||
multi::many0,
|
multi::many0,
|
||||||
sequence::{delimited, preceded, terminated, tuple},
|
sequence::{delimited, preceded, terminated, tuple},
|
||||||
IResult,
|
AsChar, IResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Parse a whitespace.
|
/// Parse a whitespace.
|
||||||
@ -82,24 +82,22 @@ fn result<'input, E: ParseError<&'input str>>(
|
|||||||
fn export<'input, E: ParseError<&'input str>>(
|
fn export<'input, E: ParseError<&'input str>>(
|
||||||
input: &'input str,
|
input: &'input str,
|
||||||
) -> IResult<&'input str, Export, E> {
|
) -> IResult<&'input str, Export, E> {
|
||||||
//(@interface export "name")
|
map(
|
||||||
let (remains, (export_name, input_types, output_types)): (
|
delimited(
|
||||||
&str,
|
char('('),
|
||||||
(&str, Option<Vec<InterfaceType>>, Option<Vec<InterfaceType>>),
|
|
||||||
) = delimited(
|
|
||||||
char('('),
|
|
||||||
preceded(
|
|
||||||
opt(whitespace),
|
|
||||||
preceded(
|
preceded(
|
||||||
tag("@interface"),
|
opt(whitespace),
|
||||||
preceded(
|
preceded(
|
||||||
whitespace,
|
tag("@interface"),
|
||||||
preceded(
|
preceded(
|
||||||
tag("export"),
|
whitespace,
|
||||||
preceded(
|
preceded(
|
||||||
whitespace,
|
tag("export"),
|
||||||
tuple((
|
tuple((
|
||||||
preceded(char('"'), cut(terminated(string, char('"')))),
|
preceded(
|
||||||
|
whitespace,
|
||||||
|
preceded(char('"'), cut(terminated(string, char('"')))),
|
||||||
|
),
|
||||||
opt(preceded(whitespace, param)),
|
opt(preceded(whitespace, param)),
|
||||||
opt(preceded(whitespace, result)),
|
opt(preceded(whitespace, result)),
|
||||||
)),
|
)),
|
||||||
@ -107,18 +105,86 @@ fn export<'input, E: ParseError<&'input str>>(
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
char(')'),
|
||||||
),
|
),
|
||||||
char(')'),
|
|(name, input_types, output_types)| Export {
|
||||||
)(input)?;
|
name,
|
||||||
|
|
||||||
Ok((
|
|
||||||
remains,
|
|
||||||
Export {
|
|
||||||
name: export_name,
|
|
||||||
input_types: input_types.unwrap_or_else(|| vec![]),
|
input_types: input_types.unwrap_or_else(|| vec![]),
|
||||||
output_types: output_types.unwrap_or_else(|| vec![]),
|
output_types: output_types.unwrap_or_else(|| vec![]),
|
||||||
},
|
},
|
||||||
))
|
)(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a `(import …)`.
|
||||||
|
fn import_qualifier<'input, E: ParseError<&'input str>>(
|
||||||
|
input: &'input str,
|
||||||
|
) -> IResult<&'input str, (&'input str, &'input str), E> {
|
||||||
|
delimited(
|
||||||
|
char('('),
|
||||||
|
preceded(
|
||||||
|
opt(whitespace),
|
||||||
|
preceded(
|
||||||
|
tag("import"),
|
||||||
|
tuple((
|
||||||
|
preceded(
|
||||||
|
whitespace,
|
||||||
|
preceded(char('"'), cut(terminated(string, char('"')))),
|
||||||
|
),
|
||||||
|
preceded(
|
||||||
|
whitespace,
|
||||||
|
preceded(char('"'), cut(terminated(string, char('"')))),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
char(')'),
|
||||||
|
)(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a `$…`.
|
||||||
|
fn index_variable<'input, E: ParseError<&'input str>>(
|
||||||
|
input: &'input str,
|
||||||
|
) -> IResult<&'input str, &'input str, E> {
|
||||||
|
preceded(
|
||||||
|
char('$'),
|
||||||
|
take_while1(move |c: char| c.is_alphanum() || c == '_'),
|
||||||
|
)(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse an `Import`.
|
||||||
|
fn import<'input, E: ParseError<&'input str>>(
|
||||||
|
input: &'input str,
|
||||||
|
) -> IResult<&'input str, Import, E> {
|
||||||
|
map(
|
||||||
|
delimited(
|
||||||
|
char('('),
|
||||||
|
preceded(
|
||||||
|
opt(whitespace),
|
||||||
|
preceded(
|
||||||
|
tag("@interface"),
|
||||||
|
preceded(
|
||||||
|
whitespace,
|
||||||
|
preceded(
|
||||||
|
tag("func"),
|
||||||
|
tuple((
|
||||||
|
opt(preceded(whitespace, index_variable)),
|
||||||
|
preceded(whitespace, import_qualifier),
|
||||||
|
opt(preceded(whitespace, param)),
|
||||||
|
opt(preceded(whitespace, result)),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
char(')'),
|
||||||
|
),
|
||||||
|
|(_index, (namespace, name), input_types, output_types)| Import {
|
||||||
|
namespace,
|
||||||
|
name,
|
||||||
|
input_types: input_types.unwrap_or_else(|| vec![]),
|
||||||
|
output_types: output_types.unwrap_or_else(|| vec![]),
|
||||||
|
},
|
||||||
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -239,4 +305,90 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(export::<()>(input), Ok(("", output)));
|
assert_eq!(export::<()>(input), Ok(("", output)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_export_escaped_name() {
|
||||||
|
let input = r#"(@interface export "fo\"o")"#;
|
||||||
|
let output = Export {
|
||||||
|
name: r#"fo\"o"#,
|
||||||
|
input_types: vec![],
|
||||||
|
output_types: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(export::<()>(input), Ok(("", output)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_import_qualifier() {
|
||||||
|
let input = r#"(import "ns" "name")"#;
|
||||||
|
let output = ("ns", "name");
|
||||||
|
|
||||||
|
assert_eq!(import_qualifier::<()>(input), Ok(("", output)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_import_with_no_param_no_result() {
|
||||||
|
let input = r#"(@interface func $ns_foo (import "ns" "foo"))"#;
|
||||||
|
let output = Import {
|
||||||
|
namespace: "ns",
|
||||||
|
name: "foo",
|
||||||
|
input_types: vec![],
|
||||||
|
output_types: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(import::<()>(input), Ok(("", output)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_import_with_no_index_variable_no_param_no_result() {
|
||||||
|
let input = r#"(@interface func (import "ns" "foo"))"#;
|
||||||
|
let output = Import {
|
||||||
|
namespace: "ns",
|
||||||
|
name: "foo",
|
||||||
|
input_types: vec![],
|
||||||
|
output_types: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(import::<()>(input), Ok(("", output)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_import_with_some_param_no_result() {
|
||||||
|
let input = r#"(@interface func $ns_foo (import "ns" "foo") (param i32))"#;
|
||||||
|
let output = Import {
|
||||||
|
namespace: "ns",
|
||||||
|
name: "foo",
|
||||||
|
input_types: vec![InterfaceType::I32],
|
||||||
|
output_types: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(import::<()>(input), Ok(("", output)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_import_with_no_param_some_result() {
|
||||||
|
let input = r#"(@interface func $ns_foo (import "ns" "foo") (result i32))"#;
|
||||||
|
let output = Import {
|
||||||
|
namespace: "ns",
|
||||||
|
name: "foo",
|
||||||
|
input_types: vec![],
|
||||||
|
output_types: vec![InterfaceType::I32],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(import::<()>(input), Ok(("", output)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_import_with_some_param_some_result() {
|
||||||
|
let input =
|
||||||
|
r#"(@interface func $ns_foo (import "ns" "foo") (param String) (result i32 i32))"#;
|
||||||
|
let output = Import {
|
||||||
|
namespace: "ns",
|
||||||
|
name: "foo",
|
||||||
|
input_types: vec![InterfaceType::String],
|
||||||
|
output_types: vec![InterfaceType::I32, InterfaceType::I32],
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(import::<()>(input), Ok(("", output)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user