Skip to content

Commit

Permalink
new operators, first try at optional chain
Browse files Browse the repository at this point in the history
  • Loading branch information
FreeMasen committed Feb 19, 2024
1 parent 5811733 commit b8f33b4
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ pub enum Expr<T> {
Update(UpdateExpr<T>),
/// yield a value from inside of a generator function
Yield(YieldExpr<T>),
OptionalChain(Box<Expr<T>>),
}

impl<T> IntoAllocated for Expr<T>
Expand Down Expand Up @@ -134,6 +135,7 @@ where
Expr::Unary(inner) => Expr::Unary(inner.into_allocated()),
Expr::Update(inner) => Expr::Update(inner.into_allocated()),
Expr::Yield(inner) => Expr::Yield(inner.into_allocated()),
Expr::OptionalChain(inner) => Expr::OptionalChain(inner.into_allocated()),
}
}
}
Expand Down Expand Up @@ -602,6 +604,7 @@ where
}
}
}

/// A Template literal preceded by a function identifier
/// see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates) for more details
#[derive(PartialEq, Debug, Clone)]
Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@ pub enum AssignOp {
XOrEqual,
AndEqual,
PowerOfEqual,
DoubleAmpersandEqual,
DoublePipeEqual,
DoubleQuestionmarkEqual,
}

/// The available logical operators
Expand All @@ -375,6 +378,7 @@ pub enum AssignOp {
pub enum LogicalOp {
Or,
And,
NullishCoalescing,
}

/// The available operations for `Binary` Exprs
Expand Down
5 changes: 5 additions & 0 deletions src/spanned/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ mod expr {
Expr::Update(inner) => Self::Update(inner.into()),
Expr::Yield(inner) => Self::Yield(inner.into()),
Expr::Wrapped(inner) => inner.expr.into(),
Expr::OptionalChain(inner) => Self::OptionalChain(Box::new((*inner.expr).into())),
}
}
}
Expand Down Expand Up @@ -692,6 +693,9 @@ impl From<AssignOp> for crate::AssignOp {
AssignOp::XOrEqual(_) => Self::XOrEqual,
AssignOp::AndEqual(_) => Self::AndEqual,
AssignOp::PowerOfEqual(_) => Self::PowerOfEqual,
AssignOp::DoubleAmpersandEqual(_) => Self::DoubleAmpersandEqual,
AssignOp::DoublePipeEqual(_) => Self::DoublePipeEqual,
AssignOp::DoubleQuestionmarkEqual(_) => Self::DoubleQuestionmarkEqual,
}
}
}
Expand All @@ -701,6 +705,7 @@ impl From<LogicalOp> for crate::LogicalOp {
match other {
LogicalOp::Or(_) => Self::Or,
LogicalOp::And(_) => Self::And,
LogicalOp::NullishCoalescing(_) => Self::NullishCoalescing,
}
}
}
Expand Down
39 changes: 35 additions & 4 deletions src/spanned/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use crate::spanned::{Class, Func, FuncArg, FuncBody, Ident};
use crate::IntoAllocated;

use super::tokens::{
AssignOp, Asterisk, Async, Await, BinaryOp, CloseBrace, CloseBracket, CloseParen, Colon, Comma,
Ellipsis, False, FatArrow, ForwardSlash, Get, LogicalOp, New, Null, OpenBrace, OpenBracket,
OpenParen, Period, QuasiQuote, QuestionMark, Quote, Set, Static, Super, This, Token, True,
UnaryOp, UpdateOp, Yield,
self, AssignOp, Asterisk, Async, Await, BinaryOp, CloseBrace, CloseBracket, CloseParen, Colon,
Comma, Ellipsis, False, FatArrow, ForwardSlash, Get, LogicalOp, New, Null, OpenBrace,
OpenBracket, OpenParen, Period, QuasiQuote, QuestionMark, Quote, Set, Static, Super, This,
Token, True, UnaryOp, UpdateOp, Yield,
};
use super::{FuncArgEntry, ListEntry, Node, Slice, SourceLocation};
#[cfg(feature = "serde")]
Expand Down Expand Up @@ -97,6 +97,7 @@ pub enum Expr<T> {
Wrapped(Box<WrappedExpr<T>>),
/// yield a value from inside of a generator function
Yield(YieldExpr<T>),
OptionalChain(OptionalChain<T>),
}

impl<T> IntoAllocated for Expr<T>
Expand Down Expand Up @@ -139,6 +140,7 @@ where
Expr::Update(inner) => Expr::Update(inner.into_allocated()),
Expr::Wrapped(inner) => Expr::Wrapped(inner.into_allocated()),
Expr::Yield(inner) => Expr::Yield(inner.into_allocated()),
Expr::OptionalChain(inner) => Expr::OptionalChain(inner.into_allocated()),
}
}
}
Expand Down Expand Up @@ -172,6 +174,7 @@ impl<T> Node for Expr<T> {
Expr::Update(inner) => inner.loc(),
Expr::Yield(inner) => inner.loc(),
Expr::Wrapped(inner) => inner.loc(),
Expr::OptionalChain(inner) => inner.loc(),
}
}
}
Expand Down Expand Up @@ -1008,6 +1011,34 @@ impl Node for MemberIndexer {
}
}

#[derive(PartialEq, Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct OptionalChain<T> {
pub expr: Box<Expr<T>>,
pub op: tokens::QuestionMarkDot,
}

impl<T> IntoAllocated for OptionalChain<T>
where
T: ToString,
{
type Allocated = OptionalChain<String>;
fn into_allocated(self) -> Self::Allocated {
OptionalChain {
expr: Box::new((*self.expr).into_allocated()),
op: self.op,
}
}
}

impl<T> Node for OptionalChain<T> {
fn loc(&self) -> SourceLocation {
let start = self.expr.loc().start;
let end = self.op.end();
SourceLocation { start, end }
}
}

/// A ternery expression
/// ```js
/// var a = true ? 'stuff' : 'things';
Expand Down
13 changes: 13 additions & 0 deletions src/spanned/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ define_token!(CloseBracket, "]");
define_token!(Colon, ":");
define_token!(Comma, ",");
define_token!(DoubleAmpersand, "&&");
define_token!(DoubleAmpersandEqual, "&&=");
define_token!(DoubleAsterisk, "**");
define_token!(DoubleAsteriskEqual, "**=");
define_token!(DoubleEqual, "==");
Expand All @@ -171,6 +172,9 @@ define_token!(DoubleGreaterThanEqual, ">>=");
define_token!(DoubleLessThan, "<<");
define_token!(DoubleLessThanEqual, "<<=");
define_token!(DoublePipe, "||");
define_token!(DoublePipeEqual, "||=");
define_token!(DoubleQuestionmark, "??");
define_token!(DoubleQuestionmarkEqual, "??=");
define_token!(DoubleQuote, "\"");
define_token!(Ellipsis, "...");
define_token!(Equal, "=");
Expand All @@ -194,6 +198,7 @@ define_token!(PipeEqual, "|=");
define_token!(Plus, "+");
define_token!(PlusEqual, "+=");
define_token!(QuestionMark, "?");
define_token!(QuestionMarkDot, "?.");
define_token!(Semicolon, ";");
define_token!(SingleQuote, "'");
define_token!(Tilde, "~");
Expand Down Expand Up @@ -282,6 +287,9 @@ pub enum AssignOp {
XOrEqual(CaretEqual),
AndEqual(AmpersandEqual),
PowerOfEqual(DoubleAsteriskEqual),
DoubleAmpersandEqual(DoubleAmpersandEqual),
DoublePipeEqual(DoublePipeEqual),
DoubleQuestionmarkEqual(DoubleQuestionmarkEqual),
}

impl Node for AssignOp {
Expand All @@ -300,6 +308,9 @@ impl Node for AssignOp {
AssignOp::XOrEqual(tok) => tok.loc(),
AssignOp::AndEqual(tok) => tok.loc(),
AssignOp::PowerOfEqual(tok) => tok.loc(),
AssignOp::DoubleAmpersandEqual(tok) => tok.loc(),
AssignOp::DoublePipeEqual(tok) => tok.loc(),
AssignOp::DoubleQuestionmarkEqual(tok) => tok.loc(),
}
}
}
Expand All @@ -310,13 +321,15 @@ impl Node for AssignOp {
pub enum LogicalOp {
Or(DoublePipe),
And(DoubleAmpersand),
NullishCoalescing(DoubleQuestionmark),
}

impl Node for LogicalOp {
fn loc(&self) -> SourceLocation {
match self {
LogicalOp::Or(tok) => tok.loc(),
LogicalOp::And(tok) => tok.loc(),
LogicalOp::NullishCoalescing(tok) => tok.loc(),
}
}
}
Expand Down

0 comments on commit b8f33b4

Please sign in to comment.