Skip to content

Commit 0ba010e

Browse files
authored
Merge pull request #28 from peterhuene/ident-extern-name
Allow identifiers for import/export `as` clause.
2 parents 0a6d10f + 4ef2818 commit 0ba010e

13 files changed

Lines changed: 236 additions & 39 deletions

File tree

LANGUAGE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ package-decl ::= `package` package-name `;`
321321
package-name ::= id (':' id)+ ('@' version)?
322322
version ::= <SEMVER>
323323
324-
import-statement ::= 'import' id ('as' string)? ':' import-type ';'
324+
import-statement ::= 'import' id ('as' (id | string))? ':' import-type ';'
325325
import-type ::= package-path | func-type | inline-interface | id
326326
package-path ::= id (':' id)+ ('/' id)+ ('@' version)?
327327
@@ -410,7 +410,7 @@ postfix-expr ::= access-expr | named-access-expr
410410
access-expr ::= '.' id
411411
named-access-expr ::= '[' string ']'
412412
413-
export-statement ::= 'export' expr ('as' string)? ';'
413+
export-statement ::= 'export' expr ('as' (id | string))? ';'
414414
415415
id ::= '%'?[a-z][a-z0-9]*('-'[a-z][a-z0-9]*)*
416416
string ::= '"' character-that-is-not-a-double-quote* '"'

crates/wac-parser/src/ast/export.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::{
2-
expr::Expr, parse_optional, parse_token, DocComment, Lookahead, Parse, ParseResult, Peek,
2+
expr::Expr, parse_optional, parse_token, DocComment, ExternName, Lookahead, Parse, ParseResult,
3+
Peek,
34
};
45
use crate::lexer::{Lexer, Token};
56
use miette::SourceSpan;
@@ -14,7 +15,7 @@ pub struct ExportStatement<'a> {
1415
/// The span of the export keyword.
1516
pub span: SourceSpan,
1617
/// The optional name to use for the export.
17-
pub name: Option<super::String<'a>>,
18+
pub name: Option<ExternName<'a>>,
1819
/// The expression to export.
1920
pub expr: Expr<'a>,
2021
}

crates/wac-parser/src/ast/import.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,53 @@ use miette::SourceSpan;
77
use semver::Version;
88
use serde::Serialize;
99

10+
/// Represents an extern name following an `as` clause in the AST.
11+
#[derive(Debug, Clone, Serialize)]
12+
#[serde(rename_all = "camelCase")]
13+
pub enum ExternName<'a> {
14+
/// The "as" clause is an identifier.
15+
Ident(Ident<'a>),
16+
/// The "as" clause is a string.
17+
String(super::String<'a>),
18+
}
19+
20+
impl ExternName<'_> {
21+
/// Gets the span of the extern name.
22+
pub fn span(&self) -> SourceSpan {
23+
match self {
24+
Self::Ident(ident) => ident.span,
25+
Self::String(string) => string.span,
26+
}
27+
}
28+
29+
/// Gets the string value of the extern name.
30+
pub fn as_str(&self) -> &str {
31+
match self {
32+
Self::Ident(ident) => ident.string,
33+
Self::String(string) => string.value,
34+
}
35+
}
36+
}
37+
38+
impl Peek for ExternName<'_> {
39+
fn peek(lookahead: &mut Lookahead) -> bool {
40+
Ident::peek(lookahead) || super::String::peek(lookahead)
41+
}
42+
}
43+
44+
impl<'a> Parse<'a> for ExternName<'a> {
45+
fn parse(lexer: &mut Lexer<'a>) -> ParseResult<Self> {
46+
let mut lookahead = Lookahead::new(lexer);
47+
if Ident::peek(&mut lookahead) {
48+
Ok(Self::Ident(Parse::parse(lexer)?))
49+
} else if super::String::peek(&mut lookahead) {
50+
Ok(Self::String(Parse::parse(lexer)?))
51+
} else {
52+
Err(lookahead.error())
53+
}
54+
}
55+
}
56+
1057
/// Represents an import statement in the AST.
1158
#[derive(Debug, Clone, Serialize)]
1259
#[serde(rename_all = "camelCase")]
@@ -16,7 +63,7 @@ pub struct ImportStatement<'a> {
1663
/// The identifier of the imported item.
1764
pub id: Ident<'a>,
1865
/// The optional import name.
19-
pub name: Option<super::String<'a>>,
66+
pub name: Option<ExternName<'a>>,
2067
/// The type of the imported item.
2168
pub ty: ImportType<'a>,
2269
}

crates/wac-parser/src/ast/printer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl<'a, W: Write> DocumentPrinter<'a, W> {
8484
)?;
8585

8686
if let Some(name) = &statement.name {
87-
write!(self.writer, " as {name}", name = self.source(name.span))?;
87+
write!(self.writer, " as {name}", name = self.source(name.span()))?;
8888
}
8989

9090
write!(self.writer, ": ")?;
@@ -752,7 +752,7 @@ impl<'a, W: Write> DocumentPrinter<'a, W> {
752752
self.expr(&stmt.expr)?;
753753

754754
if let Some(name) = &stmt.name {
755-
write!(self.writer, " as {name}", name = self.source(name.span))?;
755+
write!(self.writer, " as {name}", name = self.source(name.span()))?;
756756
}
757757

758758
write!(self.writer, ";")

crates/wac-parser/src/resolution/ast.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,9 @@ impl<'a> AstResolver<'a> {
235235
_ => kind,
236236
};
237237

238-
let (name, span) = if let Some(name) = stmt.name {
238+
let (name, span) = if let Some(name) = &stmt.name {
239239
// Override the span to the `as` clause string
240-
(name.value, name.span)
240+
(name.as_str(), name.span())
241241
} else {
242242
// If the item is an instance with an id, use the id
243243
if let ItemKind::Instance(id) = kind {
@@ -359,8 +359,8 @@ impl<'a> AstResolver<'a> {
359359
) -> ResolutionResult<()> {
360360
log::debug!("resolving export statement");
361361
let item = self.expr(state, &stmt.expr)?;
362-
let (name, span) = if let Some(name) = stmt.name {
363-
(name.value, name.span)
362+
let (name, span) = if let Some(name) = &stmt.name {
363+
(name.as_str(), name.span())
364364
} else {
365365
(
366366
self.infer_export_name(state, item)

crates/wac-parser/tests/parser/export.wac

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,8 @@ export e;
66
/// Export an alias of an item (default name)
77
export e["foo"];
88

9-
/// Export an alias of an item with a different name
9+
/// Export an alias of an item with a different name with string
1010
export e["foo"] as "bar";
11+
12+
/// Export an alias of an item with a different name with identifier
13+
export e["foo"] as foo-bar;

crates/wac-parser/tests/parser/export.wac.result

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,30 +90,86 @@
9090
"Export": {
9191
"docs": [
9292
{
93-
"comment": "Export an alias of an item with a different name",
93+
"comment": "Export an alias of an item with a different name with string",
9494
"span": {
9595
"offset": 129,
96-
"length": 52
96+
"length": 64
9797
}
9898
}
9999
],
100100
"span": {
101-
"offset": 182,
101+
"offset": 194,
102102
"length": 6
103103
},
104104
"name": {
105-
"value": "bar",
106-
"span": {
107-
"offset": 201,
108-
"length": 5
105+
"string": {
106+
"value": "bar",
107+
"span": {
108+
"offset": 213,
109+
"length": 5
110+
}
111+
}
112+
},
113+
"expr": {
114+
"primary": {
115+
"ident": {
116+
"string": "e",
117+
"span": {
118+
"offset": 201,
119+
"length": 1
120+
}
121+
}
122+
},
123+
"postfix": [
124+
{
125+
"namedAccess": {
126+
"span": {
127+
"offset": 202,
128+
"length": 7
129+
},
130+
"string": {
131+
"value": "foo",
132+
"span": {
133+
"offset": 203,
134+
"length": 5
135+
}
136+
}
137+
}
138+
}
139+
]
140+
}
141+
}
142+
},
143+
{
144+
"Export": {
145+
"docs": [
146+
{
147+
"comment": "Export an alias of an item with a different name with identifier",
148+
"span": {
149+
"offset": 221,
150+
"length": 68
151+
}
152+
}
153+
],
154+
"span": {
155+
"offset": 290,
156+
"length": 6
157+
},
158+
"name": {
159+
"ident": {
160+
"string": "foo-bar",
161+
"span": {
162+
"offset": 309,
163+
"length": 7
164+
}
109165
}
110166
},
111167
"expr": {
112168
"primary": {
113169
"ident": {
114170
"string": "e",
115171
"span": {
116-
"offset": 189,
172+
"offset": 297,
117173
"length": 1
118174
}
119175
}
@@ -122,13 +178,13 @@
122178
{
123179
"namedAccess": {
124180
"span": {
125-
"offset": 190,
181+
"offset": 298,
126182
"length": 7
127183
},
128184
"string": {
129185
"value": "foo",
130186
"span": {
131-
"offset": 191,
187+
"offset": 299,
132188
"length": 5
133189
}
134190
}

crates/wac-parser/tests/parser/import.wac

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import b: x;
99
/// Import by package path
1010
import c: foo:bar/baz;
1111

12-
/// Import by func type with kebab name
12+
/// Import by func type with kebab name string
1313
import d as "hello-world": func(name: string);
1414

1515
/// Import by inline interface
@@ -18,4 +18,7 @@ import e: interface {
1818
};
1919

2020
/// Import by package path with version
21-
import f: foo:bar/baz@1.0.0;
21+
import f: foo:bar/baz@1.0.0;
22+
23+
/// Import by func type with kebab name identifier
24+
import g as hello-world: func(name: string);

0 commit comments

Comments
 (0)