1use std::str;
10use std::str::FromStr;
11use ast::ASTNode;
12use ast::ASTNode::*;
13use super::nom::{digit, hex_digit};
16named!(parse_int_overflow<ASTNode>, map!(
20 map_res!(map_res!(digit, str::from_utf8), FromStr::from_str),
21 ASTNode::Float));
22
23named!(parse_int<ASTNode>, map!(
24 map_res!(map_res!(digit, str::from_utf8), FromStr::from_str),
25 ASTNode::Integer));
26
27named!(parse_hex_int<ASTNode>,
28 do_parse!(
29 preceded!(tag!("0"), alt!(tag!("x") | tag!("X"))) >>
30 hex: map_res!(
31 map_res!(hex_digit, str::from_utf8),
32 |h| i64::from_str_radix(h, 16))
33 >> (ast!(Integer, hex))));
34
35named!(parse_float_exp, recognize!(do_parse!(
36 alt!(tag!("e") | tag!("E"))
37 >> opt!(alt!(tag!("+") | tag!("-")))
38 >> digit
39 >> ())));
40
41named!(parse_float<ASTNode>,
42 do_parse!(
43 float: map_res!( map_res!( recognize!( do_parse!(
44 alt!(
45 delimited!(digit, tag!("."), opt!(complete!(digit))) |
46 delimited!(opt!(digit), tag!("."), digit) |
47 digit)
48 >> opt!(complete!(parse_float_exp))
49 >> ())),
50 str::from_utf8), FromStr::from_str)
51 >> (ast!(Float, float)))
52 );
53
54
55named!(pub parse_number<ASTNode>, dbg_dmp!(alt!(
59 complete!(parse_hex_int) |
61 complete!(parse_float) |
62 parse_int |
63 parse_int_overflow
64)));
65
66#[cfg(test)]
67mod tests {
68 ast_test!(parse_int_1, parse_int, "20", ast!(Integer, 20));
71
72 ast_panic_test!(parse_int_3, parse_int, "5678987656789876520999999999999");
74
75 ast_panic_test!(parse_int_4, parse_int, "-20");
77 ast_panic_test!(parse_int_5, parse_int, "+20");
78
79
80 ast_test!(parse_hex_1, parse_hex_int, "0X20", ast!(Integer, 0x20));
81 ast_test!(parse_hex_2, parse_hex_int, "0x20", ast!(Integer, 0x20));
82 ast_test!(parse_hex_3, parse_hex_int, "0x20a", ast!(Integer, 0x20A));
83 ast_test!(parse_hex_4, parse_hex_int, "0x20aB", ast!(Integer, 0x20AB));
84 ast_test!(parse_hex_5, parse_hex_int, "0X20F", ast!(Integer, 0x20F));
85 ast_panic_test!(parse_hex_6, parse_hex_int, "20");
87 ast_panic_test!(parse_hex_7, parse_hex_int, "-0x20");
89 ast_panic_test!(parse_hex_8, parse_hex_int, "+0x20");
90
91
92 ast_test!(parse_float_1, parse_float, "3.0", ast!(Float, 3.0));
93 ast_test!(parse_float_2, parse_float, ".1", ast!(Float, 0.1));
94 ast_test!(parse_float_3, parse_float, "1.", ast!(Float, 1.0));
95 ast_test!(parse_float_4, parse_float, "3.1416", ast!(Float, 3.1416));
96 ast_test!(parse_float_5, parse_float, "314.16e-2", ast!(Float, 314.16e-2));
97 ast_test!(parse_float_6, parse_float, "0.31416E1", ast!(Float, 0.31416E1));
98 ast_test!(parse_float_7, parse_float, "34e1", ast!(Float, 340.0));
99 ast_test!(parse_float_8, parse_float, "34e+1", ast!(Float, 340.0));
100 ast_test!(parse_float_9, parse_float, "34e-1", ast!(Float, 3.4));
101 ast_test!(parse_float_10, parse_float, "34.e-1", ast!(Float, 3.4));
102 ast_test!(parse_float_11, parse_float, ".2e1", ast!(Float, 2.0));
103 ast_panic_test!(parse_float_12, parse_float, ".e1");
104
105 ast_panic_test!(parse_float_13, parse_float, "-20.0");
107 ast_panic_test!(parse_float_14, parse_float, "+20.0");
108
109 ast_test!(parse_number_1, parse_number, "20", ast!(Integer, 20));
110 ast_test!(parse_number_2, parse_number, "20.0", ast!(Float, 20.0));
111 ast_test!(parse_number_3, parse_number, "0x20", ast!(Integer, 0x20));
112 ast_test!(parse_number_4, parse_number, "1000000000000000000000000", ast!(Float, 1e+24));
113 }