Browse Source

* refactored code generator (improved code indent)

master
Bergmann89 9 years ago
parent
commit
4c018e3f6e
4 changed files with 159 additions and 102 deletions
  1. +0
    -11
      tests/ShaderFileTests.lpi
  2. +2
    -2
      tests/testfiles/result_IfElifElseEnd_Inline_0.shdr
  3. +2
    -2
      tests/testfiles/result_IfElifElseEnd_Inline_1.shdr
  4. +155
    -87
      uengShaderGeneratorArgs.pas

+ 0
- 11
tests/ShaderFileTests.lpi View File

@@ -56,32 +56,26 @@
<Unit3>
<Filename Value="..\uengShaderFileTypes.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderFileTypes"/>
</Unit3>
<Unit4>
<Filename Value="..\uengShaderFile.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderFile"/>
</Unit4>
<Unit5>
<Filename Value="..\uengShaderGenerator.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderGenerator"/>
</Unit5>
<Unit6>
<Filename Value="..\uengShaderFileConstants.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderFileConstants"/>
</Unit6>
<Unit7>
<Filename Value="..\uengShaderFileExpression.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderFileExpression"/>
</Unit7>
<Unit8>
<Filename Value="..\uengShaderFileHelper.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderFileHelper"/>
</Unit8>
<Unit9>
<Filename Value="..\uengShaderFileParser.pas"/>
@@ -90,7 +84,6 @@
<Unit10>
<Filename Value="..\uengShaderFileScope.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderFileScope"/>
</Unit10>
<Unit11>
<Filename Value="..\uengShaderGeneratorArgs.pas"/>
@@ -120,7 +113,6 @@
<Unit17>
<Filename Value="..\uengShaderPartIf.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderPartIf"/>
</Unit17>
<Unit18>
<Filename Value="..\uengShaderPartInclude.pas"/>
@@ -141,12 +133,10 @@
<Unit22>
<Filename Value="..\uengShaderPartParameter.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderPartParameter"/>
</Unit22>
<Unit23>
<Filename Value="..\uengShaderPartProc.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderPartProc"/>
</Unit23>
<Unit24>
<Filename Value="..\uengShaderPartScope.pas"/>
@@ -159,7 +149,6 @@
<Unit26>
<Filename Value="..\uengShaderCodePart.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uengShaderCodePart"/>
</Unit26>
</Units>
</ProjectOptions>


+ 2
- 2
tests/testfiles/result_IfElifElseEnd_Inline_0.shdr View File

@@ -1,4 +1,4 @@
some code here = this code;
some code here =
this code *
more code;
this code *
more code;

+ 2
- 2
tests/testfiles/result_IfElifElseEnd_Inline_1.shdr View File

@@ -1,4 +1,4 @@
some code here = that code;
some code here =
that code *
more code;
that code *
more code;

+ 155
- 87
uengShaderGeneratorArgs.pas View File

@@ -148,6 +148,69 @@ uses
const
WHITESPACES = [' ', #9];

type
TCodeBlock = class(TStringList)
private
function GetLast: String;
function GetDepth(const aIndex: Integer): Integer;
procedure SetLast(aValue: String);
procedure SetDepth(const aIndex: Integer; aValue: Integer);
public
property Last: String read GetLast write SetLast;
property Depth[const aIndex: Integer]: Integer read GetDepth write SetDepth;

function Add(const aString: String; const aDepth: Integer): Integer; reintroduce;
procedure Clear; override;

constructor Create;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TCodeBlock////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TCodeBlock.GetLast: String;
begin
result := Get(Count-1);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TCodeBlock.GetDepth(const aIndex: Integer): Integer;
begin
result := PtrInt(Objects[aIndex]);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TCodeBlock.SetLast(aValue: String);
begin
Put(Count-1, aValue);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TCodeBlock.SetDepth(const aIndex: Integer; aValue: Integer);
begin
Objects[aIndex] := TObject(PtrInt(aValue));
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TCodeBlock.Add(const aString: String; const aDepth: Integer): Integer;
begin
result := inherited AddObject(aString, TObject(PtrInt(aDepth)));
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TCodeBlock.Clear;
begin
inherited Clear;
Add('', 0);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TCodeBlock.Create;
begin
inherited Create;
Clear;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderGeneratorArgs.TCodePart///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -204,7 +267,6 @@ type
gfToken, // current line has a token in it
gfTokenOnly, // current line has only a token (or whitespaces) in it
gfPrevIsEmpty, // previouse line was empty (or whitespaces only)
gfCodeIsEmpty, // nothing has added to code
gfAddToPrev // add current line to previouse line
);
TGenFlags = set of TGenFlag;
@@ -212,124 +274,117 @@ type
var
i: Integer;
f: TGenFlags;
line: String;
cb: TCodeBlock;

function GetStrOffset(const aStr: String): Integer;
function GetCurrentIndent(const aStr: String): Integer;
var
len: Integer;
begin
result := 0;
len := Length(aStr);
while (result < len) and (aStr[result+1] in WHITESPACES) do
inc(result);
end;

function GetOffset(const aCodePart: TCodePart): Integer;
begin
result := GetStrOffset(line);
end;

function GetMinOffset(aStartIndex: Integer): Integer;
begin
if (Trim(line) <> '')
then result := GetStrOffset(line)
else result := High(Integer);
while (aStartIndex < aCode.Count) do begin
if (Trim(aCode[aStartIndex]) <> '') then
result := Min(result, GetStrOffset(aCode[aStartIndex]));
inc(aStartIndex);
end;
if (result >= High(Integer)) then
result := 0;
if (Trim(aStr) <> '') then begin
result := 1;
len := Length(aStr);
while (result <= len) and (aStr[result] in WHITESPACES) do
inc(result);
dec(result);
end else
result := High(Integer);
end;

function TrimLeftLen(const aStr: String; aLen: Integer): String;
function IndentStr(const aStr: String; const aIndent: Integer): String;
var
i, len: Integer;
begin
i := 1;
len := Length(aStr);
while (i <= len) and (aStr[i] in WHITESPACES) and (aLen > 0) do begin
inc(i);
dec(aLen);
end;
result := Copy(aStr, i, len - i + 1);
end;

function PrepareStr(const aStr: String; const aOffset: Integer): String;
i, l: Integer;
begin
if (aOffset > 0)
then result := StringOfChar(' ', aOffset) + aStr
else result := TrimLeftLen(aStr, -aOffset);
if (aIndent < 0) then begin
i := 1;
l := Length(aStr);
while (i <= l) and (i <= -aIndent) and (aStr[i] in WHITESPACES) do
inc(i);
result := copy(aStr, i, l - i + 1);
end else if (aIndent > 0) then
result := StringOfChar(' ', aIndent) + aStr
else
result := aStr;
end;

procedure IndentBlock(aStartIndex: Integer; const aIndent: Integer);
procedure IndentBlock(aDepth, aIndent: Integer);
var
o: Integer;
i, minCurIndent: Integer;
begin
o := aIndent - GetMinOffset(aStartIndex);
while (aStartIndex < aCode.Count) do begin
aCode[aStartIndex] := PrepareStr(aCode[aStartIndex], o);
inc(aStartIndex);
i := cb.Count-1;
minCurIndent := High(Integer);
while (i >= 0) and (cb.Depth[i] = aDepth) do begin
minCurIndent := min(minCurIndent, GetCurrentIndent(cb[i]));
dec(i);
end;
inc(i);
aIndent := aIndent - minCurIndent;
while (i < cb.Count) do begin
cb[i] := IndentStr(cb[i], aIndent);
cb.Depth[i] := cb.Depth[i] - 1;
inc(i);
end;
if (Trim(line) <> '') then
line := PrepareStr(line, o);
end;

procedure ProgressBlock(const aIndent: Integer);
procedure ProgressBlock(const aIndent, aDepth: Integer);
var
s: String;
cp: TCodePart;
FirstLineIndex: Integer;
tmp: Integer;
begin
FirstLineIndex := aCode.Count;
while (i < fItems.Count) do begin
cp := fItems[i];
inc(i);

if (Trim(cb.Last) = '') then
cb.Depth[cb.Count-1] := aDepth;

case cp.Token of
gtLineBreak: begin
if (Trim(line) = '') then begin
if (Trim(cb.Last) = '') then begin
if (f * [gfTokenOnly, gfPrevIsEmpty] = []) then begin
aCode.Add(line);
Include(f, gfPrevIsEmpty);
end;
cb.Add('', aDepth);
end else
cb.Last := '';
end else begin
if (gfAddToPrev in f) and not (gfCodeIsEmpty in f)
then aCode[aCode.Count-1] := aCode[aCode.Count-1] + TrimLeft(line)
else aCode.Add(line);
if (gfAddToPrev in f) and (cb.Count >= 2) then begin
cb[cb.Count-2] := cb[cb.Count-2] + TrimLeft(cb.Last);
cb.Last := '';
end else
cb.Add('', aDepth);
Exclude(f, gfPrevIsEmpty);
Exclude(f, gfCodeIsEmpty);
end;
Exclude(f, gfToken);
Exclude(f, gfTokenOnly);
Exclude(f, gfAddToPrev);
line := '';
f := f - [gfToken, gfTokenOnly, gfAddToPrev];
end;

gtToken: begin
Include(f, gfToken);
if (Trim(line) = '') then
if (Trim(cb.Last) = '') then
Include(f, gfTokenOnly);
end;

gtBlockBegin: begin
Include(f, gfPrevIsEmpty);
ProgressBlock(GetStrOffset(line) + cp.Indent);
tmp := GetCurrentIndent(cb.Last);
if (tmp <> High(Integer))
then tmp := aIndent + tmp
else tmp := aIndent;
if (Trim(cb.Last) <> '') then
inc(tmp, 4);
inc(tmp, cp.Indent);
ProgressBlock(tmp, aDepth + 1);
end;

gtBlockEnd: begin
IndentBlock(FirstLineIndex, aIndent);
IndentBlock(aDepth, aIndent);
exit;
end;

gtAppendToPrev: begin
if (Trim(line) = '') and not (gfPrevIsEmpty in f) then
if (Trim(cb.Last) = '') and not (gfPrevIsEmpty in f) then
include(f, gfAddToPrev);
end;
else
s := cp.Code;
line := line + s;
cb.Last := cb.Last + cp.Code;
end;
end;
end;
@@ -339,29 +394,43 @@ var
var
cp: TCodePart;
s: String;
sl: TStringList;
begin
s := '';
for cp in fItems do
s := s + cp.DebugText;
sl := TStringList.Create;
try
sl.Text := s;
sl.SaveToFile('C:\Users\Erik\Desktop\tmp\debug.txt');
finally
FreeAndNil(sl);
end;
aCode.Text := aCode.Text + s + sLineBreak + sLineBreak;
end;
{$ENDIF}

var
s, e: Integer;
begin
i := 0;
f := [gfPrevIsEmpty, gfCodeIsEmpty];
line := '';
{$IFDEF DEBUG}
GenerateDebugCode;
{$ENDIF}
ProgressBlock(0);

i := 0;
f := [gfPrevIsEmpty];
cb := TCodeBlock.Create;
try
ProgressBlock(0, 0);
s := 0;
e := cb.Count-1;
while (s < cb.Count) and (Trim(cb[s]) = '') do
inc(s);
while (e >= 0) and (Trim(cb[e]) = '') do
dec(e);
for i := s to e do
aCode.Add(
{$IFDEF DEBUG}
Format('[%02d]%s', [cb.Depth[i], cb[i]])
{$ELSE}
cb[i]
{$ENDIF}
);
finally
FreeAndNil(cb);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -737,10 +806,9 @@ begin
// insert temp variable
s := Format('%s_ret%.4d', [aName, fInlineReturnCounter]);
inc(fInlineReturnCounter);
csi.Items.Insert(i, TCodePart.Create(gtLineBreak, ''));
csi.Items.Insert(i+1, TCodePart.Create(gtNormal, aRetType + ' ' + s));
csi.Items.Insert(i+2, TCodePart.Create(gtCommandEnd, ';'));
csi.Items.Insert(i+3, TCodePart.Create(gtLineBreak, ''));
csi.Items.Insert(i+0, TCodePart.Create(gtNormal, aRetType + ' ' + s));
csi.Items.Insert(i+1, TCodePart.Create(gtCommandEnd, ';'));
csi.Items.Insert(i+2, TCodePart.Create(gtLineBreak, ''));

// replace "return" with temp variable
for cp in csi.Items do


Loading…
Cancel
Save