mirror of https://github.com/boa-dev/boa.git
Jason Williams
6 years ago
13 changed files with 507 additions and 12 deletions
@ -0,0 +1,17 @@ |
|||||||
|
use js::function::Function; |
||||||
|
use js::value::{to_value, ResultValue, Value}; |
||||||
|
|
||||||
|
/// Create a new array
|
||||||
|
pub fn make_array(_: Vec<Value>, _: Value, _: Value, this: Value) -> ResultValue { |
||||||
|
this.set_field_slice("length", to_value(0i32)); |
||||||
|
Ok(Value::undefined()) |
||||||
|
} |
||||||
|
/// Create a new `Array` object
|
||||||
|
pub fn _create() -> Value { |
||||||
|
let array = Function::make(make_array, &[]); |
||||||
|
array |
||||||
|
} |
||||||
|
/// Initialise the global object with the `Array` object
|
||||||
|
pub fn init(global: Value) { |
||||||
|
global.set_field_slice("Array", _create()); |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
use gc::Gc; |
||||||
|
use js::value::{to_value, ResultValue, Value, ValueData}; |
||||||
|
|
||||||
|
/// Create a new boolean
|
||||||
|
pub fn make_boolean(_: Vec<Value>, _: Value, _: Value, this: Value) -> ResultValue { |
||||||
|
Ok(Gc::new(ValueData::Undefined)) |
||||||
|
} |
||||||
|
/// Create a new `Boolean` object
|
||||||
|
pub fn _create(global: Value) -> Value { |
||||||
|
let boolean = to_value(make_boolean); |
||||||
|
boolean |
||||||
|
} |
||||||
|
/// Initialise the global object with the `Error` object
|
||||||
|
pub fn init(global: Value) { |
||||||
|
let global_ptr = global.borrow(); |
||||||
|
global_ptr.set_field_slice("Boolean", _create(global)); |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
use js::function::Function; |
||||||
|
use js::value::{from_value, ResultValue, Value}; |
||||||
|
use std::iter::FromIterator; |
||||||
|
use time::{now, strftime}; |
||||||
|
/// Print a javascript value to the standard output stream
|
||||||
|
pub fn log(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
let args: Vec<String> = FromIterator::from_iter( |
||||||
|
args.iter() |
||||||
|
.map(|x| from_value::<String>(x.clone()).unwrap()), |
||||||
|
); |
||||||
|
println!("{}: {}", strftime("%X", &now()).unwrap(), args.join(" ")); |
||||||
|
Ok(Value::undefined()) |
||||||
|
} |
||||||
|
/// Print a javascript value to the standard error stream
|
||||||
|
pub fn error(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
let args: Vec<String> = FromIterator::from_iter( |
||||||
|
args.iter() |
||||||
|
.map(|x| from_value::<String>(x.clone()).unwrap()), |
||||||
|
); |
||||||
|
eprintln!("{}: {}", strftime("%X", &now()).unwrap(), args.join(" ")); |
||||||
|
Ok(Value::undefined()) |
||||||
|
} |
||||||
|
/// Create a new `console` object
|
||||||
|
pub fn _create(global: Value) -> Value { |
||||||
|
let console = Value::new_obj(Some(global)); |
||||||
|
console.set_field_slice("log", Function::make(log, &["object"])); |
||||||
|
console.set_field_slice("error", Function::make(error, &["error"])); |
||||||
|
console.set_field_slice("exception", Function::make(error, &["error"])); |
||||||
|
console |
||||||
|
} |
||||||
|
/// Initialise the global object with the `console` object
|
||||||
|
pub fn init(global: Value) { |
||||||
|
global.set_field_slice("console", _create(global.clone())); |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
use js::function::Function; |
||||||
|
use js::object::PROTOTYPE; |
||||||
|
use js::value::{to_value, ResultValue, Value}; |
||||||
|
|
||||||
|
/// Create a new error
|
||||||
|
pub fn make_error(args: Vec<Value>, _: Value, _: Value, this: Value) -> ResultValue { |
||||||
|
if args.len() >= 1 { |
||||||
|
this.set_field_slice("message", to_value(args.get(0).unwrap().to_string())); |
||||||
|
} |
||||||
|
Ok(Value::undefined()) |
||||||
|
} |
||||||
|
/// Get the string representation of the error
|
||||||
|
pub fn to_string(_: Vec<Value>, _: Value, _: Value, this: Value) -> ResultValue { |
||||||
|
let name = this.get_field_slice("name"); |
||||||
|
let message = this.get_field_slice("message"); |
||||||
|
Ok(to_value(format!("{}: {}", name, message).to_string())) |
||||||
|
} |
||||||
|
/// Create a new `Error` object
|
||||||
|
pub fn _create(global: Value) -> Value { |
||||||
|
let prototype = Value::new_obj(Some(global)); |
||||||
|
prototype.set_field_slice("message", to_value("")); |
||||||
|
prototype.set_field_slice("name", to_value("Error")); |
||||||
|
prototype.set_field_slice("toString", Function::make(to_string, &[])); |
||||||
|
let error = Function::make(make_error, &["message"]); |
||||||
|
error.set_field_slice(PROTOTYPE, prototype); |
||||||
|
error |
||||||
|
} |
||||||
|
/// Initialise the global object with the `Error` object
|
||||||
|
pub fn init(global: Value) { |
||||||
|
global.set_field_slice("Error", _create(global.clone())); |
||||||
|
} |
@ -0,0 +1,195 @@ |
|||||||
|
use js::function::Function; |
||||||
|
use js::value::{from_value, to_value, ResultValue, Value}; |
||||||
|
use rand::random; |
||||||
|
use std::f64; |
||||||
|
|
||||||
|
/// Get the absolute value of a number
|
||||||
|
pub fn abs(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().abs() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the arccos of a number
|
||||||
|
pub fn acos(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().acos() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the arcsine of a number
|
||||||
|
pub fn asin(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().asin() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the arctangent of a number
|
||||||
|
pub fn atan(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().atan() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the arctangent of a numbers
|
||||||
|
pub fn atan2(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)) |
||||||
|
.unwrap() |
||||||
|
.atan2(args.get(1).to_num()) |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the cubic root of a number
|
||||||
|
pub fn cbrt(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().cbrt() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get lowest integer above a number
|
||||||
|
pub fn ceil(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().ceil() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the cosine of a number
|
||||||
|
pub fn cos(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().cos() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the power to raise the natural logarithm to get the number
|
||||||
|
pub fn exp(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().exp() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the highest integer below a number
|
||||||
|
pub fn floor(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().floor() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the natural logarithm of a number
|
||||||
|
pub fn log(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().log(f64::consts::E) |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the maximum of several numbers
|
||||||
|
pub fn max(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
let mut max = f64::NEG_INFINITY; |
||||||
|
for arg in args.iter() { |
||||||
|
let num = arg.to_num(); |
||||||
|
max = max.max(num); |
||||||
|
} |
||||||
|
Ok(to_value(max)) |
||||||
|
} |
||||||
|
/// Get the minimum of several numbers
|
||||||
|
pub fn min(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
let mut max = f64::INFINITY; |
||||||
|
for arg in args.iter() { |
||||||
|
let num = arg.to_num(); |
||||||
|
max = max.min(num); |
||||||
|
} |
||||||
|
Ok(to_value(max)) |
||||||
|
} |
||||||
|
/// Raise a number to a power
|
||||||
|
pub fn pow(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 2 { |
||||||
|
let num: f64 = from_value(*args.get(0)).unwrap(); |
||||||
|
let power: f64 = from_value(*args.get(1)).unwrap(); |
||||||
|
num.powf(power) |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Generate a random floating-point number between 0 and 1
|
||||||
|
pub fn _random(_: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(random::<f64>())) |
||||||
|
} |
||||||
|
/// Round a number to the nearest integer
|
||||||
|
pub fn round(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().round() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the sine of a number
|
||||||
|
pub fn sin(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().sin() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the square root of a number
|
||||||
|
pub fn sqrt(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().sqrt() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Get the tangent of a number
|
||||||
|
pub fn tan(args: Vec<Value>, _: Value, _: Value, _: Value) -> ResultValue { |
||||||
|
Ok(to_value(if args.len() >= 1 { |
||||||
|
from_value::<f64>(*args.get(0)).unwrap().tan() |
||||||
|
} else { |
||||||
|
f64::NAN |
||||||
|
})) |
||||||
|
} |
||||||
|
/// Create a new `Math` object
|
||||||
|
pub fn _create(global: Value) -> Value { |
||||||
|
let math = Value::new_obj(Some(global)); |
||||||
|
math.set_field_slice("E", to_value(f64::consts::E)); |
||||||
|
math.set_field_slice("LN2", to_value(f64::consts::LN_2)); |
||||||
|
math.set_field_slice("LN10", to_value(f64::consts::LN_10)); |
||||||
|
math.set_field_slice("LOG2E", to_value(f64::consts::LOG2_E)); |
||||||
|
math.set_field_slice("LOG10E", to_value(f64::consts::LOG10_E)); |
||||||
|
math.set_field_slice("SQRT1_2", to_value(0.5f64.sqrt())); |
||||||
|
math.set_field_slice("SQRT2", to_value(f64::consts::SQRT2)); |
||||||
|
math.set_field_slice("PI", to_value(f64::consts::PI)); |
||||||
|
math.set_field_slice("abs", Function::make(abs, ["num1", "num2"])); |
||||||
|
math.set_field_slice("acos", Function::make(acos, ["num1", "num2"])); |
||||||
|
math.set_field_slice("asin", Function::make(asin, ["num1", "num2"])); |
||||||
|
math.set_field_slice("atan", Function::make(atan, ["num1", "num2"])); |
||||||
|
math.set_field_slice("atan2", Function::make(atan2, ["num1", "num2"])); |
||||||
|
math.set_field_slice("cbrt", Function::make(cbrt, ["num1", "num2"])); |
||||||
|
math.set_field_slice("ceil", Function::make(ceil, ["num1", "num2"])); |
||||||
|
math.set_field_slice("cos", Function::make(cos, ["num1", "num2"])); |
||||||
|
math.set_field_slice("exp", Function::make(exp, ["num1", "num2"])); |
||||||
|
math.set_field_slice("floor", Function::make(floor, ["num"])); |
||||||
|
math.set_field_slice("log", Function::make(log, ["num1", "num2"])); |
||||||
|
math.set_field_slice("max", Function::make(max, ["num1", "num2"])); |
||||||
|
math.set_field_slice("min", Function::make(min, ["num1", "num2"])); |
||||||
|
math.set_field_slice("pow", Function::make(pow, ["num1", "num2"])); |
||||||
|
math.set_field_slice("random", Function::make(_random, [])); |
||||||
|
math.set_field_slice("round", Function::make(round, ["num"])); |
||||||
|
math.set_field_slice("sin", Function::make(sin, ["num"])); |
||||||
|
math.set_field_slice("sqrt", Function::make(sqrt, ["num"])); |
||||||
|
math.set_field_slice("tan", Function::make(tan, ["num"])); |
||||||
|
math |
||||||
|
} |
||||||
|
/// Initialise the `Math` object on the global object
|
||||||
|
pub fn init(global: Value) { |
||||||
|
global.set_field_slice("Math", _create(global)); |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
use js::function::Function; |
||||||
|
use js::object::{Property, PROTOTYPE}; |
||||||
|
use js::value::{from_value, to_value, ResultValue, Value}; |
||||||
|
|
||||||
|
/// Create new string
|
||||||
|
pub fn make_string(_: Vec<Value>, _: Value, _: Value, this: Value) -> ResultValue { |
||||||
|
this.set_field_slice("length", to_value(0i32)); |
||||||
|
Ok(Value::undefined()) |
||||||
|
} |
||||||
|
/// Get a string's length
|
||||||
|
pub fn get_string_length(_: Vec<Value>, _: Value, _: Value, this: Value) -> ResultValue { |
||||||
|
let this_str: String = from_value(this).unwrap(); |
||||||
|
Ok(to_value::<i32>(this_str.len() as i32)) |
||||||
|
} |
||||||
|
/// Create a new `String` object
|
||||||
|
pub fn _create(global: Value) -> Value { |
||||||
|
let string = Function::make(make_string, ["string"]); |
||||||
|
let proto = Value::new_obj(Some(global)); |
||||||
|
let prop = Property { |
||||||
|
configurable: false, |
||||||
|
enumerable: false, |
||||||
|
writable: false, |
||||||
|
value: Value::undefined(), |
||||||
|
get: Function::make(get_string_length, []), |
||||||
|
set: Value::undefined(), |
||||||
|
}; |
||||||
|
proto.set_prop_slice("length", prop); |
||||||
|
string.set_field_slice(PROTOTYPE, proto); |
||||||
|
string |
||||||
|
} |
||||||
|
/// Initialise the `String` object on the global object
|
||||||
|
pub fn init(global: Value) { |
||||||
|
global.set_field_slice("String", _create(global)); |
||||||
|
} |
Loading…
Reference in new issue