mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
toExponential, toFixed
This commit is contained in:
@@ -10,6 +10,7 @@ mod math;
|
||||
mod native_frame_function;
|
||||
mod native_function;
|
||||
mod number_builtin;
|
||||
mod number_methods;
|
||||
mod operations;
|
||||
mod stack_frame;
|
||||
mod string_builtin;
|
||||
|
||||
91
valuescript_vm/src/number_methods.rs
Normal file
91
valuescript_vm/src/number_methods.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{
|
||||
native_function::NativeFunction,
|
||||
vs_value::{Val, ValTrait},
|
||||
};
|
||||
|
||||
pub fn op_sub_number(_number: f64, subscript: &Val) -> Val {
|
||||
match subscript.val_to_string().as_str() {
|
||||
"toExponential" => Val::Static(&TO_EXPONENTIAL),
|
||||
"toFixed" => Val::Static(&TO_FIXED),
|
||||
"toLocaleString" => Val::Static(&TODO_LOCALE),
|
||||
_ => Val::Undefined,
|
||||
}
|
||||
}
|
||||
|
||||
static TO_FIXED: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Val {
|
||||
match this {
|
||||
Val::Number(number) => {
|
||||
let mut precision = match params.get(0) {
|
||||
Some(p) => p.to_number(),
|
||||
_ => return Val::String(Rc::new(this.val_to_string())),
|
||||
};
|
||||
|
||||
precision = f64::floor(precision);
|
||||
|
||||
if precision < 1.0 || precision > 100.0 {
|
||||
panic!("TODO: exceptions: RangeError: precision must be between 1 and 100");
|
||||
}
|
||||
|
||||
Val::String(Rc::new(format!("{:.*}", precision as usize, number)))
|
||||
}
|
||||
_ => panic!("TODO: exceptions/number indirection"),
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static TO_EXPONENTIAL: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, params: Vec<Val>| -> Val {
|
||||
match this {
|
||||
Val::Number(number) => match params.get(0) {
|
||||
Some(p) => {
|
||||
let mut precision = p.to_number();
|
||||
precision = f64::floor(precision);
|
||||
|
||||
if precision < 0.0 || precision > 100.0 {
|
||||
panic!("TODO: exceptions: RangeError: precision must be between 0 and 100");
|
||||
}
|
||||
|
||||
format_exponential(*number, Some(precision as usize))
|
||||
}
|
||||
None => format_exponential(*number, None),
|
||||
},
|
||||
_ => panic!("TODO: exceptions/number indirection"),
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static TODO_LOCALE: NativeFunction = NativeFunction {
|
||||
fn_: |this: &mut Val, _params: Vec<Val>| -> Val {
|
||||
match this {
|
||||
Val::Number(_number) => panic!("TODO: locale"),
|
||||
_ => panic!("TODO: exceptions/number indirection"),
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
fn format_exponential(number: f64, precision: Option<usize>) -> Val {
|
||||
let exp_format = match precision {
|
||||
Some(p) => format!("{:.*e}", p, number),
|
||||
None => format!("{:e}", number),
|
||||
};
|
||||
|
||||
let mut parts = exp_format.splitn(2, 'e');
|
||||
|
||||
let mantissa = parts.next().unwrap();
|
||||
|
||||
let exponent = match parts.next() {
|
||||
Some(e) => e,
|
||||
None => return Val::String(Rc::new(exp_format)),
|
||||
};
|
||||
|
||||
let string = if exponent.starts_with('-') {
|
||||
format!("{}e{}", mantissa, exponent)
|
||||
} else {
|
||||
format!("{}e+{}", mantissa, exponent)
|
||||
};
|
||||
|
||||
Val::String(Rc::new(string))
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::number_methods::op_sub_number;
|
||||
use crate::string_methods::op_sub_string;
|
||||
|
||||
use super::vs_value::Val;
|
||||
@@ -240,8 +241,8 @@ pub fn op_sub(left: Val, right: Val) -> Val {
|
||||
Val::Void => std::panic!("Shouldn't happen"),
|
||||
Val::Undefined => std::panic!("Not implemented: exceptions"),
|
||||
Val::Null => std::panic!("Not implemented: exceptions"),
|
||||
Val::Bool(_) => Val::Undefined, // TODO: toString etc
|
||||
Val::Number(_) => Val::Undefined, // TODO: toString etc
|
||||
Val::Bool(_) => Val::Undefined, // TODO: toString etc
|
||||
Val::Number(number) => op_sub_number(number, &right),
|
||||
Val::String(string_data) => op_sub_string(&string_data, &right),
|
||||
Val::Array(array_data) => {
|
||||
let right_index = match right.to_index() {
|
||||
|
||||
Reference in New Issue
Block a user