Skip to content

Commit

Permalink
allow skipping elements in array destructuring pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Jul 16, 2024
1 parent 84a1a4e commit 825ffe4
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 23 deletions.
2 changes: 1 addition & 1 deletion crates/dash_compiler/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl<'cx, 'interner> InstructionBuilder<'cx, 'interner> {
Ok(())
}

fn write_bool(&mut self, b: bool) {
pub fn write_bool(&mut self, b: bool) {
self.write(b.into());
}

Expand Down
26 changes: 15 additions & 11 deletions crates/dash_compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -905,17 +905,21 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {
ib.build_arraydestruct(field_count);

for name in fields {
let id = ib
.current_scope_mut()
.add_local(name, binding.kind, None)
.map_err(|_| Error::LocalLimitExceeded(span))?;
ib.write_bool(name.is_some());
if let Some(name) = name {
let id = ib
.current_scope_mut()
.add_local(name, binding.kind, None)
.map_err(|_| Error::LocalLimitExceeded(span))?;

let id = ib
.current_function_mut()
.cp
.add(Constant::Number(id as f64))
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;

let var_id = ib
.current_function_mut()
.cp
.add(Constant::Number(id as f64))
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;
ib.writew(var_id);
ib.writew(id);
}
}
}
}
Expand Down Expand Up @@ -2050,7 +2054,7 @@ impl<'interner> Visitor<Result<(), Error>> for FunctionCompiler<'interner> {
match var.binding.name {
VariableDeclarationName::Identifier(ident) => it.push(ident),
VariableDeclarationName::ArrayDestructuring { ref fields, rest } => {
it.extend(fields.iter().copied());
it.extend(fields.iter().copied().flatten());
it.extend(rest);
}
VariableDeclarationName::ObjectDestructuring { ref fields, rest } => {
Expand Down
10 changes: 7 additions & 3 deletions crates/dash_middle/src/parser/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,8 +686,9 @@ pub enum VariableDeclarationName {
},
/// Array destructuring: [ a ] = [ 1 ]
ArrayDestructuring {
/// Elements to destructure
fields: Vec<Symbol>,
/// Elements to destructure.
/// For `[a,,b]` this stores `[Some(a), None, Some(b)]`
fields: Vec<Option<Symbol>>,
/// The rest element, if present
rest: Option<Symbol>,
},
Expand Down Expand Up @@ -726,7 +727,10 @@ impl fmt::Display for VariableDeclarationName {
write!(f, ", ")?;
}

write!(f, "{name}")?;
match name {
Some(name) => write!(f, "{name}")?,
None => f.write_char(',')?,
}
}

if let Some(rest) = rest {
Expand Down
5 changes: 4 additions & 1 deletion crates/dash_parser/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,9 @@ impl<'a, 'interner> Parser<'a, 'interner> {
self.advance();
break;
}
TokenType::Comma => {
fields.push(None);
}
TokenType::Dot => {
// Skip the dot
self.advance();
Expand All @@ -641,7 +644,7 @@ impl<'a, 'interner> Parser<'a, 'interner> {
other if other.is_identifier() => {
let name = other.as_identifier().unwrap();
self.advance();
fields.push(name);
fields.push(Some(name));
}
_ => {
self.create_error(Error::unexpected_token(cur, TokenType::DUMMY_IDENTIFIER));
Expand Down
16 changes: 9 additions & 7 deletions crates/dash_vm/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2038,13 +2038,15 @@ mod handlers {
pub fn arraydestruct<'vm>(mut cx: DispatchContext<'vm>) -> Result<Option<HandleResult>, Unrooted> {
let array = cx.pop_stack_rooted();

let mut iter = BackwardSequence::<NumberWConstant>::new_u16(&mut cx).enumerate();

while let Some((i, NumberWConstant(id))) = iter.next_infallible(&mut cx) {
let id = id as usize;
let key = cx.scope.intern_usize(i);
let prop = array.get_property(&mut cx.scope, key.into())?;
cx.set_local(id, prop);
let mut iter = BackwardSequence::<Option<NumberWConstant>>::new_u16(&mut cx).enumerate();

while let Some((i, id)) = iter.next_infallible(&mut cx) {
if let Some(NumberWConstant(id)) = id {
let id = id as usize;
let key = cx.scope.intern_usize(i);
let prop = array.get_property(&mut cx.scope, key.into())?;
cx.set_local(id, prop);
}
}

Ok(None)
Expand Down

0 comments on commit 825ffe4

Please sign in to comment.