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