1use 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 >> 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}