1use core::{error::Error, fmt::Display};
4
5use alloc::{
6 boxed::Box,
7 collections::{BTreeMap, btree_set::BTreeSet},
8 format,
9 string::{String, ToString},
10 vec::Vec,
11};
12
13use crate::{
14 WasmValue,
15 ast::{Node, NodeType},
16 lex::{Keyword, Lexer, Span, Token},
17 untyped::{UntypedFuncCall, UntypedValue},
18};
19
20pub struct Parser<'source> {
22 lex: Lexer<'source>,
23 curr: Option<Token>,
24}
25
26impl<'source> Parser<'source> {
27 pub fn new(source: &'source str) -> Self {
29 Self::with_lexer(Lexer::new(source))
30 }
31
32 pub fn with_lexer(lexer: Lexer<'source>) -> Self {
34 Self {
35 lex: lexer,
36 curr: None,
37 }
38 }
39
40 pub fn parse_value<V: WasmValue>(&mut self, ty: &V::Type) -> Result<V, ParserError> {
43 let node = self.parse_node()?;
44 node.to_wasm_value(ty, self.lex.source())
45 }
46
47 pub fn parse_raw_value(&mut self) -> Result<UntypedValue<'source>, ParserError> {
49 let node = self.parse_node()?;
50 Ok(UntypedValue::new(self.lex.source(), node))
51 }
52
53 pub fn parse_raw_func_call(&mut self) -> Result<UntypedFuncCall<'source>, ParserError> {
56 self.advance()?;
57 let name = self.parse_label()?;
58 self.advance()?;
59 self.expect_token(Token::ParenOpen)?;
60
61 let params = if self.next_is(Token::ParenClose) {
62 self.advance()?;
63 None
64 } else {
65 Some(self.parse_tuple()?)
66 };
67 Ok(UntypedFuncCall::new(self.lex.source(), name, params))
68 }
69
70 pub fn finish(&mut self) -> Result<(), ParserError> {
72 match self.lex.clone().spanned().next() {
73 None => Ok(()),
74 Some((_, span)) => Err(ParserError::new(
75 ParserErrorKind::TrailingCharacters,
76 span.clone(),
77 )),
78 }
79 }
80
81 fn parse_node(&mut self) -> Result<Node, ParserError> {
82 Ok(match self.advance()? {
83 Token::Number => self.leaf_node(NodeType::Number),
84 Token::Char => self.leaf_node(NodeType::Char),
85 Token::String => self.leaf_node(NodeType::String),
86 Token::MultilineString => self.leaf_node(NodeType::MultilineString),
87 Token::ParenOpen => self.parse_tuple()?,
88 Token::BracketOpen => self.parse_list()?,
89 Token::BraceOpen => self.parse_record_or_flags()?,
90 Token::LabelOrKeyword => match Keyword::decode(self.slice()) {
91 Some(Keyword::True) => self.leaf_node(NodeType::BoolTrue),
92 Some(Keyword::False) => self.leaf_node(NodeType::BoolFalse),
93 Some(Keyword::Some) => self.parse_option(NodeType::OptionSome)?,
94 Some(Keyword::None) => self.parse_option(NodeType::OptionNone)?,
95 Some(Keyword::Ok) => self.parse_result(NodeType::ResultOk)?,
96 Some(Keyword::Err) => self.parse_result(NodeType::ResultErr)?,
97 Some(Keyword::Inf | Keyword::Nan) => self.leaf_node(NodeType::Number),
98 None => self.parse_label_maybe_payload()?,
99 },
100 Token::BraceClose
101 | Token::ParenClose
102 | Token::BracketClose
103 | Token::Colon
104 | Token::Comma => return Err(self.unexpected_token()),
105 })
106 }
107
108 fn parse_tuple(&mut self) -> Result<Node, ParserError> {
109 let start = self.span().start;
110 let children = self.parse_comma_separated_nodes(Token::ParenClose)?;
111 let span = start..self.span().end;
112 if children.is_empty() {
113 return Err(ParserError::new(ParserErrorKind::EmptyTuple, span));
114 }
115 Ok(Node::new(NodeType::Tuple, span, children))
116 }
117
118 fn parse_list(&mut self) -> Result<Node, ParserError> {
119 let start = self.span().start;
120 let children = self.parse_comma_separated_nodes(Token::BracketClose)?;
121 Ok(Node::new(NodeType::List, start..self.span().end, children))
122 }
123
124 fn parse_record_or_flags(&mut self) -> Result<Node, ParserError> {
125 let start = self.span().start;
126 self.advance()?;
127
128 match self.token() {
129 Token::Colon => {
131 self.advance()?; self.expect_token(Token::BraceClose)?;
133 return Ok(Node::new(NodeType::Record, start..self.span().end, []));
134 }
135 Token::BraceClose => return Ok(Node::new(NodeType::Flags, start..self.span().end, [])),
137 _ => (),
138 }
139
140 if self.next_is(Token::Colon) {
142 self.finish_record(start)
143 } else {
144 self.finish_flags(start)
145 }
146 }
147
148 fn finish_record(&mut self, start: usize) -> Result<Node, ParserError> {
149 let mut seen = BTreeSet::new();
150 let mut children = Vec::with_capacity(2);
151 loop {
152 let label = self.parse_label()?;
154 let field = self.slice().trim_start_matches('%');
156 if !seen.insert(field) {
157 return Err(ParserError::with_detail(
158 ParserErrorKind::DuplicateField,
159 label.span(),
160 format!("{field:?}"),
161 ));
162 }
163 self.advance()?;
165 self.expect_token(Token::Colon)?;
166 let value = self.parse_node()?;
168 children.extend([label, value]);
169 if self.advance()? == Token::Comma {
171 self.advance()?;
172 }
173 if self.token() == Token::BraceClose {
174 break;
175 }
176 }
177 Ok(Node::new(
178 NodeType::Record,
179 start..self.span().end,
180 children,
181 ))
182 }
183
184 fn finish_flags(&mut self, start: usize) -> Result<Node, ParserError> {
185 let mut flags = BTreeMap::new();
186 loop {
187 let label = self.parse_label()?;
189 let span = label.span();
191 let flag = self.slice().trim_start_matches('%');
192 if flags.insert(flag, label).is_some() {
193 return Err(ParserError::with_detail(
194 ParserErrorKind::DuplicateFlag,
195 span,
196 format!("{flag:?}"),
197 ));
198 }
199 if self.advance()? == Token::Comma {
201 self.advance()?;
202 }
203 if self.token() == Token::BraceClose {
204 break;
205 }
206 }
207 Ok(Node::new(
208 NodeType::Flags,
209 start..self.span().end,
210 flags.into_values(),
211 ))
212 }
213
214 fn parse_label_maybe_payload(&mut self) -> Result<Node, ParserError> {
215 let start = self.span().start;
216 let label = self.parse_label()?;
217 if self.next_is(Token::ParenOpen) {
218 self.advance()?;
219 let payload = self.parse_node()?;
220 self.advance()?;
221 self.expect_token(Token::ParenClose)?;
222 Ok(Node::new(
223 NodeType::VariantWithPayload,
224 start..self.span().end,
225 [label, payload],
226 ))
227 } else {
228 Ok(label)
229 }
230 }
231
232 fn parse_option(&mut self, ty: NodeType) -> Result<Node, ParserError> {
233 let start = self.span().start;
234 let payload = match ty {
235 NodeType::OptionSome => {
236 self.advance()?;
237 self.expect_token(Token::ParenOpen)?;
238 let payload = self.parse_node()?;
239 self.advance()?;
240 self.expect_token(Token::ParenClose)?;
241 Some(payload)
242 }
243 NodeType::OptionNone => None,
244 _ => unreachable!(),
245 };
246 Ok(Node::new(ty, start..self.span().end, payload))
247 }
248
249 fn parse_result(&mut self, ty: NodeType) -> Result<Node, ParserError> {
250 let start = self.span().start;
251 let mut payload = None;
252 if self.next_is(Token::ParenOpen) {
253 self.advance()?;
254 self.expect_token(Token::ParenOpen)?;
255 payload = Some(self.parse_node()?);
256 self.advance()?;
257 self.expect_token(Token::ParenClose)?;
258 }
259 Ok(Node::new(ty, start..self.span().end, payload))
260 }
261
262 fn parse_label(&mut self) -> Result<Node, ParserError> {
263 self.expect_token(Token::LabelOrKeyword)?;
264 Ok(self.leaf_node(NodeType::Label))
265 }
266
267 fn advance(&mut self) -> Result<Token, ParserError> {
268 let token = match self.lex.next() {
269 Some(Ok(token)) => token,
270 Some(Err(span)) => {
271 let span = span.unwrap_or_else(|| self.lex.span());
272 return Err(ParserError::new(ParserErrorKind::InvalidToken, span));
273 }
274 None => {
275 return Err(ParserError::new(
276 ParserErrorKind::UnexpectedEnd,
277 self.lex.span(),
278 ));
279 }
280 };
281 self.curr = Some(token);
282 Ok(token)
283 }
284
285 fn token(&self) -> Token {
286 self.curr.unwrap()
287 }
288
289 fn span(&self) -> Span {
290 self.lex.span()
291 }
292
293 fn slice(&self) -> &'source str {
294 &self.lex.source()[self.span()]
295 }
296
297 fn next_is(&mut self, token: Token) -> bool {
298 self.lex.clone().next().and_then(|res| res.ok()) == Some(token)
299 }
300
301 fn expect_token(&self, token: Token) -> Result<(), ParserError> {
302 if self.token() == token {
303 Ok(())
304 } else {
305 Err(self.unexpected_token())
306 }
307 }
308
309 fn unexpected_token(&self) -> ParserError {
310 ParserError::with_detail(ParserErrorKind::UnexpectedToken, self.span(), self.token())
311 }
312
313 fn parse_comma_separated_nodes(&mut self, end_token: Token) -> Result<Vec<Node>, ParserError> {
314 let mut nodes = Vec::new();
315 if self.next_is(end_token) {
316 self.advance()?;
317 return Ok(nodes);
318 }
319 loop {
320 nodes.push(self.parse_node()?);
321
322 match self.advance()? {
323 Token::Comma => {
324 if self.next_is(end_token) {
325 self.advance()?;
326 break;
327 }
328 }
329 _ => {
330 self.expect_token(end_token)?;
331 break;
332 }
333 }
334 }
335 Ok(nodes)
336 }
337
338 fn leaf_node(&self, ty: NodeType) -> Node {
339 Node::new(ty, self.span(), [])
340 }
341}
342
343#[derive(Debug)]
345pub struct ParserError {
346 kind: ParserErrorKind,
347 span: Span,
348 detail: Option<String>,
349 source: Option<Box<dyn Error + Send + Sync + 'static>>,
350}
351
352impl ParserError {
353 pub(crate) fn new(kind: ParserErrorKind, span: Span) -> Self {
354 Self {
355 kind,
356 span,
357 detail: None,
358 source: None,
359 }
360 }
361
362 pub(crate) fn with_detail(kind: ParserErrorKind, span: Span, detail: impl Display) -> Self {
363 Self {
364 kind,
365 span,
366 detail: Some(detail.to_string()),
367 source: None,
368 }
369 }
370
371 pub(crate) fn with_source(
372 kind: ParserErrorKind,
373 span: Span,
374 source: impl Into<Box<dyn Error + Send + Sync>>,
375 ) -> Self {
376 Self {
377 kind,
378 span,
379 detail: None,
380 source: Some(source.into()),
381 }
382 }
383
384 pub fn kind(&self) -> ParserErrorKind {
386 self.kind
387 }
388
389 pub fn span(&self) -> Span {
391 self.span.clone()
392 }
393
394 pub fn detail(&self) -> Option<&str> {
396 self.detail.as_deref()
397 }
398}
399
400impl Display for ParserError {
401 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
402 if let Some(source) = &self.source {
403 write!(f, "{}: {} at {:?}", self.kind, source, self.span)
404 } else if let Some(detail) = &self.detail {
405 write!(f, "{}: {} at {:?}", self.kind, detail, self.span)
406 } else {
407 write!(f, "{} at {:?}", self.kind, self.span)
408 }
409 }
410}
411
412impl Error for ParserError {
413 fn source(&self) -> Option<&(dyn Error + 'static)> {
414 Some(self.source.as_deref()? as _)
415 }
416}
417
418#[derive(Clone, Copy, Debug, PartialEq)]
420#[non_exhaustive]
421#[allow(missing_docs)]
422pub enum ParserErrorKind {
423 EmptyTuple,
424 MultipleChars,
425 InvalidEscape,
426 InvalidMultilineString,
427 InvalidParams,
428 InvalidToken,
429 InvalidType,
430 InvalidValue,
431 TrailingCharacters,
432 UnexpectedEnd,
433 UnexpectedToken,
434 DuplicateField,
435 DuplicateFlag,
436 WasmValueError,
437}
438
439impl Display for ParserErrorKind {
440 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
441 let msg = match self {
442 ParserErrorKind::EmptyTuple => "empty tuple",
443 ParserErrorKind::MultipleChars => "multiple characters in char value",
444 ParserErrorKind::InvalidEscape => "invalid character escape",
445 ParserErrorKind::InvalidMultilineString => "invalid multiline string",
446 ParserErrorKind::InvalidParams => "invalid params",
447 ParserErrorKind::InvalidToken => "invalid token",
448 ParserErrorKind::InvalidType => "invalid value type",
449 ParserErrorKind::InvalidValue => "invalid value",
450 ParserErrorKind::TrailingCharacters => "trailing characters after value",
451 ParserErrorKind::UnexpectedEnd => "unexpected end of input",
452 ParserErrorKind::UnexpectedToken => "unexpected token",
453 ParserErrorKind::DuplicateField => "duplicate field",
454 ParserErrorKind::DuplicateFlag => "duplicate flag",
455 ParserErrorKind::WasmValueError => "error converting Wasm value",
456 };
457 write!(f, "{msg}")
458 }
459}
460
461#[cfg(test)]
462mod tests {
463 use super::*;
464 use crate::value::{Type, Value};
465
466 #[test]
467 fn parse_option_or_result() {
468 let ty = Type::option(Type::BOOL);
469 assert_eq!(
470 parse_value("some(true)", &ty),
471 Value::make_option(&ty, Some(Value::make_bool(true))).unwrap()
472 );
473 let ty = Type::result(Some(Type::BOOL), None);
474 assert_eq!(
475 parse_value("ok(false)", &ty),
476 Value::make_result(&ty, Ok(Some(Value::make_bool(false)))).unwrap()
477 );
478 }
479
480 #[test]
481 fn parse_flat_option_or_result() {
482 let ty = Type::option(Type::BOOL);
483 assert_eq!(
484 parse_value("true", &ty),
485 Value::make_option(&ty, Some(Value::make_bool(true))).unwrap()
486 );
487 let ty = Type::result(Some(Type::BOOL), None);
488 assert_eq!(
489 parse_value("false", &ty),
490 Value::make_result(&ty, Ok(Some(Value::make_bool(false)))).unwrap()
491 );
492 }
493
494 #[test]
495 fn parse_record_reordering() {
496 let ty = Type::record([("red", Type::S32), ("green", Type::CHAR)]).unwrap();
497 assert_eq!(
499 parse_value("{red: 0, green: 'a'}", &ty),
500 Value::make_record(
501 &ty,
502 [
503 ("red", Value::make_s32(0)),
504 ("green", Value::make_char('a'))
505 ]
506 )
507 .unwrap()
508 );
509 assert_eq!(
511 parse_value("{green: 'a', red: 0}", &ty),
512 Value::make_record(
513 &ty,
514 [
515 ("red", Value::make_s32(0)),
516 ("green", Value::make_char('a'))
517 ]
518 )
519 .unwrap()
520 );
521 }
522
523 #[test]
524 fn parse_record_with_optional_fields() {
525 let field_ty = Type::option(Type::CHAR);
526 let ty = Type::record([("red", Type::S32), ("green", field_ty.clone())]).unwrap();
527 assert_eq!(
529 parse_value("{red: 0, green: some('a')}", &ty),
530 Value::make_record(
531 &ty,
532 [
533 ("red", Value::make_s32(0)),
534 (
535 "green",
536 Value::make_option(&field_ty, Some(Value::make_char('a'))).unwrap()
537 )
538 ]
539 )
540 .unwrap()
541 );
542 assert_eq!(
544 parse_value("{red: 0, green: 'a'}", &ty),
545 Value::make_record(
546 &ty,
547 [
548 ("red", Value::make_s32(0)),
549 (
550 "green",
551 Value::make_option(&field_ty, Some(Value::make_char('a'))).unwrap()
552 )
553 ]
554 )
555 .unwrap()
556 );
557 assert_eq!(
559 parse_value("{red: 0, green: none}", &ty),
560 Value::make_record(
561 &ty,
562 [
563 ("red", Value::make_s32(0)),
564 ("green", Value::make_option(&field_ty, None).unwrap())
565 ]
566 )
567 .unwrap()
568 );
569 assert_eq!(
571 parse_value("{red: 0}", &ty),
572 Value::make_record(
573 &ty,
574 [
575 ("red", Value::make_s32(0)),
576 ("green", Value::make_option(&field_ty, None).unwrap())
577 ]
578 )
579 .unwrap()
580 );
581 }
582
583 #[test]
584 fn parse_flag_reordering() {
585 let ty = Type::flags(["hot", "cold"]).unwrap();
586 assert_eq!(
588 parse_value("{hot, cold}", &ty),
589 Value::make_flags(&ty, ["hot", "cold"]).unwrap()
590 );
591 assert_eq!(
593 parse_value("{cold, hot}", &ty),
594 Value::make_flags(&ty, ["hot", "cold"]).unwrap()
595 );
596 }
597
598 #[test]
599 fn parse_percent_identifiers() {
600 let ty = Type::record([
601 ("red", Type::S32),
602 ("green", Type::CHAR),
603 ("color-42-2A-5d", Type::BOOL),
604 ])
605 .unwrap();
606 assert_eq!(
608 parse_value("{ %red: 0, %green: 'a', %color-42-2A-5d: true }", &ty),
609 Value::make_record(
610 &ty,
611 [
612 ("red", Value::make_s32(0)),
613 ("green", Value::make_char('a')),
614 ("color-42-2A-5d", Value::make_bool(true))
615 ]
616 )
617 .unwrap()
618 );
619 }
620
621 #[test]
622 fn parse_prefixed_keyword_variant_cases() {
623 let ty = Type::list(
624 Type::variant([
625 ("true", Some(Type::U8)),
626 ("false", None),
627 ("inf", Some(Type::U8)),
628 ("nan", None),
629 ("some", Some(Type::U8)),
630 ("none", None),
631 ("ok", Some(Type::U8)),
632 ("err", None),
633 ])
634 .unwrap(),
635 );
636 parse_value(
637 "[%true(1), %false, %inf(1), %nan, %some(1), %none, %ok(1), %err]",
638 &ty,
639 );
640 }
641
642 #[test]
643 fn reject_unprefixed_keyword_enum_cases() {
644 let cases = ["true", "false", "inf", "nan", "none", "ok", "err"];
645 let ty = Type::enum_ty(cases).unwrap();
646 for case in cases {
647 let err = Parser::new(case).parse_value::<Value>(&ty).unwrap_err();
648 assert_eq!(err.kind(), ParserErrorKind::InvalidType);
649 }
650 }
651
652 #[test]
653 fn parse_unprefixed_keyword_fields() {
654 let ty = Type::record([
655 ("true", Type::U8),
656 ("false", Type::U8),
657 ("inf", Type::U8),
658 ("nan", Type::U8),
659 ("some", Type::U8),
660 ("none", Type::U8),
661 ("ok", Type::U8),
662 ("err", Type::U8),
663 ])
664 .unwrap();
665 parse_value(
666 "{true: 1, false: 1, inf: 1, nan: 1, some: 1, none: 1, ok: 1, err: 1}",
667 &ty,
668 );
669 }
670
671 #[test]
672 fn parse_unprefixed_keyword_flags() {
673 let ty = Type::flags(["true", "false", "inf", "nan", "some", "none", "ok", "err"]).unwrap();
674 parse_value("{true, false, inf, nan, some, none, ok, err}", &ty);
675 }
676
677 #[test]
678 fn reject_unprefixed_some_variant_case() {
679 let ty = Type::variant([("some", Some(Type::U8))]).unwrap();
680 let err = Parser::new("some(1)")
681 .parse_value::<Value>(&ty)
682 .unwrap_err();
683 assert_eq!(err.kind(), ParserErrorKind::InvalidType);
684 }
685
686 fn parse_value(input: &str, ty: &Type) -> Value {
687 Parser::new(input)
688 .parse_value(ty)
689 .unwrap_or_else(|err| panic!("error decoding {input:?}: {err}"))
690 }
691}