Browse Source

string length now supported

pull/5/head
Jason Williams 6 years ago
parent
commit
f92be3bd21
  1. 1
      src/bin/bin.rs
  2. 4
      src/lib/exec.rs
  3. 14
      src/lib/js/value.rs
  4. 4
      tests/js/test.js

1
src/bin/bin.rs

@ -12,7 +12,6 @@ pub fn main() {
// Setup executor // Setup executor
let expr = Parser::new(tokens).parse_all().unwrap(); let expr = Parser::new(tokens).parse_all().unwrap();
print!("{:#?}", expr);
let mut engine: Interpreter = Executor::new(); let mut engine: Interpreter = Executor::new();
let result = engine.run(&expr); let result = engine.run(&expr);

4
src/lib/exec.rs

@ -95,6 +95,9 @@ impl Executor for Interpreter {
ExprDef::ConstExpr(Const::Undefined) => Ok(Gc::new(ValueData::Undefined)), ExprDef::ConstExpr(Const::Undefined) => Ok(Gc::new(ValueData::Undefined)),
ExprDef::ConstExpr(Const::Num(num)) => Ok(to_value(num)), ExprDef::ConstExpr(Const::Num(num)) => Ok(to_value(num)),
ExprDef::ConstExpr(Const::Int(num)) => Ok(to_value(num)), ExprDef::ConstExpr(Const::Int(num)) => Ok(to_value(num)),
// we can't move String from Const into value, because const is a garbage collected value
// Which means Drop() get's called on Const, but str will be gone at that point.
// Do Const values need to be garbage collected? We no longer need them once we've generated Values
ExprDef::ConstExpr(Const::String(ref str)) => Ok(to_value(str.to_owned())), ExprDef::ConstExpr(Const::String(ref str)) => Ok(to_value(str.to_owned())),
ExprDef::ConstExpr(Const::Bool(val)) => Ok(to_value(val)), ExprDef::ConstExpr(Const::Bool(val)) => Ok(to_value(val)),
ExprDef::ConstExpr(Const::RegExp(_, _, _)) => Ok(to_value(None::<()>)), ExprDef::ConstExpr(Const::RegExp(_, _, _)) => Ok(to_value(None::<()>)),
@ -128,7 +131,6 @@ impl Executor for Interpreter {
} }
ExprDef::GetConstFieldExpr(ref obj, ref field) => { ExprDef::GetConstFieldExpr(ref obj, ref field) => {
let val_obj = self.run(obj)?; let val_obj = self.run(obj)?;
println!("{:?}", val_obj.get_field(String::from("length")));
Ok(val_obj.borrow().get_field(field.clone())) Ok(val_obj.borrow().get_field(field.clone()))
} }
ExprDef::GetFieldExpr(ref obj, ref field) => { ExprDef::GetFieldExpr(ref obj, ref field) => {

14
src/lib/js/value.rs

@ -55,6 +55,13 @@ impl ValueData {
Gc::new(ValueData::Object(GcCell::new(obj))) Gc::new(ValueData::Object(GcCell::new(obj)))
} }
/// Similar to `new_obj`, but you can pass a prototype to create from
pub fn new_obj_from_prototype(proto: Value) -> Value {
let mut obj: ObjectData = HashMap::new();
obj.insert(INSTANCE_PROTOTYPE.to_string(), Property::new(proto));
Gc::new(ValueData::Object(GcCell::new(obj)))
}
/// Returns true if the value is an object /// Returns true if the value is an object
pub fn is_object(&self) -> bool { pub fn is_object(&self) -> bool {
match *self { match *self {
@ -152,6 +159,13 @@ impl ValueData {
/// Resolve the property in the object /// Resolve the property in the object
/// Returns a copy of the Property /// Returns a copy of the Property
pub fn get_prop(&self, field: String) -> Option<Property> { pub fn get_prop(&self, field: String) -> Option<Property> {
// handle length
// Spidermonkey has its own GetLengthProperty: https://searchfox.org/mozilla-central/source/js/src/vm/Interpreter-inl.h#154
// TODO: Maybe we need a GetLengthProperty for value types
if let ValueData::String(ref s) = *self {
return Some(Property::new(to_value(s.len() as f64)))
}
let obj: ObjectData = match *self { let obj: ObjectData = match *self {
ValueData::Object(ref obj) => { ValueData::Object(ref obj) => {
let hash = obj.clone(); let hash = obj.clone();

4
tests/js/test.js

@ -1,2 +1,2 @@
a = { a: 1 }; var a = 'jabra888';
a; a.length;
Loading…
Cancel
Save