From ba6e29d6fd8df2434cb372b94c7aaccb68bc272f Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Mon, 1 Feb 2021 09:20:13 +0000 Subject: introduce `templates` (#4603) --- lib/parse.js | 95 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 54 insertions(+), 41 deletions(-) (limited to 'lib/parse.js') diff --git a/lib/parse.js b/lib/parse.js index 5b77d675..bc72550f 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -145,6 +145,43 @@ function is_identifier_string(str) { return /^[a-z_$][a-z0-9_$]*$/i.test(str); } +function decode_escape_sequence(seq) { + switch (seq[0]) { + case "b": return "\b"; + case "f": return "\f"; + case "n": return "\n"; + case "r": return "\r"; + case "t": return "\t"; + case "u": + var code; + if (seq.length == 5) { + code = seq.slice(1); + } else if (seq[1] == "{" && seq.slice(-1) == "}") { + code = seq.slice(2, -1); + } else { + return; + } + var num = parseInt(code, 16); + if (num < 0 || isNaN(num)) return; + if (num < 0x10000) return String.fromCharCode(num); + if (num > 0x10ffff) return; + return String.fromCharCode((num >> 10) + 0xd7c0) + String.fromCharCode((num & 0x03ff) + 0xdc00); + case "v": return "\u000b"; + case "x": + if (seq.length != 3) return; + var num = parseInt(seq.slice(1), 16); + if (num < 0 || isNaN(num)) return; + return String.fromCharCode(num); + case "\r": + case "\n": + return ""; + default: + if (seq == "0") return "\0"; + if (seq[0] >= "0" && seq[0] <= "9") return; + return seq; + } +} + function parse_js_number(num) { var match; if (match = RE_BIN_NUMBER.exec(num)) return parseInt(match[1], 2); @@ -340,36 +377,23 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { } function read_escaped_char(in_string) { - var ch = next(true, in_string); - switch (ch.charCodeAt(0)) { - case 110: return "\n"; - case 114: return "\r"; - case 116: return "\t"; - case 98: return "\b"; - case 118: return "\u000b"; // \v - case 102: return "\f"; - case 120: return String.fromCharCode(hex_bytes(2)); // \x - case 117: // \u - if (peek() != "{") return String.fromCharCode(hex_bytes(4)); - next(); - var num = 0; - do { - var digit = parseInt(next(true), 16); - if (isNaN(digit)) parse_error("Invalid hex-character pattern in string"); - num = num * 16 + digit; - } while (peek() != "}"); - next(); - if (num < 0x10000) return String.fromCharCode(num); - if (num > 0x10ffff) parse_error("Invalid character code: " + num); - return String.fromCharCode((num >> 10) + 0xd7c0) + String.fromCharCode((num & 0x03ff) + 0xdc00); - case 13: // \r - // DOS newline - if (peek() == "\n") next(true, in_string); - case 10: return ""; // \n - } - if (ch >= "0" && ch <= "7") - return read_octal_escape_sequence(ch); - return ch; + var seq = next(true, in_string); + if (seq >= "0" && seq <= "7") return read_octal_escape_sequence(seq); + if (seq == "u") { + var ch = next(true, in_string); + seq += ch; + if (ch != "{") { + seq += next(true, in_string) + next(true, in_string) + next(true, in_string); + } else do { + ch = next(true, in_string); + seq += ch; + } while (ch != "}"); + } else if (seq == "x") { + seq += next(true, in_string) + next(true, in_string); + } + var str = decode_escape_sequence(seq); + if (typeof str != "string") parse_error("Invalid escape sequence: \\" + seq); + return str; } function read_octal_escape_sequence(ch) { @@ -388,17 +412,6 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { return String.fromCharCode(parseInt(ch, 8)); } - function hex_bytes(n) { - var num = 0; - for (; n > 0; --n) { - var digit = parseInt(next(true), 16); - if (isNaN(digit)) - parse_error("Invalid hex-character pattern in string"); - num = (num << 4) | digit; - } - return num; - } - var read_string = with_eof_error("Unterminated string constant", function(quote_char) { var quote = next(), ret = ""; for (;;) { -- cgit v1.2.3