Browse Source

update

pull/5/head
Jason Williams 6 years ago
parent
commit
a47d710754
  1. 69
      src/lib/exec.rs
  2. 2
      src/lib/js/function.rs

69
src/lib/exec.rs

@ -7,7 +7,7 @@ use std::borrow::Borrow;
use std::collections::HashMap; use std::collections::HashMap;
use syntax::ast::constant::Const; use syntax::ast::constant::Const;
use syntax::ast::expr::{Expr, ExprDef}; use syntax::ast::expr::{Expr, ExprDef};
use syntax::ast::op::{BinOp, CompOp}; use syntax::ast::op::{BinOp, BitOp, CompOp, LogOp, NumOp, UnaryOp};
/// A variable scope /// A variable scope
pub struct Scope { pub struct Scope {
/// The value of `this` in the scope /// The value of `this` in the scope
@ -25,7 +25,7 @@ pub trait Executor {
/// Resolve the global variable `name` /// Resolve the global variable `name`
fn get_global(&self, name: String) -> Value; fn get_global(&self, name: String) -> Value;
/// Create a new scope and return it /// Create a new scope and return it
fn make_scope(&mut self, this: Value) -> Scope; fn make_scope(&mut self, this: Value) -> &Scope;
/// Destroy the current scope /// Destroy the current scope
fn destroy_scope(&mut self) -> Scope; fn destroy_scope(&mut self) -> Scope;
/// Run an expression /// Run an expression
@ -43,26 +43,26 @@ pub struct Interpreter {
impl Interpreter { impl Interpreter {
#[inline(always)] #[inline(always)]
/// Get the current scope /// Get the current scope
pub fn scope(&self) -> Scope { pub fn scope(&self) -> &Scope {
*self.scopes.get(self.scopes.len() - 1).unwrap() self.scopes.get(self.scopes.len() - 1).unwrap()
} }
} }
impl Executor for Interpreter { impl Executor for Interpreter {
fn new() -> Interpreter { fn new() -> Interpreter {
let global = ValueData::new_obj(None); let global = ValueData::new_obj(None);
object::init(global); object::init(global.clone());
console::init(global); console::init(global.clone());
math::init(global); math::init(global.clone());
array::init(global); array::init(global.clone());
function::init(global); function::init(global.clone());
json::init(global); json::init(global.clone());
string::init(global); string::init(global.clone());
Interpreter { Interpreter {
global: global, global: global.clone(),
scopes: vec![Scope { scopes: vec![Scope {
this: global, this: global.clone(),
vars: global, vars: global.clone(),
}], }],
} }
} }
@ -75,13 +75,13 @@ impl Executor for Interpreter {
self.global.borrow().get_field(name) self.global.borrow().get_field(name)
} }
fn make_scope(&mut self, this: Value) -> Scope { fn make_scope(&mut self, this: Value) -> &Scope {
let scope = Scope { let scope = Scope {
this: this, this: this,
vars: ValueData::new_obj(None), vars: ValueData::new_obj(None),
}; };
self.scopes.push(scope); self.scopes.push(scope);
scope &scope
} }
fn destroy_scope(&mut self) -> Scope { fn destroy_scope(&mut self) -> Scope {
@ -110,7 +110,7 @@ impl Executor for Interpreter {
ExprDef::LocalExpr(ref name) => { ExprDef::LocalExpr(ref name) => {
let mut val = Gc::new(ValueData::Undefined); let mut val = Gc::new(ValueData::Undefined);
for scope in self.scopes.iter().rev() { for scope in self.scopes.iter().rev() {
let vars = scope.vars; let vars = scope.vars.clone();
let vars_ptr = vars.borrow(); let vars_ptr = vars.borrow();
match *vars_ptr.clone() { match *vars_ptr.clone() {
ValueData::Object(ref obj) => match obj.borrow().get(name) { ValueData::Object(ref obj) => match obj.borrow().get(name) {
@ -262,20 +262,20 @@ impl Executor for Interpreter {
let v_a = *v_r_a; let v_a = *v_r_a;
let v_b = *v_r_b; let v_b = *v_r_b;
Ok(Gc::new(match *op { Ok(Gc::new(match *op {
OpAdd => v_a + v_b, NumOp::Add => v_a + v_b,
OpSub => v_a - v_b, NumOp::Sub => v_a - v_b,
OpMul => v_a * v_b, NumOp::Mul => v_a * v_b,
OpDiv => v_a / v_b, NumOp::Div => v_a / v_b,
OpMod => v_a % v_b, NumOp::Mod => v_a % v_b,
})) }))
} }
ExprDef::UnaryOpExpr(ref op, ref a) => { ExprDef::UnaryOpExpr(ref op, ref a) => {
let v_r_a = try!(self.run(a)); let v_r_a = try!(self.run(a));
let v_a = *v_r_a; let v_a = *v_r_a;
Ok(match *op { Ok(match *op {
UnaryMinus => to_value(-v_a.to_num()), UnaryOp::Minus => to_value(-v_a.to_num()),
UnaryPlus => to_value(v_a.to_num()), UnaryOp::Plus => to_value(v_a.to_num()),
UnaryNot => Gc::new(!v_a), UnaryOp::Not => Gc::new(!v_a),
_ => unreachable!(), _ => unreachable!(),
}) })
} }
@ -285,11 +285,11 @@ impl Executor for Interpreter {
let v_a = *v_r_a; let v_a = *v_r_a;
let v_b = *v_r_b; let v_b = *v_r_b;
Ok(Gc::new(match *op { Ok(Gc::new(match *op {
BitAnd => v_a & v_b, BitOp::And => v_a & v_b,
BitOr => v_a | v_b, BitOp::Or => v_a | v_b,
BitXor => v_a ^ v_b, BitOp::Xor => v_a ^ v_b,
BitShl => v_a << v_b, BitOp::Shl => v_a << v_b,
BitShr => v_a >> v_b, BitOp::Shr => v_a >> v_b,
})) }))
} }
ExprDef::BinOpExpr(BinOp::Comp(ref op), ref a, ref b) => { ExprDef::BinOpExpr(BinOp::Comp(ref op), ref a, ref b) => {
@ -316,8 +316,8 @@ impl Executor for Interpreter {
let v_a = from_value::<bool>(try!(self.run(a))).unwrap(); let v_a = from_value::<bool>(try!(self.run(a))).unwrap();
let v_b = from_value::<bool>(try!(self.run(b))).unwrap(); let v_b = from_value::<bool>(try!(self.run(b))).unwrap();
Ok(match *op { Ok(match *op {
LogAnd => to_value(v_a && v_b), LogOp::And => to_value(v_a && v_b),
LogOr => to_value(v_a || v_b), LogOp::Or => to_value(v_a || v_b),
}) })
} }
ExprDef::ConstructExpr(ref callee, ref args) => { ExprDef::ConstructExpr(ref callee, ref args) => {
@ -360,7 +360,10 @@ impl Executor for Interpreter {
let val = try!(self.run(val_e)); let val = try!(self.run(val_e));
match ref_e.def { match ref_e.def {
ExprDef::LocalExpr(ref name) => { ExprDef::LocalExpr(ref name) => {
self.scope().vars.borrow().set_field(name.clone(), val); self.scope()
.vars
.borrow()
.set_field(name.clone(), val.clone());
} }
ExprDef::GetConstFieldExpr(ref obj, ref field) => { ExprDef::GetConstFieldExpr(ref obj, ref field) => {
let val_obj = try!(self.run(obj)); let val_obj = try!(self.run(obj));

2
src/lib/js/function.rs

@ -72,6 +72,6 @@ pub fn _create() -> Value {
} }
/// Initialise the global object with the `Function` object /// Initialise the global object with the `Function` object
pub fn init(global: Value) { pub fn init(global: Value) {
let global_ptr = &global; let global_ptr = global;
global_ptr.set_field_slice("Function", _create()); global_ptr.set_field_slice("Function", _create());
} }

Loading…
Cancel
Save