MCPcopy Create free account
hub / github.com/dylan-sutton-chavez/edge-python / call_int

Method call_int

compiler/src/modules/vm/builtins/numeric.rs:113–165  ·  view source on GitHub ↗
(&mut self, argc: u16, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val])

Source from the content-addressed store, hash-verified

111 }
112
113 pub fn call_int(&mut self, argc: u16, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val]) -> Result<(), VmErr> {
114 // Two-arg form `int(string, base)`: parse the string in the given radix.
115 if argc == 2 {
116 let base_v = self.pop()?;
117 let o = self.pop()?;
118 if !base_v.is_int() { return Err(cold_type("int() base must be an integer")); }
119 let base = base_v.as_int();
120 let s = match self.heap.try_get(o) {
121 Some(HeapObj::Str(s)) => s.clone(),
122 Some(HeapObj::Bytes(b)) => core::str::from_utf8(b).map_err(|_| cold_value("int() bytes not valid utf-8"))?.into(),
123 _ => return Err(cold_type("int() can't convert non-string with explicit base")),
124 };
125 let i = parse_int_radix(&s, base)?;
126 let v = self.int_to_val(Some(i))?;
127 self.push(v); return Ok(());
128 }
129 if argc == 0 { self.push(Val::int(0)); return Ok(()); }
130 if argc > 2 { for _ in 0..argc { let _ = self.pop(); } return Err(cold_type("int() takes at most 2 arguments")); }
131 let o = self.pop()?;
132 // Already an int (inline or LongInt), pass through unchanged.
133 if o.is_int() { self.push(o); return Ok(()); }
134 if o.is_heap() && matches!(self.heap.get(o), HeapObj::LongInt(_)) {
135 self.push(o); return Ok(());
136 }
137 let i: i128 = if o.is_float() {
138 let f = o.as_float();
139 if f.is_nan() { return Err(cold_value("cannot convert float NaN to integer")); }
140 if f.is_infinite() { return Err(VmErr::Raised(alloc::string::String::from("OverflowError: cannot convert float infinity to integer"))); }
141 let t = ftrunc(f);
142 // i128::MAX as f64 rounds up past the true max, so reject before the saturating cast.
143 if !(-1.7014118346046923e38..=1.7014118346046921e38).contains(&t) { return Err(cold_overflow()); }
144 t as i128
145 }
146 else if o.is_bool() { o.as_bool() as i128 }
147 else if o.is_heap() && let HeapObj::Str(s) = self.heap.get(o) {
148 let s = s.clone();
149 parse_int_radix(&s, 10)?
150 }
151 else if o.is_heap() && let HeapObj::Bytes(b) = self.heap.get(o) {
152 parse_int_radix(core::str::from_utf8(b).map_err(|_| cold_value("int() bytes not valid utf-8"))?, 10)?
153 }
154 else if o.is_heap() && matches!(self.heap.get(o), HeapObj::Instance(..)) {
155 // Honor a user `__int__` method.
156 match self.try_call_dunder(o, "__int__", &[], chunk, slots)? {
157 Some(r) if r.is_int() || r.is_bool() => self.as_i128(r).unwrap_or(r.as_bool() as i128),
158 Some(_) => return Err(cold_type("__int__ returned non-int")),
159 None => return Err(cold_type("int() requires a number or string")),
160 }
161 }
162 else { return Err(cold_type("int() requires a number or string")); };
163 let v = self.int_to_val(Some(i))?;
164 self.push(v); Ok(())
165 }
166
167 /* Converts int or parseable string to floating point. */
168 pub fn call_float(&mut self, argc: u16) -> Result<(), VmErr> {

Callers 2

handle_functionMethod · 0.80
dispatch_nativeMethod · 0.80

Calls 15

cold_typeFunction · 0.85
cold_valueFunction · 0.85
parse_int_radixFunction · 0.85
ftruncFunction · 0.85
cold_overflowFunction · 0.85
is_intMethod · 0.80
as_intMethod · 0.80
try_getMethod · 0.80
int_to_valMethod · 0.80
pushMethod · 0.80
is_heapMethod · 0.80
is_floatMethod · 0.80

Tested by

no test coverage detected