Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions crates/oxc_parser/src/js/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,13 @@ impl<'a> ParserImpl<'a> {
let lit = self.parse_literal_null();
Expression::NullLiteral(self.alloc(lit))
}
Kind::DecimalBigInt | Kind::BinaryBigInt | Kind::OctalBigInt | Kind::HexBigInt => {
let lit = self.parse_literal_bigint();
Expression::BigIntLiteral(self.alloc(lit))
}
kind if kind.is_number() => {
if self.cur_src().ends_with('n') {
let lit = self.parse_literal_bigint();
Expression::BigIntLiteral(self.alloc(lit))
} else {
let lit = self.parse_literal_number();
Expression::NumericLiteral(self.alloc(lit))
}
let lit = self.parse_literal_number();
Expression::NumericLiteral(self.alloc(lit))
}
_ => self.unexpected(),
}
Expand Down Expand Up @@ -342,17 +341,17 @@ impl<'a> ParserImpl<'a> {
let token = self.cur_token();
let kind = token.kind();
let has_separator = token.has_separator();
let base = match kind {
Kind::Decimal => BigintBase::Decimal,
Kind::Binary => BigintBase::Binary,
Kind::Octal => BigintBase::Octal,
Kind::Hex => BigintBase::Hex,
let (base, number_kind) = match kind {
Kind::DecimalBigInt => (BigintBase::Decimal, Kind::Decimal),
Kind::BinaryBigInt => (BigintBase::Binary, Kind::Binary),
Kind::OctalBigInt => (BigintBase::Octal, Kind::Octal),
Kind::HexBigInt => (BigintBase::Hex, Kind::Hex),
_ => return self.unexpected(),
};
let span = token.span();
let raw = self.cur_src();
let src = raw.strip_suffix('n').unwrap();
let value = parse_big_int(src, kind, has_separator, self.ast.allocator);
let value = parse_big_int(src, number_kind, has_separator, self.ast.allocator);

self.bump_any();
self.ast.big_int_literal(span, value, Some(Atom::from(raw)), base)
Expand Down
21 changes: 20 additions & 1 deletion crates/oxc_parser/src/lexer/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ pub enum Kind {
PositiveExponential,
// for `1e-10`
NegativeExponential,
// BigInt Literals (numeric literals with 'n' suffix)
DecimalBigInt,
BinaryBigInt,
OctalBigInt,
HexBigInt,
// 12.9.4 String Literals
/// String Type
Str,
Expand Down Expand Up @@ -210,7 +215,17 @@ impl Kind {
pub fn is_number(self) -> bool {
matches!(
self,
Float | Decimal | Binary | Octal | Hex | PositiveExponential | NegativeExponential
Float
| Decimal
| Binary
| Octal
| Hex
| PositiveExponential
| NegativeExponential
| DecimalBigInt
| BinaryBigInt
| OctalBigInt
| HexBigInt
)
}

Expand Down Expand Up @@ -660,6 +675,10 @@ impl Kind {
Binary => "binary",
Octal => "octal",
Hex => "hex",
DecimalBigInt => "decimal bigint",
BinaryBigInt => "binary bigint",
OctalBigInt => "octal bigint",
HexBigInt => "hex bigint",
Str | String => "string",
RegExp => "/regexp/",
NoSubstitutionTemplate => "${}",
Expand Down
17 changes: 13 additions & 4 deletions crates/oxc_parser/src/lexer/numeric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl Lexer<'_> {
}
Some(b'n') => {
self.consume_char();
self.check_after_numeric_literal(Kind::Decimal)
self.check_after_numeric_literal(Kind::DecimalBigInt)
}
Some(n) if n.is_ascii_digit() => self.read_legacy_octal(),
_ => self.check_after_numeric_literal(Kind::Decimal),
Expand All @@ -33,7 +33,7 @@ impl Lexer<'_> {
if self.next_ascii_byte_eq(b'.') {
return self.decimal_literal_after_decimal_point_after_digits();
} else if self.next_ascii_byte_eq(b'n') {
return self.check_after_numeric_literal(Kind::Decimal);
return self.check_after_numeric_literal(Kind::DecimalBigInt);
}

let kind = self.optional_exponent().map_or(Kind::Decimal, |kind| kind);
Expand Down Expand Up @@ -78,8 +78,17 @@ impl Lexer<'_> {
_ => break,
}
}
self.next_ascii_byte_eq(b'n');
self.check_after_numeric_literal(kind)
let final_kind = if self.next_ascii_byte_eq(b'n') {
match kind {
Kind::Binary => Kind::BinaryBigInt,
Kind::Octal => Kind::OctalBigInt,
Kind::Hex => Kind::HexBigInt,
_ => unreachable!(),
}
} else {
kind
};
self.check_after_numeric_literal(final_kind)
}

fn read_legacy_octal(&mut self) -> Kind {
Expand Down
Loading