Skip to content

Commit

Permalink
support optional dynamic property access
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Dec 25, 2024
1 parent 49a3cb4 commit d848f71
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 4 deletions.
4 changes: 4 additions & 0 deletions crates/dash_compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,10 @@ impl Visitor<Result<(), Error>> for FunctionCompiler<'_> {
ib.build_static_prop_access(ident, false)
.map_err(|_| Error::ConstantPoolLimitExceeded(span))?;
}
OptionalChainingComponent::Dyn(expr) => {
ib.accept_expr(expr)?;
ib.build_dynamic_prop_access(false);
}
}
}
ib.build_jmp(Label::IfEnd, true);
Expand Down
2 changes: 1 addition & 1 deletion crates/dash_lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ impl<'a, 'interner> Lexer<'a, 'interner> {
b'~' => self.token(TokenType::BitwiseNot),
b'?' => self.conditional_token(TokenType::Conditional, &[
("?=", TokenType::LogicalNullishAssignment),
(".[", TokenType::OptionalBracket),
(".[", TokenType::OptionalSquareBrace),
(".(", TokenType::OptionalCall),
("?", TokenType::NullishCoalescing),
(".", TokenType::OptionalDot),
Expand Down
2 changes: 1 addition & 1 deletion crates/dash_middle/src/lexer/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ pub enum TokenType {
OptionalDot,

#[display(fmt = "?.[")]
OptionalBracket,
OptionalSquareBrace,

#[display(fmt = "?.(")]
OptionalCall,
Expand Down
4 changes: 4 additions & 0 deletions crates/dash_middle/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ impl fmt::Display for OptionalChainingExpression {
for component in &self.components {
match component {
OptionalChainingComponent::Ident(symbol) => write!(f, ".{symbol}")?,
OptionalChainingComponent::Dyn(expr) => write!(f, "[{expr}]")?,
}
}
Ok(())
Expand All @@ -85,7 +86,10 @@ impl fmt::Display for OptionalChainingExpression {

#[derive(Debug, Clone)]
pub enum OptionalChainingComponent {
/// ?.x
Ident(Symbol),
/// ?.[expr]
Dyn(Expr),
}

#[derive(Debug, Clone, Display)]
Expand Down
22 changes: 20 additions & 2 deletions crates/dash_parser/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ impl Parser<'_, '_> {
TokenType::Dot,
TokenType::LeftSquareBrace,
TokenType::OptionalDot,
TokenType::OptionalSquareBrace,
]),
false,
)
Expand Down Expand Up @@ -411,9 +412,26 @@ impl Parser<'_, '_> {
TokenType::LeftSquareBrace => {
let property = self.parse_expression()?;
self.eat(TokenType::RightSquareBrace, true)?;
if let ExprKind::Chaining(c) = &mut expr.kind {
c.components.push(OptionalChainingComponent::Dyn(property));
expr.span = expr.span.to(self.previous()?.span);
} else {
expr = Expr {
span: expr.span.to(self.previous()?.span),
kind: ExprKind::property_access(true, expr, property),
};
}
}
TokenType::OptionalSquareBrace => {
let property = self.parse_expression()?;
self.eat(TokenType::RightSquareBrace, true)?;
let span = expr.span.to(self.previous()?.span);
expr = Expr {
span: expr.span.to(property.span),
kind: ExprKind::property_access(true, expr, property),
span,
kind: ExprKind::Chaining(OptionalChainingExpression {
base: Box::new(expr),
components: vec![OptionalChainingComponent::Dyn(property)],
}),
};
}
_ => unreachable!(),
Expand Down

0 comments on commit d848f71

Please sign in to comment.