nom_lua/
var.rs

1// Copyright 2017 The nom-lua project developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use ast::ASTNode;
10use ast::ASTNode::*;
11use exp::{parse_prefixexp, parse_exp};
12use name::parse_name;
13use nom::IResult;
14
15named!(pub parse_varlist<ASTNode>, map!(
16            map!(do_parse!(
17                   a: parse_var
18                >> b: many0!(preceded!(ws!(tag!(",")), parse_var))
19                >> ((a,b))
20            ), |(a, mut b): (_, Vec < ASTNode >) | { b.insert(0, a); b }),
21ASTNode::VarList));
22
23named!(pub parse_var<ASTNode>, alt!(
24    map!(do_parse!(
25           name: parse_name
26        >> r: opt!(alt!(complete!(delimited!(ws!(tag!("[")), ws!(parse_exp), tag!("]"))) |
27                        complete!(preceded!(ws!(tag!(".")), parse_name))))
28        >> ((name, r))
29        ), |(name, r)| {
30            if let Some(rest) = r {
31                match rest {
32                    ASTNode::Name(_) => {
33                        return astb!(VarListAccess, astb!(PrefixExp, astb!(Var, name)), rest);
34                    },
35                    _ => {
36                        return astb!(VarPrefixed, astb!(PrefixExp, astb!(Var, name)), rest);
37                    },
38                }
39            }
40
41            astb!(Var, name)
42        }
43    ) |
44    do_parse!(
45           pe: parse_prefixexp
46           // The ws!'s are this way, to not eat any whitespace
47           // outside of the expression
48        >> e: delimited!(ws!(tag!("[")), ws!(parse_exp), tag!("]"))
49        >> (astb!(VarPrefixed, pe, e))) |
50    do_parse!(
51           pe: parse_prefixexp
52        >> n: preceded!(ws!(tag!(".")), parse_name)
53        >> (astb!(VarListAccess, pe, n)))
54));
55
56#[cfg(test)]
57mod tests {
58    use ast::ASTNode::*;
59
60    ast_test!(parse_var_1, parse_var, "ayy", astb!(Var, ast!(Name, "ayy".into())));
61    ast_test!(parse_var_2, parse_var, "ayy [ true ]",
62              astb!(VarPrefixed,
63                    astb!(PrefixExp, astb!(Var, ast!(Name, "ayy".into()))),
64                    ast!(Bool, true)));
65    ast_test!(parse_var_3, parse_var, "ayy.zxc",
66              astb!(VarListAccess,
67                    astb!(PrefixExp, astb!(Var, ast!(Name, "ayy".into()))),
68                    ast!(Name, "zxc".into())));
69
70    ast_test!(parse_varlist_1, parse_varlist, "xcz", ast!(VarList, vec![
71        astb!(Var, ast!(Name, "xcz".into()))
72    ]));
73    ast_test!(parse_varlist_2, parse_varlist, "xcz , mcx", ast!(VarList, vec![
74        astb!(Var, ast!(Name, "xcz".into())),
75        astb!(Var, ast!(Name, "mcx".into()))
76    ]));
77    ast_test!(parse_varlist_3, parse_varlist, "lak , k, jd3", ast!(VarList, vec![
78        astb!(Var, ast!(Name, "lak".into())),
79        astb!(Var, ast!(Name, "k".into())),
80        astb!(Var, ast!(Name, "jd3".into()))
81    ]));
82}