Browse Source

treat key words and type names separately

master
g2384 5 years ago
parent
commit
087d3ffc36
5 changed files with 93 additions and 36 deletions
  1. +1
    -0
      README.md
  2. +19
    -14
      VHDLFormatter.js
  3. +20
    -16
      VHDLFormatter.ts
  4. +25
    -1
      index.html
  5. +28
    -5
      tests/VHDLFormatterUnitTests.ts

+ 1
- 0
README.md View File

@ -10,6 +10,7 @@ VHDL formatter web online written in javascript
- use local storage to store settings
- add `main.js`
- treat key words and type names separately
### 2.3 [2018-02-22]


+ 19
- 14
VHDLFormatter.js View File

@ -118,23 +118,19 @@ function ReplaceKeyWords(text, keywords) {
}
return text;
}
function SetKeywordCase(input, keywordcase, keywords, typenames) {
function SetKeywordCase(input, keywordcase, keywords) {
let inputcase = keywordcase.toLowerCase();
switch (keywordcase.toLowerCase()) {
switch (inputcase) {
case "lowercase":
ToLowerCases(keywords);
ToLowerCases(typenames);
break;
case "defaultcase":
ToCamelCases(keywords);
ToCamelCases(typenames);
break;
case "uppercase":
ToUpperCases(keywords);
ToUpperCases(typenames);
}
input = ReplaceKeyWords(input, keywords);
input = ReplaceKeyWords(input, typenames);
return input;
}
function SetNewLinesAfterSymbols(text, newLineSettings) {
@ -160,13 +156,14 @@ function SetNewLinesAfterSymbols(text, newLineSettings) {
}
exports.SetNewLinesAfterSymbols = SetNewLinesAfterSymbols;
class BeautifierSettings {
constructor(removeComments, removeReport, checkAlias, signAlign, signAlignAll, keywordCase, indentation, newLineSettings, endOfLine) {
constructor(removeComments, removeReport, checkAlias, signAlign, signAlignAll, keywordCase, typeNameCase, indentation, newLineSettings, endOfLine) {
this.RemoveComments = removeComments;
this.RemoveAsserts = removeReport;
this.CheckAlias = checkAlias;
this.SignAlignRegional = signAlign;
this.SignAlignAll = signAlignAll;
this.KeywordCase = keywordCase;
this.TypeNameCase = typeNameCase;
this.Indentation = indentation;
this.NewLineSettings = newLineSettings;
this.EndOfLine = endOfLine;
@ -190,7 +187,8 @@ function beautify(input, settings) {
input = input.replace(/@@comments[0-9]+/g, '');
comments = [];
}
input = SetKeywordCase(input, "uppercase", KeyWords, TypeNames);
input = SetKeywordCase(input, "uppercase", KeyWords);
input = SetKeywordCase(input, "uppercase", TypeNames);
input = RemoveExtraNewLines(input);
input = input.replace(/[\t ]+/g, ' ');
input = input.replace(/\([\t ]+/g, '\(');
@ -204,10 +202,13 @@ function beautify(input, settings) {
input = arr.join("\r\n");
input = input.replace(/(PORT|GENERIC)\s+MAP/g, '$1 MAP');
input = input.replace(/(PORT|PROCESS|GENERIC)[\s]*\(/g, '$1 (');
input = SetNewLinesAfterSymbols(input, settings.NewLineSettings);
arr = input.split("\r\n");
ApplyNoNewLineAfter(arr, settings.NewLineSettings.noNewLineAfter);
input = arr.join("\r\n");
let newLineSettings = settings.NewLineSettings;
if (newLineSettings != null) {
input = SetNewLinesAfterSymbols(input, newLineSettings);
arr = input.split("\r\n");
ApplyNoNewLineAfter(arr, newLineSettings.noNewLineAfter);
input = arr.join("\r\n");
}
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(/(\d+e) +([+\-]) +(\d+)/g, '$1$2$3'); // fix exponential notation format broken by previous step
@ -237,7 +238,8 @@ function beautify(input, settings) {
}
arr = FormattedLineToString(result, settings.Indentation);
input = arr.join("\r\n");
input = SetKeywordCase(input, settings.KeywordCase, KeyWords, TypeNames);
input = SetKeywordCase(input, settings.KeywordCase, KeyWords);
input = SetKeywordCase(input, settings.TypeNameCase, TypeNames);
input = replaceEscapedWords(input, quotes, ILQuote);
input = replaceEscapedWords(input, singleQuotes, ILSingleQuote);
input = replaceEscapedComments(input, comments, ILCommentPrefix);
@ -253,7 +255,7 @@ exports.beautify = beautify;
function replaceEscapedWords(input, arr, prefix) {
for (var i = 0; i < arr.length; i++) {
var text = arr[i];
var regex = new RegExp(prefix + "{" + text.length + "}");
var regex = new RegExp("(" + prefix + "){" + text.length + "}");
input = input.replace(regex, text);
}
return input;
@ -281,6 +283,9 @@ function FormattedLineToString(arr, indentation) {
if (arr == null) {
return result;
}
if (indentation == null) {
indentation = "";
}
arr.forEach(i => {
if (i instanceof FormattedLine) {
if (i.Line.length > 0) {


+ 20
- 16
VHDLFormatter.ts View File

@ -152,24 +152,20 @@ function ReplaceKeyWords(text: string, keywords: Array<string>): string {
return text;
}
function SetKeywordCase(input: string, keywordcase: string, keywords: string[], typenames: string[]): string {
function SetKeywordCase(input: string, keywordcase: string, keywords: string[]): string {
let inputcase: string = keywordcase.toLowerCase();
switch (keywordcase.toLowerCase()) {
switch (inputcase) {
case "lowercase":
ToLowerCases(keywords);
ToLowerCases(typenames);
break;
case "defaultcase":
ToCamelCases(keywords);
ToCamelCases(typenames);
break;
case "uppercase":
ToUpperCases(keywords);
ToUpperCases(typenames);
}
input = ReplaceKeyWords(input, keywords);
input = ReplaceKeyWords(input, typenames);
return input;
}
@ -203,11 +199,12 @@ export class BeautifierSettings {
SignAlignAll: boolean;
SignAlignKeyWords: Array<string>;
KeywordCase: string;
TypeNameCase: string;
Indentation: string;
NewLineSettings: NewLineSettings;
EndOfLine: string;
constructor(removeComments: boolean, removeReport: boolean, checkAlias: boolean,
signAlign: boolean, signAlignAll: boolean, keywordCase: string, indentation: string,
signAlign: boolean, signAlignAll: boolean, keywordCase: string, typeNameCase: string, indentation: string,
newLineSettings: NewLineSettings, endOfLine: string) {
this.RemoveComments = removeComments;
this.RemoveAsserts = removeReport;
@ -215,6 +212,7 @@ export class BeautifierSettings {
this.SignAlignRegional = signAlign;
this.SignAlignAll = signAlignAll;
this.KeywordCase = keywordCase;
this.TypeNameCase = typeNameCase;
this.Indentation = indentation;
this.NewLineSettings = newLineSettings;
this.EndOfLine = endOfLine;
@ -241,7 +239,8 @@ export function beautify(input: string, settings: BeautifierSettings) {
comments = [];
}
input = SetKeywordCase(input, "uppercase", KeyWords, TypeNames);
input = SetKeywordCase(input, "uppercase", KeyWords);
input = SetKeywordCase(input, "uppercase", TypeNames);
input = RemoveExtraNewLines(input);
input = input.replace(/[\t ]+/g, ' ');
input = input.replace(/\([\t ]+/g, '\(');
@ -256,11 +255,13 @@ export function beautify(input: string, settings: BeautifierSettings) {
input = arr.join("\r\n");
input = input.replace(/(PORT|GENERIC)\s+MAP/g, '$1 MAP');
input = input.replace(/(PORT|PROCESS|GENERIC)[\s]*\(/g, '$1 (');
input = SetNewLinesAfterSymbols(input, settings.NewLineSettings);
arr = input.split("\r\n");
ApplyNoNewLineAfter(arr, settings.NewLineSettings.noNewLineAfter);
input = arr.join("\r\n");
let newLineSettings = settings.NewLineSettings;
if (newLineSettings != null) {
input = SetNewLinesAfterSymbols(input, newLineSettings);
arr = input.split("\r\n");
ApplyNoNewLineAfter(arr, newLineSettings.noNewLineAfter);
input = arr.join("\r\n");
}
input = input.replace(/([a-zA-Z0-9\); ])\);(@@comments[0-9]+)?@@end/g, '$1\r\n);$2@@end');
input = input.replace(/[ ]?([&=:\-<>\+|\*])[ ]?/g, ' $1 ');
@ -292,13 +293,13 @@ export function beautify(input: string, settings: BeautifierSettings) {
arr = FormattedLineToString(result, settings.Indentation);
input = arr.join("\r\n");
input = SetKeywordCase(input, settings.KeywordCase, KeyWords, TypeNames);
input = SetKeywordCase(input, settings.KeywordCase, KeyWords);
input = SetKeywordCase(input, settings.TypeNameCase, TypeNames);
input = replaceEscapedWords(input, quotes, ILQuote);
input = replaceEscapedWords(input, singleQuotes, ILSingleQuote);
input = replaceEscapedComments(input, comments, ILCommentPrefix);
input = replaceEscapedWords(input, backslashes, ILBackslash);
input = input.replace(new RegExp(ILSemicolon, "g"), ";");
input = input.replace(/@@[a-z]+/g, "");
var escapedTexts = new RegExp("[" + ILBackslash + ILQuote + ILSingleQuote + "]", "g");
@ -310,7 +311,7 @@ export function beautify(input: string, settings: BeautifierSettings) {
function replaceEscapedWords(input: string, arr: Array<string>, prefix: string): string {
for (var i = 0; i < arr.length; i++) {
var text = arr[i];
var regex = new RegExp(prefix + "{" + text.length + "}");
var regex = new RegExp("(" + prefix + "){" + text.length + "}");
input = input.replace(regex, text);
}
return input;
@ -343,6 +344,9 @@ export function FormattedLineToString(arr: (FormattedLine | FormattedLine[])[],
if (arr == null) {
return result;
}
if (indentation == null) {
indentation = "";
}
arr.forEach(i => {
if (i instanceof FormattedLine) {
if (i.Line.length > 0) {


+ 25
- 1
index.html View File

@ -1,6 +1,7 @@
<html>
<head>
<meta charset="UTF-8">
<title>VHDL Beautifier, Formatter Online</title>
<style>
body {
@ -201,6 +202,12 @@
.checkbox input[type="checkbox"]:focus+label::before {
outline: #333 auto 5px;
}
.inline-note {
color: #888;
margin-left: 10px;
display: inline-block;
}
</style>
<link href="highlight.css" rel="stylesheet" />
<script src="highlight.js"></script>
@ -240,13 +247,27 @@
<input type="checkbox" id="no_format" onclick="noFormat()">
<label for="no_format">Only highlight, don't format</label>
</div>
<form id="keyword">Keyword Case:
<form id="keyword">Keyword case:
<label>
<input type="radio" name="keywordcase" value="UpperCase" checked="checked">UPPERCASE</label> |
<label>
<input type="radio" name="keywordcase" value="LowerCase">lowercase</label> |
<label>
<input type="radio" name="keywordcase" value="DefaultCase">Default</label>
<div class="inline-note">
e.g. begin, case, when
</div>
</form>
<form id="typename">Type name case:
<label>
<input type="radio" name="typenamecase" value="UpperCase" checked="checked">UPPERCASE</label> |
<label>
<input type="radio" name="typenamecase" value="LowerCase">lowercase</label> |
<label>
<input type="radio" name="typenamecase" value="DefaultCase">Default</label>
<div class="inline-note">
e.g. boolean, natural, string
</div>
</form>
<fieldset id="new_line_after_div">
<legend>New line after</legend>
@ -459,6 +480,7 @@
document.getElementById("use_space").checked = indentation != "\t";
document.getElementById("customise_indentation").value = indentation;
document.getElementById("keyword").elements.namedItem("keywordcase").value = beautifierSettings.KeywordCase;
document.getElementById("typename").elements.namedItem("typenamecase").value = beautifierSettings.TypeNameCase;
document.getElementById("mix_letter").checked = setting.mixLetter;
var eof = beautifierSettings.EndOfLine
eof = eof.replace(/\r/g, "\\r");
@ -514,6 +536,7 @@
var compress = document.getElementById("compress").checked;
var cust_indent = document.getElementById("customise_indentation").value;
var keywordcase = document.getElementById("keyword").elements.namedItem("keywordcase").value;
var typenamecase = document.getElementById("typename").elements.namedItem("typenamecase").value;
var mix_letter = document.getElementById("mix_letter").checked;
var endOfLine = document.getElementById("cust_eol").value;
endOfLine = endOfLine.replace(/\\r/g, "\r");
@ -556,6 +579,7 @@
beautifierSettings = new BeautifierSettings(remove_comments, remove_report, check_alias, sign_align,
sign_align_all,
keywordcase,
typenamecase,
indentation,
newLineSettings,
endOfLine);


+ 28
- 5
tests/VHDLFormatterUnitTests.ts View File

@ -917,6 +917,8 @@ function IntegrationTest() {
IntegrationTest76();
IntegrationTest77();
IntegrationTest78();
IntegrationTest79();
IntegrationTest80();
}
function IntegrationTest23() {
@ -1078,6 +1080,7 @@ function IntegrationTest44() {
function IntegrationTest45() {
let settings = GetDefaultSettings();
settings.KeywordCase = "lowercase";
settings.TypeNameCase = "lowercase";
settings.Indentation = " ";
let input = 'REPORT\n"A_ARITH_MOD_tester.main Tester is now ready. A total OF " &\nINTEGER\'image(totalTests) & " tests have been detected.";';
let expected = 'report\r\n "A_ARITH_MOD_tester.main Tester is now ready. A total OF " &\r\n integer\'image(totalTests) & " tests have been detected.";';
@ -1088,6 +1091,7 @@ function IntegrationTest45() {
function IntegrationTest46() {
let settings = GetDefaultSettings();
settings.KeywordCase = "lowercase";
settings.TypeNameCase = "lowercase";
let input = 'impure function delay(\r\n l : integer\r\n) return time is\r\n variable r : real;\r\nbegin\r\n result := 2ps;\r\n return result;\r\nend function;';
let actual = beautify(input, settings);
assertAndCountTest("impure function indent", input, actual);
@ -1096,6 +1100,7 @@ function IntegrationTest46() {
function IntegrationTest47() {
let settings = GetDefaultSettings();
settings.KeywordCase = "lowercase";
settings.TypeNameCase = "lowercase";
settings.Indentation = " ";
let input = 'result := 1\r\n 1\r\n + 1; -- hello';
let actual = beautify(input, settings);
@ -1105,6 +1110,7 @@ function IntegrationTest47() {
function IntegrationTest48() {
let settings = GetDefaultSettings();
settings.KeywordCase = "lowercase";
settings.TypeNameCase = "lowercase";
let input = 'function delay(\r\n l : integer\r\n) return time is\r\n variable r : real;\r\nbegin\r\n result := 2ps;\r\n return result;\r\nend function;';
let actual = beautify(input, settings);
assertAndCountTest("function indent", input, actual);
@ -1139,6 +1145,7 @@ function IntegrationTest51() {
function IntegrationTest52() {
let settings = GetDefaultSettings();
settings.KeywordCase = "lowercase";
settings.TypeNameCase = "lowercase";
let input = 'function a(\r\n b : integer\r\n c : integer\r\n) return integer;\r\n\r\nimpure function a(\r\n b : integer\r\n c : integer\r\n) return integer;\r\n\r\nfunction a(\r\n b : integer\r\n c : integer\r\n) return integer;';
let actual = beautify(input, settings);
assertAndCountTest("function without sequential statements", input, actual);
@ -1147,6 +1154,7 @@ function IntegrationTest52() {
function IntegrationTest53() {
let settings = GetDefaultSettings();
settings.KeywordCase = "lowercase";
settings.TypeNameCase = "lowercase";
let input = 'function a(\r\n b : integer\r\n c : integer\r\n) return integer;\r\n\r\nimpure function a(\r\n b : integer\r\n c : integer\r\n) return integer;\r\n\r\nfunction a(\r\n b : integer\r\n c : integer\r\n) return integer;';
let actual = beautify(input, settings);
assertAndCountTest("function without sequential statements, without new line", input, actual);
@ -1185,6 +1193,7 @@ function IntegrationTest57() {
function IntegrationTest58() {
let settings = GetDefaultSettings();
settings.KeywordCase = "lowercase";
settings.TypeNameCase = "lowercase";
let input = 'package body a is\r\n procedure b(\r\n signal a : in boolean;\r\n b : boolean\r\n ) is\r\n begin\r\n a = 1\r\n end procedure b;\r\nend a;';
let actual = beautify(input, settings);
assertAndCountTest("package body", input, actual);
@ -1193,6 +1202,7 @@ function IntegrationTest58() {
function IntegrationTest59() {
let settings = GetDefaultSettings();
settings.KeywordCase = "lowercase";
settings.TypeNameCase = "lowercase";
let input = 'package body a is\r\n procedure b(\r\n signal a : in boolean;\r\n b : boolean) is\r\n begin\r\n a = 1\r\n end procedure b;\r\nend a;';
let actual = beautify(input, settings);
assertAndCountTest("package body 2", input, actual);
@ -1343,19 +1353,32 @@ function IntegrationTest76() {
function IntegrationTest77() {
let settings = GetDefaultSettings();
settings.SignAlignAll = true;
let input = "WHEN -2;\r\nSIGNAL +0;";
let actual = beautify(input, settings);
assertAndCountTest("negative sign and number", input, actual);
assertAndCountTest("negative sign and number after key word", input, actual);
}
function IntegrationTest78() {
let settings = GetDefaultSettings();
settings.SignAlignAll = true;
let input = "sfixed(4 downto - 18);\r\nx <= to_sfixed( - 2.3, x);\r\nresize(x + 1, 4, - 18) when others;";
let expected = "sfixed(4 DOWNTO -18);\r\nx <= to_sfixed(-2.3, x);\r\nresize(x + 1, 4, -18) WHEN OTHERS;";
let actual = beautify(input, settings);
assertAndCountTest("negative sign and number", expected, actual);
assertAndCountTest("negative sign and number after symbol", expected, actual);
}
function IntegrationTest79() {
let settings = new BeautifierSettings(false, false, false, false, false, "lowercase", "uppercase", null, null, "\r\n");
settings.SignAlignAll = true;
let input = "case when others;\r\nx : STRING;\r\ny : BIT;";
let actual = beautify(input, settings);
assertAndCountTest("uppercase typename and lowercase keyword", input, actual);
}
function IntegrationTest80() {
let settings = GetDefaultSettings();
let input = 'FUNCTION "abs" (arg : sfixed) RETURN sfixed;';
let actual = beautify(input, settings);
assertAndCountTest("function name in quotes", input, actual);
}
function GetDefaultSettings(indentation: string = " "): BeautifierSettings {
@ -1367,7 +1390,7 @@ function GetDefaultSettings(indentation: string = " "): BeautifierSettings {
}
function getDefaultBeautifierSettings(newLineSettings: NewLineSettings, indentation: string = " "): BeautifierSettings {
return new BeautifierSettings(false, false, false, false, false, "uppercase", indentation, newLineSettings, "\r\n");
return new BeautifierSettings(false, false, false, false, false, "uppercase", "uppercase", indentation, newLineSettings, "\r\n");
}
function IntegrationTest20() {


Loading…
Cancel
Save