瀏覽代碼

* implemented unit tests for $INHERITED and fixed some issues

master
Bergmann89 11 年之前
父節點
當前提交
427f7962f1
共有 15 個文件被更改,包括 429 次插入 和 128 次删除
  1. +36
    -0
      tests/testfiles/code_Class_InheritedFunc.shdr
  2. +19
    -0
      tests/testfiles/code_Class_InheritedMain.shdr
  3. +27
    -0
      tests/testfiles/result_Class_InheritedFunc.shdr
  4. +16
    -0
      tests/testfiles/result_Class_InheritedMain.shdr
  5. +12
    -0
      tests/uShaderFileTestCase.pas
  6. +1
    -1
      uengShaderFile.inc
  7. +1
    -1
      uengShaderFileConstants.pas
  8. +1
    -1
      uengShaderFileExpression.pas
  9. +52
    -14
      uengShaderFileHelper.pas
  10. +90
    -54
      uengShaderGeneratorArgs.pas
  11. +140
    -36
      uengShaderPartCall.pas
  12. +1
    -1
      uengShaderPartClass.pas
  13. +0
    -1
      uengShaderPartEcho.pas
  14. +0
    -1
      uengShaderPartKeyValuePair.pas
  15. +33
    -18
      uengShaderPartProc.pas

+ 36
- 0
tests/testfiles/code_Class_InheritedFunc.shdr 查看文件

@@ -0,0 +1,36 @@
{$STATIC BaseVec 'vec2(0.0)'}

{$CLASS Base1}
{$FUNC 'vec2' 'TestProc' 'vec2' 'aVec'}
vec2 tmp = aVec;
tmp += vec2(1.0);
return tmp;
{$END}
{$END}

{$CLASS Base2}
{$FUNC 'vec2' 'TestProc' 'vec2' 'aVec'}
return aVec + vec2(1.0);
{$END}
{$END}

{$CLASS SimpleClass $EXTENDS Base1 Base2}
{$UNIFORM 'sampler2D' 'uTexture0'}
{$UNIFORM 'sampler2D' 'uTexture1'}
{$UNIFORM 'vec4' 'uColor'}
{$FUNC 'vec2' 'TestProc' 'vec2' 'aVec'}
vec2 v = aVec;
v = {$INHERITED Base1 TestProc BaseVec $INLINE};
v = {$INHERITED Base2 'v'};
return v;
{$END}
{$MAIN}
vec2 texCoord = {$CALL TestProc 'gl_TexCoord[0]'};
gl_FragColor =
texture2D(uTexture0, texCoord) *
texture2D(uTexture1, texCoord) *
uColor;
{$END}
{$END}

+ 19
- 0
tests/testfiles/code_Class_InheritedMain.shdr 查看文件

@@ -0,0 +1,19 @@
{$CLASS Base1}
{$MAIN}
gl_FragColor.r = 1.0;
{$END}
{$END}

{$CLASS Base2}
{$MAIN}
gl_FragColor.g = 1.0;
{$END}
{$END}

{$CLASS SimpleClass $EXTENDS Base1 Base2}
{$MAIN}
{$INHERITED Base1};
{$INHERITED Base2};
gl_FragColor.ba = vec2(1.0);
{$END}
{$END}

+ 27
- 0
tests/testfiles/result_Class_InheritedFunc.shdr 查看文件

@@ -0,0 +1,27 @@
uniform sampler2D uTexture0;
uniform sampler2D uTexture1;
uniform vec4 uColor;

vec2 Base2_TestProc(vec2 aVec)
{
return aVec + vec2(1.0);
}

vec2 SimpleClass_TestProc(vec2 aVec)
{
vec2 v = aVec;
vec2 tmp = (vec2(0.0));
tmp += vec2(1.0);
v = (tmp);
v = Base2_TestProc(v);
return v;
}

void main(void)
{
vec2 texCoord = SimpleClass_TestProc(gl_TexCoord[0]);
gl_FragColor =
texture2D(uTexture0, texCoord) *
texture2D(uTexture1, texCoord) *
uColor;
}

+ 16
- 0
tests/testfiles/result_Class_InheritedMain.shdr 查看文件

@@ -0,0 +1,16 @@
void Base2_main(void)
{
gl_FragColor.g = 1.0;
}

void Base1_main(void)
{
gl_FragColor.r = 1.0;
}

void main(void)
{
Base1_main();
Base2_main();
gl_FragColor.ba = vec2(1.0);
}

+ 12
- 0
tests/uShaderFileTestCase.pas 查看文件

@@ -48,6 +48,8 @@ type
TTestCase_Class = class(TShaderFileTestCase) TTestCase_Class = class(TShaderFileTestCase)
published published
procedure Simple; procedure Simple;
procedure InheritedFunc;
procedure InheritedMain;
end; end;


implementation implementation
@@ -194,6 +196,16 @@ begin
DoTest('code_Class_Simple.shdr', 'SimpleClass', 'result_Class_Simple.shdr'); DoTest('code_Class_Simple.shdr', 'SimpleClass', 'result_Class_Simple.shdr');
end; end;


procedure TTestCase_Class.InheritedFunc;
begin
DoTest('code_Class_InheritedFunc.shdr', 'SimpleClass', 'result_Class_InheritedFunc.shdr');
end;

procedure TTestCase_Class.InheritedMain;
begin
DoTest('code_Class_InheritedMain.shdr', 'SimpleClass', 'result_Class_InheritedMain.shdr');
end;

initialization initialization
RegisterTest(TTestCase_IfElifElseEnd); RegisterTest(TTestCase_IfElifElseEnd);
RegisterTest(TTestCase_FuncProcMain); RegisterTest(TTestCase_FuncProcMain);


+ 1
- 1
uengShaderFile.inc 查看文件

@@ -1,3 +1,3 @@
{.$DEFINE EXPRESSION_ADD_BRACKET} // add brackets to expressions {.$DEFINE EXPRESSION_ADD_BRACKET} // add brackets to expressions
{$DEFINE USE_BITSPACE_UTILS} // use bitSpace Utils {$DEFINE USE_BITSPACE_UTILS} // use bitSpace Utils
{$DEFINE DEBUG} // enable debug output
{.$DEFINE DEBUG} // enable debug output

+ 1
- 1
uengShaderFileConstants.pas 查看文件

@@ -25,7 +25,7 @@ const


TOKEN_CLASS = TOKEN_CHAR_IDENT + 'CLASS'; //{$CLASS PhongLight $EXTENDS Normal Glow} TOKEN_CLASS = TOKEN_CHAR_IDENT + 'CLASS'; //{$CLASS PhongLight $EXTENDS Normal Glow}
TOKEN_EXTENDS = TOKEN_CHAR_IDENT + 'EXTENDS'; TOKEN_EXTENDS = TOKEN_CHAR_IDENT + 'EXTENDS';
TOKEN_INHERITED = TOKEN_CHAR_IDENT + 'INHERITED'; //{$INHERITED BaseClassMethod 'param1' 'param2'}
TOKEN_INHERITED = TOKEN_CHAR_IDENT + 'INHERITED'; //{$INHERITED BaseClass MethodName 'param1' 'param2' $INLINE}


TOKEN_INCLUDE = TOKEN_CHAR_IDENT + 'INCLUDE'; //{$INCLUDE 'Normal.frag'} TOKEN_INCLUDE = TOKEN_CHAR_IDENT + 'INCLUDE'; //{$INCLUDE 'Normal.frag'}




+ 1
- 1
uengShaderFileExpression.pas 查看文件

@@ -693,7 +693,7 @@ begin
walker := TengKeyValuePairSearchWalker.Create(sr); walker := TengKeyValuePairSearchWalker.Create(sr);
try try
walker.Name := param.Name; walker.Name := param.Name;
walker.SearchFlags := [sfSearchChildrenLazy, sfSearchParents];
walker.SearchFlags := [sfSearchChildren, sfSearchParents];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty, TengShaderPartStatic); walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty, TengShaderPartStatic);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope); walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile); walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);


+ 52
- 14
uengShaderFileHelper.pas 查看文件

@@ -6,7 +6,7 @@ unit uengShaderFileHelper;
interface interface


uses uses
uengShaderPart, uengShaderFileParser;
uengShaderPart, uengShaderFileParser, uengShaderPartClass;


type type
TInfoFlag = ( TInfoFlag = (
@@ -83,6 +83,16 @@ type
property Name: String read fName write fName; property Name: String read fName write fName;
end; end;


TengInheritedSearchWalker = class(TengSearchWalker)
private
fName: String;
protected
function Check(const aPart: TengShaderPart): Boolean; override;
public
property Name: String read fName write fName;
constructor Create(const aClass: TengShaderPartClass; const aResults: TengSearchResults);
end;

TengProcSearchWalker = class(TengSearchWalker) TengProcSearchWalker = class(TengSearchWalker)
private private
fName: String; fName: String;
@@ -98,7 +108,7 @@ implementation
uses uses
sysutils, sysutils,
uengShaderFileConstants, uengShaderFileTypes, uengShaderPartKeyValuePair, uengShaderPartProc, uengShaderFileConstants, uengShaderFileTypes, uengShaderPartKeyValuePair, uengShaderPartProc,
uengShaderPartIf, uengShaderPartClass;
uengShaderPartIf;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function IsValidIdentifier(const aIdent: String): Boolean; function IsValidIdentifier(const aIdent: String): Boolean;
@@ -195,14 +205,12 @@ end;
//TengSearchWalker////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengSearchWalker//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengSearchWalker.Visit(const aPart, aSender: TengShaderPart; const aArgs: Pointer); procedure TengSearchWalker.Visit(const aPart, aSender: TengShaderPart; const aArgs: Pointer);
var
args: TArgs;


function VisitChild(const aItem: TengShaderPart): Boolean; function VisitChild(const aItem: TengShaderPart): Boolean;
var var
c: CengShaderPart; c: CengShaderPart;
begin begin
result := (sfSearchChildren in args.Flags) and Assigned(aItem) and (aItem <> aSender);
result := Assigned(aItem) and (aItem <> aSender);
if not result then if not result then
exit; exit;
for c in fChildrenDoNotLeave do for c in fChildrenDoNotLeave do
@@ -217,7 +225,7 @@ var
var var
c: CengShaderPart; c: CengShaderPart;
begin begin
result := (sfSearchParents in args.Flags) and Assigned(aPart.Parent) and (aPart.Parent <> aSender);
result := Assigned(aPart.Parent) and (aPart.Parent <> aSender);
if not result then if not result then
exit; exit;
for c in fParentsDoNotLeave do for c in fParentsDoNotLeave do
@@ -231,6 +239,7 @@ var
var var
p: TengShaderPart; p: TengShaderPart;
c: TengShaderPartClass; c: TengShaderPartClass;
args: TArgs;
nextArgs: TArgs; nextArgs: TArgs;
begin begin
if not Assigned(aPart) then if not Assigned(aPart) then
@@ -240,23 +249,31 @@ begin
else else
args.Flags := fSearchFlags; args.Flags := fSearchFlags;


// visit parent
// calculate args for next iteration
nextArgs := args; nextArgs := args;
if (sfSearchChildrenLazy in nextArgs.Flags) then if (sfSearchChildrenLazy in nextArgs.Flags) then
nextArgs.Flags := nextArgs.Flags + [sfSearchChildren] - [sfSearchChildrenLazy]; nextArgs.Flags := nextArgs.Flags + [sfSearchChildren] - [sfSearchChildrenLazy];
if Check(aPart.Parent) then
fResults.Add(aPart.Parent);
if VisitParent then
Visit(aPart.Parent, aPart, @nextArgs);


// visit inherited
// sfSearchParents
if (sfSearchParents in args.Flags) then begin
if Check(aPart.Parent) then
fResults.Add(aPart.Parent);
if VisitParent then
Visit(aPart.Parent, aPart, @nextArgs);
end;

// sfSearchInherited
if (sfSearchInherited in args.Flags) and (aPart is TengShaderPartClass) then begin if (sfSearchInherited in args.Flags) and (aPart is TengShaderPartClass) then begin
for c in (aPart as TengShaderPartClass).InheritedClasses do
for c in (aPart as TengShaderPartClass).InheritedClasses do begin
if Check(c) then
fResults.Add(c);
Visit(c, aPart, @nextArgs); Visit(c, aPart, @nextArgs);
end;
end; end;


// visit children
// sfSearchChildren
if (sfSearchChildren in args.Flags) then begin if (sfSearchChildren in args.Flags) then begin
// sfEvaluateIf, sfIgnoreIf
if (aPart is TengShaderPartIf) then with (aPart as TengShaderPartIf) do begin if (aPart is TengShaderPartIf) then with (aPart as TengShaderPartIf) do begin
if (sfEvaluateIf in args.Flags) then begin if (sfEvaluateIf in args.Flags) then begin
if Expression.GetValue if Expression.GetValue
@@ -269,6 +286,7 @@ begin
exit; exit;
end; end;


// normal children
for p in aPart do begin for p in aPart do begin
if Check(p) then if Check(p) then
fResults.Add(p); fResults.Add(p);
@@ -309,6 +327,26 @@ begin
((aPart as TengShaderPartKeyValuePair).Name = fName); ((aPart as TengShaderPartKeyValuePair).Name = fName);
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengInheritedSearchWalker/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengInheritedSearchWalker.Check(const aPart: TengShaderPart): Boolean;
begin
result :=
inherited Check(aPart) and
(aPart is TengShaderPartClass) and
((aPart as TengShaderPartClass).Name = fName);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengInheritedSearchWalker.Create(const aClass: TengShaderPartClass; const aResults: TengSearchResults);
begin
inherited Create(aResults);
ResultTypes := CengShaderPartArr.Create(TengShaderPartClass);
SearchFlags := [sfSearchInherited, sfIgnoreOwner];
Owner := aClass;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengProcSearchWalker////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengProcSearchWalker//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 90
- 54
uengShaderGeneratorArgs.pas 查看文件

@@ -17,6 +17,7 @@ uses
type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengGenerateFlag = ( TengGenerateFlag = (
gfGenerateProcedureMain, // generate main procedure code
gfGenerateProcedureCode, // generate procedure code gfGenerateProcedureCode, // generate procedure code
gfGenerateProcedureCall, // generate procedure call gfGenerateProcedureCall, // generate procedure call
gfGenerateInlineCode, // generate procedure as inline code gfGenerateInlineCode, // generate procedure as inline code
@@ -59,7 +60,7 @@ type
property DebugText: String read GetDebugText; property DebugText: String read GetDebugText;
property Indent: Integer read fIndent; property Indent: Integer read fIndent;
property Token: TengGeneratorToken read fToken; property Token: TengGeneratorToken read fToken;
constructor Create(const aToken: TengGeneratorToken; const aText: String; const aIndent: Integer = 0);
constructor Create(const aToken: TengGeneratorToken; const aText: String; const aIndent: Integer = High(Integer));
end; end;
TCodePartList = specialize TutlSimpleList<TCodePart>; TCodePartList = specialize TutlSimpleList<TCodePart>;


@@ -109,19 +110,19 @@ type
property ProcParams: TStrings read GetProcParams; property ProcParams: TStrings read GetProcParams;
property MaxParameterLength: Integer read fMaxParameterLength; property MaxParameterLength: Integer read fMaxParameterLength;


procedure PushCode;
procedure PushFlags(const aFlags: TengGenerateFlags);
procedure PushProcParams(const aParams: TStrings);
function PushCode: TengShaderGeneratorArgs;
function PushFlags(const aFlags: TengGenerateFlags): TengShaderGeneratorArgs;
function PushProcParams(const aParams: TStrings): TengShaderGeneratorArgs;


procedure PopCode(const aFlags: TengPopCodeFlags);
procedure PopFlags;
procedure PopProcParams;
function PopCode(const aFlags: TengPopCodeFlags): TengShaderGeneratorArgs;
function PopFlags: TengShaderGeneratorArgs;
function PopProcParams: TengShaderGeneratorArgs;


function AddText(const aText: String): TengShaderGeneratorArgs; function AddText(const aText: String): TengShaderGeneratorArgs;
function AddToken(const aToken: String): TengShaderGeneratorArgs; function AddToken(const aToken: String): TengShaderGeneratorArgs;
function AddCommandEnd(const aToken: String): TengShaderGeneratorArgs; function AddCommandEnd(const aToken: String): TengShaderGeneratorArgs;
function AddLineBreak: TengShaderGeneratorArgs; function AddLineBreak: TengShaderGeneratorArgs;
function BeginBlock(const aIndent: Integer = 0): TengShaderGeneratorArgs;
function BeginBlock(const aIndent: Integer = High(Integer)): TengShaderGeneratorArgs;
function EndBlock(const aCanAppend: Boolean = false): TengShaderGeneratorArgs; function EndBlock(const aCanAppend: Boolean = false): TengShaderGeneratorArgs;
function AppendToPrevLine: TengShaderGeneratorArgs; function AppendToPrevLine: TengShaderGeneratorArgs;


@@ -130,8 +131,8 @@ type
procedure AddProcedure(const aProc: TengShaderPart); procedure AddProcedure(const aProc: TengShaderPart);


function ExtractCurrentCommand(const aCommand: TCodeStackItem): Integer; function ExtractCurrentCommand(const aCommand: TCodeStackItem): Integer;
procedure ReplaceIdents(const aOld, aNew: TStrings);
procedure ReplaceReturns(const aCommand: TCodeStackItem; const aRetType, aName: String);
function ReplaceIdents(const aOld, aNew: TStrings): TengShaderGeneratorArgs;
function ReplaceReturns(const aCommand: TCodeStackItem; const aRetType, aName: String): TengShaderGeneratorArgs;


procedure GenerateCode(const aCode: TengShaderCode); procedure GenerateCode(const aCode: TengShaderCode);


@@ -234,7 +235,9 @@ begin
gtNormal: result := '[N]' + fText; gtNormal: result := '[N]' + fText;
gtLineBreak: result := sLineBreak; gtLineBreak: result := sLineBreak;
gtCommandEnd: result := '[C]' + fText; gtCommandEnd: result := '[C]' + fText;
gtBlockBegin: result := format('[B%d]', [fIndent]);
gtBlockBegin: if (fIndent = High(Integer))
then result := '[B]'
else result := format('[B%d]', [fIndent]);
gtBlockEnd: result := '[E]'; gtBlockEnd: result := '[E]';
gtToken: result := '[T' + fText + ']'; gtToken: result := '[T' + fText + ']';
gtAppendToPrev: result := '[A]'; gtAppendToPrev: result := '[A]';
@@ -276,11 +279,36 @@ var
f: TGenFlags; f: TGenFlags;
cb: TCodeBlock; cb: TCodeBlock;


function GetCurrentIndent(const aStr: String): Integer;
{$IFDEF DEBUG}
procedure GenerateDebugCode;
var
cp: TCodePart;
s: String;
begin
s := '';
for cp in fItems do
s := s + cp.DebugText;
aCode.Text := aCode.Text + s + sLineBreak + sLineBreak;
end;

procedure GenerateCurrentCode(const aHeader: String);
var
i: Integer;
begin
aCode.Add(aHeader);
for i := 0 to cb.Count-1 do
aCode.Add(Format('[%02d]%s|', [cb.Depth[i], cb[i]]));
aCode.Add('');
aCode.Add('');
aCode.Add('');
end;
{$ENDIF}

function GetCurrentIndent(const aStr: String; const aIgnoreEmptyLines: Boolean): Integer;
var var
len: Integer; len: Integer;
begin begin
if (Trim(aStr) <> '') then begin
if (Trim(aStr) <> '') or not aIgnoreEmptyLines then begin
result := 1; result := 1;
len := Length(aStr); len := Length(aStr);
while (result <= len) and (aStr[result] in WHITESPACES) do while (result <= len) and (aStr[result] in WHITESPACES) do
@@ -290,10 +318,12 @@ var
result := High(Integer); result := High(Integer);
end; end;


function IndentStr(const aStr: String; const aIndent: Integer): String;
function IndentStr(const aStr: String; aIndent: Integer): String;
var var
i, l: Integer; i, l: Integer;
begin begin
if (aStr = '') then
aIndent := 0;
if (aIndent < 0) then begin if (aIndent < 0) then begin
i := 1; i := 1;
l := Length(aStr); l := Length(aStr);
@@ -306,26 +336,26 @@ var
result := aStr; result := aStr;
end; end;


procedure IndentBlock(aDepth, aIndent: Integer);
procedure IndentBlock(aDepth, aAbsIndent: Integer);
var var
i, minCurIndent: Integer;
i, indent, minCurIndent: Integer;
begin begin
i := cb.Count-1; i := cb.Count-1;
minCurIndent := High(Integer); minCurIndent := High(Integer);
while (i >= 0) and (cb.Depth[i] = aDepth) do begin while (i >= 0) and (cb.Depth[i] = aDepth) do begin
minCurIndent := min(minCurIndent, GetCurrentIndent(cb[i]));
minCurIndent := min(minCurIndent, GetCurrentIndent(cb[i], true));
dec(i); dec(i);
end; end;
inc(i); inc(i);
aIndent := aIndent - minCurIndent;
indent := aAbsIndent - minCurIndent;
while (i < cb.Count) do begin while (i < cb.Count) do begin
cb[i] := IndentStr(cb[i], aIndent);
cb[i] := IndentStr(cb[i], indent);
cb.Depth[i] := cb.Depth[i] - 1; cb.Depth[i] := cb.Depth[i] - 1;
inc(i); inc(i);
end; end;
end; end;


procedure ProgressBlock(const aIndent, aDepth: Integer);
procedure ProgressBlock(const aCurrentBlockIndent, aDepth: Integer);
var var
cp: TCodePart; cp: TCodePart;
tmp: Integer; tmp: Integer;
@@ -364,18 +394,25 @@ var


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


gtBlockEnd: begin gtBlockEnd: begin
IndentBlock(aDepth, aIndent);
{$IFDEF DEBUG}
GenerateCurrentCode(Format('------====== DEBUG STEP BEFORE INDENT (%d) ======------', [aCurrentBlockIndent]));
{$ENDIF}
IndentBlock(aDepth, aCurrentBlockIndent);
{$IFDEF DEBUG}
GenerateCurrentCode(Format('------====== DEBUG STEP AFTER INDENT (%d) ======------', [aCurrentBlockIndent]));
{$ENDIF}
exit; exit;
end; end;


@@ -389,19 +426,6 @@ var
end; end;
end; end;


{$IFDEF DEBUG}
procedure GenerateDebugCode;
var
cp: TCodePart;
s: String;
begin
s := '';
for cp in fItems do
s := s + cp.DebugText;
aCode.Text := aCode.Text + s + sLineBreak + sLineBreak;
end;
{$ENDIF}

var var
s, e: Integer; s, e: Integer;
begin begin
@@ -423,7 +447,7 @@ begin
for i := s to e do for i := s to e do
aCode.Add( aCode.Add(
{$IFDEF DEBUG} {$IFDEF DEBUG}
Format('[%02d]%s', [cb.Depth[i], cb[i]])
Format('[%02d]%s|', [cb.Depth[i], cb[i]])
{$ELSE} {$ELSE}
cb[i] cb[i]
{$ENDIF} {$ENDIF}
@@ -580,25 +604,28 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.PushCode;
function TengShaderGeneratorArgs.PushCode: TengShaderGeneratorArgs;
begin begin
fCode.PushLast(TCodeStackItem.Create); fCode.PushLast(TCodeStackItem.Create);
result := self;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.PushFlags(const aFlags: TengGenerateFlags);
function TengShaderGeneratorArgs.PushFlags(const aFlags: TengGenerateFlags): TengShaderGeneratorArgs;
begin begin
fFlagStack.PushLast(aFlags); fFlagStack.PushLast(aFlags);
result := self;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.PushProcParams(const aParams: TStrings);
function TengShaderGeneratorArgs.PushProcParams(const aParams: TStrings): TengShaderGeneratorArgs;
begin begin
fProcParams.PushLast(aParams); fProcParams.PushLast(aParams);
result := self;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.PopCode(const aFlags: TengPopCodeFlags);
function TengShaderGeneratorArgs.PopCode(const aFlags: TengPopCodeFlags): TengShaderGeneratorArgs;
var var
csi: TCodeStackItem; csi: TCodeStackItem;
begin begin
@@ -618,18 +645,21 @@ begin
finally finally
FreeAndNil(csi); FreeAndNil(csi);
end; end;
result := self;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.PopFlags;
function TengShaderGeneratorArgs.PopFlags: TengShaderGeneratorArgs;
begin begin
fFlagStack.PopLast(true); fFlagStack.PopLast(true);
result := self;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.PopProcParams;
function TengShaderGeneratorArgs.PopProcParams: TengShaderGeneratorArgs;
begin begin
fProcParams.PopLast; fProcParams.PopLast;
result := self;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -747,7 +777,7 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.ReplaceIdents(const aOld, aNew: TStrings);
function TengShaderGeneratorArgs.ReplaceIdents(const aOld, aNew: TStrings): TengShaderGeneratorArgs;
var var
rx: TRegExpr; rx: TRegExpr;
i: Integer; i: Integer;
@@ -765,10 +795,11 @@ begin
finally finally
FreeAndNil(rx); FreeAndNil(rx);
end; end;
result := self;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.ReplaceReturns(const aCommand: TCodeStackItem; const aRetType, aName: String);
function TengShaderGeneratorArgs.ReplaceReturns(const aCommand: TCodeStackItem; const aRetType, aName: String): TengShaderGeneratorArgs;
var var
rx: TRegExpr; rx: TRegExpr;
RetCount, i, j: Integer; RetCount, i, j: Integer;
@@ -778,7 +809,7 @@ var
begin begin
rx := TRegExpr.Create; rx := TRegExpr.Create;
try try
rx.Expression := '([^A-z0-9_]+|^)return([^A-z0-9_]+|$)';
rx.Expression := '^(.*?\s+)return\s*(.*)$';
csi := fCode.Last; csi := fCode.Last;


// find number of "return" in code // find number of "return" in code
@@ -812,7 +843,7 @@ begin


// replace "return" with temp variable // replace "return" with temp variable
for cp in csi.Items do for cp in csi.Items do
cp.Text := rx.Replace(cp.Text, '$1' + s + ' =$2', true);
cp.Text := rx.Replace(cp.Text, '$1' + s + ' = $2', true);


// merge code // merge code
csi.Merge(aCommand, csi.Items.Count); csi.Merge(aCommand, csi.Items.Count);
@@ -825,16 +856,20 @@ begin
cp := csi.Items[i]; cp := csi.Items[i];
if rx.Exec(cp.Text) then begin if rx.Exec(cp.Text) then begin
csi.Items.Insert(i, TCodePart.Create(gtNormal, rx.Match[1])); csi.Items.Insert(i, TCodePart.Create(gtNormal, rx.Match[1]));
cp.Text := rx.Replace(cp.Text, '(', true);
cp.Text := rx.Replace(cp.Text, '($2', true);


// replace last gtCommandEnd with ')' and delete everything behind
// replace last gtCommandEnd with ')' and delete everything code behind
j := csi.Items.Count-1; j := csi.Items.Count-1;
while (j > i) and not (csi.Items[j].Token = gtCommandEnd) do while (j > i) and not (csi.Items[j].Token = gtCommandEnd) do
dec(j); dec(j);
if (j > i) then if (j > i) then
csi.Items[j] := TCodePart.Create(gtNormal, ')'); csi.Items[j] := TCodePart.Create(gtNormal, ')');
while (csi.Items.Count-1 > j) do
csi.Items.PopLast(true);
inc(j);
while (j < csi.Items.Count) do begin
if (csi.Items[j].Token in [gtNormal, gtLineBreak, gtCommandEnd])
then csi.Items.Delete(j)
else inc(j);
end;


// merge // merge
csi.Merge(aCommand, i+1); csi.Merge(aCommand, i+1);
@@ -845,6 +880,7 @@ begin
finally finally
FreeAndNil(rx); FreeAndNil(rx);
end; end;
result := self;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 140
- 36
uengShaderPartCall.pas 查看文件

@@ -7,7 +7,8 @@ interface


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs;
uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs, uengShaderPartClass,
uengShaderPartProc, uengShaderPartKeyValuePair;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -16,6 +17,8 @@ type
private { member } private { member }
fName: String; fName: String;
fParameters: TStringList; fParameters: TStringList;

function FindKeyValuePair(const aName: String): TengShaderPartKeyValuePair;
protected { virtual getter } protected { virtual getter }
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
@@ -28,7 +31,6 @@ type
private private
function GetParameters: TStrings; function GetParameters: TStrings;
public public
property Name: String read fName;
property Parameters: TStrings read GetParameters; property Parameters: TStrings read GetParameters;


constructor Create(const aParent: TengShaderPart); override; constructor Create(const aParent: TengShaderPart); override;
@@ -41,8 +43,12 @@ type


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartInherited = class(TengShaderPartCall) TengShaderPartInherited = class(TengShaderPartCall)
{ Class Methods }
{ Code Loading & Storage }
private
fInline: Boolean;
fClass: TengShaderPartClass;
protected protected
function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ Code Generation } { Code Generation }
@@ -58,23 +64,44 @@ type
implementation implementation


uses uses
uengShaderPartProc, uengShaderPartClass, uengShaderFileConstants, uengShaderFileTypes,
uengShaderFileHelper, uengShaderGenerator, uengShaderFile;
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderGenerator,
uengShaderFile, uengShaderPartScope;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartCall//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartCall////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartCall.FindKeyValuePair(const aName: String): TengShaderPartKeyValuePair;
var
sr: TengSearchResults;
walker: TengKeyValuePairSearchWalker;
begin
sr := TengSearchResults.Create;
walker := TengKeyValuePairSearchWalker.Create(sr);
try
walker.Name := aName;
walker.SearchFlags := [sfSearchChildren, sfSearchParents];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty, TengShaderPartStatic);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile);
walker.Run(fParent);
result := (ExtractSearchResult(self, aName, sr) as TengShaderPartKeyValuePair);
finally
FreeAndNil(walker);
FreeAndNil(sr);
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartCall.GetText: String; function TengShaderPartCall.GetText: String;
var var
i: Integer; i: Integer;
begin begin
result := TOKEN_CHAR_BEGIN + GetTokenName;
if (fName <> '') then
result := result + ' ' + fName;
result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + fName;
for i := 0 to fParameters.Count-1 do begin for i := 0 to fParameters.Count-1 do begin
if (PtrInt(fParameters.Objects[i]) <> 0)
then result := result + ' ' + TOKEN_CHAR_QUOTE + fParameters[i] + TOKEN_CHAR_QUOTE
else result := result + ' ' + fParameters[i];
if Assigned(fParameters.Objects[i])
then result := result + ' ' + TengShaderPartKeyValuePair(fParameters.Objects[i]).Name
else result := result + ' ' + TOKEN_CHAR_QUOTE + fParameters[i] + TOKEN_CHAR_QUOTE;
end; end;
result := result + TOKEN_CHAR_END; result := result + TOKEN_CHAR_END;
end; end;
@@ -89,15 +116,18 @@ begin
if (aParams.Count < 2) then if (aParams.Count < 2) then
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self); raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);


result := '';
fParameters.Clear; fParameters.Clear;
with aParams[1] do begin
if not IsValidIdentifier(fName) then
raise EengInvalidIdentifier.Create(Name, self);
fName := Name;

result := '';
fName := aParams[1].Name;
if not IsValidIdentifier(fName) then
raise EengInvalidIdentifier.Create(fName, aParams[1].Line, aParams[1].Col, Filename, self);

for i := 2 to aParams.Count-1 do begin
if not aParams[i].Quoted
then fParameters.AddObject(aParams[i].Name, FindKeyValuePair(aParams[i].Name))
else fParameters.AddObject(aParams[i].Name, nil);
end; end;
for i := 2 to aParams.Count-1 do
fParameters.AddObject(aParams[i].Name, TObject(PtrInt(aParams[i].Quoted)));
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -111,7 +141,7 @@ begin
sr := TengSearchResults.Create; sr := TengSearchResults.Create;
walker := TengProcSearchWalker.Create(sr); walker := TengProcSearchWalker.Create(sr);
try try
walker.Name := Name;
walker.Name := fName;
walker.SearchFlags := [sfEvaluateIf, sfSearchChildren, sfSearchInherited]; walker.SearchFlags := [sfEvaluateIf, sfSearchChildren, sfSearchInherited];
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderGenerator); walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderGenerator);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile); walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
@@ -160,25 +190,92 @@ end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartInherited/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartInherited///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartInherited.GetText: String;
begin
result := inherited GetText;
if fInline then
Insert(' ' + TOKEN_INLINE, result, Length(result) - 1);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartInherited.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartInherited.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;

function FindInheritedClass(const aName: string): TengShaderPartClass;
var
sr: TengSearchResults;
walker: TengInheritedSearchWalker;
begin
sr := TengSearchResults.Create;
walker := TengInheritedSearchWalker.Create((GetParent(TengShaderPartClass) as TengShaderPartClass), sr);
try
walker.Name := aName;
walker.Run(walker.Owner);
result := (ExtractSearchResult(self, aName, sr, [ifWarning]) as TengShaderPartClass);
finally
FreeAndNil(walker);
FreeAndNil(sr);
end;
end;

type
TExpectedPart = (epClass, epProc, epParam);
TExpectedParts = set of TExpectedPart;

var var
i: Integer; i: Integer;
expected: TExpectedParts;
begin begin
if (aParams[0].Name <> GetTokenName) then with aParams[0] do if (aParams[0].Name <> GetTokenName) then with aParams[0] do
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self); raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);


fName := '';
fName := '';
result := '';
fClass := nil;
fInline := false;
expected := [epClass, epProc, epParam];
fParameters.Clear; fParameters.Clear;
if (aParams.Count >= 2) then begin
if not IsValidIdentifier(aParams[1].Name) and (aParams[1].Name <> TOKEN_MAIN) then
with aParams[1] do
raise EengInvalidIdentifier.Create(Name, Line, Col, Filename, self);
fName := aParams[1].Name;
for i := 2 to aParams.Count-1 do
fParameters.AddObject(aParams[i].Name, TObject(PtrInt(aParams[i].Quoted)));
for i := 1 to aParams.Count-1 do begin

// quoted parameter
if aParams[i].Quoted then begin
if not (epParam in expected) then
raise EengUnexpectedToken.Create(aParams[i].Name, '[none]', aParams[i].Line, aParams[i].Col, Filename, self);
fParameters.AddObject(aParams[i].Name, nil);
expected := expected - [epClass, epProc];
continue;
end;

// inline
if (aParams[i].Name = TOKEN_INLINE) then begin
fInline := true;
continue;
end;

// class
if (epClass in expected) then begin
fClass := FindInheritedClass(aParams[i].Name);
if Assigned(fClass) then begin
expected := expected - [epClass];
continue;
end;
end;

// proc
if (epProc in expected) then begin
fName := aParams[i].Name;
expected := expected - [epClass, epProc];
continue;
end;

// unquoted param
if (epParam in expected) then begin
fParameters.AddObject(aParams[i].Name, FindKeyValuePair(aParams[i].Name));
continue;
end;

raise EengUnexpectedToken.Create(aParams[i].Name, '[none]', aParams[i].Line, aParams[i].Col, Filename, self);
end; end;
result := '';
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -188,20 +285,22 @@ procedure TengShaderPartInherited.GenerateCodeIntern(const aArgs: TengShaderGene
var var
sr: TengSearchResults; sr: TengSearchResults;
walker: TengProcSearchWalker; walker: TengProcSearchWalker;
ParentProc: TengShaderPartProc;
c: TengShaderPartClass;
begin begin
sr := TengSearchResults.Create; sr := TengSearchResults.Create;
walker := TengProcSearchWalker.Create(sr); walker := TengProcSearchWalker.Create(sr);
try try
ParentProc := (GetParent(TengShaderPartProc) as TengShaderPartProc);
walker.Name := Name;
walker.Name := fName;
if (walker.Name = '') then if (walker.Name = '') then
walker.Name := ParentProc.Name;
walker.Owner := ParentProc;
walker.SearchFlags := [sfEvaluateIf, sfIgnoreOwner, sfSearchChildrenLazy, sfSearchInherited];
walker.Name := (GetParent(TengShaderPartProc) as TengShaderPartProc).Name;
walker.SearchFlags := [sfEvaluateIf, sfSearchChildren, sfSearchInherited];
walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderPartClass); walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderPartClass);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartClass); walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartClass);
walker.Run(ParentProc);
if not Assigned(fClass) then begin
for c in (GetParent(TengShaderPartClass) as TengShaderPartClass).InheritedClasses do
walker.Run(c);
end else
walker.Run(fClass);
result := (ExtractSearchResult(self, walker.Name, sr) as TengShaderPartProc); result := (ExtractSearchResult(self, walker.Name, sr) as TengShaderPartProc);
finally finally
FreeAndNil(walker); FreeAndNil(walker);
@@ -211,7 +310,9 @@ procedure TengShaderPartInherited.GenerateCodeIntern(const aArgs: TengShaderGene


procedure GenCode(const aProc: TengShaderPartProc; const aParams: TStrings); procedure GenCode(const aProc: TengShaderPartProc; const aParams: TStrings);
begin begin
aArgs.PushFlags(aArgs.Flags + [gfGenerateInlineCode]);
if fInline
then aArgs.PushFlags(aArgs.Flags + [gfGenerateInlineCode, gfGenerateProcedureCall] - [gfGenerateProcedureCode])
else aArgs.PushFlags(aArgs.Flags + [gfGenerateProcedureCall] - [gfGenerateProcedureCode]);
aArgs.PushProcParams(aParams); aArgs.PushProcParams(aParams);
try try
aProc.GenerateCodeIntern(aArgs); aProc.GenerateCodeIntern(aArgs);
@@ -231,6 +332,9 @@ begin
if (fParameters.Count > 0) then begin if (fParameters.Count > 0) then begin
if (fParameters.Count <> proc.ParameterCount) then if (fParameters.Count <> proc.ParameterCount) then
raise EengInvalidParamterCount.Create(proc.name + ' expexts ' + IntToStr(proc.ParameterCount) + ' parameters', self); raise EengInvalidParamterCount.Create(proc.name + ' expexts ' + IntToStr(proc.ParameterCount) + ' parameters', self);
for i := 0 to fParameters.Count-1 do
if Assigned(fParameters.Objects[i]) then
fParameters[i] := TengShaderPartKeyValuePair(fParameters.Objects[i]).Value;
GenCode(proc, fParameters); GenCode(proc, fParameters);
end else begin end else begin
params := TStringList.Create; params := TStringList.Create;


+ 1
- 1
uengShaderPartClass.pas 查看文件

@@ -207,7 +207,7 @@ begin
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartMain); walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartMain);
walker.Run(self); walker.Run(self);
main := (ExtractSearchResult(self, TengShaderPartMain.GetTokenName, sr) as TengShaderPartMain); main := (ExtractSearchResult(self, TengShaderPartMain.GetTokenName, sr) as TengShaderPartMain);
aArgs.PushFlags([gfGenerateProcedureCode]);
aArgs.PushFlags([gfGenerateProcedureCode, gfGenerateProcedureMain]);
try try
main.GenerateCodeIntern(aArgs); main.GenerateCodeIntern(aArgs);
finally finally


+ 0
- 1
uengShaderPartEcho.pas 查看文件

@@ -68,7 +68,6 @@ begin
walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile); walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile);
walker.SearchFlags := [ walker.SearchFlags := [
sfSearchChildrenLazy, sfSearchChildrenLazy,
sfSearchChildren,
sfSearchParents sfSearchParents
]; ];
walker.Run(self); walker.Run(self);


+ 0
- 1
uengShaderPartKeyValuePair.pas 查看文件

@@ -147,7 +147,6 @@ begin
walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile); walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile);
walker.SearchFlags := [ walker.SearchFlags := [
sfSearchChildrenLazy, sfSearchChildrenLazy,
sfSearchChildren,
sfSearchParents sfSearchParents
]; ];
walker.Run(self); walker.Run(self);


+ 33
- 18
uengShaderPartProc.pas 查看文件

@@ -39,7 +39,7 @@ type


{ Code Generation } { Code Generation }
protected protected
function GenerateHeaderCode: String; virtual;
function GenerateHeaderCode(const aArgs: TengShaderGeneratorArgs): String; virtual;
procedure GenerateInlineCode(const aArgs: TengShaderGeneratorArgs); virtual; procedure GenerateInlineCode(const aArgs: TengShaderGeneratorArgs); virtual;
public public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override; procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;
@@ -68,7 +68,7 @@ type


{ Code Generation } { Code Generation }
protected protected
function GenerateHeaderCode: String; override;
function GenerateHeaderCode(const aArgs: TengShaderGeneratorArgs): String; override;


{ General } { General }
public public
@@ -86,7 +86,7 @@ type


{ Code Generation } { Code Generation }
protected protected
function GenerateHeaderCode: String; override;
function GenerateHeaderCode(const aArgs: TengShaderGeneratorArgs): String; override;
procedure GenerateInlineCode(const aArgs: TengShaderGeneratorArgs); override; procedure GenerateInlineCode(const aArgs: TengShaderGeneratorArgs); override;


{ Class Methods } { Class Methods }
@@ -98,7 +98,7 @@ implementation


uses uses
RegExpr, RegExpr,
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartClass;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartProc//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartProc////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -184,9 +184,10 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartProc.GenerateHeaderCode: String;
function TengShaderPartProc.GenerateHeaderCode(const aArgs: TengShaderGeneratorArgs): String;
var var
p: TengShaderPartProcParam; p: TengShaderPartProcParam;
c: TengShaderPartClass;
begin begin
result := ''; result := '';
for p in fParameters do begin for p in fParameters do begin
@@ -196,7 +197,9 @@ begin
end; end;
if (result = '') then if (result = '') then
result := 'void'; result := 'void';
result := 'void ' + fName + '(' + result + ')';
if GetParent(TengShaderPartClass, c)
then result := 'void ' + c.Name + '_' + fName + '(' + result + ')'
else result := 'void ' + fName + '(' + result + ')';
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -240,6 +243,7 @@ end;
procedure TengShaderPartProc.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); procedure TengShaderPartProc.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
var var
s, params: String; s, params: String;
c: TengShaderPartClass;
begin begin
// generate inline code // generate inline code
if (aArgs.Flags * [gfGenerateProcedureCall, gfGenerateProcedureCode] <> []) and if (aArgs.Flags * [gfGenerateProcedureCall, gfGenerateProcedureCode] <> []) and
@@ -252,7 +256,7 @@ begin
end else if (gfGenerateProcedureCode in aArgs.Flags) then begin end else if (gfGenerateProcedureCode in aArgs.Flags) then begin
aArgs aArgs
.AddLineBreak .AddLineBreak
.AddText(GenerateHeaderCode)
.AddText(GenerateHeaderCode(aArgs))
.AddLineBreak .AddLineBreak
.AddCommandEnd('{') .AddCommandEnd('{')
.AddLineBreak .AddLineBreak
@@ -274,7 +278,9 @@ begin
params := params + ', '; params := params + ', ';
params := params + s; params := params + s;
end; end;
aArgs.AddText(fName + '(' + params + ')');
if GetParent(TengShaderPartClass, c)
then aArgs.AddText(c.Name + '_' + fName + '(' + params + ')')
else aArgs.AddText(fName + '(' + params + ')');
aArgs.AddProcedure(self); aArgs.AddProcedure(self);
end; end;
end; end;
@@ -327,9 +333,13 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartMain.GenerateHeaderCode: String;
function TengShaderPartMain.GenerateHeaderCode(const aArgs: TengShaderGeneratorArgs): String;
var
c: TengShaderPartClass;
begin begin
result := 'void main(void)';
if not (gfGenerateProcedureMain in aArgs.Flags) and GetParent(TengShaderPartClass, c)
then result := 'void ' + c.Name + '_main(void)'
else result := 'void main(void)';
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -368,9 +378,10 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartFunc.GenerateHeaderCode: String;
function TengShaderPartFunc.GenerateHeaderCode(const aArgs: TengShaderGeneratorArgs): String;
var var
p: TengShaderPartProcParam; p: TengShaderPartProcParam;
c: TengShaderPartClass;
begin begin
result := ''; result := '';
for p in fParameters do begin for p in fParameters do begin
@@ -380,7 +391,9 @@ begin
end; end;
if (result = '') then if (result = '') then
result := 'void'; result := 'void';
result := fReturnType + ' ' + fName + '(' + result + ')';
if GetParent(TengShaderPartClass, c)
then result := fReturnType + ' ' + c.Name + '_' + fName + '(' + result + ')'
else result := fReturnType + ' ' + fName + '(' + result + ')';
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -392,15 +405,17 @@ begin
csi := TengShaderGeneratorArgs.TCodeStackItem.Create; csi := TengShaderGeneratorArgs.TCodeStackItem.Create;
try try
indent := aArgs.ExtractCurrentCommand(csi); indent := aArgs.ExtractCurrentCommand(csi);
aArgs.PushCode;
aArgs.BeginBlock;
aArgs
.PushCode
.BeginBlock;
try try
inherited GenerateInlineCode(aArgs); inherited GenerateInlineCode(aArgs);
finally finally
aArgs.EndBlock;
aArgs.AddText(StringOfChar(' ', indent));
aArgs.ReplaceReturns(csi, fReturnType, fName);
aArgs.PopCode([pcfAppend]);
aArgs
.EndBlock
.AddText(StringOfChar(' ', indent))
.ReplaceReturns(csi, fReturnType, fName)
.PopCode([pcfAppend]);
end; end;
finally finally
FreeAndNil(csi); FreeAndNil(csi);


Loading…
取消
儲存