Skip to content

Commit

Permalink
Merge 8825e4b into e49be36
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonwilliams authored Jul 16, 2020
2 parents e49be36 + 8825e4b commit c3c395c
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 39 deletions.
40 changes: 8 additions & 32 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@
"type": "process",
"label": "Cargo Run",
"command": "cargo",
"args": [
"run",
"--bin",
"boa",
"./tests/js/test.js"
],
"args": ["run", "--bin", "boa", "./tests/js/test.js"],
"group": {
"kind": "build",
"isDefault": true
Expand All @@ -30,12 +25,7 @@
"type": "process",
"label": "Cargo Run (Profiler)",
"command": "cargo",
"args": [
"run",
"--features",
"Boa/profiler",
"../tests/js/test.js"
],
"args": ["run", "--features", "Boa/profiler", "../tests/js/test.js"],
"group": "build",
"options": {
"env": {
Expand All @@ -51,12 +41,7 @@
"type": "process",
"label": "Get Tokens",
"command": "cargo",
"args": [
"run",
"--",
"-t=Debug",
"./tests/js/test.js"
],
"args": ["run", "--", "-t=Debug", "./tests/js/test.js"],
"group": "build",
"presentation": {
"clear": true
Expand All @@ -66,24 +51,18 @@
"type": "process",
"label": "Get AST",
"command": "cargo",
"args": [
"run",
"--",
"-a=Debug",
"./tests/js/test.js"
],
"args": ["run", "--", "-a=Debug", "./tests/js/test.js"],
"group": "build",
"presentation": {
"clear": true
},
"problemMatcher": []
},
{
"type": "process",
"label": "Cargo Test",
"command": "cargo",
"args": [
"test"
],
"args": ["test"],
"group": {
"kind": "test",
"isDefault": true
Expand All @@ -96,11 +75,8 @@
"type": "process",
"label": "Cargo Test Build",
"command": "cargo",
"args": [
"test",
"--no-run"
],
"args": ["test", "--no-run"],
"group": "build"
}
]
}
}
17 changes: 13 additions & 4 deletions boa/src/exec/iteration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,20 @@ impl Executable for ForLoop {

match interpreter.get_current_state() {
InterpreterState::Break(_label) => {
// TODO break to label.

// Loops 'consume' breaks.
interpreter.set_current_state(InterpreterState::Executing);
// // If a label is set we want to break the current block and still keep state as Break if the label is a block above
// if let Some(stmt_label) = &self.label {
// if let Some(brk_label) = label {
// // We have a label, but not for the current statement
// // break without resetting to executing
// if stmt_label != brk_label {
break;
// }
// }
// }

// // Loops 'consume' breaks.
// interpreter.set_current_state(InterpreterState::Executing);
// break;
}
InterpreterState::Return => {
return Ok(result);
Expand Down
38 changes: 38 additions & 0 deletions boa/src/syntax/ast/node/labelled_smt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use super::Node;
use gc::{Finalize, Trace};
use std::fmt;

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

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
pub struct Label {
stmt: Box<Node>,
label: Box<str>,
}

impl Label {
pub(super) fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", format!("{}: {}", self.label, self.stmt))
}

pub fn new(stmt: Node, label: Box<str>) -> Self {
Self {
stmt: stmt.into(),
label,
}
}
}

impl From<Label> for Node {
fn from(label_stmt: Label) -> Node {
Node::Label(label_stmt)
}
}

impl fmt::Display for Label {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.display(f)
}
}
6 changes: 6 additions & 0 deletions boa/src/syntax/ast/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod expression;
pub mod field;
pub mod identifier;
pub mod iteration;
pub mod labelled_smt;
pub mod object;
pub mod operator;
pub mod return_smt;
Expand All @@ -31,6 +32,7 @@ pub use self::{
field::{GetConstField, GetField},
identifier::Identifier,
iteration::{Continue, DoWhileLoop, ForLoop, WhileLoop},
labelled_smt::Label,
object::Object,
operator::{Assign, BinOp, UnaryOp},
return_smt::Return,
Expand Down Expand Up @@ -116,6 +118,9 @@ pub enum Node {
/// An 'if' statement. [More information](./conditional/struct.If.html).
If(If),

/// A labelled Statement.
Label(Label),

/// A `let` declaration list. [More information](./declaration/struct.LetDeclList.html).
LetDeclList(LetDeclList),

Expand Down Expand Up @@ -222,6 +227,7 @@ impl Node {
Self::WhileLoop(ref while_loop) => while_loop.display(f, indentation),
Self::DoWhileLoop(ref do_while) => do_while.display(f, indentation),
Self::If(ref if_smt) => if_smt.display(f, indentation),
Self::Label(ref label) => label.display(f),
Self::Switch(ref switch) => switch.display(f, indentation),
Self::Object(ref obj) => obj.display(f, indentation),
Self::ArrayDecl(ref arr) => Display::fmt(arr, f),
Expand Down
2 changes: 1 addition & 1 deletion boa/src/syntax/parser/statement/iteration/for_statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use crate::{
///
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for
/// [spec]: https://tc39.es/ecma262/#sec-for-statement
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone)]
pub(in crate::syntax::parser::statement) struct ForStatement {
allow_yield: AllowYield,
allow_await: AllowAwait,
Expand Down
52 changes: 52 additions & 0 deletions boa/src/syntax/parser/statement/labelled_stm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use super::{LabelIdentifier, Statement};
use crate::{
syntax::{
ast::{node::Label, Punctuator},
parser::{
cursor::Cursor, error::ParseError, AllowAwait, AllowReturn, AllowYield, TokenParser,
},
},
BoaProfiler,
};
/// Labelled Statement Parsing
///
/// More information
/// - [MDN documentation][mdn]
/// - [ECMAScript specification][spec]
///
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label
/// [spec]: https://tc39.es/ecma262/#sec-labelled-statements
#[derive(Debug, Clone, Copy)]
pub(super) struct LabelledStatement {
allow_yield: AllowYield,
allow_await: AllowAwait,
allow_return: AllowReturn,
}

impl LabelledStatement {
pub(super) fn new<Y, A, R>(allow_yield: Y, allow_await: A, allow_return: R) -> Self
where
Y: Into<AllowYield>,
A: Into<AllowAwait>,
R: Into<AllowReturn>,
{
Self {
allow_yield: allow_yield.into(),
allow_await: allow_await.into(),
allow_return: allow_return.into(),
}
}
}

impl TokenParser for LabelledStatement {
type Output = Label;

fn parse(self, cursor: &mut Cursor<'_>) -> Result<Self::Output, ParseError> {
let _timer = BoaProfiler::global().start_event("Label", "Parsing");
let name = LabelIdentifier::new(self.allow_yield, self.allow_await).parse(cursor)?;
cursor.expect(Punctuator::Colon, "Labelled Statement")?;
let stmt =
Statement::new(self.allow_yield, self.allow_await, self.allow_return).parse(cursor)?;
Ok(Label::new(stmt, name))
}
}
22 changes: 20 additions & 2 deletions boa/src/syntax/parser/statement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod declaration;
mod expression;
mod if_stm;
mod iteration;
mod labelled_stm;
mod return_stm;
mod switch;
mod throw;
Expand All @@ -36,9 +37,10 @@ use self::{
};
use super::{AllowAwait, AllowReturn, AllowYield, Cursor, ParseError, TokenParser};
use crate::{
syntax::ast::{node, Keyword, Node, Punctuator, TokenKind},
syntax::ast::{node, Keyword, Node, Punctuator, Token, TokenKind},
BoaProfiler,
};
use labelled_stm::LabelledStatement;

/// Statement parsing.
///
Expand Down Expand Up @@ -162,6 +164,22 @@ impl TokenParser for Statement {
.parse(cursor)
.map(Node::from)
}
// Create guard to check if the next token is a `:` then we know we're sitting on a label
// if not fall back to ExpressionStatement
TokenKind::Identifier(_)
if matches!(
cursor.peek(1),
Some(Token {
kind: TokenKind::Punctuator(Punctuator::Colon),
..
})
) =>
{
LabelledStatement::new(self.allow_yield, self.allow_await, self.allow_return)
.parse(cursor)
.map(Node::from)
}

// TODO: https://tc39.es/ecma262/#prod-LabelledStatement
// TokenKind::Punctuator(Punctuator::Semicolon) => {
// return Ok(Node::new(NodeBase::Nope, tok.pos))
Expand Down Expand Up @@ -350,7 +368,7 @@ impl TokenParser for StatementListItem {
/// - [ECMAScript specification][spec]
///
/// [spec]: https://tc39.es/ecma262/#prod-LabelIdentifier
type LabelIdentifier = BindingIdentifier;
pub(super) type LabelIdentifier = BindingIdentifier;

/// Binding identifier parsing.
///
Expand Down

0 comments on commit c3c395c

Please sign in to comment.