From 670a8c0a76d077d609f0a7951c4b823ac4f04155 Mon Sep 17 00:00:00 2001 From: Yui T Date: Fri, 21 Nov 2014 18:09:50 -0800 Subject: [PATCH] Binary and octal integer literal support --- .../diagnosticInformationMap.generated.ts | 4 +- src/compiler/diagnosticMessages.json | 11 ++++- src/compiler/emitter.ts | 6 ++- src/compiler/scanner.ts | 41 +++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index a87b1f8cc2..13587df29e 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -124,7 +124,9 @@ module ts { Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1159, category: DiagnosticCategory.Error, key: "Tagged templates are only available when targeting ECMAScript 6 and higher." }, Unterminated_template_literal: { code: 1160, category: DiagnosticCategory.Error, key: "Unterminated template literal." }, Unterminated_regular_expression_literal: { code: 1161, category: DiagnosticCategory.Error, key: "Unterminated regular expression literal." }, - An_object_member_cannot_be_declared_optional: { code: 1160, category: DiagnosticCategory.Error, key: "An object member cannot be declared optional." }, + An_object_member_cannot_be_declared_optional: { code: 1162, category: DiagnosticCategory.Error, key: "An object member cannot be declared optional." }, + Binary_digits_expected: { code: 1163, category: DiagnosticCategory.Error, key: "Binary digits expected." }, + Octal_digits_expected: { code: 1164, category: DiagnosticCategory.Error, key: "Octal digits expected." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7c966f7c95..427eba4531 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -487,10 +487,17 @@ "category": "Error", "code": 1161 }, - "An object member cannot be declared optional.": { "category": "Error", - "code": 1160 + "code": 1162 + }, + "Binary digits expected.": { + "category": "Error", + "code": 1163 + }, + "Octal digits expected.": { + "category": "Error", + "code": 1164 }, "Duplicate identifier '{0}'.": { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index bc74f8304d..9e7b831fd2 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -794,6 +794,11 @@ module ts { if (compilerOptions.sourceMap && (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) { writer.writeLiteral(text); } + else if (node.kind === SyntaxKind.NumericLiteral && compilerOptions.target < ScriptTarget.ES6 && + ((text.charCodeAt(1) === CharacterCodes.B || text.charCodeAt(1) === CharacterCodes.b || + text.charCodeAt(1) === CharacterCodes.O || text.charCodeAt(1) === CharacterCodes.o))) { + write(node.text); + } else { write(text); } @@ -802,7 +807,6 @@ module ts { if (compilerOptions.target < ScriptTarget.ES6 && isTemplateLiteralKind(node.kind)) { return getTemplateLiteralAsStringLiteral(node) } - return getSourceTextOfLocalNode(node); } } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index e08f481ba9..596155c813 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -520,6 +520,27 @@ module ts { return +(text.substring(start, pos)); } + function scanBinaryOrOctalDigits(base: number): number { + if (base !== 2 && base !== 8) { + return -1; + } + var value = 0; + while (true) { + var ch = text.charCodeAt(pos); + var valueOfCh = ch - CharacterCodes._0; + if (!isDigit(ch)) { + break; + } + // We know at this point that ch must be digit + if (valueOfCh >= base) { + return -1; + } + value = value * base + valueOfCh; + pos++; + } + return value; + } + function scanHexDigits(count: number, mustMatchCount?: boolean): number { var digits = 0; var value = 0; @@ -933,6 +954,26 @@ module ts { tokenValue = "" + value; return SyntaxKind.NumericLiteral; } + else if (pos + 2 < len && (text.charCodeAt(pos + 1) === CharacterCodes.B || text.charCodeAt(pos + 1) === CharacterCodes.b)) { + pos += 2; + var value = scanBinaryOrOctalDigits(/* binary */2); + if (value < 0) { + error(Diagnostics.Binary_digits_expected); + value = 0; + } + tokenValue = "" + value; + return SyntaxKind.NumericLiteral; + } + else if (pos + 2 < len && (text.charCodeAt(pos + 1) === CharacterCodes.O || text.charCodeAt(pos + 1) === CharacterCodes.o)) { + pos += 2; + var value = scanBinaryOrOctalDigits(/* octal */8); + if (value < 0) { + error(Diagnostics.Octal_digits_expected); + value = 0; + } + tokenValue = "" + value; + return SyntaxKind.NumericLiteral; + } // Try to parse as an octal if (pos + 1 < len && isOctalDigit(text.charCodeAt(pos + 1))) { tokenValue = "" + scanOctalDigits();