Browse Source

support extended identifier (backslash names); fix exponential notation

master
g2384 5 years ago
parent
commit
79fc211f5a
4 changed files with 104 additions and 46 deletions
  1. +2
    -0
      README.md
  2. +41
    -21
      VHDLFormatter.js
  3. +42
    -24
      VHDLFormatter.ts
  4. +19
    -1
      tests/VHDLFormatterUnitTests.ts

+ 2
- 0
README.md View File

@ -10,6 +10,8 @@ VHDL formatter web online written in javascript
- bugfix "remove non-comment code by mistake" - bugfix "remove non-comment code by mistake"
- add `tests` folder, improve the project management - add `tests` folder, improve the project management
- support extended identifier (backslash names)
- fix exponential notation
### 2.2 [2018-10-16] ### 2.2 [2018-10-16]


+ 41
- 21
VHDLFormatter.js View File

@ -1,9 +1,11 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
let isTesting = false; let isTesting = false;
const ILCommentPrefix = "@@comments";
const ILQuotesPrefix = "@@quotes";
const ILSingleQuotesPrefix = "@@singlequotes";
const ILEscape = "@@";
const ILCommentPrefix = ILEscape + "comments";
const ILQuotesPrefix = ILEscape + "quotes";
const ILSingleQuotesPrefix = ILEscape + "singlequotes";
const ILBackslashesPrefix = ILEscape + "backslash";
var FormatMode; var FormatMode;
(function (FormatMode) { (function (FormatMode) {
FormatMode[FormatMode["Default"] = 0] = "Default"; FormatMode[FormatMode["Default"] = 0] = "Default";
@ -150,17 +152,19 @@ function MixLetters(input) {
} }
return arr.join(""); return arr.join("");
} }
function EscapeComments(arr, comments, commentIndex) {
function EscapeComments(arr) {
var comments = [];
var count = 0;
for (var i = 0; i < arr.length; i++) { for (var i = 0; i < arr.length; i++) {
let line = arr[i];
var line = arr[i];
var commentStartIndex = line.indexOf("--"); var commentStartIndex = line.indexOf("--");
if (commentStartIndex >= 0) { if (commentStartIndex >= 0) {
comments.push(line.substr(commentStartIndex)); comments.push(line.substr(commentStartIndex));
arr[i] = line.substr(0, commentStartIndex) + ILCommentPrefix + commentIndex;
commentIndex++;
arr[i] = line.substr(0, commentStartIndex) + ILCommentPrefix + count;
count++;
} }
} }
return commentIndex;
return comments;
} }
function ToLowerCases(arr) { function ToLowerCases(arr) {
for (var i = 0; i < arr.length; i++) { for (var i = 0; i < arr.length; i++) {
@ -243,14 +247,14 @@ function beautify(input, settings) {
input = input.replace(/\r\n/g, "\n"); input = input.replace(/\r\n/g, "\n");
input = input.replace(/\n/g, "\r\n"); input = input.replace(/\n/g, "\r\n");
var arr = input.split("\r\n"); var arr = input.split("\r\n");
var comments = [], commentsIndex = 0;
commentsIndex = EscapeComments(arr, comments, commentsIndex);
var comments = EscapeComments(arr);
var backslashes = escapeBackslashes(arr);
RemoveLeadingWhitespaces(arr); RemoveLeadingWhitespaces(arr);
input = arr.join("\r\n"); input = arr.join("\r\n");
if (settings.RemoveComments) { if (settings.RemoveComments) {
input = input.replace(/\r\n[ \t]*@@comments[0-9]+[ \t]*\r\n/g, '\r\n'); input = input.replace(/\r\n[ \t]*@@comments[0-9]+[ \t]*\r\n/g, '\r\n');
input = input.replace(/@@comments[0-9]+/g, ''); input = input.replace(/@@comments[0-9]+/g, '');
commentsIndex = 0;
comments = [];
} }
input = RemoveExtraNewLines(input); input = RemoveExtraNewLines(input);
input = input.replace(/[\t ]+/g, ' '); input = input.replace(/[\t ]+/g, ' ');
@ -274,9 +278,10 @@ function beautify(input, settings) {
arr = input.split("\r\n"); arr = input.split("\r\n");
ApplyNoNewLineAfter(arr, settings.NewLineSettings.noNewLineAfter); ApplyNoNewLineAfter(arr, settings.NewLineSettings.noNewLineAfter);
input = arr.join("\r\n"); input = arr.join("\r\n");
//new
input = input.replace(/([a-zA-Z0-9\); ])\);(@@comments[0-9]+)?@@end/g, '$1\r\n);$2@@end'); input = input.replace(/([a-zA-Z0-9\); ])\);(@@comments[0-9]+)?@@end/g, '$1\r\n);$2@@end');
input = input.replace(/[ ]?([&=:\-<>\+|\*])[ ]?/g, ' $1 '); input = input.replace(/[ ]?([&=:\-<>\+|\*])[ ]?/g, ' $1 ');
// Fix reals in expoential format broken by previous step
input = input.replace(/(\d+e) +([+\-]) +(\d+)/g, '$1$2$3');
input = input.replace(/[ ]?([,])[ ]?/g, '$1 '); input = input.replace(/[ ]?([,])[ ]?/g, '$1 ');
input = input.replace(/[ ]?(['"])(THEN)/g, '$1 $2'); input = input.replace(/[ ]?(['"])(THEN)/g, '$1 $2');
input = input.replace(/[ ]?(\?)?[ ]?(<|:|>|\/)?[ ]+(=)?[ ]?/g, ' $1$2$3 '); input = input.replace(/[ ]?(\?)?[ ]?(<|:|>|\/)?[ ]+(=)?[ ]?/g, ' $1$2$3 ');
@ -300,20 +305,35 @@ function beautify(input, settings) {
arr = FormattedLineToString(result, settings.Indentation); arr = FormattedLineToString(result, settings.Indentation);
input = arr.join("\r\n"); input = arr.join("\r\n");
input = SetKeywordCase(input, settings.KeywordCase, KeyWords, TypeNames); input = SetKeywordCase(input, settings.KeywordCase, KeyWords, TypeNames);
for (var k = 0; k < quotes.length; k++) {
input = input.replace(ILQuotesPrefix + k, quotes[k]);
}
for (var k = 0; k < singleQuotes.length; k++) {
input = input.replace(ILSingleQuotesPrefix + k, singleQuotes[k]);
}
for (var k = 0; k < commentsIndex; k++) {
input = input.replace(ILCommentPrefix + k, comments[k]);
}
input = replaceEscapedWords(input, quotes, ILQuotesPrefix);
input = replaceEscapedWords(input, singleQuotes, ILSingleQuotesPrefix);
input = replaceEscapedWords(input, comments, ILCommentPrefix);
input = replaceEscapedWords(input, backslashes, ILBackslashesPrefix);
input = input.replace(/@@semicolon/g, ";"); input = input.replace(/@@semicolon/g, ";");
input = input.replace(/@@[a-z]+/g, ""); input = input.replace(/@@[a-z]+/g, "");
return input; return input;
} }
exports.beautify = beautify; exports.beautify = beautify;
function replaceEscapedWords(input, arr, prefix) {
for (var i = 0; i < arr.length; i++) {
input = input.replace(prefix + i, arr[i]);
}
return input;
}
function escapeBackslashes(arr) {
var escaped = [];
var count = 0;
for (var i = 0; i < arr.length; i++) {
var sequence = arr[i].match(/\\[^\\]+\\/g);
if (sequence != null) {
for (var j = 0; j < sequence.length; j++) {
arr[i] = arr[i].replace(sequence[j], ILBackslashesPrefix + count);
escaped[count++] = sequence[j];
}
}
}
return escaped;
}
function RemoveLeadingWhitespaces(arr) { function RemoveLeadingWhitespaces(arr) {
for (var i = 0; i < arr.length; i++) { for (var i = 0; i < arr.length; i++) {
arr[i] = arr[i].replace(/^\s+/, ""); arr[i] = arr[i].replace(/^\s+/, "");


+ 42
- 24
VHDLFormatter.ts View File

@ -1,7 +1,9 @@
let isTesting = false; let isTesting = false;
const ILCommentPrefix = "@@comments";
const ILQuotesPrefix = "@@quotes";
const ILSingleQuotesPrefix = "@@singlequotes";
const ILEscape = "@@";
const ILCommentPrefix = ILEscape + "comments";
const ILQuotesPrefix = ILEscape + "quotes";
const ILSingleQuotesPrefix = ILEscape + "singlequotes";
const ILBackslashesPrefix = ILEscape + "backslash";
enum FormatMode { enum FormatMode {
Default, Default,
@ -183,17 +185,19 @@ function MixLetters(input: string) {
return arr.join(""); return arr.join("");
} }
function EscapeComments(arr: Array<string>, comments: Array<string>, commentIndex: number): number {
function EscapeComments(arr: Array<string>): Array<string> {
var comments = [];
var count = 0;
for (var i = 0; i < arr.length; i++) { for (var i = 0; i < arr.length; i++) {
let line: string = arr[i];
var line: string = arr[i];
var commentStartIndex = line.indexOf("--"); var commentStartIndex = line.indexOf("--");
if (commentStartIndex >= 0) { if (commentStartIndex >= 0) {
comments.push(line.substr(commentStartIndex)); comments.push(line.substr(commentStartIndex));
arr[i] = line.substr(0, commentStartIndex) + ILCommentPrefix + commentIndex;
commentIndex++
arr[i] = line.substr(0, commentStartIndex) + ILCommentPrefix + count;
count++;
} }
} }
return commentIndex
return comments
} }
function ToLowerCases(arr: Array<string>) { function ToLowerCases(arr: Array<string>) {
@ -295,16 +299,15 @@ export function beautify(input: string, settings: BeautifierSettings) {
input = input.replace(/\r\n/g, "\n"); input = input.replace(/\r\n/g, "\n");
input = input.replace(/\n/g, "\r\n"); input = input.replace(/\n/g, "\r\n");
var arr = input.split("\r\n"); var arr = input.split("\r\n");
var comments = [],
commentsIndex = 0;
commentsIndex = EscapeComments(arr, comments, commentsIndex);
var comments = EscapeComments(arr);
var backslashes = escapeBackslashes(arr);
RemoveLeadingWhitespaces(arr); RemoveLeadingWhitespaces(arr);
input = arr.join("\r\n"); input = arr.join("\r\n");
if (settings.RemoveComments) { if (settings.RemoveComments) {
input = input.replace(/\r\n[ \t]*@@comments[0-9]+[ \t]*\r\n/g, '\r\n'); input = input.replace(/\r\n[ \t]*@@comments[0-9]+[ \t]*\r\n/g, '\r\n');
input = input.replace(/@@comments[0-9]+/g, ''); input = input.replace(/@@comments[0-9]+/g, '');
commentsIndex = 0;
comments = [];
} }
input = RemoveExtraNewLines(input); input = RemoveExtraNewLines(input);
@ -333,9 +336,9 @@ export function beautify(input: string, settings: BeautifierSettings) {
ApplyNoNewLineAfter(arr, settings.NewLineSettings.noNewLineAfter); ApplyNoNewLineAfter(arr, settings.NewLineSettings.noNewLineAfter);
input = arr.join("\r\n"); input = arr.join("\r\n");
//new
input = input.replace(/([a-zA-Z0-9\); ])\);(@@comments[0-9]+)?@@end/g, '$1\r\n);$2@@end'); input = input.replace(/([a-zA-Z0-9\); ])\);(@@comments[0-9]+)?@@end/g, '$1\r\n);$2@@end');
input = input.replace(/[ ]?([&=:\-<>\+|\*])[ ]?/g, ' $1 '); input = input.replace(/[ ]?([&=:\-<>\+|\*])[ ]?/g, ' $1 ');
input = input.replace(/(\d+e) +([+\-]) +(\d+)/g, '$1$2$3');// Fix exponential notation format broken by previous step
input = input.replace(/[ ]?([,])[ ]?/g, '$1 '); input = input.replace(/[ ]?([,])[ ]?/g, '$1 ');
input = input.replace(/[ ]?(['"])(THEN)/g, '$1 $2'); input = input.replace(/[ ]?(['"])(THEN)/g, '$1 $2');
input = input.replace(/[ ]?(\?)?[ ]?(<|:|>|\/)?[ ]+(=)?[ ]?/g, ' $1$2$3 '); input = input.replace(/[ ]?(\?)?[ ]?(<|:|>|\/)?[ ]+(=)?[ ]?/g, ' $1$2$3 ');
@ -361,23 +364,38 @@ export function beautify(input: string, settings: BeautifierSettings) {
input = arr.join("\r\n"); input = arr.join("\r\n");
input = SetKeywordCase(input, settings.KeywordCase, KeyWords, TypeNames); input = SetKeywordCase(input, settings.KeywordCase, KeyWords, TypeNames);
for (var k = 0; k < quotes.length; k++) {
input = input.replace(ILQuotesPrefix + k, quotes[k]);
}
for (var k = 0; k < singleQuotes.length; k++) {
input = input.replace(ILSingleQuotesPrefix + k, singleQuotes[k]);
}
for (var k = 0; k < commentsIndex; k++) {
input = input.replace(ILCommentPrefix + k, comments[k]);
}
input = replaceEscapedWords(input, quotes, ILQuotesPrefix);
input = replaceEscapedWords(input, singleQuotes, ILSingleQuotesPrefix);
input = replaceEscapedWords(input, comments, ILCommentPrefix);
input = replaceEscapedWords(input, backslashes, ILBackslashesPrefix);
input = input.replace(/@@semicolon/g, ";"); input = input.replace(/@@semicolon/g, ";");
input = input.replace(/@@[a-z]+/g, ""); input = input.replace(/@@[a-z]+/g, "");
return input; return input;
} }
function replaceEscapedWords(input: string, arr: Array<string>, prefix: string): string {
for (var i = 0; i < arr.length; i++) {
input = input.replace(prefix + i, arr[i]);
}
return input;
}
function escapeBackslashes(arr: Array<string>) {
var escaped = [];
var count = 0;
for (var i = 0; i < arr.length; i++) {
var sequence = arr[i].match(/\\[^\\]+\\/g);
if (sequence != null) {
for (var j = 0; j < sequence.length; j++) {
arr[i] = arr[i].replace(sequence[j], ILBackslashesPrefix + count);
escaped[count++] = sequence[j];
}
}
}
return escaped;
}
function RemoveLeadingWhitespaces(arr: Array<string>) { function RemoveLeadingWhitespaces(arr: Array<string>) {
for (var i = 0; i < arr.length; i++) { for (var i = 0; i < arr.length; i++) {
arr[i] = arr[i].replace(/^\s+/, ""); arr[i] = arr[i].replace(/^\s+/, "");


+ 19
- 1
tests/VHDLFormatterUnitTests.ts View File

@ -909,6 +909,8 @@ function IntegrationTest() {
IntegrationTest68(); IntegrationTest68();
IntegrationTest69(); IntegrationTest69();
IntegrationTest70(); IntegrationTest70();
IntegrationTest71();
IntegrationTest72();
} }
function IntegrationTest23() { function IntegrationTest23() {
@ -1313,7 +1315,7 @@ function IntegrationTest66() {
let input = 'component a is\r\n generic (b\r\n );\r\n port (\r\n c\r\n );\r\n end component;\r\n-- anything1\r\n-- anything2'; let input = 'component a is\r\n generic (b\r\n );\r\n port (\r\n c\r\n );\r\n end component;\r\n-- anything1\r\n-- anything2';
let expected = 'COMPONENT a IS\r\n GENERIC (\r\n b\r\n );\r\n PORT (\r\n c\r\n );\r\nEND COMPONENT;\r\n-- anything1\r\n-- anything2'; let expected = 'COMPONENT a IS\r\n GENERIC (\r\n b\r\n );\r\n PORT (\r\n c\r\n );\r\nEND COMPONENT;\r\n-- anything1\r\n-- anything2';
let actual = beautify(input, settings); let actual = beautify(input, settings);
assertAndCountTest("port map no new line 2", expected, actual);
assertAndCountTest("component generic", expected, actual);
} }
function IntegrationTest67() { function IntegrationTest67() {
@ -1348,6 +1350,22 @@ function IntegrationTest70() {
assertAndCountTest("multiline assignment", expected, actual); assertAndCountTest("multiline assignment", expected, actual);
} }
function IntegrationTest71() {
let settings = GetDefaultSettings();
let input = 'VARIABLE \\#$)!?\\ : INTEGER;\r\nVARIABLE \\try this in verilog\\ : BIT;\r\nVARIABLE \\Buffer\\ : BIT;';
let expected = 'VARIABLE \\#$)!?\\ : INTEGER;\r\nVARIABLE \\try this in verilog\\ : BIT;\r\nVARIABLE \\Buffer\\ : BIT;';
let actual = beautify(input, settings);
assertAndCountTest("backslash, extended indentifier", expected, actual);
}
function IntegrationTest72() {
let settings = GetDefaultSettings();
let input = 'test := 12e+6';
let expected = 'test := 12e+6';
let actual = beautify(input, settings);
assertAndCountTest("scientific notation", expected, actual);
}
function GetDefaultSettings() { function GetDefaultSettings() {
let new_line_after_symbols = new NewLineSettings(); let new_line_after_symbols = new NewLineSettings();
new_line_after_symbols.newLineAfter = ["then", ";"]; new_line_after_symbols.newLineAfter = ["then", ";"];


Loading…
Cancel
Save