mirror of
https://github.com/bendtherules/ask262.git
synced 2026-08-19 00:31:06 +00:00
Merge commit '6e92d2345e8231a44556ce7d416451f5f3e6c398' as 'engine262'
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import { OutOfRange, unreachable } from '../helpers.mts';
|
||||
import type { ParseNode } from '../parser/ParseNode.mts';
|
||||
import { UTF16SurrogatePairToCodePoint } from './all.mts';
|
||||
import { Unicode, type CodePoint } from '#self';
|
||||
|
||||
export type CharacterValueAcceptNode =
|
||||
| ParseNode.RegExp.CharacterEscape
|
||||
| ParseNode.RegExp.RegExpUnicodeEscapeSequence
|
||||
| ParseNode.RegExp.ClassAtom
|
||||
| ParseNode.RegExp.ClassEscape
|
||||
| ParseNode.RegExp.ClassSetCharacter;
|
||||
|
||||
/** https://tc39.es/ecma262/#sec-patterns-static-semantics-character-value */
|
||||
export function CharacterValue(node: CharacterValueAcceptNode): CodePoint {
|
||||
switch (node.type) {
|
||||
case 'CharacterEscape':
|
||||
switch (node.production) {
|
||||
case 'ControlEscape':
|
||||
switch (node.ControlEscape) {
|
||||
case 't':
|
||||
return 0x0009 as CodePoint;
|
||||
case 'n':
|
||||
return 0x000A as CodePoint;
|
||||
case 'v':
|
||||
return 0x000B as CodePoint;
|
||||
case 'f':
|
||||
return 0x000C as CodePoint;
|
||||
case 'r':
|
||||
return 0x000D as CodePoint;
|
||||
default:
|
||||
unreachable(node.ControlEscape);
|
||||
}
|
||||
case 'AsciiLetter': {
|
||||
// 1. Let ch be the code point matched by ControlLetter.
|
||||
const ch = node.AsciiLetter;
|
||||
// 2. Let i be ch's code point value.
|
||||
const i = ch.codePointAt(0)!;
|
||||
// 3. Return the remainder of dividing i by 32.
|
||||
return i % 32 as CodePoint;
|
||||
}
|
||||
case 'HexEscapeSequence':
|
||||
// 1. Return the numeric value of the code unit that is the SV of HexEscapeSequence.
|
||||
return Number.parseInt(`${node.HexEscapeSequence.HexDigit_a}${node.HexEscapeSequence.HexDigit_b}`, 16) as CodePoint;
|
||||
case 'RegExpUnicodeEscapeSequence':
|
||||
return CharacterValue(node.RegExpUnicodeEscapeSequence);
|
||||
case '0':
|
||||
// 1. Return the code point value of U+0000 (NULL).
|
||||
return 0x0000 as CodePoint;
|
||||
case 'IdentityEscape': {
|
||||
// 1. Let ch be the code point matched by IdentityEscape.
|
||||
const ch = node.IdentityEscape.codePointAt(0)!;
|
||||
// 2. Return the code point value of ch.
|
||||
return ch as CodePoint;
|
||||
}
|
||||
default:
|
||||
unreachable(node);
|
||||
}
|
||||
case 'RegExpUnicodeEscapeSequence':
|
||||
switch (true) {
|
||||
case 'Hex4Digits' in node:
|
||||
return node.Hex4Digits as CodePoint;
|
||||
case 'CodePoint' in node:
|
||||
return node.CodePoint as CodePoint;
|
||||
case 'HexTrailSurrogate' in node:
|
||||
return UTF16SurrogatePairToCodePoint(node.HexLeadSurrogate!, node.HexTrailSurrogate!);
|
||||
case 'HexLeadSurrogate' in node:
|
||||
return node.HexLeadSurrogate as CodePoint;
|
||||
default:
|
||||
throw new OutOfRange('CharacterValue', node);
|
||||
}
|
||||
case 'ClassAtom':
|
||||
switch (node.production) {
|
||||
case '-':
|
||||
// 1. Return the code point value of U+002D (HYPHEN-MINUS).
|
||||
return 0x002D as CodePoint;
|
||||
case 'SourceCharacter': {
|
||||
// 1. Let ch be the code point matched by SourceCharacter.
|
||||
const ch = node.SourceCharacter.codePointAt(0)!;
|
||||
// 2. Return ch.
|
||||
return ch as CodePoint;
|
||||
}
|
||||
case 'ClassEscape':
|
||||
return CharacterValue(node.ClassEscape);
|
||||
default:
|
||||
unreachable(node);
|
||||
}
|
||||
case 'ClassEscape':
|
||||
switch (node.production) {
|
||||
case 'b':
|
||||
// 1. Return the code point value of U+0008 (BACKSPACE).
|
||||
return 0x0008 as CodePoint;
|
||||
case '-':
|
||||
// 1. Return the code point value of U+002D (HYPHEN-MINUS).
|
||||
return 0x002D as CodePoint;
|
||||
case 'CharacterEscape':
|
||||
return CharacterValue(node.CharacterEscape);
|
||||
case 'CharacterClassEscape':
|
||||
throw new OutOfRange('CharacterValue', node);
|
||||
default:
|
||||
unreachable(node);
|
||||
}
|
||||
case 'ClassSetCharacter': {
|
||||
if (node.production === 'CharacterEscape') {
|
||||
return CharacterValue(node.CharacterEscape);
|
||||
} else {
|
||||
return Unicode.toCodePoint(node.UnicodeCharacter);
|
||||
}
|
||||
}
|
||||
default:
|
||||
unreachable(node);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user