1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use super::pattern::is_valid_pattern_identifier;
use super::ParseCtx;
use super::Parser;
use crate::ast::ClassOrObjectMemberKey;
use crate::error::SyntaxError;
use crate::error::SyntaxErrorType;
use crate::error::SyntaxResult;
use crate::num::JsNumber;
use crate::session::SessionString;
use crate::source::SourceRange;
use crate::token::TokenType;
use core::str::FromStr;
fn parse_radix(raw: &str, radix: u32) -> Result<f64, ()> {
u64::from_str_radix(raw, radix)
.map_err(|_| ())
.map(|v| v as f64)
}
pub fn normalise_literal_number<'a>(raw: SourceRange<'a>) -> SyntaxResult<'a, JsNumber> {
match raw.as_str() {
s if s.starts_with("0b") || s.starts_with("0B") => parse_radix(&s[2..], 2),
s if s.starts_with("0o") || s.starts_with("0o") => parse_radix(&s[2..], 8),
s if s.starts_with("0x") || s.starts_with("0X") => parse_radix(&s[2..], 16),
s => f64::from_str(s).map_err(|_| ()),
}
.map(|n| JsNumber(n))
.map_err(|_| SyntaxError::from_loc(raw, SyntaxErrorType::MalformedLiteralNumber, None))
}
pub fn normalise_literal_bigint<'a>(
ctx: ParseCtx<'a>,
raw: SourceRange<'a>,
) -> SyntaxResult<'a, SessionString<'a>> {
let mut norm = ctx.session.new_string();
norm.push_str(raw.as_str());
Ok(norm)
}
pub fn normalise_literal_string<'a>(
ctx: ParseCtx<'a>,
raw: SourceRange<'a>,
) -> SyntaxResult<'a, SessionString<'a>> {
let mut norm = ctx.session.new_string();
norm.push_str(&raw.as_str()[1..raw.len() - 1]);
Ok(norm)
}
impl<'a> Parser<'a> {
pub fn parse_and_normalise_literal_string(
&mut self,
ctx: ParseCtx<'a>,
) -> SyntaxResult<'a, SessionString<'a>> {
let t = self.require(TokenType::LiteralString)?;
let s = normalise_literal_string(ctx, t.loc)?;
Ok(s)
}
pub fn parse_class_or_object_member_key(
&mut self,
ctx: ParseCtx<'a>,
) -> SyntaxResult<'a, ClassOrObjectMemberKey<'a>> {
Ok(if self.consume_if(TokenType::BracketOpen)?.is_match() {
let expr = self.parse_expr(ctx, TokenType::BracketClose)?;
self.require(TokenType::BracketClose)?;
ClassOrObjectMemberKey::Computed(expr)
} else {
let name = self.next()?;
if !is_valid_pattern_identifier(name.typ, ctx.rules) {
return Err(name.error(SyntaxErrorType::ExpectedNotFound));
};
ClassOrObjectMemberKey::Direct(name.loc)
})
}
}