libcst_native/parser/
numbers.rs1use regex::Regex;
7
8use crate::nodes::deflated::{Expression, Float, Imaginary, Integer};
9
10static HEX: &str = r"0[xX](?:_?[0-9a-fA-F])+";
11static BIN: &str = r"0[bB](?:_?[01])+";
12static OCT: &str = r"0[oO](?:_?[0-7])+";
13static DECIMAL: &str = r"(?:0(?:_?0)*|[1-9](?:_?[0-9])*)";
14
15static EXPONENT: &str = r"[eE][-+]?[0-9](?:_?[0-9])*";
16static POINT_FLOAT: &str = r"([0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?|\.[0-9](?:_?[0-9])*)";
18static EXP_FLOAT: &str = r"[0-9](?:_?[0-9])*";
19
20thread_local! {
21 static INTEGER_RE: Regex =
22 Regex::new(format!("^({}|{}|{}|{})$", HEX, BIN, OCT, DECIMAL).as_str()).expect("regex");
23 static FLOAT_RE: Regex =
24 Regex::new(
25 format!(
26 "^({}({})?|{}{})$",
27 POINT_FLOAT, EXPONENT, EXP_FLOAT, EXPONENT
28 )
29 .as_str(),
30 )
31 .expect("regex");
32 static IMAGINARY_RE: Regex =
33 Regex::new(
34 format!(
35 r"^([0-9](?:_?[0-9])*[jJ]|({}({})?|{}{})[jJ])$",
36 POINT_FLOAT, EXPONENT, EXP_FLOAT, EXPONENT
37 )
38 .as_str(),
39 )
40 .expect("regex");
41}
42
43pub(crate) fn parse_number(raw: &str) -> Expression {
44 if INTEGER_RE.with(|r| r.is_match(raw)) {
45 Expression::Integer(Box::new(Integer {
46 value: raw,
47 lpar: Default::default(),
48 rpar: Default::default(),
49 }))
50 } else if FLOAT_RE.with(|r| r.is_match(raw)) {
51 Expression::Float(Box::new(Float {
52 value: raw,
53 lpar: Default::default(),
54 rpar: Default::default(),
55 }))
56 } else if IMAGINARY_RE.with(|r| r.is_match(raw)) {
57 Expression::Imaginary(Box::new(Imaginary {
58 value: raw,
59 lpar: Default::default(),
60 rpar: Default::default(),
61 }))
62 } else {
63 Expression::Integer(Box::new(Integer {
64 value: raw,
65 lpar: Default::default(),
66 rpar: Default::default(),
67 }))
68 }
69}