Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 111 additions & 95 deletions Cargo.lock

Large diffs are not rendered by default.

23 changes: 14 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,28 @@ owo-colors = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }

[features]
default = []
wat = ["wac-parser/wat"]

[workspace.dependencies]
wac-parser = { path = "crates/wac-parser" }
wac-parser = { path = "crates/wac-parser", default-features = false }
wit-parser = "0.12.1"
wasmparser = "0.113.3"
wasmparser = "0.115.0"
wit-component = "0.16.0"
anyhow = "1.0.75"
clap = { version = "4.4.3", features = ["derive"] }
pest = "2.7.3"
pest_derive = "2.7.3"
clap = { version = "4.4.6", features = ["derive"] }
pest = "2.7.4"
pest_derive = "2.7.4"
from-pest = "0.3.2"
pest-ast = "0.3.4"
semver = "1.0.18"
semver = "1.0.20"
pretty_env_logger = "0.5.0"
log = "0.4.20"
tokio = { version = "1.32.0", default-features = false, features = ["macros", "rt-multi-thread"] }
tokio = { version = "1.33.0", default-features = false, features = ["macros", "rt-multi-thread"] }
owo-colors = "3.5.0"
indexmap = { version = "2.0.0", features = ["serde"] }
indexmap = { version = "2.0.2", features = ["serde"] }
id-arena = "2.2.1"
serde = { version = "1.0.188", features = ["derive"] }
serde = { version = "1.0.189", features = ["derive"] }
serde_json = "1.0.107"
wat = "1.0.77"
4 changes: 4 additions & 0 deletions crates/wac-parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ serde = { workspace = true }
wasmparser = { workspace = true }
wit-parser = { workspace = true }
wit-component = { workspace = true }
wat = { workspace = true, optional = true }

[features]
default = ["wat"]

[dev-dependencies]
pretty_assertions = "1.4.0"
Expand Down
15 changes: 11 additions & 4 deletions crates/wac-parser/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,10 @@ where
}

/// Creates a new error with the given message, file path, and span.
pub fn new_error_with_span(msg: impl fmt::Display, path: &Path, span: Span) -> anyhow::Error {
let msg = msg.to_string();
pub fn new_error_with_span(path: &Path, span: Span, msg: impl fmt::Display) -> anyhow::Error {
let mut e = Error::new_from_span(
ErrorVariant::CustomError::<Rule> {
message: msg.clone(),
message: msg.to_string(),
},
span,
);
Expand All @@ -56,7 +55,15 @@ pub fn new_error_with_span(msg: impl fmt::Display, path: &Path, span: Span) -> a
e = e.with_path(path)
}

anyhow!(e).context(msg)
let (line, column) = match e.line_col {
pest::error::LineColLocation::Pos((l, c)) => (l, c),
pest::error::LineColLocation::Span((l, c), _) => (l, c),
};

anyhow!(format!(
"{path}:{line}:{column}: {msg}\n\n{e}",
path = path.display()
))
}

/// Used to indent output when displaying AST nodes.
Expand Down
4 changes: 2 additions & 2 deletions crates/wac-parser/src/ast/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ mod test {

roundtrip::<ExportStatement>(
Rule::ExportStatement,
"export new foo:bar { foo, bar: (new baz:qux {...}), baz: foo[\"baz\"].qux };",
"export new foo:bar {\n foo,\n bar: (new baz:qux { ... }),\n baz: foo[\"baz\"].qux,\n};",
"export new foo:bar { foo, \"bar\": (new baz:qux {...}), \"baz\": foo[\"baz\"].qux };",
"export new foo:bar {\n foo,\n \"bar\": (new baz:qux { ... }),\n \"baz\": foo[\"baz\"].qux,\n};",
)
.unwrap();
}
Expand Down
75 changes: 69 additions & 6 deletions crates/wac-parser/src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use super::{
AstDisplay, Ident, Indenter, PackageName,
};
use crate::parser::Rule;
use pest::Span;
use pest_ast::FromPest;
use serde::Serialize;
use std::fmt;
Expand Down Expand Up @@ -172,8 +173,8 @@ display!(InstantiationArgument);
#[pest_ast(rule(Rule::NamedInstantiationArgument))]
#[serde(rename_all = "camelCase")]
pub struct NamedInstantiationArgument<'a> {
/// The identifier in the argument.
pub id: Ident<'a>,
/// The name of the argument.
pub name: InstantiationArgumentName<'a>,
/// The colon in the argument.
pub colon: Colon<'a>,
/// The expression in the argument.
Expand All @@ -182,13 +183,46 @@ pub struct NamedInstantiationArgument<'a> {

impl AstDisplay for NamedInstantiationArgument<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>, indenter: &mut Indenter) -> fmt::Result {
write!(f, "{id}{colon} ", id = self.id, colon = self.colon)?;
self.name.fmt(f, indenter)?;
write!(f, "{colon} ", colon = self.colon)?;
self.expr.fmt(f, indenter)
}
}

display!(NamedInstantiationArgument);

/// Represents the argument name in an instantiation argument in the AST.
#[derive(Debug, Clone, Serialize, FromPest)]
#[pest_ast(rule(Rule::InstantiationArgumentName))]
#[serde(rename_all = "camelCase")]
pub enum InstantiationArgumentName<'a> {
/// The argument name is an identifier.
Ident(Ident<'a>),
/// The argument name is a string.
String(super::String<'a>),
}

impl<'a> InstantiationArgumentName<'a> {
/// Gets the span of the instantiation argument name.
pub fn span(&self) -> Span<'a> {
match self {
InstantiationArgumentName::Ident(ident) => ident.0,
InstantiationArgumentName::String(string) => string.0,
}
}
}

impl AstDisplay for InstantiationArgumentName<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>, _indenter: &mut Indenter) -> fmt::Result {
match self {
InstantiationArgumentName::Ident(ident) => ident.fmt(f, _indenter),
InstantiationArgumentName::String(string) => string.fmt(f, _indenter),
}
}
}

display!(InstantiationArgumentName);

/// Represents a nested expression in the AST.
#[derive(Debug, Clone, Serialize, FromPest)]
#[pest_ast(rule(Rule::NestedExpr))]
Expand Down Expand Up @@ -223,11 +257,21 @@ pub enum PostfixExpr<'a> {
NamedAccess(NamedAccessExpr<'a>),
}

impl<'a> PostfixExpr<'a> {
/// Gets the span of the postfix expression.
pub fn span(&self) -> pest::Span<'a> {
match self {
PostfixExpr::Access(access) => access.span(),
PostfixExpr::NamedAccess(access) => access.span(),
}
}
}

impl AstDisplay for PostfixExpr<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>, indenter: &mut Indenter) -> fmt::Result {
match self {
PostfixExpr::Access(access) => access.fmt(f, indenter),
PostfixExpr::NamedAccess(named_access) => named_access.fmt(f, indenter),
PostfixExpr::NamedAccess(access) => access.fmt(f, indenter),
}
}
}
Expand All @@ -245,6 +289,13 @@ pub struct AccessExpr<'a> {
pub id: Ident<'a>,
}

impl<'a> AccessExpr<'a> {
/// Gets the span of the access expression.
pub fn span(&self) -> Span<'a> {
Span::new(self.dot.0.get_input(), self.dot.0.start(), self.id.0.end()).unwrap()
}
}

impl AstDisplay for AccessExpr<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>, _indenter: &mut Indenter) -> fmt::Result {
write!(f, "{dot}{id}", dot = self.dot, id = self.id)
Expand All @@ -266,6 +317,18 @@ pub struct NamedAccessExpr<'a> {
pub close: CloseBracket<'a>,
}

impl<'a> NamedAccessExpr<'a> {
/// Gets the span of the access expression.
pub fn span(&self) -> Span<'a> {
Span::new(
self.open.0.get_input(),
self.open.0.start(),
self.close.0.end(),
)
.unwrap()
}
}

impl AstDisplay for NamedAccessExpr<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>, _indenter: &mut Indenter) -> fmt::Result {
write!(
Expand Down Expand Up @@ -303,8 +366,8 @@ mod test {

roundtrip::<Expr>(
Rule::Expr,
"new foo:bar { foo, bar: (new baz:qux {...}), baz: foo[\"baz\"].qux }",
"new foo:bar {\n foo,\n bar: (new baz:qux { ... }),\n baz: foo[\"baz\"].qux,\n}",
"new foo:bar { foo, \"bar\": (new baz:qux {...}), \"baz\": foo[\"baz\"].qux }",
"new foo:bar {\n foo,\n \"bar\": (new baz:qux { ... }),\n \"baz\": foo[\"baz\"].qux,\n}",
)
.unwrap();
}
Expand Down
4 changes: 2 additions & 2 deletions crates/wac-parser/src/ast/let.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ mod test {

roundtrip::<LetStatement>(
Rule::LetStatement,
"let x = new foo:bar { foo, bar: (new baz:qux {...}), baz: foo[\"baz\"].qux };",
"let x = new foo:bar {\n foo,\n bar: (new baz:qux { ... }),\n baz: foo[\"baz\"].qux,\n};",
"let x = new foo:bar { foo, \"bar\": (new baz:qux {...}), \"baz\": foo[\"baz\"].qux };",
"let x = new foo:bar {\n foo,\n \"bar\": (new baz:qux { ... }),\n \"baz\": foo[\"baz\"].qux,\n};",
)
.unwrap();
}
Expand Down
1 change: 1 addition & 0 deletions crates/wac-parser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ mod pest {
Self::NewExprBody => "new expression body",
Self::InstantiationArgument => "instantiation argument",
Self::NamedInstantiationArgument => "named instantiation argument",
Self::InstantiationArgumentName => "instantiation argument name",
Self::NestedExpr => "nested expression",
Self::PostfixExpr => "postfix expression",
Self::AccessExpr => "access expression",
Expand Down
Loading