Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Divide the run() function #422

Merged
merged 52 commits into from
Jun 6, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
c4fb91c
Merge pull request #4 from boa-dev/master
May 26, 2020
7ffc0c8
Adding Object Execution trait
May 26, 2020
57fa83d
Moved Object AST related parts into their own files
May 26, 2020
88a5ba3
Rustfmt
May 26, 2020
e51d8be
Make clippy happier
May 26, 2020
4c058c0
Starting to reimplement switch
May 26, 2020
744dee8
Remove extra newline
May 27, 2020
dc6b371
Replaced AST object new with From
May 27, 2020
8995fb2
Merge branch 'divide_run' of https://github.com/Lan2u/boa into divide…
May 27, 2020
d91ac61
Rustfmt
May 27, 2020
274910a
Merge pull request #5 from Lan2u/divide_run
May 27, 2020
4b0bed1
Starting to move switch AST into seperate files
May 27, 2020
8ff5590
Seperated switch AST node into seperate files
May 27, 2020
d0e82b5
Merge: Seperated switch AST node into seperate files
May 27, 2020
6851036
Started moving GetConstField related parts into own file
May 27, 2020
153f0b1
Correcting various references to Node::GetConstField to use new signa…
May 28, 2020
c0404f3
Extracted GetField code
May 29, 2020
e33a1a5
Fmt, clippy
May 29, 2020
9969748
Merge pull request #7 from Lan2u/divide_run_get_const_field
May 29, 2020
4937dc3
WhileLoop
May 29, 2020
ad07527
Impl fmt::display for WhileLoop
May 29, 2020
be04070
DoWhileLoop struct created
May 29, 2020
58f83f7
Seperated out do while loop
May 29, 2020
26fdf9d
Merge pull request #8 from Lan2u/divide_run_dowhile
May 30, 2020
13daec1
Created Return struct
May 30, 2020
2116152
Seperated Return statement out
May 30, 2020
cc7261a
Seperated IF statement out
May 30, 2020
c858a79
Removed unused imports, fmt
May 30, 2020
b5ca4b8
Created Break struct
May 30, 2020
94dcacc
Break impl
May 31, 2020
5c90059
Conditional Op impl
May 31, 2020
4e267c3
Continue impl
May 31, 2020
e3882d7
Throw impl
May 31, 2020
bb33532
Spread impl
May 31, 2020
022b48e
Object initalizer now returns Object in result rather than Node
May 31, 2020
57cace0
Update boa/src/exec/throw/mod.rs
Jun 1, 2020
e96f79c
Update boa/src/syntax/ast/node/break_node.rs
Jun 1, 2020
44da6aa
Update boa/src/syntax/ast/node/conditional.rs
Jun 1, 2020
43a046f
Update boa/src/syntax/ast/node/iteration.rs
Jun 1, 2020
7604c0f
Made Switch::new() more generic, added TODO for break in Switch::run()
Jun 1, 2020
ba5a63b
Merge branch 'divide_run' of https://github.com/Lan2u/boa into divide…
Jun 1, 2020
b7a641b
Making parse functions return the actual result of the parse rather t…
Jun 1, 2020
ea45b26
Reworked switch::new, added Case struct
Jun 1, 2020
7733da2
Switch::run() refractored, rustfmt
Jun 1, 2020
cf75799
Merge branch 'master' into divide_run
Jun 1, 2020
b73182e
Update boa/src/syntax/ast/node/return_smt.rs
Jun 1, 2020
e95b6e4
Update boa/src/syntax/ast/node/switch.rs
Jun 1, 2020
e6072c8
Update boa/src/syntax/ast/node/return_smt.rs
Jun 1, 2020
ad91f42
Small fixes to return_smt
Jun 1, 2020
b0293ac
Merge branch 'master' into divide_run
Jun 3, 2020
2234ed6
Merge branch 'master' into divide_run
Jun 5, 2020
e50a741
Finished merge
Jun 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 3 additions & 31 deletions boa/src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod block;
mod declaration;
mod expression;
mod iteration;
mod object;
mod operator;
mod statement_list;
#[cfg(test)]
Expand All @@ -24,7 +25,7 @@ use crate::{
realm::Realm,
syntax::ast::{
constant::Const,
node::{FormalParameter, MethodDefinitionKind, Node, PropertyDefinition, StatementList},
node::{FormalParameter, Node, StatementList},
},
};
use std::{borrow::Borrow, ops::Deref};
Expand Down Expand Up @@ -447,36 +448,7 @@ impl Executable for Node {
}
Ok(result)
}
Node::Object(ref properties) => {
let global_val = &interpreter
.realm()
.environment
.get_global_object()
.expect("Could not get the global object");
let obj = Value::new_object(Some(global_val));

// TODO: Implement the rest of the property types.
for property in properties.iter() {
match property {
PropertyDefinition::Property(key, value) => {
obj.borrow()
.set_field(&key.clone(), value.run(interpreter)?);
}
PropertyDefinition::MethodDefinition(kind, name, func) => {
if let MethodDefinitionKind::Ordinary = kind {
obj.borrow()
.set_field(&name.clone(), func.run(interpreter)?);
} else {
// TODO: Implement other types of MethodDefinitionKinds.
unimplemented!("other types of property method definitions.");
}
}
i => unimplemented!("{:?} type of property", i),
}
}

Ok(obj)
}
Node::Object(ref obj) => obj.run(interpreter),
Node::ArrayDecl(ref arr) => arr.run(interpreter),
// <https://tc39.es/ecma262/#sec-createdynamicfunction>
Node::FunctionDecl(ref decl) => decl.run(interpreter),
Expand Down
43 changes: 43 additions & 0 deletions boa/src/exec/object/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//! Object execution.

use super::{Executable, Interpreter};
use crate::{
builtins::value::{ResultValue, Value},
syntax::ast::node::MethodDefinitionKind,
syntax::ast::node::{Object, PropertyDefinition},
};

use std::borrow::Borrow;

impl Executable for Object {
fn run(&self, interpreter: &mut Interpreter) -> ResultValue {
let global_val = &interpreter
.realm()
.environment
.get_global_object()
.expect("Could not get the global object");
let obj = Value::new_object(Some(global_val));

// TODO: Implement the rest of the property types.
for property in self.properties().iter() {
match property {
PropertyDefinition::Property(key, value) => {
obj.borrow()
.set_field(&key.clone(), value.run(interpreter)?);
}
PropertyDefinition::MethodDefinition(kind, name, func) => {
if let MethodDefinitionKind::Ordinary = kind {
obj.borrow()
.set_field(&name.clone(), func.run(interpreter)?);
} else {
// TODO: Implement other types of MethodDefinitionKinds.
unimplemented!("other types of property method definitions.");
}
}
i => unimplemented!("{:?} type of property", i),
}
}

Ok(obj)
}
}
54 changes: 5 additions & 49 deletions boa/src/syntax/ast/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod declaration;
pub mod expression;
pub mod identifier;
pub mod iteration;
pub mod object;
pub mod operator;
pub mod statement_list;
pub mod try_node;
Expand All @@ -20,6 +21,7 @@ pub use self::{
expression::{Call, New},
identifier::Identifier,
iteration::ForLoop,
object::Object,
operator::{Assign, BinOp, UnaryOp},
statement_list::StatementList,
try_node::{Catch, Finally, Try},
Expand Down Expand Up @@ -214,26 +216,8 @@ pub enum Node {
/// A `new` expression. [More information](./expression/struct.New.html).
New(New),

/// Objects in JavaScript may be defined as an unordered collection of related data, of
/// primitive or reference types, in the form of “key: value” pairs.
///
/// Objects can be initialized using `new Object()`, `Object.create()`, or using the literal
/// notation.
///
/// An object initializer is an expression that describes the initialization of an
/// [`Object`][object]. Objects consist of properties, which are used to describe an object.
/// Values of object properties can either contain [`primitive`][primitive] data types or other
/// objects.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-ObjectLiteral
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer
/// [object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
/// [primitive]: https://developer.mozilla.org/en-US/docs/Glossary/primitive
Object(Box<[PropertyDefinition]>),
/// An object. [More information](./object/struct.Object.html).
Object(Object),

/// The `return` statement ends function execution and specifies a value to be returned to the
/// function caller.
Expand Down Expand Up @@ -442,14 +426,6 @@ impl Node {
)
}

/// Creates an `Object` AST node.
pub fn object<D>(def: D) -> Self
where
D: Into<Box<[PropertyDefinition]>>,
{
Self::Object(def.into())
}

/// Creates a `Return` AST node.
pub fn return_node<E, OE>(expr: OE) -> Self
where
Expand Down Expand Up @@ -582,27 +558,7 @@ impl Node {
def.display(f, indentation + 1)?;
write!(f, "{}}}", indent)
}
Self::Object(ref properties) => {
f.write_str("{\n")?;
for property in properties.iter() {
match property {
PropertyDefinition::IdentifierReference(key) => {
write!(f, "{} {},", indent, key)?;
}
PropertyDefinition::Property(key, value) => {
write!(f, "{} {}: {},", indent, key, value)?;
}
PropertyDefinition::SpreadObject(key) => {
write!(f, "{} ...{},", indent, key)?;
}
PropertyDefinition::MethodDefinition(_kind, _key, _node) => {
// TODO: Implement display for PropertyDefinition::MethodDefinition.
unimplemented!("Display for PropertyDefinition::MethodDefinition");
}
}
}
f.write_str("}")
}
Self::Object(ref obj) => obj.display(f, indentation),
Self::ArrayDecl(ref arr) => Display::fmt(arr, f),
Self::VarDeclList(ref list) => Display::fmt(list, f),
Self::FunctionDecl(ref decl) => decl.display(f, indentation),
Expand Down
88 changes: 88 additions & 0 deletions boa/src/syntax/ast/node/object.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//! Object node.

use super::Node;
use gc::{Finalize, Trace};
use std::fmt;

use crate::syntax::ast::node::PropertyDefinition;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// Objects in JavaScript may be defined as an unordered collection of related data, of
/// primitive or reference types, in the form of “key: value” pairs.
///
/// Objects can be initialized using `new Object()`, `Object.create()`, or using the literal
/// notation.
///
/// An object initializer is an expression that describes the initialization of an
/// [`Object`][object]. Objects consist of properties, which are used to describe an object.
/// Values of object properties can either contain [`primitive`][primitive] data types or other
/// objects.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-ObjectLiteral
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer
/// [object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
/// [primitive]: https://developer.mozilla.org/en-US/docs/Glossary/primitive

Lan2u marked this conversation as resolved.
Show resolved Hide resolved
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct Object {
properties: Box<[PropertyDefinition]>,
}

impl Object {
/// Creates an `Object` AST node.
pub fn new<D>(props: D) -> Self
Lan2u marked this conversation as resolved.
Show resolved Hide resolved
where
D: Into<Box<[PropertyDefinition]>>,
{
Self {
properties: props.into(),
}
}

pub fn properties(&self) -> &[PropertyDefinition] {
&self.properties
}

/// Implements the display formatting with indentation.
pub(super) fn display(&self, f: &mut fmt::Formatter<'_>, indent: usize) -> fmt::Result {
f.write_str("{\n")?;
for property in self.properties().iter() {
match property {
PropertyDefinition::IdentifierReference(key) => {
write!(f, "{} {},", indent, key)?;
}
PropertyDefinition::Property(key, value) => {
write!(f, "{} {}: {},", indent, key, value)?;
}
PropertyDefinition::SpreadObject(key) => {
write!(f, "{} ...{},", indent, key)?;
}
PropertyDefinition::MethodDefinition(_kind, _key, _node) => {
// TODO: Implement display for PropertyDefinition::MethodDefinition.
unimplemented!("Display for PropertyDefinition::MethodDefinition");
}
}
}
f.write_str("}")
}
}

impl fmt::Display for Object {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.display(f, 0)
}
}

impl From<Object> for Node {
fn from(obj: Object) -> Self {
Self::Object(obj)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mod tests;

use crate::syntax::{
ast::{
node::{self, FunctionExpr, MethodDefinitionKind, Node},
node::{self, FunctionExpr, MethodDefinitionKind, Node, Object},
token::{Token, TokenKind},
Punctuator,
},
Expand Down Expand Up @@ -82,7 +82,7 @@ impl TokenParser for ObjectLiteral {
}
}

Ok(Node::object(elements))
Ok(Object::new(elements).into())
Lan2u marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::syntax::{
ast::{
node::{
ConstDecl, ConstDeclList, FormalParameter, FunctionExpr, MethodDefinitionKind, Node,
PropertyDefinition,
ConstDecl, ConstDeclList, FormalParameter, FunctionExpr, MethodDefinitionKind,
Object, PropertyDefinition,
},
Const,
},
Expand All @@ -23,9 +23,7 @@ fn check_object_literal() {
b: false,
};
",
vec![
ConstDeclList::from(vec![ConstDecl::new("x", Node::object(object_properties))]).into(),
],
vec![ConstDeclList::from(vec![ConstDecl::new("x", Object::new(object_properties))]).into()],
);
}

Expand All @@ -47,9 +45,7 @@ fn check_object_short_function() {
b() {},
};
",
vec![
ConstDeclList::from(vec![ConstDecl::new("x", Node::object(object_properties))]).into(),
],
vec![ConstDeclList::from(vec![ConstDecl::new("x", Object::new(object_properties))]).into()],
);
}

Expand All @@ -75,9 +71,7 @@ fn check_object_short_function_arguments() {
b(test) {}
};
",
vec![
ConstDeclList::from(vec![ConstDecl::new("x", Node::object(object_properties))]).into(),
],
vec![ConstDeclList::from(vec![ConstDecl::new("x", Object::new(object_properties))]).into()],
);
}

Expand All @@ -98,9 +92,7 @@ fn check_object_getter() {
get b() {}
};
",
vec![
ConstDeclList::from(vec![ConstDecl::new("x", Node::object(object_properties))]).into(),
],
vec![ConstDeclList::from(vec![ConstDecl::new("x", Object::new(object_properties))]).into()],
);
}

Expand All @@ -125,8 +117,6 @@ fn check_object_setter() {
set b(test) {}
};
",
vec![
ConstDeclList::from(vec![ConstDecl::new("x", Node::object(object_properties))]).into(),
],
vec![ConstDeclList::from(vec![ConstDecl::new("x", Object::new(object_properties))]).into()],
);
}