1use crate::runtime::context::JSContext;
2use crate::value::JSValue;
3
4pub fn global_parseint(ctx: &mut JSContext, args: &[JSValue]) -> JSValue {
5 if args.is_empty() {
6 return JSValue::new_float(f64::NAN);
7 }
8 let s = if args[0].is_string() {
9 ctx.get_atom_str(args[0].get_atom())
10 } else if args[0].is_int() {
11 return args[0];
12 } else if args[0].is_float() {
13 return JSValue::new_int(args[0].get_float().trunc() as i64);
14 } else {
15 return JSValue::new_float(f64::NAN);
16 };
17
18 let mut input = s.trim_start();
19 let mut sign = 1i64;
20 if let Some(rest) = input.strip_prefix('-') {
21 sign = -1;
22 input = rest;
23 } else if let Some(rest) = input.strip_prefix('+') {
24 input = rest;
25 }
26
27 let mut radix = if args.len() > 1 {
28 if args[1].is_int() {
29 args[1].get_int() as i32
30 } else if args[1].is_float() {
31 args[1].get_float() as i32
32 } else {
33 0
34 }
35 } else {
36 0
37 };
38
39 if radix != 0 && !(2..=36).contains(&radix) {
40 return JSValue::new_float(f64::NAN);
41 }
42
43 if radix == 0 {
44 if input.starts_with("0x") || input.starts_with("0X") {
45 radix = 16;
46 input = &input[2..];
47 } else {
48 radix = 10;
49 }
50 } else if radix == 16 && (input.starts_with("0x") || input.starts_with("0X")) {
51 input = &input[2..];
52 }
53
54 let mut digits = String::new();
55 for ch in input.chars() {
56 if ch.to_digit(radix as u32).is_some() {
57 digits.push(ch);
58 } else {
59 break;
60 }
61 }
62
63 if digits.is_empty() {
64 return JSValue::new_float(f64::NAN);
65 }
66
67 match i64::from_str_radix(&digits, radix as u32) {
68 Ok(v) => JSValue::new_int(sign.saturating_mul(v)),
69 Err(_) => JSValue::new_float(f64::NAN),
70 }
71}
72
73pub fn global_parsefloat(ctx: &mut JSContext, args: &[JSValue]) -> JSValue {
74 if args.is_empty() {
75 return JSValue::new_float(f64::NAN);
76 }
77 let s = if args[0].is_string() {
78 ctx.get_atom_str(args[0].get_atom())
79 } else if args[0].is_float() || args[0].is_int() {
80 return args[0];
81 } else {
82 return JSValue::new_float(f64::NAN);
83 };
84 match s.trim().parse::<f64>() {
85 Ok(v) => JSValue::new_float(v),
86 Err(_) => JSValue::new_float(f64::NAN),
87 }
88}