microcad_lang/parse/
call.rs1use crate::{ord_map::*, parse::*, parser::*, syntax::*};
5
6impl Parse for Call {
7 fn parse(pair: Pair) -> ParseResult<Self> {
8 Parser::ensure_rule(&pair, Rule::call);
9 let mut inner = pair.inner();
10 let first = inner.next().expect("Expected qualified name");
11
12 Ok(Call {
13 name: QualifiedName::parse(first)?,
14 argument_list: crate::find_rule!(pair, argument_list)?,
15 src_ref: pair.clone().into(),
16 })
17 }
18}
19
20impl Parse for ArgumentList {
21 fn parse(pair: Pair) -> ParseResult<Self> {
22 Parser::ensure_rule(&pair, Rule::argument_list);
23 let mut argument_list = ArgumentList(Refer::new(OrdMap::default(), pair.clone().into()));
24
25 match pair.as_rule() {
26 Rule::argument_list => {
27 for pair in pair.inner() {
28 match pair.as_rule() {
29 Rule::named_argument | Rule::expression => {
30 argument_list
31 .try_push(Argument::parse(pair)?)
32 .map_err(ParseError::DuplicateArgument)?;
33 }
34 Rule::COMMENT => {}
35 rule => unreachable!("Expected argument, found {rule:?}"),
36 }
37 }
38
39 Ok(argument_list)
40 }
41 rule => {
42 unreachable!("ArgumentList::parse expected argument list, found {rule:?}")
43 }
44 }
45 }
46}
47
48impl Parse for Argument {
49 fn parse(pair: Pair) -> ParseResult<Self> {
50 match pair.clone().as_rule() {
51 Rule::named_argument => {
52 let mut inner = pair.inner();
53 let first = inner.next().expect(INTERNAL_PARSE_ERROR);
54 let second = inner.next().expect(INTERNAL_PARSE_ERROR);
55
56 Ok(Argument {
57 id: Some(Identifier::parse(first)?),
58 expression: Expression::parse(second)?,
59 src_ref: pair.src_ref(),
60 })
61 }
62 Rule::expression => Ok(Argument {
63 id: None,
64 expression: Expression::parse(pair.clone())?,
65 src_ref: pair.into(),
66 }),
67 rule => unreachable!("Argument::parse expected argument, found {rule:?}"),
68 }
69 }
70}
71
72impl Parse for MethodCall {
73 fn parse(pair: Pair) -> ParseResult<Self> {
74 Ok(MethodCall {
75 name: pair.find(Rule::qualified_name).expect(INTERNAL_PARSE_ERROR),
76 argument_list: pair.find(Rule::argument_list).unwrap_or_default(),
77 src_ref: pair.clone().into(),
78 })
79 }
80}
81
82#[test]
83fn call() {
84 use crate::{parser::*, syntax::*};
85 use pest::Parser as _;
86
87 let pair = Pair::new(
88 Parser::parse(Rule::call, "foo(1, 2, bar = 3, baz = 4)")
89 .expect("test error")
90 .next()
91 .expect("test error"),
92 0,
93 );
94
95 let call = Call::parse(pair).expect("test error");
96
97 assert_eq!(call.name, "foo".into());
98 assert_eq!(call.argument_list.len(), 4);
99
100 let named = call
102 .argument_list
103 .iter()
104 .filter(|arg| arg.id.is_some())
105 .count();
106 assert_eq!(named, 2);
107}