浏览代码

* refactored exceptions

* started implementation of code generation
master
Bergmann89 11 年前
父节点
当前提交
5426ac2513
共有 20 个文件被更改,包括 712 次插入 和 231 次删除
  1. +44
    -3
      uengShaderCodeGenerator.pas
  2. +88
    -22
      uengShaderFile.pas
  3. +33
    -30
      uengShaderFileExpression.pas
  4. +4
    -4
      uengShaderFileHelper.pas
  5. +10
    -13
      uengShaderFileParser.pas
  6. +329
    -46
      uengShaderFileTypes.pas
  7. +69
    -39
      uengShaderPart.pas
  8. +5
    -5
      uengShaderPartCall.pas
  9. +36
    -11
      uengShaderPartClass.pas
  10. +1
    -1
      uengShaderPartCntr.pas
  11. +1
    -1
      uengShaderPartComment.pas
  12. +3
    -3
      uengShaderPartEcho.pas
  13. +23
    -5
      uengShaderPartIf.pas
  14. +10
    -20
      uengShaderPartInclude.pas
  15. +32
    -5
      uengShaderPartKeyValuePair.pas
  16. +8
    -8
      uengShaderPartMeta.pas
  17. +4
    -4
      uengShaderPartParameter.pas
  18. +9
    -9
      uengShaderPartProc.pas
  19. +1
    -0
      uengShaderPartScope.pas
  20. +2
    -2
      uengShaderPartText.pas

+ 44
- 3
uengShaderCodeGenerator.pas 查看文件

@@ -7,15 +7,56 @@ interface


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPartCntr;
uengShaderFileParser, uengShaderPart, uengShaderPartScope, uengShaderPartKeyValuePair;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderCodeGenerator = class(TengShaderPartCntr)

TengShaderCodeGenerator = class(TengShaderPartScope)
{ Code Loading & Storage }
private
fProperties: TengShaderPartPropertyMap;

protected
fInherited: TengShaderPartList;
procedure UpdateInherited; virtual;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;

{ General }
public
constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override;
end; end;


implementation implementation


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderCodeGenerator///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.UpdateInherited;
begin
// TODO
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodeGenerator.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
begin
result := inherited ParseIntern(aArgs, aParams);
UpdateInherited;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderCodeGenerator.Create(const aParent: TengShaderPart);
begin
inherited Create(aParent);
fInherited := TengShaderPartList.Create(false);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TengShaderCodeGenerator.Destroy;
begin
FreeAndNil(fInherited);
inherited Destroy;
end;

end. end.



+ 88
- 22
uengShaderFile.pas 查看文件

@@ -12,7 +12,7 @@ interface


uses uses
Classes, sysutils, Classes, sysutils,
uengShaderPart, uengShaderCodeGenerator, uengShaderFileParser, uengShaderFileTypes
uengShaderPart, uengShaderPartClass, uengShaderCodeGenerator, uengShaderFileParser, uengShaderFileTypes


{$IFDEF USE_BITSPACE_UTILS} {$IFDEF USE_BITSPACE_UTILS}
, uutlSerialization , uutlSerialization
@@ -27,17 +27,27 @@ type
fFilename: String; fFilename: String;
fFileReader: IutlFileReader; fFileReader: IutlFileReader;
fFileWriter: IutlFileWriter; fFileWriter: IutlFileWriter;
protected { virtual getter }
fClasses: TengShaderPartClassMap;
private
function GetGenerator(const aName: String): TengShaderCodeGenerator;
function GetGeneratorCount: Integer;
function GetGeneratorNames(const aIndex: Integer): String;
procedure UpdateClasses;
protected
function GetFilename: String; override; function GetFilename: String; override;
function GetFileReader: IengShaderFileReader; override; function GetFileReader: IengShaderFileReader; override;
function GetFileWriter: IengShaderFileWriter; override; function GetFileWriter: IengShaderFileWriter; override;


{ General } { General }
protected
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList); override;
public public
procedure LoadFromFile(const aFilename: String; const aFlags: TengShaderFileLoadFlags = []; const aFileReader: IengShaderFileReader = nil);
property Generator [const aName: String]: TengShaderCodeGenerator read GetGenerator;
property GeneratorNames[const aIndex: Integer]: String read GetGeneratorNames;
property GeneratorCount: Integer read GetGeneratorCount;

procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil);
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil); procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
procedure Clear; override;
constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override; destructor Destroy; override;
end; end;


@@ -48,6 +58,54 @@ uses


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderFile//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderFile.GetGenerator(const aName: String): TengShaderCodeGenerator;
begin
result := fClasses[aName];
if not Assigned(result) then
result := self;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderFile.GetGeneratorCount: Integer;
begin
result := fClasses.Count+1;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderFile.GetGeneratorNames(const aIndex: Integer): String;
begin
if (aIndex < 0) or (aIndex >= Count) then
raise EengOutOfRange.Create(0, Count-1, aIndex, self);
if (aIndex = 0)
then result := ''
else result := fClasses.Keys[aIndex-1];
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.UpdateClasses;
var
l: TengShaderPart.TSearchResults;
p: TengShaderPart;
new, old: TengShaderPartClass;

begin
l := TengShaderPart.TSearchResults.Create;
try
fClasses.Clear;
FindAll([sfSearchChildren], [TengShaderPartClass], l);
for p in l do begin
new := (p as TengShaderPartClass);
old := fClasses[new.Name];
if Assigned(old) then
raise EengDuplicateIdentifier.Create(new.Name, new, old, self);
fClasses.Add(new.Name, new);
end;
finally
FreeAndNil(l);
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderFile.GetFilename: String; function TengShaderFile.GetFilename: String;
begin begin
@@ -71,16 +129,7 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList);
begin
if (sfCurrentFileOnly in aFlags) then
exclude(aFlags, sfSearchParents);
inherited FindIntern(aFlags, aDepth, aTypes, aList);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFlags: TengShaderFileLoadFlags;
const aFileReader: IengShaderFileReader);
procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader);
var var
args: TengParseArgs; args: TengParseArgs;
token: String; token: String;
@@ -95,28 +144,28 @@ begin
try try
Clear; Clear;
if not fFileReader.LoadStream(aFilename, ms) then if not fFileReader.LoadStream(aFilename, ms) then
raise EengShaderPart.Create('unable to open file: ' + aFilename, Line, Col, Filename);
raise EengShaderPart.Create('unable to open file: ' + aFilename, Parent);
ms.Position := 0; ms.Position := 0;
fFilename := aFilename; fFilename := aFilename;
args := TengParseArgs.Create(ms, Filename); args := TengParseArgs.Create(ms, Filename);
try try
args.Flags := aFlags;
token := ParseText(args); token := ParseText(args);
if (token <> '') then with args do if (token <> '') then with args do
raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename);
raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename, self);
if (Root = self) then
UpdateClasses;
finally finally
FreeAndNil(args); FreeAndNil(args);
end; end;
finally finally
if not (lfLazyInclude in aFlags) then
fFileReader := nil;
fFileReader := nil;
end; end;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter); procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
var var
l: TengShaderPart.TSearchList;
l: TengShaderPart.TSearchResults;
i: Integer; i: Integer;
sl: TStringList; sl: TStringList;
ms: TMemoryStream; ms: TMemoryStream;
@@ -127,7 +176,7 @@ begin
if not Assigned(fFileWriter) then if not Assigned(fFileWriter) then
fFileWriter := TengShaderFileWriter.Create; fFileWriter := TengShaderFileWriter.Create;


l := TengShaderPart.TSearchList.Create;
l := TengShaderPart.TSearchResults.Create;
sl := TStringList.Create; sl := TStringList.Create;
ms := TMemoryStream.Create; ms := TMemoryStream.Create;
try try
@@ -146,9 +195,26 @@ begin
end; end;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.Clear;
begin
inherited Clear;
fClasses.Clear;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderFile.Create(const aParent: TengShaderPart);
begin
inherited Create(aParent);
if not Assigned(fRoot) then
fRoot := self;
fClasses := TengShaderPartClassMap.Create(false);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TengShaderFile.Destroy; destructor TengShaderFile.Destroy;
begin begin
FreeAndNil(fClasses);
fFileReader := nil; fFileReader := nil;
fFileWriter := nil; fFileWriter := nil;
inherited Destroy; inherited Destroy;


+ 33
- 30
uengShaderFileExpression.pas 查看文件

@@ -13,17 +13,19 @@ type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengExpressionItem = class(TObject) TengExpressionItem = class(TObject)
private private
fOwner: TObject;
fLine: Integer; fLine: Integer;
fCol: Integer; fCol: Integer;
fFilename: String; fFilename: String;
public public
property Owner: TObject read fOwner;
property Line: Integer read fLine; property Line: Integer read fLine;
property Col: Integer read fCol; property Col: Integer read fCol;
property Filename: String read fFilename; property Filename: String read fFilename;


function GetText: String; virtual; function GetText: String; virtual;
function GetValue: Variant; virtual; function GetValue: Variant; virtual;
constructor Create(const aLine, aCol: Integer; const aFilename: String);
constructor Create(const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,7 +35,7 @@ type
public public
function GetText: String; override; function GetText: String; override;
function GetValue: Variant; override; function GetValue: Variant; override;
constructor Create(const aValue: Variant; const aLine, aCol: Integer; const aFilename: String);
constructor Create(const aValue: Variant; const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -43,7 +45,7 @@ type
public public
function GetText: String; override; function GetText: String; override;
function GetValue: Variant; override; function GetValue: Variant; override;
constructor Create(const aName: String; const aLine, aCol: Integer; const aFilename: String);
constructor Create(const aName: String; const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -54,7 +56,7 @@ type
property Child: TengExpressionItem read fChild write fChild; property Child: TengExpressionItem read fChild write fChild;
function GetText: String; override; function GetText: String; override;
function GetValue: Variant; override; function GetValue: Variant; override;
constructor Create(const aChild: TengExpressionItem; const aLine, aCol: Integer; const aFilename: String);
constructor Create(const aChild: TengExpressionItem; const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
destructor Destroy; override; destructor Destroy; override;
end; end;


@@ -76,7 +78,7 @@ type
function GetText: String; override; function GetText: String; override;
function GetValue: Variant; override; function GetValue: Variant; override;


constructor Create(const aUnaryOp: TengExpressionUnaryOperator; const aLine, aCol: Integer; const aFilename: String);
constructor Create(const aUnaryOp: TengExpressionUnaryOperator; const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
destructor Destroy; override; destructor Destroy; override;
end; end;


@@ -100,11 +102,11 @@ type
function GetText: String; override; function GetText: String; override;
function GetValue: Variant; override; function GetValue: Variant; override;


constructor Create(const aOperator: TengExpressionBinaryOperator; const aLine, aCol: Integer; const aFilename: String);
constructor Create(const aOperator: TengExpressionBinaryOperator; const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
destructor Destroy; override; destructor Destroy; override;
end; end;


function ParseExpression(const aParam: TengTokenParameterList; aIndex: Integer): TengExpressionItem;
function ParseExpression(const aOwner: TObject; const aParam: TengTokenParameterList; aIndex: Integer): TengExpressionItem;


implementation implementation


@@ -162,9 +164,10 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengExpressionItem.Create(const aLine, aCol: Integer; const aFilename: String);
constructor TengExpressionItem.Create(const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
begin begin
inherited Create; inherited Create;
fOwner := aOwner;
fLine := aLine; fLine := aLine;
fCol := aCol; fCol := aCol;
fFilename := aFilename; fFilename := aFilename;
@@ -185,9 +188,9 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengExpressionValue.Create(const aValue: Variant; const aLine, aCol: Integer; const aFilename: String);
constructor TengExpressionValue.Create(const aValue: Variant; const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
begin begin
inherited Create(aLine, aCol, aFilename);
inherited Create(aOwner, aLine, aCol, aFilename);
fValue := aValue; fValue := aValue;
end; end;


@@ -206,9 +209,9 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengExpressionVariable.Create(const aName: String; const aLine, aCol: Integer; const aFilename: String);
constructor TengExpressionVariable.Create(const aName: String; const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
begin begin
inherited Create(aLine, aCol, aFilename);
inherited Create(aOwner, aLine, aCol, aFilename);
fName := aName; fName := aName;
end; end;


@@ -231,9 +234,9 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengExpressionGroup.Create(const aChild: TengExpressionItem; const aLine, aCol: Integer; const aFilename: String);
constructor TengExpressionGroup.Create(const aChild: TengExpressionItem; const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
begin begin
inherited Create(aLine, aCol, aFilename);
inherited Create(aOwner, aLine, aCol, aFilename);
fChild := aChild; fChild := aChild;
end; end;


@@ -250,7 +253,7 @@ end;
function TengExpressionUnaryOperation.GetText: String; function TengExpressionUnaryOperation.GetText: String;
begin begin
if not Assigned(fChild) then if not Assigned(fChild) then
EengExpression.Create('no child assigned', Line, Col, Filename);
EengExpression.Create('no child assigned', self);
result := result :=
{$IFDEF EXPRESSION_ADD_BRACKET}TOKEN_OP_GROUP_BEGIN+{$ENDIF} {$IFDEF EXPRESSION_ADD_BRACKET}TOKEN_OP_GROUP_BEGIN+{$ENDIF}
EXPRESSION_UNARY_OPERATIONS[fUnaryOp] + ' ' + fChild.GetText EXPRESSION_UNARY_OPERATIONS[fUnaryOp] + ' ' + fChild.GetText
@@ -263,7 +266,7 @@ var
v: Variant; v: Variant;
begin begin
if not Assigned(fChild) then if not Assigned(fChild) then
raise EengExpression.Create('no child assigned', Line, Col, Filename);
raise EengExpression.Create('no child assigned', self);
try try
case fUnaryOp of case fUnaryOp of


@@ -293,14 +296,14 @@ begin
raise EengInvalidParamter.Create( raise EengInvalidParamter.Create(
ex.Message + '("' + GetText + '" ==> ' + ex.Message + '("' + GetText + '" ==> ' +
EXPRESSION_UNARY_OPERATIONS[fUnaryOp] + ' ' + v + '")', EXPRESSION_UNARY_OPERATIONS[fUnaryOp] + ' ' + v + '")',
Line, Col, Filename);
Line, Col, Filename, Owner);
end; end;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengExpressionUnaryOperation.Create(const aUnaryOp: TengExpressionUnaryOperator; const aLine, aCol: Integer; const aFilename: String);
constructor TengExpressionUnaryOperation.Create(const aUnaryOp: TengExpressionUnaryOperator; const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
begin begin
inherited Create(aLine, aCol, aFilename);
inherited Create(aOwner, aLine, aCol, aFilename);
fChild := nil; fChild := nil;
fUnaryOp := aUnaryOp; fUnaryOp := aUnaryOp;
end; end;
@@ -364,14 +367,14 @@ begin
raise EengInvalidParamter.Create( raise EengInvalidParamter.Create(
ex.Message + ' ("' + GetText + '" ==> "' + v1 + ' ' + ex.Message + ' ("' + GetText + '" ==> "' + v1 + ' ' +
EXPRESSION_BINARY_OPERATIONS[fBinaryOp] + ' ' + v2 + '")', EXPRESSION_BINARY_OPERATIONS[fBinaryOp] + ' ' + v2 + '")',
fLine, fCol, fFilename);
fLine, fCol, fFilename, fOwner);
end; end;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengExpressionBinaryOperation.Create(const aOperator: TengExpressionBinaryOperator; const aLine, aCol: Integer; const aFilename: String);
constructor TengExpressionBinaryOperation.Create(const aOperator: TengExpressionBinaryOperator; const aOwner: TObject; const aLine, aCol: Integer; const aFilename: String);
begin begin
inherited Create(aLine, aCol, aFilename);
inherited Create(aOwner, aLine, aCol, aFilename);
fBinaryOp := aOperator; fBinaryOp := aOperator;
fFirst := nil; fFirst := nil;
fSecond := nil; fSecond := nil;
@@ -401,13 +404,13 @@ type
{$ENDIF} {$ENDIF}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function ParseExpression(const aParam: TengTokenParameterList; aIndex: Integer): TengExpressionItem;
function ParseExpression(const aOwner: TObject; const aParam: TengTokenParameterList; aIndex: Integer): TengExpressionItem;
var var
p: TengTokenParameter; p: TengTokenParameter;


procedure RaiseEx(const aMsg: String); procedure RaiseEx(const aMsg: String);
begin begin
raise EengExpression.Create(aMsg, p.Line, p.Col, aParam.Filename);
raise EengExpression.Create(aMsg, p.Line, p.Col, aParam.Filename, aOwner);
end; end;


function NextParam: Boolean; function NextParam: Boolean;
@@ -531,7 +534,7 @@ var
if not NextParam then if not NextParam then
RaiseEx('unexpected end'); RaiseEx('unexpected end');
tmp := BuildTree(aDepth + 1); tmp := BuildTree(aDepth + 1);
ei := TengExpressionGroup.Create(tmp, l, c, aParam.Filename);
ei := TengExpressionGroup.Create(tmp, aOwner, l, c, aParam.Filename);
try try
MergeItems(stack, ei); MergeItems(stack, ei);
if (p.Name <> TOKEN_OP_GROUP_END) then if (p.Name <> TOKEN_OP_GROUP_END) then
@@ -552,7 +555,7 @@ var
end else if IsUnaryOperation(p.Name, uOp) then begin end else if IsUnaryOperation(p.Name, uOp) then begin
if not (exUnaryOperation in expected) then if not (exUnaryOperation in expected) then
RaiseEx('unexpected operator: ' + p.Name); RaiseEx('unexpected operator: ' + p.Name);
ei := TengExpressionUnaryOperation.Create(uOp, p.Line, p.Col, aParam.Filename);
ei := TengExpressionUnaryOperation.Create(uOp, aOwner, p.Line, p.Col, aParam.Filename);
try try
MergeItems(stack, ei); MergeItems(stack, ei);
expected := [exVariable]; expected := [exVariable];
@@ -567,7 +570,7 @@ var
end else if IsBinaryOperation(p.Name, bOp) then begin end else if IsBinaryOperation(p.Name, bOp) then begin
if not (exBinaryOperation in expected) then if not (exBinaryOperation in expected) then
RaiseEx('unexpected operator: ' + p.Name); RaiseEx('unexpected operator: ' + p.Name);
ei := TengExpressionBinaryOperation.Create(bOp, p.Line, p.Col, aParam.Filename);
ei := TengExpressionBinaryOperation.Create(bOp, aOwner, p.Line, p.Col, aParam.Filename);
try try
MergeItems(stack, ei); MergeItems(stack, ei);
expected := [exVariable, exValue, exGroupBegin, exUnaryOperation]; expected := [exVariable, exValue, exGroupBegin, exUnaryOperation];
@@ -580,7 +583,7 @@ var
end else if p.Quoted and IsValidIdentifier(p.Name) then begin end else if p.Quoted and IsValidIdentifier(p.Name) then begin
if not (exValue in expected) then if not (exValue in expected) then
RaiseEx('unexpected value: ' + p.Name); RaiseEx('unexpected value: ' + p.Name);
ei := TengExpressionValue.Create(p.Name, p.Line, p.Col, aParam.Filename);
ei := TengExpressionValue.Create(p.Name, aOwner,p.Line, p.Col, aParam.Filename);
try try
MergeItems(stack, ei); MergeItems(stack, ei);
expected := [exGroupEnd, exBinaryOperation]; expected := [exGroupEnd, exBinaryOperation];
@@ -593,7 +596,7 @@ var
end else if IsValidIdentifier(p.Name) then begin end else if IsValidIdentifier(p.Name) then begin
if not (exVariable in expected) then if not (exVariable in expected) then
RaiseEx('unexpected variable: ' + p.Name); RaiseEx('unexpected variable: ' + p.Name);
ei := TengExpressionVariable.Create(p.Name, p.Line, p.Col, aParam.Filename);
ei := TengExpressionVariable.Create(p.Name, aOwner, p.Line, p.Col, aParam.Filename);
try try
MergeItems(stack, ei); MergeItems(stack, ei);
expected := [exGroupEnd, exBinaryOperation]; expected := [exGroupEnd, exBinaryOperation];
@@ -623,7 +626,7 @@ var
begin begin
dec(aIndex); dec(aIndex);
if not NextParam then with aParam[0] do if not NextParam then with aParam[0] do
raise EengShaderPartInternal.Create('invalid parameter count in expression', Line, Col, aParam.Filename);
raise EengShaderPartInternal.Create('invalid parameter count in expression', Line, Col, aParam.Filename, aOwner);
result := BuildTree; result := BuildTree;
end; end;




+ 4
- 4
uengShaderFileHelper.pas 查看文件

@@ -40,12 +40,12 @@ begin
try try
oldLine := aArgs.Line; oldLine := aArgs.Line;
oldCol := aArgs.Col; oldCol := aArgs.Col;
if not aArgs.ExtractToken(param) then
raise EengUnexpectedToken.Create(TOKEN_NONE, TOKEN_END, oldLine, oldCol, aShaderPart.Filename);
if not aArgs.ExtractToken(aShaderPart, param) then
EengUnexpectedToken.Create(TOKEN_NONE, TOKEN_END, oldLine, oldCol, aShaderPart.Filename, aShaderPart);
if (param[0].Name <> TOKEN_END) then if (param[0].Name <> TOKEN_END) then
raise EengUnexpectedToken.Create(param[0].Name, TOKEN_END, oldLine, oldCol, aShaderPart.Filename);
EengUnexpectedToken.Create(param[0].Name, TOKEN_END, oldLine, oldCol, aShaderPart.Filename, aShaderPart);
if (param.Count <> 1) then if (param.Count <> 1) then
raise EengInvalidParamterCount.Create(TOKEN_END, 1, oldLine, oldCol, aShaderPart.Filename);
EengInvalidParamterCount.Create(TOKEN_END, 1, oldLine, oldCol, aShaderPart.Filename, aShaderPart);
result := ''; result := '';
finally finally
FreeAndNil(param); FreeAndNil(param);


+ 10
- 13
uengShaderFileParser.pas 查看文件

@@ -37,7 +37,6 @@ type
private private
fFilename: String; fFilename: String;
fCode: TStringList; fCode: TStringList;
fFlags: TengShaderFileLoadFlags;
fLineLength: Integer; fLineLength: Integer;
fLineCount: Integer; fLineCount: Integer;
fCurrentLine: String; fCurrentLine: String;
@@ -63,12 +62,10 @@ type
property Col: Integer read fCol write SetCol; property Col: Integer read fCol write SetCol;
property Line: Integer read fLine write SetLine; property Line: Integer read fLine write SetLine;


property Flags: TengShaderFileLoadFlags read fFlags write fFlags;

procedure NextCol; procedure NextCol;
procedure NextLine; procedure NextLine;
function ExtractToken(const aParameters: TengTokenParameterList): Boolean;
function GetTokenPreview(var aToken: String): Boolean;
function ExtractToken(const aSender: TObject; const aParameters: TengTokenParameterList): Boolean;
function GetTokenPreview(const aSender: TObject; var aToken: String): Boolean;


constructor Create(const aStream: TStream; const aFilename: String); constructor Create(const aStream: TStream; const aFilename: String);
destructor Destroy; override; destructor Destroy; override;
@@ -138,7 +135,7 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengParseArgs.ExtractToken(const aParameters: TengTokenParameterList): Boolean;
function TengParseArgs.ExtractToken(const aSender: TObject; const aParameters: TengTokenParameterList): Boolean;
type type
TCharType = ( TCharType = (
ctUnknown, ctUnknown,
@@ -173,9 +170,9 @@ var
(s[len] = TOKEN_CHAR_QUOTE)) then (s[len] = TOKEN_CHAR_QUOTE)) then
begin begin
if not (s[1] = TOKEN_CHAR_QUOTE) then if not (s[1] = TOKEN_CHAR_QUOTE) then
raise EengShaderPart.Create('missing leading quote char', Line, Col, Filename);
raise EengShaderPart.Create('missing leading quote char', Line, Col, Filename, aSender);
if not (s[len] = TOKEN_CHAR_QUOTE) then if not (s[len] = TOKEN_CHAR_QUOTE) then
raise EengShaderPart.Create('missing trailing quote char', Line, Col, Filename);
raise EengShaderPart.Create('missing trailing quote char', Line, Col, Filename, aSender);
delete(s, len, 1); delete(s, len, 1);
delete(s, 1, 1); delete(s, 1, 1);
p.Quoted := true; p.Quoted := true;
@@ -221,7 +218,7 @@ begin
else if not (pfInToken in pf) then else if not (pfInToken in pf) then
Include(pf, pfInToken) Include(pf, pfInToken)
else else
EengShaderPart.Create('invalid char in token', Line, Col, Filename);
EengShaderPart.Create('invalid char in token', Line, Col, Filename, aSender);
end; end;


TOKEN_CHAR_END: begin TOKEN_CHAR_END: begin
@@ -229,7 +226,7 @@ begin
AddPart(not (pfIsComment in pf)); AddPart(not (pfIsComment in pf));
NextCol; NextCol;
if (aParameters.Count <= 0) or (aParameters[0].Name = TOKEN_CHAR_IDENT) then if (aParameters.Count <= 0) or (aParameters[0].Name = TOKEN_CHAR_IDENT) then
raise EengShaderPart.Create('empty token', Line, Col, Filename);
raise EengShaderPart.Create('empty token', Line, Col, Filename, aSender);
exit; exit;
end else end else
s := s + CurrentChar; s := s + CurrentChar;
@@ -274,7 +271,7 @@ begin
s := s + sLineBreak; s := s + sLineBreak;
NextLine; NextLine;
end; end;
raise EengShaderPart.Create('incomplete token', oldLine, oldCol, Filename);
raise EengShaderPart.Create('incomplete token', oldLine, oldCol, Filename, aSender);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -284,7 +281,7 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengParseArgs.GetTokenPreview(var aToken: String): Boolean;
function TengParseArgs.GetTokenPreview(const aSender: TObject; var aToken: String): Boolean;
var var
c: Integer; c: Integer;
begin begin
@@ -307,7 +304,7 @@ begin
until (c > LineLength) or not (CurrentLine[c] in VALID_TOKEN_CHARS); until (c > LineLength) or not (CurrentLine[c] in VALID_TOKEN_CHARS);
aToken := Trim(aToken); aToken := Trim(aToken);
if (aToken = TOKEN_CHAR_IDENT) then if (aToken = TOKEN_CHAR_IDENT) then
raise EengInvalidToken.Create('empty token', Line, Col, Filename);
raise EengInvalidToken.Create('empty token', Line, Col, Filename, aSender);
end; end;


TOKEN_CHAR_COMMENT: TOKEN_CHAR_COMMENT:


+ 329
- 46
uengShaderFileTypes.pas 查看文件

@@ -24,130 +24,413 @@ type
{$ENDIF} {$ENDIF}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderFileLoadFlag = (
lfLazyInclude // include files will only be loaded when needed (this will store a reference to the passed IengShaderFileReader)
);
TengShaderFileLoadFlags = set of TengShaderFileLoadFlag;

//Exceptions////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengShaderPart = class(Exception) EengShaderPart = class(Exception)
protected
function GenerateMessage: String; virtual;
public public
Sender: TObject;
Line: Integer; Line: Integer;
Col: Integer; Col: Integer;
Filename: String; Filename: String;


constructor Create(const aMsg: String; const aLine, aCol: Integer; const aFilename: String); overload;
procedure PrintTrace(const aLines: TStrings);
function PrintTrace: String;

constructor Create(const aSender: TObject); overload;
constructor Create(const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
constructor Create(const aMsg: String; const aSender: TObject); overload;
constructor Create(const aMsg: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
end; end;
EengShaderPartInternal = class(EengShaderPart); EengShaderPartInternal = class(EengShaderPart);
EengExpression = class(EengShaderPart); EengExpression = class(EengShaderPart);


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengInvalidToken = class(EengShaderPartInternal) EengInvalidToken = class(EengShaderPartInternal)
constructor Create(const aClassName: String; const aToken: String; const aLine, aCol: Integer; const aFilename: String); overload;
protected
function GenerateMessage: String; override;
public
SenderClassName: String;
Token: String;
constructor Create(const aSenderClassName: String; const aToken: String; const aSender: TObject); overload;
constructor Create(const aSenderClassName: String; const aToken: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengUnexpectedToken = class(EengShaderPart) EengUnexpectedToken = class(EengShaderPart)
constructor Create(const aToken, aExpected: String; const aLine, aCol: Integer; const aFilename: String); overload;
protected
function GenerateMessage: String; override;
public
Token: String;
Expected: String;
constructor Create(const aToken, aExpected: String; const aSender: TObject); overload;
constructor Create(const aToken, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengInvalidParamter = class(EengShaderPart) EengInvalidParamter = class(EengShaderPart)
constructor Create(const aParam, aExpected: String; const aLine, aCol: Integer; const aFilename: String); overload;
protected
function GenerateMessage: String; override;
public
Param: String;
Expected: String;
constructor Create(const aParam, aExpected: String; const aSender: TObject); overload;
constructor Create(const aParam, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengInvalidParamterCount = class(EengShaderPart) EengInvalidParamterCount = class(EengShaderPart)
constructor Create(const aToken: String; const aExpected, aLine, aCol: Integer; const aFilename: String); overload;
constructor Create(const aToken: String; const aExpectedMin, aExpectedMax, aLine, aCol: Integer; const aFilename: String); overload;
protected
function GenerateMessage: String; override;
public
Token: String;
ExpectedMin: Integer;
ExpectedMax: Integer;
constructor Create(const aToken: String; const aExpected: Integer; const aSender: TObject); overload;
constructor Create(const aToken: String; const aExpectedMin, aExpectedMax: Integer; const aSender: TObject); overload;
constructor Create(const aToken: String; const aExpected, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
constructor Create(const aToken: String; const aExpectedMin, aExpectedMax, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengInvalidIdentifier = class(EengShaderPart) EengInvalidIdentifier = class(EengShaderPart)
constructor Create(const aIdentifier: String; const aLine, aCol: Integer; const aFilename: String); overload;
protected
function GenerateMessage: String; override;
public
Identifier: String;
constructor Create(const aIdentifier: String; const aSender: TObject); overload;
constructor Create(const aIdentifier: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengOutOfRange = class(EengShaderPartInternal) EengOutOfRange = class(EengShaderPartInternal)
constructor Create(const aMin, aMax, aIndex, aLine, aCol: Integer; const aFilename: String); overload;
protected
function GenerateMessage: String; override;
public
Min: Integer;
Max: Integer;
Index: Integer;
constructor Create(const aMin, aMax, aIndex: Integer; const aSender: TObject); overload;
constructor Create(const aMin, aMax, aIndex, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengDuplicateIdentifier = class(EengShaderPart)
protected
function GenerateMessage: String; override;
public
Name: String;
New: TObject;
Old: TObject;
constructor Create(const aName: String; const aNew, aOld, aSender: TObject); overload;
constructor Create(const aName: String; const aNew, aOld: TObject; aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
end; end;


implementation implementation


uses
uengShaderPart;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//EengShaderPart//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengShaderPart////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengShaderPart.Create(const aMsg: String; const aLine, aCol: Integer; const aFilename: String);
function EengShaderPart.GenerateMessage: String;
begin
result := ''; // DUMMY
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure EengShaderPart.PrintTrace(const aLines: TStrings);

function GetName(const aPart: TengShaderPart): String;
begin
result := aPart.GetTokenName;
if (result = '')
then result := aPart.ClassName
else result := result + ' (' + aPart.ClassName + ')';
end;

var
p: TengShaderPart;
begin
if not Assigned(Sender) or not
(Sender is TengShaderPart) then
exit;
p := (Sender as TengShaderPart);
aLines.Text := Message;
while Assigned(p) do begin
aLines.Add(Format('%s (%d:%d): %s', [p.Filename, p.Line, p.Col, GetName(p)]));
p := p.Parent;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function EengShaderPart.PrintTrace: String;
var
sl: TStringList;
begin
sl := TStringList.Create;
try
PrintTrace(sl);
result := sl.Text;
finally
FreeAndNil(sl);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengShaderPart.Create(const aSender: TObject);
begin
Create(GenerateMessage, aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengShaderPart.Create(const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
begin
Create(GenerateMessage, aLine, aCol, aFilename, aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengShaderPart.Create(const aMsg: String; const aSender: TObject);
begin
Sender := nil;
if Assigned(aSender)
then Create(
aMsg,
(aSender as TengShaderPart).Line,
(aSender as TengShaderPart).Col,
(aSender as TengShaderPart).Filename,
aSender)
else inherited Create(Format('%s: %s', [
ClassName,
aMsg]));
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengShaderPart.Create(const aMsg: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
begin begin
inherited Create(Format('%s (file: %s; line: %d; col: %d): %s', [ClassName, ExtractFileName(aFilename), aLine+1, aCol, aMsg]));
Sender := aSender;
Line := aLine; Line := aLine;
Col := aCol; Col := aCol;
Filename := aFilename; Filename := aFilename;
inherited Create(Format('%s (%s %d:%d): %s',[
ClassName,
ExtractFileName(Filename),
Line+1,
Col,
aMsg]))
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//EengInvalidToken////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengInvalidToken//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidToken.Create(const aClassName: String; const aToken: String; const aLine, aCol: Integer; const aFilename: String);
function EengInvalidToken.GenerateMessage: String;
begin begin
inherited Create('invalid token: ' + aClassName + ' <> '+ aToken, aLine, aCol, aFilename);
result := 'invalid token: ' + SenderClassName + ' <> '+ Token;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidToken.Create(const aSenderClassName: String; const aToken: String; const aSender: TObject);
begin
SenderClassName := aSenderClassName;
Token := aToken;
inherited Create(aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidToken.Create(const aSenderClassName: String; const aToken: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
begin
SenderClassName := aSenderClassName;
Token := aToken;
inherited Create(aLine, aCol, aFilename, aSender);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//EengUnexpectedToken/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengUnexpectedToken///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengUnexpectedToken.Create(const aToken, aExpected: String; const aLine, aCol: Integer; const aFilename: String);
var
s: String;
function EengUnexpectedToken.GenerateMessage: String;
begin begin
s := 'unexpected token: ' + aToken;
if (aExpected <> '') then
s := s + '(expected ' + aExpected + ')';
inherited Create(s, aLine, aCol, aFilename);
result := 'unexpected token: ' + Token;
if (Expected <> '') then
result := result + '(expected ' + Expected + ')';
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengUnexpectedToken.Create(const aToken, aExpected: String; const aSender: TObject);
begin
Token := aToken;
Expected := aExpected;
inherited Create(aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengUnexpectedToken.Create(const aToken, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
begin
Token := aToken;
Expected := aExpected;
inherited Create(aLine, aCol, aFilename, aSender);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//EengInvalidParamter/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengInvalidParamter///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidParamter.Create(const aParam, aExpected: String; const aLine, aCol: Integer; const aFilename: String);
var
s: String;
function EengInvalidParamter.GenerateMessage: String;
begin
result := 'invalid parameter: ' + Param;
if (Expected <> '') then
result := result + '(expected ' + Expected + ')';
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidParamter.Create(const aParam, aExpected: String; const aSender: TObject);
begin
Param := aParam;
Expected := aExpected;
inherited Create(aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidParamter.Create(const aParam, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
begin begin
s := 'invalid parameter: ' + aParam;
if (aExpected <> '') then
s := s + '(expected ' + aExpected + ')';
inherited Create(s, aLine, aCol, aFilename);
Param := aParam;
Expected := aExpected;
inherited Create(aLine, aCol, aFilename, aSender);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//EengInvalidParamterCount////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengInvalidParamterCount//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidParamterCount.Create(const aToken: String; const aExpected, aLine, aCol: Integer; const aFilename: String);
function EengInvalidParamterCount.GenerateMessage: String;
begin begin
inherited Create('invalid parameter count in ' + aToken + '(expected ' + IntToStr(aExpected) + ' parameter)', aLine, aCol, aFilename);
result := 'invalid parameter count in ' + Token + '(expected ';
if (ExpectedMin = ExpectedMax) then
result := result + IntToStr(ExpectedMin)
else if (ExpectedMax < 0) then
result := result + ' at least ' + IntToStr(ExpectedMin)
else
result := IntToStr(ExpectedMin) + ' to ' + IntToStr(ExpectedMax);
result := result + 'parameter)';
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidParamterCount.Create(const aToken: String; const aExpectedMin, aExpectedMax, aLine, aCol: Integer; const aFilename: String);
var
s: String;
constructor EengInvalidParamterCount.Create(const aToken: String; const aExpected: Integer; const aSender: TObject);
begin
Token := aToken;
ExpectedMin := aExpected;
ExpectedMax := aExpected;
inherited Create(aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidParamterCount.Create(const aToken: String; const aExpectedMin, aExpectedMax: Integer; const aSender: TObject);
begin
Token := aToken;
ExpectedMin := aExpectedMin;
ExpectedMax := aExpectedMax;
inherited Create(aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidParamterCount.Create(const aToken: String; const aExpected, aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
begin
Token := aToken;
ExpectedMin := aExpected;
ExpectedMax := aExpected;
inherited Create(aLine, aCol, aFilename, aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidParamterCount.Create(const aToken: String; const aExpectedMin, aExpectedMax, aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
begin begin
s := 'invalid parameter count in ' + aToken + '(expected ';
if (aExpectedMax < 0)
then s := s + ' at least '+ IntToStr(aExpectedMin)
else s := s + IntToStr(aExpectedMin) + ' to ' + IntToStr(aExpectedMax);
s := s + ' parameter)';
inherited Create(s, aLine, aCol, aFilename);
Token := aToken;
ExpectedMin := aExpectedMin;
ExpectedMax := aExpectedMax;
inherited Create(aLine, aCol, aFilename, aSender);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//EengInvalidIdentifier///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengInvalidIdentifier/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidIdentifier.Create(const aIdentifier: String; const aLine, aCol: Integer; const aFilename: String);
function EengInvalidIdentifier.GenerateMessage: String;
begin begin
inherited Create('invalid identifier: ' + aIdentifier, aLine, aCol, aFilename);
result := 'invalid identifier: ' + Identifier;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidIdentifier.Create(const aIdentifier: String; const aSender: TObject);
begin
Identifier := aIdentifier;
inherited Create(aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengInvalidIdentifier.Create(const aIdentifier: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
begin
Identifier := aIdentifier;
inherited Create(aLine, aCol, aFilename, aSender);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//EengOutOfRange//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengOutOfRange////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengOutOfRange.Create(const aMin, aMax, aIndex, aLine, aCol: Integer; const aFilename: String);
function EengOutOfRange.GenerateMessage: String;
begin
result := format('index (%d) out of range (%d:%d)', [Index, Min, Max])
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengOutOfRange.Create(const aMin, aMax, aIndex: Integer; const aSender: TObject);
begin
Min := aMin;
Max := aMax;
Index := aIndex;
inherited Create(aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengOutOfRange.Create(const aMin, aMax, aIndex, aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
begin
Min := aMin;
Max := aMax;
Index := aIndex;
inherited Create(aLine, aCol, aFilename, aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//EengDuplicateIdentifier///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function EengDuplicateIdentifier.GenerateMessage: String;
begin
result := 'duplicate identifier: ' + Name;
if (New is TengShaderPart) then
result := result + Format('(%s %d:%d)', [
(New as TengShaderPart).Filename,
(New as TengShaderPart).Line,
(New as TengShaderPart).Col]);
if (Old is TengShaderPart) then
result := result + Format('(previously declared here %s %d:%d)', [
(Old as TengShaderPart).Filename,
(Old as TengShaderPart).Line,
(Old as TengShaderPart).Col]);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengDuplicateIdentifier.Create(const aName: String; const aNew, aOld, aSender: TObject);
begin
Name := aName;
New := aNew;
Old := aOld;
inherited Create(aSender);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor EengDuplicateIdentifier.Create(const aName: String; const aNew, aOld: TObject; aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
begin begin
inherited Create(format('index (%d) out of range (%d:%d)', [aIndex, aMin, aMax]), aLine, aCol, aFilename);
Name := aName;
New := aNew;
Old := aOld;
inherited Create(aLine, aCol, aFilename, aSender);
end; end;


end. end.


+ 69
- 39
uengShaderPart.pas 查看文件

@@ -11,19 +11,25 @@ uses
uengShaderFileParser, uengShaderFileTypes uengShaderFileParser, uengShaderFileTypes


{$IFDEF USE_BITSPACE_UTILS} {$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics;
, uutlGenerics
{$ELSE} {$ELSE}
, fgl;
, fgl
{$ENDIF} {$ENDIF}
;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderFileSearchFlag = ( TengShaderFileSearchFlag = (
sfFirstOnly, // search first match only
sfEvaluateIf, // evaluate if statements before search and process with suitable subtree
sfSearchChildren, // search in children
sfSearchParents, // search in parents
sfCurrentFileOnly // do not search in other files
sfFirstOnly, // search first match only
sfEvaluateIf, // evaluate if statements before search and process with suitable subtree

sfSearchChildren, // search in children
sfSearchParents, // search in parents
sfSearchInherited, // search in inherited

sfCurrentFileOnly, // do not leave current file
sfCurrentScopeOnly, // do not leave current scopes
sfCurrentGeneratorOnly // do not leave current generator
); );
TengShaderFileSearchFlags = set of TengShaderFileSearchFlag; TengShaderFileSearchFlags = set of TengShaderFileSearchFlag;


@@ -44,17 +50,18 @@ type
constructor Create(const aOwner: TengShaderPart); constructor Create(const aOwner: TengShaderPart);
end; end;


TSearchList = class(TengShaderPartList)
TSearchResults = class(specialize TutlHashSet<TengShaderPart>)
public public
constructor Create; constructor Create;
end; end;


{ Code Loading & Storage } { Code Loading & Storage }
private { members } private { members }
fRoot: TengShaderPart;
fParent: TengShaderPart; fParent: TengShaderPart;
fLine: Integer; fLine: Integer;
fCol: Integer; fCol: Integer;
protected
fRoot: TengShaderPart;
protected { virtual getter } protected { virtual getter }
function GetCount: Integer; virtual; function GetCount: Integer; virtual;
function GetChild(const aIndex: Integer): TengShaderPart; virtual; function GetChild(const aIndex: Integer): TengShaderPart; virtual;
@@ -68,8 +75,6 @@ type
function ParseText(const aArgs: TengParseArgs): String; function ParseText(const aArgs: TengParseArgs): String;


{ General } { General }
protected
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList); virtual;
public { general methods } public { general methods }
property Root: TengShaderPart read fRoot; property Root: TengShaderPart read fRoot;
property Parent: TengShaderPart read fParent; property Parent: TengShaderPart read fParent;
@@ -86,8 +91,12 @@ type


function HasParent(const aType: CengShaderPart; const aIncludeSelf: Boolean = false): Boolean; function HasParent(const aType: CengShaderPart; const aIncludeSelf: Boolean = false): Boolean;
function GetParent(const aType: CengShaderPart; out aPart): Boolean; function GetParent(const aType: CengShaderPart; out aPart): Boolean;
function GetParent(const aType: CengShaderPart): TengShaderPart;

function FindFirst(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart): TengShaderPart; function FindFirst(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart): TengShaderPart;
procedure FindAll(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart; const aList: TSearchList);
procedure FindAll(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart; const aList: TSearchResults);
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchResults); virtual;

function GetEnumerator: TEnumerator; function GetEnumerator: TEnumerator;


constructor Create(const aParent: TengShaderPart); virtual; constructor Create(const aParent: TengShaderPart); virtual;
@@ -99,11 +108,16 @@ type
class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); virtual; class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); virtual;
end; end;


function CheckType(const aShaderPart: TengShaderPart; const aTypes: array of CengShaderPart): Boolean;

implementation implementation


uses uses
uengShaderFileConstants;
uengShaderPartScope, uengShaderCodeGenerator, uengShaderFile, uengShaderFileConstants;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Helper////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function CheckType(const aShaderPart: TengShaderPart; const aTypes: array of CengShaderPart): Boolean; function CheckType(const aShaderPart: TengShaderPart; const aTypes: array of CengShaderPart): Boolean;
var var
c: CengShaderPart; c: CengShaderPart;
@@ -141,9 +155,9 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart.TSearchList////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart.TSearchResults////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPart.TSearchList.Create;
constructor TengShaderPart.TSearchResults.Create;
begin begin
inherited Create(false); inherited Create(false);
end; end;
@@ -202,33 +216,13 @@ begin
fCol := aArgs.Col; fCol := aArgs.Col;
fLine := aArgs.Line; fLine := aArgs.Line;
if (GetTokenName <> '') then if (GetTokenName <> '') then
aArgs.ExtractToken(params);
aArgs.ExtractToken(self, params);
result := ParseIntern(aArgs, params); result := ParseIntern(aArgs, params);
finally finally
FreeAndNil(params); FreeAndNil(params);
end; end;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList);
var
c: TengShaderPart;
begin
if (sfFirstOnly in aFlags) and (aList.Count > 0) then
exit;

if CheckType(self, aTypes) then
aList.Add(self);

if (sfSearchChildren in aFlags) then begin
for c in self do
c.FindIntern(aFlags, aDepth+1, aTypes, aList);
end;

if (sfSearchParents in aFlags) and Assigned(Parent) then
Parent.FindIntern(aFlags, aDepth-1, aTypes, aList);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPart.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
begin begin
@@ -255,12 +249,19 @@ begin
result := false; result := false;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.GetParent(const aType: CengShaderPart): TengShaderPart;
begin
if not GetParent(aType, result) then
raise EengShaderPartInternal.Create(GetTokenName + ' ha sno parent of type ' + aType.GetTokenName, self);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.FindFirst(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart): TengShaderPart; function TengShaderPart.FindFirst(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart): TengShaderPart;
var var
l: TSearchList;
l: TSearchResults;
begin begin
l := TSearchList.Create;
l := TSearchResults.Create;
try try
FindIntern(aFlags + [sfFirstOnly], 0, aTypes, l); FindIntern(aFlags + [sfFirstOnly], 0, aTypes, l);
if (l.Count > 0) if (l.Count > 0)
@@ -272,11 +273,40 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.FindAll(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart; const aList: TSearchList);
procedure TengShaderPart.FindAll(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart; const aList: TSearchResults);
begin begin
FindIntern(aFlags, 0, aTypes, aList); FindIntern(aFlags, 0, aTypes, aList);
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchResults);
var
c: TengShaderPart;
begin
if (sfFirstOnly in aFlags) and (aList.Count > 0) then
exit;

if (sfSearchChildren in aFlags) then begin
for c in self do
if (not (sfCurrentScopeOnly in aFlags) or not (c is TengShaderPartScope)) and
(not (sfCurrentFileOnly in aFlags) or not (c is TengShaderFile)) and
(not (sfCurrentGeneratorOnly in aFlags) or not (c is TengShaderCodeGenerator))
then
c.FindIntern(aFlags, aDepth+1, aTypes, aList);
end;

if CheckType(self, aTypes) then
aList.Add(self);

if (sfSearchParents in aFlags) and
Assigned(Parent) and
(not (sfCurrentScopeOnly in aFlags) or not (self is TengShaderPartScope)) and
(not (sfCurrentFileOnly in aFlags) or not (self is TengShaderFile)) and
(not (sfCurrentGeneratorOnly in aFlags) or not (self is TengShaderCodeGenerator))
then
Parent.FindIntern(aFlags, aDepth-1, aTypes, aList);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.GetEnumerator: TEnumerator; function TengShaderPart.GetEnumerator: TEnumerator;
begin begin


+ 5
- 5
uengShaderPartCall.pas 查看文件

@@ -74,15 +74,15 @@ var
i: Integer; i: Integer;
begin begin
if (aParams[0].Name <> GetTokenName) then if (aParams[0].Name <> GetTokenName) then
raise EengInvalidToken.Create(ClassName, aParams[0].Name, Line, Col, Filename);
raise EengInvalidToken.Create(ClassName, aParams[0].Name, Line, Col, Filename, self);
if (aParams.Count < 2) then if (aParams.Count < 2) then
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);


result := ''; result := '';
fParameters.Clear; fParameters.Clear;
with aParams[1] do begin with aParams[1] do begin
if not IsValidIdentifier(fName) then if not IsValidIdentifier(fName) then
raise EengInvalidIdentifier.Create(Name, Line, Col, Filename);
raise EengInvalidIdentifier.Create(Name, self);
fName := Name; fName := Name;
end; end;
for i := 2 to aParams.Count-1 do for i := 2 to aParams.Count-1 do
@@ -123,14 +123,14 @@ var
i: Integer; i: Integer;
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);
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);


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


+ 36
- 11
uengShaderPartClass.pas 查看文件

@@ -7,7 +7,12 @@ interface


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderCodeGenerator, uengShaderFileParser;
uengShaderPart, uengShaderCodeGenerator, uengShaderFileParser

{$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics
{$ENDIF}
;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -32,12 +37,14 @@ type
{ Class Methods } { Class Methods }
public public
class function GetTokenName: String; override; class function GetTokenName: String; override;
class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); override;
end; end;
TengShaderPartClassMap = specialize TutlMap<string, TengShaderPartClass>;


implementation implementation


uses uses
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;
uengShaderFile, uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartIf;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartClass/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartClass///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -68,27 +75,24 @@ function TengShaderPartClass.ParseIntern(const aArgs: TengParseArgs; const aPara
var var
i: Integer; i: Integer;
begin begin
if (aParams[0].Name <> GetTokenName) then
raise EengInvalidToken.Create(ClassName, aParams[0].Name, Line, Col, Filename);
if (aParams[0].Name <> GetTokenName) then with aParams[0] do
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count < 2) then if (aParams.Count < 2) then
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);
with aParams[1] do begin with aParams[1] do begin
if not IsValidIdentifier(Name) then if not IsValidIdentifier(Name) then
raise EengInvalidIdentifier.Create(Name, Line, Col, Filename);
raise EengInvalidIdentifier.Create(Name, self);
fName := Name; fName := Name;
end; end;
if (aParams.Count > 2) then begin if (aParams.Count > 2) then begin
if (aParams.Count < 4) then if (aParams.Count < 4) then
raise EengInvalidParamterCount.Create(GetTokenName, 4, -1, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 4, -1, self);
if (aParams[2].Name <> TOKEN_EXTENDS) then with aParams[2] do if (aParams[2].Name <> TOKEN_EXTENDS) then with aParams[2] do
raise EengInvalidParamter.Create(aParams[2].Name, TOKEN_EXTENDS, Line, Col, Filename);
raise EengInvalidParamter.Create(aParams[2].Name, TOKEN_EXTENDS, Line, Col, Filename, self);
fExtends.Clear; fExtends.Clear;
for i := 3 to aParams.Count-1 do for i := 3 to aParams.Count-1 do
fExtends.Add(aParams[i].Name); fExtends.Add(aParams[i].Name);
end; end;

// TODO fRoot.AddClass ?

result := inherited ParseIntern(aArgs, aParams); result := inherited ParseIntern(aArgs, aParams);
result := CheckEndToken(aArgs, self); result := CheckEndToken(aArgs, self);
end; end;
@@ -113,5 +117,26 @@ begin
result := TOKEN_CLASS; result := TOKEN_CLASS;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class procedure TengShaderPartClass.Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart);

procedure RaiseEx(const aToken: String);
begin
with aArgs do
raise EengShaderPart.Create('token ' + GetTokenName + ' is not allowed in ' + aToken, Line, Col, Filename, aParent);
end;

begin
inherited Validate(aArgs, aParent);
if aParent.HasParent(TengShaderPartElIf, true) then
RaiseEx(TengShaderPartElIf.GetTokenName);
if aParent.HasParent(TengShaderPartElse, true) then
RaiseEx(TengShaderPartElse.GetTokenName);
if aParent.HasParent(TengShaderPartIf, true) then
RaiseEx(TengShaderPartIf.GetTokenName);
if aParent.HasParent(TengShaderPartClass, true) then
RaiseEx(TengShaderPartClass.GetTokenName);
end;

end. end.



+ 1
- 1
uengShaderPartCntr.pas 查看文件

@@ -23,7 +23,7 @@ type
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;
public { general methods } public { general methods }
procedure Clear;
procedure Clear; virtual;
constructor Create(const aParent: TengShaderPart); override; constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override; destructor Destroy; override;
end; end;


+ 1
- 1
uengShaderPartComment.pas 查看文件

@@ -39,7 +39,7 @@ end;
function TengShaderPartComment.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartComment.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
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);
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count > 1) then if (aParams.Count > 1) then
fText := aParams[1].Name; fText := aParams[1].Name;
result := ''; result := '';


+ 3
- 3
uengShaderPartEcho.pas 查看文件

@@ -41,13 +41,13 @@ end;
function TengShaderPartEcho.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartEcho.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
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);
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count <> 2) then if (aParams.Count <> 2) then
raise EengInvalidParamterCount.Create(GetTokenName, 2, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 2, self);
result := ''; result := '';
with aParams[1] do begin with aParams[1] do begin
if not IsValidIdentifier(Name) then if not IsValidIdentifier(Name) then
raise EengInvalidIdentifier.Create(Name, Line, Col, Filename);
raise EengInvalidIdentifier.Create(Name, self);
fName := Name; fName := Name;
end; end;
end; end;


+ 23
- 5
uengShaderPartIf.pas 查看文件

@@ -27,6 +27,7 @@ type


{ General } { General }
public public
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchResults); override;
destructor Destroy; override; destructor Destroy; override;


{ Class Methods } { Class Methods }
@@ -103,7 +104,7 @@ end;
function TengShaderPartIf.GetChild(const aIndex: Integer): TengShaderPart; function TengShaderPartIf.GetChild(const aIndex: Integer): TengShaderPart;
begin begin
if (aIndex < 0) or (aIndex >= Count) then if (aIndex < 0) or (aIndex >= Count) then
raise EengOutOfRange.Create(0, Count-1, aIndex, Line, Col, Filename);
raise EengOutOfRange.Create(0, Count-1, aIndex, self);
case aIndex of case aIndex of
0: result := fIfPart; 0: result := fIfPart;
1: result := fElsePart; 1: result := fElsePart;
@@ -123,17 +124,34 @@ end;
function TengShaderPartIf.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartIf.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
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);
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count < 2) then if (aParams.Count < 2) then
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);


fExpression := ParseExpression(aParams, 1);
fExpression := ParseExpression(self, aParams, 1);


fIfPart := TengShaderPartCntr.Create(self); fIfPart := TengShaderPartCntr.Create(self);
result := fIfPart.ParseText(aArgs); result := fIfPart.ParseText(aArgs);
result := HandleToken(result, aArgs); result := HandleToken(result, aArgs);
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartIf.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchResults);
begin
if (sfEvaluateIf in aFlags) then begin
inherited FindIntern(aFlags - [sfSearchChildren], aDepth, aTypes, aList);
if (sfSearchChildren in aFlags) then begin
if fExpression.GetValue then begin
if Assigned(fIfPart) then
fIfPart.FindIntern(aFlags, aDepth, aTypes, aList);
end else begin
if Assigned(fElsePart) then
fElsePart.FindIntern(aFlags, aDepth, aTypes, aList);
end;
end;
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TengShaderPartIf.Destroy; destructor TengShaderPartIf.Destroy;
begin begin
@@ -156,7 +174,7 @@ function TengShaderPartElIf.HandeEndToken(const aToken: String; const aArgs: Ten
begin begin
result := aToken; result := aToken;
if (result <> TOKEN_END) then if (result <> TOKEN_END) then
raise EengInvalidToken.Create(ClassName, result, aArgs.Line, aArgs.Col, Filename);
raise EengInvalidToken.Create(ClassName, result, aArgs.Line, aArgs.Col, Filename, self);
end; end;


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


+ 10
- 20
uengShaderPartInclude.pas 查看文件

@@ -17,7 +17,7 @@ type
fShaderFile: TengShaderFile; fShaderFile: TengShaderFile;
fIncludeFile: String; fIncludeFile: String;
fAbsoluteFile: String; fAbsoluteFile: String;
procedure LoadShaderFile(const aFlags: TengShaderFileLoadFlags);
procedure LoadShaderFile;
protected protected
function GetCount: Integer; override; function GetCount: Integer; override;
function GetChild(const aIndex: Integer): TengShaderPart; override; function GetChild(const aIndex: Integer): TengShaderPart; override;
@@ -25,10 +25,9 @@ type
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ General } { General }
protected
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList); override;
public public
property IncludeFile: String read fIncludeFile;
property IncludeFile: String read fIncludeFile;
property ShaderFile: TengShaderFile read fShaderFile;
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil); procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
constructor Create(const aParent: TengShaderPart); override; constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override; destructor Destroy; override;
@@ -47,12 +46,12 @@ uses
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartInclude///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartInclude/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.LoadShaderFile(const aFlags: TengShaderFileLoadFlags);
procedure TengShaderPartInclude.LoadShaderFile;
begin begin
if not Assigned(fShaderFile) then if not Assigned(fShaderFile) then
fShaderFile := TengShaderFile.Create(self); fShaderFile := TengShaderFile.Create(self);
if (fShaderFile.Filename <> fAbsoluteFile) then if (fShaderFile.Filename <> fAbsoluteFile) then
fShaderFile.LoadFromFile(fAbsoluteFile, aFlags);
fShaderFile.LoadFromFile(fAbsoluteFile);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -68,7 +67,7 @@ function TengShaderPartInclude.GetChild(const aIndex: Integer): TengShaderPart;
begin begin
if Assigned(fShaderFile) and (aIndex = 0) if Assigned(fShaderFile) and (aIndex = 0)
then result := fShaderFile then result := fShaderFile
else raise EengOutOfRange.Create(0, Count-1, aIndex, Line, Col, Filename);
else raise EengOutOfRange.Create(0, Count-1, aIndex, self);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -81,28 +80,19 @@ end;
function TengShaderPartInclude.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartInclude.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
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);
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count <> 2) then if (aParams.Count <> 2) then
raise EengInvalidParamterCount.Create(GetTokenName, 2, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 2, self);
fIncludeFile := aParams[1].Name; fIncludeFile := aParams[1].Name;
fAbsoluteFile := CreateAbsolutePath(fIncludeFile, ExtractFilePath(Filename)); fAbsoluteFile := CreateAbsolutePath(fIncludeFile, ExtractFilePath(Filename));
result := ''; result := '';
if not (lfLazyInclude in aArgs.Flags) then
LoadShaderFile(aArgs.Flags);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList);
begin
if (sfCurrentFileOnly in aFlags) then
exclude(aFlags, sfSearchChildren);
inherited FindIntern(aFlags, aDepth, aTypes, aList);
LoadShaderFile;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter); procedure TengShaderPartInclude.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
begin begin
LoadShaderFile([]);
LoadShaderFile;
fIncludeFile := Format('%p_', [Pointer(fShaderFile)]) + ExtractFileName(fIncludeFile); fIncludeFile := Format('%p_', [Pointer(fShaderFile)]) + ExtractFileName(fIncludeFile);
fAbsoluteFile := CreateAbsolutePath(fIncludeFile, ExtractFilePath(aFilename)); fAbsoluteFile := CreateAbsolutePath(fIncludeFile, ExtractFilePath(aFilename));
fShaderFile.SaveToFile(fAbsoluteFile, aFileWriter); fShaderFile.SaveToFile(fAbsoluteFile, aFileWriter);


+ 32
- 5
uengShaderPartKeyValuePair.pas 查看文件

@@ -7,7 +7,12 @@ interface


uses uses
Classes, SysUtils, variants, Classes, SysUtils, variants,
uengShaderPart, uengShaderFileParser;
uengShaderPart, uengShaderFileParser

{$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics
{$ENDIF}
;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -33,7 +38,9 @@ type
{ Class Methods } { Class Methods }
public public
class function GetTokenName: String; override; class function GetTokenName: String; override;
class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); override;
end; end;
TengShaderPartPropertyMap = specialize TutlMap<string, TengShaderPartProperty>;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartDefine = class(TengShaderPartKeyValuePair) TengShaderPartDefine = class(TengShaderPartKeyValuePair)
@@ -45,7 +52,7 @@ type
implementation implementation


uses uses
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartIf;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartKeyValuePair//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartKeyValuePair////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -64,19 +71,20 @@ end;
function TengShaderPartKeyValuePair.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartKeyValuePair.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
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, GetTokenName, Line, Col, Filename);
raise EengInvalidToken.Create(ClassName, GetTokenName, Line, Col, Filename, self);
if (aParams.Count < 2) or (aParams.Count > 3) then if (aParams.Count < 2) or (aParams.Count > 3) then
raise EengInvalidParamterCount.Create(GetTokenName, 2, 3, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 2, 3, self);


result := ''; result := '';
fName := aParams[1].Name; fName := aParams[1].Name;
if not IsValidIdentifier(fName) then with aParams[1] do if not IsValidIdentifier(fName) then with aParams[1] do
raise EengInvalidIdentifier.Create(fName, Line, Col, Filename);
raise EengInvalidIdentifier.Create(fName, Line, Col, Filename, self);
if (aParams.Count >= 3) then if (aParams.Count >= 3) then
if aParams[2].Quoted then begin if aParams[2].Quoted then begin
fValue := aParams[2].Name; fValue := aParams[2].Name;
fValueName := ''; fValueName := '';
end else begin end else begin
// TODO resolve name and set value
fValue := Unassigned; fValue := Unassigned;
fValueName := aParams[2].Name; fValueName := aParams[2].Name;
end end
@@ -94,6 +102,25 @@ begin
result := TOKEN_PROPERTY; result := TOKEN_PROPERTY;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class procedure TengShaderPartProperty.Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart);

procedure RaiseEx(const aToken: String);
begin
with aArgs do
raise EengShaderPart.Create('token ' + GetTokenName + ' is not allowed in ' + aToken, Line, Col, Filename, aParent);
end;

begin
inherited Validate(aArgs, aParent);
if aParent.HasParent(TengShaderPartElIf, true) then
RaiseEx(TengShaderPartElIf.GetTokenName);
if aParent.HasParent(TengShaderPartElse, true) then
RaiseEx(TengShaderPartElse.GetTokenName);
if aParent.HasParent(TengShaderPartIf, true) then
RaiseEx(TengShaderPartIf.GetTokenName);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartDefine////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartDefine//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 8
- 8
uengShaderPartMeta.pas 查看文件

@@ -105,9 +105,9 @@ var
n: String; n: String;
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);
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count < 2) then if (aParams.Count < 2) then
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);


result := ''; result := '';
n := aParams[1].Name; n := aParams[1].Name;
@@ -117,26 +117,26 @@ begin
t := metaVersion; t := metaVersion;
if (aParams.Count = 3) then begin if (aParams.Count = 3) then begin
if (aParams[2].Name <> VERSION_EXTRA_COMPAT) and not TryStrToInt(aParams[2].Name, i) then with aParams[2] do if (aParams[2].Name <> VERSION_EXTRA_COMPAT) and not TryStrToInt(aParams[2].Name, i) then with aParams[2] do
raise EengInvalidParamter.Create('version must be an number or "' + VERSION_EXTRA_COMPAT + '"', Line, Col, Filename);
raise EengInvalidParamter.Create('version must be an number or "' + VERSION_EXTRA_COMPAT + '"', Line, Col, Filename, self);
end else if (aParams.Count = 4) then begin end else if (aParams.Count = 4) then begin
if (aParams[2].Name <> VERSION_EXTRA_COMPAT) and not TryStrToInt(aParams[2].Name, i) then with aParams[2] do if (aParams[2].Name <> VERSION_EXTRA_COMPAT) and not TryStrToInt(aParams[2].Name, i) then with aParams[2] do
raise EengInvalidParamter.Create('version must be an number or "' + VERSION_EXTRA_COMPAT + '"', Line, Col, Filename);
raise EengInvalidParamter.Create('version must be an number or "' + VERSION_EXTRA_COMPAT + '"', Line, Col, Filename, self);
if (aParams[3].Name <> VERSION_EXTRA_COMPAT) then with aParams[3] do if (aParams[3].Name <> VERSION_EXTRA_COMPAT) then with aParams[3] do
raise EengInvalidParamter.Create('only "' + VERSION_EXTRA_COMPAT + '" is alowed as second parameter', Line, Col, Filename);
raise EengInvalidParamter.Create('only "' + VERSION_EXTRA_COMPAT + '" is alowed as second parameter', Line, Col, Filename, self);
end else end else
raise EengInvalidParamterCount.Create(GetTokenName, 3, 4, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 3, 4, self);


{.$EXTENSION} {.$EXTENSION}
end else if (n = TOKEN_EXTENSION) then begin end else if (n = TOKEN_EXTENSION) then begin
t := metaExtension; t := metaExtension;
if (aParams.Count <> 4) then if (aParams.Count <> 4) then
raise EengInvalidParamterCount.Create(GetTokenName, 4, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 4, self);


{.$LAYOUT} {.$LAYOUT}
end else if (n = TOKEN_LAYOUT) then begin end else if (n = TOKEN_LAYOUT) then begin
t := metaLayout; t := metaLayout;
if (aParams.Count <> 3) then if (aParams.Count <> 3) then
raise EengInvalidParamterCount.Create(GetTokenName, 3, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 3, self);


{.VALUES} {.VALUES}
end else end else


+ 4
- 4
uengShaderPartParameter.pas 查看文件

@@ -78,9 +78,9 @@ end;
function TengShaderPartParameter.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartParameter.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
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);
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count <> 3) then if (aParams.Count <> 3) then
raise EengInvalidParamterCount.Create(GetTokenName, 3, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 3, self);


result := ''; result := '';
fType := aParams[1].Name; fType := aParams[1].Name;
@@ -104,9 +104,9 @@ end;
function TengShaderPartVar.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartVar.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
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);
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count < 3) or (aParams.Count > 4) then if (aParams.Count < 3) or (aParams.Count > 4) then
raise EengInvalidParamterCount.Create(GetTokenName, 3, 4, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 3, 4, self);


result := ''; result := '';
fType := aParams[1].Name; fType := aParams[1].Name;


+ 9
- 9
uengShaderPartProc.pas 查看文件

@@ -113,9 +113,9 @@ var
param: TengShaderPartProcParam; param: TengShaderPartProcParam;
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);
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count < 2) then if (aParams.Count < 2) then
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);


i := 2; i := 2;
result := ''; result := '';
@@ -135,7 +135,7 @@ begin
pasName: begin pasName: begin
if (aParams[i].Name = TOKEN_INLINE) then begin if (aParams[i].Name = TOKEN_INLINE) then begin
with aParams[i] do with aParams[i] do
raise EengInvalidParamter.Create('expected parameter name (found ' + TOKEN_INLINE + ')', Line, Col, Filename);
raise EengInvalidParamter.Create('expected parameter name (found ' + TOKEN_INLINE + ')', Line, Col, Filename, self);
end else begin end else begin
param.Name := aParams[i].Name; param.Name := aParams[i].Name;
fParameters.Add(param); fParameters.Add(param);
@@ -146,7 +146,7 @@ begin
inc(i); inc(i);
end; end;
if (state <> pasType) then if (state <> pasType) then
raise EengInvalidParamterCount.Create('invalid parameter count in ' + GetTokenName + '(expected multiple of 2)', Line, Col, Filename);
raise EengInvalidParamterCount.Create('invalid parameter count in ' + GetTokenName + '(expected multiple of 2)', self);
inherited ParseIntern(aArgs, aParams); inherited ParseIntern(aArgs, aParams);
result := CheckEndToken(aArgs, self); result := CheckEndToken(aArgs, self);
end; end;
@@ -176,7 +176,7 @@ class procedure TengShaderPartProc.Validate(const aArgs: TengParseArgs; const aP
begin begin
if (aParent.HasParent(TengShaderPartProc, true)) then with aArgs do if (aParent.HasParent(TengShaderPartProc, true)) then with aArgs do
raise EengShaderPart.Create('token ' + GetTokenName + ' is not allowed inside ' + raise EengShaderPart.Create('token ' + GetTokenName + ' is not allowed inside ' +
TOKEN_PROC + ', ' + TOKEN_FUNC + ' or + ' + TOKEN_MAIN, Line, Col, aParent.Filename);
TOKEN_PROC + ', ' + TOKEN_FUNC + ' or + ' + TOKEN_MAIN, Line, Col, aParent.Filename, aParent);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -193,9 +193,9 @@ var
p: TengTokenParameter; p: TengTokenParameter;
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);
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count <> 1) then if (aParams.Count <> 1) then
raise EengInvalidParamterCount.Create(GetTokenName, 1, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 1, self);


result := ''; result := '';
p.Name := 'main'; p.Name := 'main';
@@ -232,9 +232,9 @@ end;
function TengShaderPartFunc.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartFunc.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
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, aParams[0].Name, Line, Col, Filename);
raise EengInvalidToken.Create(ClassName, aParams[0].Name, Line, Col, Filename, self);
if (aParams.Count < 3) then if (aParams.Count < 3) then
raise EengInvalidParamterCount.Create(GetTokenName, 3, Line, Col, Filename);
raise EengInvalidParamterCount.Create(GetTokenName, 3, self);


fReturnType := aParams[1].Name; fReturnType := aParams[1].Name;
aParams.Delete(1); aParams.Delete(1);


+ 1
- 0
uengShaderPartScope.pas 查看文件

@@ -10,6 +10,7 @@ uses
uengShaderPartCntr; uengShaderPartCntr;


type type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartScope = class(TengShaderPartCntr) TengShaderPartScope = class(TengShaderPartCntr)


end; end;


+ 2
- 2
uengShaderPartText.pas 查看文件

@@ -75,7 +75,7 @@ begin
fText := ''; fText := '';
result := ''; result := '';
while not aArgs.EndOfLine do begin while not aArgs.EndOfLine do begin
if aArgs.GetTokenPreview(result) then begin
if aArgs.GetTokenPreview(self, result) then begin
exit; exit;
end else if (aArgs.CurrentChar in COMMAND_END_TOKENS) then begin end else if (aArgs.CurrentChar in COMMAND_END_TOKENS) then begin
result := aArgs.CurrentChar; result := aArgs.CurrentChar;
@@ -100,7 +100,7 @@ end;
function TengShaderPartLineBreak.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartLineBreak.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
begin begin
if not aArgs.EndOfLine then if not aArgs.EndOfLine then
raise EengInvalidToken.Create(ClassName, '[LineBreak]', Line, Col, Filename);
raise EengInvalidToken.Create(ClassName, '[LineBreak]', self);
aArgs.NextLine; aArgs.NextLine;
result := ''; result := '';
end; end;


正在加载...
取消
保存