1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use crate::expression::parse_variable;
use crate::literals::Variable;
use nom::{
    combinator::opt,
    error::context,
    multi::separated_list0,
    sequence::{delimited, preceded, tuple},
};

use super::{parse_expression, Expression};

use crate::parser::{
    literals::sp,
    tokens::{comma, left_paren, right_paren},
    Res, Span,
};

#[derive(Clone, Debug, PartialEq)]
pub struct Call<'a> {
    pub callee: Option<Variable<'a>>,
    pub args: Vec<Expression<'a>>,
}

pub(crate) fn args(input: Span) -> Res<Vec<Expression>> {
    context(
        "Args",
        separated_list0(preceded(sp, comma), parse_expression),
    )(input)
}

pub(crate) fn parse_call(input: Span) -> Res<Call> {
    context(
        "Call",
        tuple((
            opt(preceded(sp, parse_variable)),
            delimited(
                preceded(sp, left_paren),
                preceded(sp, args),
                preceded(sp, right_paren),
            ),
        )),
    )(input)
    .map(|(next_input, res)| {
        (
            next_input,
            Call {
                callee: res.0,
                args: res.1,
            },
        )
    })
}

#[cfg(test)]
mod tests {

    use super::*;
    use crate::literals::Token;

    #[test]
    fn test_call() {
        let string = "call()";
        let (_, res) = parse_call(Span::new(string)).unwrap();
        let e_res = Call {
            callee: Some(Token::new("call", Span::new("call"))),
            args: vec![],
        };
        assert_eq!(res, e_res);
    }
}