step_p21/parser/exchange/
parameter.rs1use crate::{
2 ast::*,
3 parser::{combinator::*, token::*},
4};
5use nom::{Parser, branch::alt, combinator::value};
6
7pub fn list(input: &str) -> ParseResult<'_, Parameter> {
9 tuple_((char_('('), opt_(comma_separated(parameter)), char_(')')))
10 .map(|(_open, params, _close)| {
11 Parameter::List(params.unwrap_or_default())
12 })
13 .parse(input)
14}
15
16pub fn parameter(input: &str) -> ParseResult<'_, Parameter> {
18 alt((typed_parameter, untyped_parameter, omitted_parameter)).parse(input)
19}
20
21pub fn typed_parameter(input: &str) -> ParseResult<'_, Parameter> {
23 tuple_((keyword, char_('('), parameter, char_(')')))
24 .map(|(name, _open, ty, _close)| Parameter::Typed {
25 keyword: name,
26 parameter: Box::new(ty),
27 })
28 .parse(input)
29}
30
31pub fn untyped_parameter(input: &str) -> ParseResult<'_, Parameter> {
34 alt((
35 char_('$').map(|_| Parameter::NotProvided),
36 real.map(Parameter::Real),
37 integer.map(Parameter::Integer),
38 string.map(Parameter::String),
39 rhs_occurrence_name.map(Parameter::Ref),
40 enumeration.map(Parameter::Enumeration),
41 list,
43 ))
44 .parse(input)
45}
46
47pub fn omitted_parameter(input: &str) -> ParseResult<'_, Parameter> {
49 value(Parameter::Omitted, char_('*')).parse(input)
50}
51
52pub fn parameter_list(input: &str) -> ParseResult<'_, Vec<Parameter>> {
54 comma_separated(parameter).parse(input)
55}
56
57#[cfg(test)]
58mod tests {
59 use crate::ast::Parameter;
60 use nom::Finish;
61
62 #[test]
63 fn untyped_parameter() {
64 let (res, record) = super::untyped_parameter("2").finish().unwrap();
65 assert_eq!(res, "");
66 assert_eq!(record, Parameter::integer(2));
67
68 let (res, record) = super::untyped_parameter("2.0").finish().unwrap();
69 assert_eq!(res, "");
70 assert_eq!(record, Parameter::real(2.0));
71 }
72
73 #[test]
74 fn parameter_list() {
75 let (res, record) =
76 super::untyped_parameter("(1, 2, 3)").finish().unwrap();
77 assert_eq!(res, "");
78 assert_eq!(
79 record,
80 Parameter::List(vec![
81 Parameter::Integer(1),
82 Parameter::Integer(2),
83 Parameter::Integer(3),
84 ])
85 );
86 }
87
88 #[test]
89 fn empty_parameter_list() {
90 let (res, record) = super::untyped_parameter("()").finish().unwrap();
91 assert_eq!(res, "");
92 assert_eq!(record, Parameter::List(vec![]));
93 }
94}