Skip to content

Commit 27bdda5

Browse files
committed
impl loop parsing for Declaration
1 parent 893bc26 commit 27bdda5

File tree

5 files changed

+65
-11
lines changed

5 files changed

+65
-11
lines changed

core/parser/src/parser/parse_loop.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use boa_ast::declaration::LexicalDeclaration;
12
use boa_ast::Position;
23
use boa_interner::Interner;
34

@@ -32,6 +33,13 @@ macro_rules! parse_cmd {
3233
ret
3334
}};
3435

36+
// or move into `peek_node!`
37+
[[PEEK NODE]: $state:ident match $($variants:ident)+] => {{
38+
if !matches!($state.peek_node(), Some($(| $crate::parser::ParsedNode::$variants(_))+)) {
39+
return Err($state.general_error(concat!("expect `", $(stringify!($variants), "` | `",)+ "` node")))
40+
}
41+
}};
42+
3543
// or move into `sub_parse!`
3644
[[SUB PARSE]: $item:expr; $state:ident <= $local:ident as $variant:ident ($point:literal)] => {{
3745
$state.push_local($crate::parser::SavedState::$variant($local));
@@ -123,8 +131,8 @@ where R: ReadChar,
123131
pub(super) struct ParseState<'a, R> {
124132
nodes: Vec<ParsedNode>,
125133
saved_state: Vec<SavedState>,
126-
cursor: &'a mut Cursor<R>,
127-
interner: &'a mut Interner,
134+
pub cursor: &'a mut Cursor<R>,
135+
pub interner: &'a mut Interner,
128136
}
129137
impl<'a, R: ReadChar> ParseState<'a, R> {
130138
pub(super) fn new(cursor: &'a mut Cursor<R>, interner: &'a mut Interner) -> Self {
@@ -162,6 +170,9 @@ impl<'a, R: ReadChar> ParseState<'a, R> {
162170
pub(super) fn pop_node(&mut self) -> ParseResult<ParsedNode> {
163171
self.nodes.pop().ok_or_else(||self.general_error("expect parsed node"))
164172
}
173+
pub(super) fn peek_node(&mut self) -> Option<&ParsedNode> {
174+
self.nodes.last()
175+
}
165176

166177
pub(super) fn pop_local_state(&mut self) -> ParseResult<SavedState> {
167178
self.saved_state.pop().ok_or_else(||self.general_error("expect saved state"))

core/parser/src/parser/statement/declaration/hoistable/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use crate::{
2727
source::ReadChar,
2828
Error,
2929
};
30+
use crate::{parse_cmd, parser::{ControlFlow, TokenLoopParser, parse_loop::ParseState}};
3031
use boa_ast::{
3132
self as ast,
3233
expression::Identifier,
@@ -125,6 +126,14 @@ where
125126
}
126127
}
127128

129+
impl<R: ReadChar> TokenLoopParser<R> for HoistableDeclaration {
130+
fn parse_loop(&mut self, state: &mut ParseState<'_, R>, _continue_point: usize) -> ParseResult<ControlFlow<R>> {
131+
let (cursor, interner) = state.mut_inner();
132+
let ok = self.parse(cursor, interner)?;
133+
parse_cmd!([DONE]: state <= Declaration(ok))
134+
}
135+
}
136+
128137
trait CallableDeclaration {
129138
fn error_context(&self) -> &'static str;
130139
fn is_default(&self) -> bool;

core/parser/src/parser/statement/declaration/lexical.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::{
1818
source::ReadChar,
1919
Error,
2020
};
21+
use crate::{parse_cmd, parser::{ControlFlow, TokenLoopParser, parse_loop::ParseState}};
2122
use ast::operations::bound_names;
2223
use boa_ast::{self as ast, declaration::Variable, Keyword, Punctuator};
2324
use boa_interner::{Interner, Sym};
@@ -121,6 +122,14 @@ where
121122
}
122123
}
123124

125+
impl<R: ReadChar> TokenLoopParser<R> for LexicalDeclaration {
126+
fn parse_loop(&mut self, state: &mut ParseState<'_, R>, _continue_point: usize) -> ParseResult<ControlFlow<R>> {
127+
let (cursor, interner) = state.mut_inner();
128+
let ok = self.parse(cursor, interner)?;
129+
parse_cmd!([DONE]: state <= Declaration(ok.into()))
130+
}
131+
}
132+
124133
/// Check if the given token is valid after the `let` keyword of a lexical declaration.
125134
pub(crate) fn allowed_token_after_let(token: Option<&Token>) -> bool {
126135
matches!(

core/parser/src/parser/statement/declaration/mod.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,39 @@ where
9191
}
9292

9393
impl<R: ReadChar> TokenLoopParser<R> for Declaration {
94-
fn parse_loop(&mut self, state: &mut ParseState<'_, R>, _continue_point: usize) -> ParseResult<ControlFlow<R>> {
95-
let (cursor, interner) = state.mut_inner();
96-
let ok = self.parse(cursor, interner)?;
97-
parse_cmd!([DONE]: state <= Declaration(ok))
94+
fn parse_loop(&mut self, state: &mut ParseState<'_, R>, continue_point: usize) -> ParseResult<ControlFlow<R>> {
95+
if continue_point == 1 {
96+
parse_cmd![[POP LOCAL]: state => Empty];
97+
parse_cmd![[PEEK NODE]: state match Declaration]; // pass value up
98+
return Ok(ControlFlow::Done)
99+
} else if continue_point > 1 {
100+
return state.continue_point_error(continue_point)
101+
}
102+
103+
let tok = state.cursor.peek(0, state.interner).or_abrupt()?;
104+
105+
match tok.kind() {
106+
TokenKind::Keyword((Keyword::Function | Keyword::Async | Keyword::Class, _)) => {
107+
let node = HoistableDeclaration::new(self.allow_yield, self.allow_await, false);
108+
parse_cmd![[SUB PARSE]: node; state <= Empty (1)];
109+
}
110+
TokenKind::Keyword((Keyword::Const | Keyword::Let, _)) => {
111+
let node = LexicalDeclaration::new(true, self.allow_yield, self.allow_await, false);
112+
parse_cmd![[SUB PARSE]: node; state <= Empty (1)];
113+
}
114+
_ => return Err(Error::expected(
115+
[
116+
Keyword::Function.to_string(),
117+
Keyword::Async.to_string(),
118+
Keyword::Class.to_string(),
119+
Keyword::Const.to_string(),
120+
Keyword::Let.to_string(),
121+
],
122+
tok.to_string(state.interner),
123+
tok.span(),
124+
"export declaration",
125+
)),
126+
}
98127
}
99128
}
100129

core/parser/src/parser/statement/mod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,6 @@ impl StatementListLocal {
410410
strict: stmt_list.strict,
411411
}
412412
}
413-
414-
pub(super) fn new_point_list_item<R: ReadChar>(state: &mut ParseState<'_, R>) -> ParseResult<Self> {
415-
return Ok(parse_cmd![[POP LOCAL]: state => StatementList])
416-
}
417413
}
418414

419415
impl<R> TokenLoopParser<R> for StatementList
@@ -424,7 +420,7 @@ where
424420
let mut local = match continue_point {
425421
0 => StatementListLocal::new(&self, state),
426422
1 => {
427-
let mut local = StatementListLocal::new_point_list_item(state)?;
423+
let mut local = parse_cmd![[POP LOCAL]: state => StatementList];
428424
Self::continue_point_list_item(&mut local, state)?;
429425
local
430426
}

0 commit comments

Comments
 (0)