| @@ -7,7 +7,7 @@ interface | |||||
| uses | uses | ||||
| Classes, SysUtils, | Classes, SysUtils, | ||||
| uengShaderFileParser, uengShaderPart, uengShaderPartScope, uengShaderPartKeyValuePair; | |||||
| uengShaderPart, uengShaderPartScope, uengShaderPartKeyValuePair; | |||||
| type | type | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -15,10 +15,6 @@ type | |||||
| { General } | { General } | ||||
| private | private | ||||
| fProperties: TengShaderPartPropertyMap; | fProperties: TengShaderPartPropertyMap; | ||||
| protected | |||||
| fInherited: TengShaderPartList; | |||||
| procedure UpdateInherited; virtual; | |||||
| procedure UpdateCache; override; | |||||
| public | public | ||||
| constructor Create(const aParent: TengShaderPart); override; | constructor Create(const aParent: TengShaderPart); override; | ||||
| destructor Destroy; override; | destructor Destroy; override; | ||||
| @@ -28,30 +24,17 @@ implementation | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderCodeGenerator/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TengShaderCodeGenerator/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderCodeGenerator.UpdateInherited; | |||||
| begin | |||||
| // DUMMY | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderCodeGenerator.UpdateCache; | |||||
| begin | |||||
| inherited UpdateCache; | |||||
| UpdateInherited; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| constructor TengShaderCodeGenerator.Create(const aParent: TengShaderPart); | constructor TengShaderCodeGenerator.Create(const aParent: TengShaderPart); | ||||
| begin | begin | ||||
| inherited Create(aParent); | inherited Create(aParent); | ||||
| fInherited := TengShaderPartList.Create(false); | |||||
| fProperties := TengShaderPartPropertyMap.Create(false); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| destructor TengShaderCodeGenerator.Destroy; | destructor TengShaderCodeGenerator.Destroy; | ||||
| begin | begin | ||||
| FreeAndNil(fInherited); | |||||
| FreeAndNil(fProperties); | |||||
| inherited Destroy; | inherited Destroy; | ||||
| end; | end; | ||||
| @@ -1,3 +1,3 @@ | |||||
| {$DEFINE EXPRESSION_ADD_BRACKET} // add brackets to expressions | |||||
| {.$DEFINE EXPRESSION_ADD_BRACKET} // add brackets to expressions | |||||
| {$DEFINE USE_BITSPACE_UTILS} // use bitSpace Utils | {$DEFINE USE_BITSPACE_UTILS} // use bitSpace Utils | ||||
| {$DEFINE DEBUG} // enable debug output | {$DEFINE DEBUG} // enable debug output | ||||
| @@ -21,6 +21,7 @@ uses | |||||
| type | type | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| TengShaderFileLogEvent = procedure(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String) of object; | |||||
| TengShaderFile = class(TengShaderCodeGenerator) | TengShaderFile = class(TengShaderCodeGenerator) | ||||
| { Code Loading & Storage } | { Code Loading & Storage } | ||||
| private | private | ||||
| @@ -36,19 +37,21 @@ type | |||||
| function GetFilename: String; override; | function GetFilename: String; override; | ||||
| function GetFileReader: IengShaderFileReader; override; | function GetFileReader: IengShaderFileReader; override; | ||||
| function GetFileWriter: IengShaderFileWriter; override; | function GetFileWriter: IengShaderFileWriter; override; | ||||
| public | |||||
| procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil); | |||||
| procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil); | |||||
| { General } | { General } | ||||
| private | private | ||||
| procedure UpdateClasses; | |||||
| fOnLog: TengShaderFileLogEvent; | |||||
| protected | protected | ||||
| procedure UpdateCache; override; | |||||
| procedure LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); override; | |||||
| public | public | ||||
| property Generator [const aName: String]: TengShaderCodeGenerator read GetGenerator; | property Generator [const aName: String]: TengShaderCodeGenerator read GetGenerator; | ||||
| property GeneratorNames[const aIndex: Integer]: String read GetGeneratorNames; | property GeneratorNames[const aIndex: Integer]: String read GetGeneratorNames; | ||||
| property GeneratorCount: Integer read GetGeneratorCount; | property GeneratorCount: Integer read GetGeneratorCount; | ||||
| property OnLog: TengShaderFileLogEvent read fOnLog write fOnLog; | |||||
| procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil); | |||||
| procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil); | |||||
| procedure Clear; override; | procedure Clear; override; | ||||
| constructor Create(const aParent: TengShaderPart); override; | constructor Create(const aParent: TengShaderPart); override; | ||||
| destructor Destroy; override; | destructor Destroy; override; | ||||
| @@ -107,35 +110,6 @@ begin | |||||
| result := Parent.FileWriter; | result := Parent.FileWriter; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderFile.UpdateClasses; | |||||
| var | |||||
| sr: TengShaderPart.TSearchResults; | |||||
| p: TengShaderPart; | |||||
| new, old: TengShaderPartClass; | |||||
| begin | |||||
| sr := TengShaderPart.TSearchResults.Create([TengShaderPartClass]); | |||||
| try | |||||
| fClasses.Clear; | |||||
| Find([sfSearchChildren], sr); | |||||
| for p in sr 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(sr); | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderFile.UpdateCache; | |||||
| begin | |||||
| inherited UpdateCache; | |||||
| UpdateClasses; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader); | procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader); | ||||
| @@ -161,8 +135,6 @@ begin | |||||
| 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, self); | raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename, self); | ||||
| if (Root = self) then | |||||
| UpdateCache; | |||||
| finally | finally | ||||
| FreeAndNil(args); | FreeAndNil(args); | ||||
| end; | end; | ||||
| @@ -174,7 +146,7 @@ end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter); | procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter); | ||||
| var | var | ||||
| sr: TengShaderPart.TSearchResults; | |||||
| sr: TengSearchResults; | |||||
| i: Integer; | i: Integer; | ||||
| sl: TStringList; | sl: TStringList; | ||||
| ms: TMemoryStream; | ms: TMemoryStream; | ||||
| @@ -185,11 +157,11 @@ begin | |||||
| if not Assigned(fFileWriter) then | if not Assigned(fFileWriter) then | ||||
| fFileWriter := TengShaderFileWriter.Create; | fFileWriter := TengShaderFileWriter.Create; | ||||
| sr := TengShaderPart.TSearchResults.Create([TengShaderPartInclude]); | |||||
| sr := TengSearchResults.Create([TengShaderPartInclude]); | |||||
| sl := TStringList.Create; | sl := TStringList.Create; | ||||
| ms := TMemoryStream.Create; | ms := TMemoryStream.Create; | ||||
| try | try | ||||
| Find([sfSearchChildren, sfChildrenFileOnly], sr); | |||||
| Find([sfSearchChildren, sfChildrenOnlyFile], sr); | |||||
| for i := 0 to sr.Count-1 do | for i := 0 to sr.Count-1 do | ||||
| (sr[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter); | (sr[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter); | ||||
| sl.Text := Text; | sl.Text := Text; | ||||
| @@ -204,6 +176,17 @@ begin | |||||
| end; | end; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderFile.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); | |||||
| var | |||||
| tmp: TengShaderFileLogEvent; | |||||
| begin | |||||
| inherited LogMsgIntern(aSender, aLogLevel, aMsg); | |||||
| tmp := fOnLog; | |||||
| if Assigned(tmp) then | |||||
| tmp(aSender, aLogLevel, aMsg); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderFile.Clear; | procedure TengShaderFile.Clear; | ||||
| begin | begin | ||||
| @@ -36,6 +36,7 @@ const | |||||
| TOKEN_PROPERTY = TOKEN_CHAR_IDENT + 'PROPERTY'; //{$PROPERTY InvertRoughmap 'false'} | TOKEN_PROPERTY = TOKEN_CHAR_IDENT + 'PROPERTY'; //{$PROPERTY InvertRoughmap 'false'} | ||||
| TOKEN_DEFINE = TOKEN_CHAR_IDENT + 'DEFINE'; //{$DEFINE RENDER_FACE_FRONT '0'} | TOKEN_DEFINE = TOKEN_CHAR_IDENT + 'DEFINE'; //{$DEFINE RENDER_FACE_FRONT '0'} | ||||
| TOKEN_UNDEF = TOKEN_CHAR_IDENT + 'UNDEF'; //{$UNDEF RENDER_FACE_FRONT} | |||||
| TOKEN_ECHO = TOKEN_CHAR_IDENT + 'ECHO'; //{$ECHO InvertRoughmap} | TOKEN_ECHO = TOKEN_CHAR_IDENT + 'ECHO'; //{$ECHO InvertRoughmap} | ||||
| TOKEN_VAR = TOKEN_CHAR_IDENT + 'VAR'; //{$VAR 'float' 'refractivity' '0.0'} | TOKEN_VAR = TOKEN_CHAR_IDENT + 'VAR'; //{$VAR 'float' 'refractivity' '0.0'} | ||||
| @@ -61,8 +62,6 @@ const | |||||
| TOKEN_OP_LOGICAL_OR = TOKEN_CHAR_IDENT + 'OR'; //{$IF test1 $OR test2} | TOKEN_OP_LOGICAL_OR = TOKEN_CHAR_IDENT + 'OR'; //{$IF test1 $OR test2} | ||||
| TOKEN_OP_LOGICAL_AND = TOKEN_CHAR_IDENT + 'AND'; //{$IF test1 $AND test2} | TOKEN_OP_LOGICAL_AND = TOKEN_CHAR_IDENT + 'AND'; //{$IF test1 $AND test2} | ||||
| TOKEN_OP_LOGICAL_XOR = TOKEN_CHAR_IDENT + 'XOR'; //{$IF test1 $XOR test2} | TOKEN_OP_LOGICAL_XOR = TOKEN_CHAR_IDENT + 'XOR'; //{$IF test1 $XOR test2} | ||||
| TOKEN_OP_DEFINED = TOKEN_CHAR_IDENT + 'DEFINED'; //{$IF $DEFINED test2} | |||||
| TOKEN_OP_SET = TOKEN_CHAR_IDENT + 'SET'; //{$IF $SET vVertex} | |||||
| TOKEN_OP_ADD = '+'; //{$IF test1 + test2} | TOKEN_OP_ADD = '+'; //{$IF test1 + test2} | ||||
| TOKEN_OP_SUBTRACT = '-'; //{$IF test1 - test2} | TOKEN_OP_SUBTRACT = '-'; //{$IF test1 - test2} | ||||
| TOKEN_OP_MULTIPLY = '*'; //{$IF test1 * test2} | TOKEN_OP_MULTIPLY = '*'; //{$IF test1 * test2} | ||||
| @@ -7,14 +7,14 @@ interface | |||||
| uses | uses | ||||
| Classes, SysUtils, variants, | Classes, SysUtils, variants, | ||||
| uengShaderPart, uengShaderFileParser; | |||||
| uengShaderPart, uengShaderFileParser, uengShaderPartKeyValuePair; | |||||
| type | type | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| TengExpressionItem = class(TengShaderPart) | TengExpressionItem = class(TengShaderPart) | ||||
| public | public | ||||
| function GetValue: Variant; virtual; | function GetValue: Variant; virtual; | ||||
| constructor Create(const aLine, aCol: Integer); | |||||
| constructor Create(const aLine, aCol: Integer); reintroduce; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -34,19 +34,24 @@ type | |||||
| TengExpressionVariable = class(TengExpressionItem) | TengExpressionVariable = class(TengExpressionItem) | ||||
| private | private | ||||
| fName: String; | fName: String; | ||||
| fPart: TengShaderPartKeyValuePair; | |||||
| public | public | ||||
| property Name: String read fName; | |||||
| property Name: String read fName; | |||||
| property Part: TengShaderPartKeyValuePair read fPart; | |||||
| 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); | |||||
| constructor Create(const aName: String; const aPart: TengShaderPartKeyValuePair; const aLine, aCol: Integer); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| TengExpressionGroup = class(TengExpressionItem) | TengExpressionGroup = class(TengExpressionItem) | ||||
| private | private | ||||
| fChild: TengExpressionItem; | fChild: TengExpressionItem; | ||||
| protected | |||||
| function GetCount: Integer; override; | |||||
| function GetChild(const aIndex: Integer): TengShaderPart; override; | |||||
| public | public | ||||
| property Child: TengExpressionItem read fChild; | property Child: TengExpressionItem read fChild; | ||||
| @@ -70,9 +75,7 @@ type | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| TengExpressionUnaryOperator = ( | TengExpressionUnaryOperator = ( | ||||
| opBinaryNot, | opBinaryNot, | ||||
| opLogicalNot, | |||||
| opDefined, | |||||
| opSet | |||||
| opLogicalNot | |||||
| ); | ); | ||||
| TengExpressionUnaryOperation = class(TengExpressionOperation) | TengExpressionUnaryOperation = class(TengExpressionOperation) | ||||
| private | private | ||||
| @@ -80,6 +83,8 @@ type | |||||
| fUnaryOp: TengExpressionUnaryOperator; | fUnaryOp: TengExpressionUnaryOperator; | ||||
| protected | protected | ||||
| function GetWeight: Integer; override; | function GetWeight: Integer; override; | ||||
| function GetCount: Integer; override; | |||||
| function GetChild(const aIndex: Integer): TengShaderPart; override; | |||||
| public | public | ||||
| property Child: TengExpressionItem read fChild; | property Child: TengExpressionItem read fChild; | ||||
| property UnaryOp: TengExpressionUnaryOperator read fUnaryOp; | property UnaryOp: TengExpressionUnaryOperator read fUnaryOp; | ||||
| @@ -107,6 +112,8 @@ type | |||||
| fBinaryOp: TengExpressionBinaryOperator; | fBinaryOp: TengExpressionBinaryOperator; | ||||
| protected | protected | ||||
| function GetWeight: Integer; override; | function GetWeight: Integer; override; | ||||
| function GetCount: Integer; override; | |||||
| function GetChild(const aIndex: Integer): TengShaderPart; override; | |||||
| public | public | ||||
| property First: TengExpressionItem read fFirst write fFirst; | property First: TengExpressionItem read fFirst write fFirst; | ||||
| property Second: TengExpressionItem read fSecond write fSecond; | property Second: TengExpressionItem read fSecond write fSecond; | ||||
| @@ -126,20 +133,12 @@ type | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper | |||||
| {$IFDEF USE_BITSPACE_UTILS} | |||||
| , uutlGenerics | |||||
| {$ELSE} | |||||
| , fgl | |||||
| {$ENDIF} | |||||
| ; | |||||
| uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper; | |||||
| const | const | ||||
| EXPRESSION_UNARY_OPERATIONS: array[TengExpressionUnaryOperator] of String = ( | EXPRESSION_UNARY_OPERATIONS: array[TengExpressionUnaryOperator] of String = ( | ||||
| TOKEN_OP_BINARY_NOT, //opBinaryNot | TOKEN_OP_BINARY_NOT, //opBinaryNot | ||||
| TOKEN_OP_LOGICAL_NOT, //opLogicalNot | |||||
| TOKEN_OP_DEFINED, //opDefined | |||||
| TOKEN_OP_SET //opSet | |||||
| TOKEN_OP_LOGICAL_NOT //opLogicalNot | |||||
| ); | ); | ||||
| EXPRESSION_BINARY_OPERATIONS: array[TengExpressionBinaryOperator] of String = ( | EXPRESSION_BINARY_OPERATIONS: array[TengExpressionBinaryOperator] of String = ( | ||||
| TOKEN_OP_BINARY_OR, //opBinaryOr | TOKEN_OP_BINARY_OR, //opBinaryOr | ||||
| @@ -165,9 +164,7 @@ const | |||||
| UNARY_OPERATION_WEIGHTS: array[TengExpressionUnaryOperator] of Integer = ( | UNARY_OPERATION_WEIGHTS: array[TengExpressionUnaryOperator] of Integer = ( | ||||
| 00, //opBinaryNot | 00, //opBinaryNot | ||||
| 00, //opLogicalNot | |||||
| 00, //opDefined | |||||
| 00 //opSet | |||||
| 00 //opLogicalNot | |||||
| ); | ); | ||||
| BINARY_OPERATION_WEIGHTS: array[TengExpressionBinaryOperator] of Integer = ( | BINARY_OPERATION_WEIGHTS: array[TengExpressionBinaryOperator] of Integer = ( | ||||
| 01, //opBinaryOr | 01, //opBinaryOr | ||||
| @@ -243,14 +240,29 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| constructor TengExpressionVariable.Create(const aName: String; const aLine, aCol: Integer); | |||||
| constructor TengExpressionVariable.Create(const aName: String; const aPart: TengShaderPartKeyValuePair; const aLine, aCol: Integer); | |||||
| begin | begin | ||||
| inherited Create(aLine, aCol); | inherited Create(aLine, aCol); | ||||
| fName := aName; | fName := aName; | ||||
| fPart := aPart; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| ///TengExpressionGroup////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //TengExpressionGroup/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengExpressionGroup.GetCount: Integer; | |||||
| begin | |||||
| result := 1; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengExpressionGroup.GetChild(const aIndex: Integer): TengShaderPart; | |||||
| begin | |||||
| if (aIndex >= 0) and (aIndex < 1) | |||||
| then result := fChild | |||||
| else raise EengOutOfRange.Create(0, 0, aIndex, self); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengExpressionGroup.GetText: String; | function TengExpressionGroup.GetText: String; | ||||
| begin | begin | ||||
| @@ -309,6 +321,20 @@ begin | |||||
| result := UNARY_OPERATION_WEIGHTS[fUnaryOp]; | result := UNARY_OPERATION_WEIGHTS[fUnaryOp]; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengExpressionUnaryOperation.GetCount: Integer; | |||||
| begin | |||||
| result := 1; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengExpressionUnaryOperation.GetChild(const aIndex: Integer): TengShaderPart; | |||||
| begin | |||||
| if (aIndex >= 0) and (aIndex < 1) | |||||
| then result := fChild | |||||
| else raise EengOutOfRange.Create(0, 0, aIndex, self); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengExpressionUnaryOperation.GetText: String; | function TengExpressionUnaryOperation.GetText: String; | ||||
| begin | begin | ||||
| @@ -339,15 +365,6 @@ begin | |||||
| v := fChild.GetValue; | v := fChild.GetValue; | ||||
| result := not Boolean(v); | result := not Boolean(v); | ||||
| end; | end; | ||||
| opDefined: begin | |||||
| // TODO | |||||
| end; | |||||
| opSet: begin | |||||
| // TODO | |||||
| end; | |||||
| else | else | ||||
| result := inherited GetValue; | result := inherited GetValue; | ||||
| end; | end; | ||||
| @@ -397,6 +414,23 @@ begin | |||||
| result := BINARY_OPERATION_WEIGHTS[fBinaryOp]; | result := BINARY_OPERATION_WEIGHTS[fBinaryOp]; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengExpressionBinaryOperation.GetCount: Integer; | |||||
| begin | |||||
| result := 2; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengExpressionBinaryOperation.GetChild(const aIndex: Integer): TengShaderPart; | |||||
| begin | |||||
| if (aIndex < 0) and (aIndex >= 2) then | |||||
| raise EengOutOfRange.Create(0, 1, aIndex, self); | |||||
| case aIndex of | |||||
| 0: result := fFirst; | |||||
| 1: result := fSecond; | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengExpressionBinaryOperation.GetText: String; | function TengExpressionBinaryOperation.GetText: String; | ||||
| begin | begin | ||||
| @@ -487,6 +521,15 @@ end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| type | type | ||||
| TkvpSearchResults = class(TengSearchResults) | |||||
| private | |||||
| fName: String; | |||||
| protected | |||||
| function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; override; | |||||
| public | |||||
| constructor Create(const aName: String); | |||||
| end; | |||||
| TExpectedParam = (exVariable, exValue, exGroupBegin, exGroupEnd, exUnaryOperation, exBinaryOperation); | TExpectedParam = (exVariable, exValue, exGroupBegin, exGroupEnd, exUnaryOperation, exBinaryOperation); | ||||
| TExpectedParams = set of TExpectedParam; | TExpectedParams = set of TExpectedParam; | ||||
| TExpressionParser = class(TObject) | TExpressionParser = class(TObject) | ||||
| @@ -495,27 +538,45 @@ type | |||||
| fParamPos: Integer; | fParamPos: Integer; | ||||
| fParams: TengTokenParameterList; | fParams: TengTokenParameterList; | ||||
| private | private | ||||
| function NextParam(var aParam: TengTokenParameter): Boolean; | |||||
| function NextParam(out aParam: TengTokenParameter): Boolean; | |||||
| function IsUnaryOperation(const aParam: String; out aOperator: TengExpressionUnaryOperator): Boolean; | function IsUnaryOperation(const aParam: String; out aOperator: TengExpressionUnaryOperator): Boolean; | ||||
| function IsBinaryOperation(const aParam: String; out aOperator: TengExpressionBinaryOperator): Boolean; | function IsBinaryOperation(const aParam: String; out aOperator: TengExpressionBinaryOperator): Boolean; | ||||
| procedure RaiseEx(const aMsg: String; const aParam: TengTokenParameter; aName: String = ''); | procedure RaiseEx(const aMsg: String; const aParam: TengTokenParameter; aName: String = ''); | ||||
| function Move(var aItem: TengExpressionItem): TengExpressionItem; | function Move(var aItem: TengExpressionItem): TengExpressionItem; | ||||
| function Merge(aOld, aNew: TengExpressionItem): TengExpressionItem; | function Merge(aOld, aNew: TengExpressionItem): TengExpressionItem; | ||||
| function GetExpr(const aExpected: TExpectedParams): TengExpressionItem; | function GetExpr(const aExpected: TExpectedParams): TengExpressionItem; | ||||
| private | |||||
| public | |||||
| function GetGroup: TengExpressionItem; | function GetGroup: TengExpressionItem; | ||||
| constructor Create(const aParent: TengShaderPart; const aParams: TengTokenParameterList; const aIndex: Integer); | constructor Create(const aParent: TengShaderPart; const aParams: TengTokenParameterList; const aIndex: Integer); | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //TkvpSearchResults///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TkvpSearchResults.CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; | |||||
| begin | |||||
| result := inherited CheckObj(aPart, aContinue); | |||||
| if result then | |||||
| result := ((aPart as TengShaderPartKeyValuePair).Name = fName); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| constructor TkvpSearchResults.Create(const aName: String); | |||||
| begin | |||||
| inherited Create([TengShaderPartKeyValuePair]); | |||||
| fName := aName; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TExpressionParser///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TExpressionParser///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TExpressionParser.NextParam(var aParam: TengTokenParameter): Boolean; | |||||
| function TExpressionParser.NextParam(out aParam: TengTokenParameter): Boolean; | |||||
| begin | begin | ||||
| inc(fParamPos); | inc(fParamPos); | ||||
| result := (fParamPos < fParams.Count); | result := (fParamPos < fParams.Count); | ||||
| if result then | |||||
| aParam := fParams[fParamPos]; | |||||
| if result | |||||
| then aParam := fParams[fParamPos] | |||||
| else FillByte(aParam, SizeOf(aParam), 0); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -607,6 +668,8 @@ var | |||||
| bOp: TengExpressionBinaryOperator; | bOp: TengExpressionBinaryOperator; | ||||
| item: TengExpressionItem; | item: TengExpressionItem; | ||||
| param: TengTokenParameter; | param: TengTokenParameter; | ||||
| sr: TkvpSearchResults; | |||||
| tmp: TengShaderPart; | |||||
| begin | begin | ||||
| item := nil; | item := nil; | ||||
| result := nil; | result := nil; | ||||
| @@ -649,7 +712,14 @@ begin | |||||
| end else if IsValidIdentifier(param.Name) then begin | end else if IsValidIdentifier(param.Name) then begin | ||||
| if not (exVariable in aExpected) then | if not (exVariable in aExpected) then | ||||
| RaiseEx('unexpected variable:', param); | RaiseEx('unexpected variable:', param); | ||||
| result := TengExpressionVariable.Create(param.Name, param.Line, param.Col); | |||||
| sr := TkvpSearchResults.Create(param.Name); | |||||
| try | |||||
| fParent.Find([], sr); | |||||
| tmp := ExtractSearchResult(fParent, param.Name, sr, param.Line, param.Col); | |||||
| result := TengExpressionVariable.Create(param.Name, (tmp as TengShaderPartKeyValuePair), param.Line, param.Col); | |||||
| finally | |||||
| FreeAndNil(sr); | |||||
| end; | |||||
| // Unknown | // Unknown | ||||
| end else | end else | ||||
| @@ -10,6 +10,7 @@ uses | |||||
| function IsValidIdentifier(const aIdent: String): Boolean; | function IsValidIdentifier(const aIdent: String): Boolean; | ||||
| function CheckEndToken(const aArgs: TengParseArgs; const aShaderPart: TengShaderPart): String; | function CheckEndToken(const aArgs: TengParseArgs; const aShaderPart: TengShaderPart): String; | ||||
| function ExtractSearchResult(const aSender: TengShaderPart; const aIdent: String; const aList: TengShaderPartList; aLine: Integer = -1; aCol: Integer = -1; aFilename: String = ''): TengShaderPart; | |||||
| implementation | implementation | ||||
| @@ -52,5 +53,36 @@ begin | |||||
| end; | end; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function ExtractSearchResult(const aSender: TengShaderPart; const aIdent: String; const aList: TengShaderPartList; | |||||
| aLine: Integer; aCol: Integer; aFilename: String): TengShaderPart; | |||||
| var | |||||
| s: String; | |||||
| i: Integer; | |||||
| begin | |||||
| result := nil; | |||||
| if (aList.Count <= 0) then | |||||
| exit; | |||||
| if Assigned(aSender) then begin | |||||
| if (aLine < 0) then | |||||
| aLine := aSender.Line; | |||||
| if (aCol < 0) then | |||||
| aCol := aSender.Col; | |||||
| if (aFilename = '') then | |||||
| aFilename := aSender.Filename; | |||||
| end; | |||||
| result := aList[0]; | |||||
| if (aList.Count > 1) and Assigned(aSender) then begin | |||||
| s := Format('use of duplicate identifier: %s (%s %d:%d)', [aIdent, aList[0].Filename, aList[0].Line + 1, aList[0].Col]) + sLineBreak + | |||||
| 'previously declared here:' + sLineBreak; | |||||
| i := 1; | |||||
| while (i < aList.Count) do begin | |||||
| s := s + Format(' %s %d:%d', [aList[i].Filename, aList[i].Line + 1, aList[i].Col]) + sLineBreak; | |||||
| inc(i); | |||||
| end; | |||||
| aSender.LogMsg(llWarning, s); | |||||
| end; | |||||
| end; | |||||
| end. | end. | ||||
| @@ -23,6 +23,12 @@ type | |||||
| TIntfObjNoRefCount = uutlCommon.TutlInterfaceNoRefCount; | TIntfObjNoRefCount = uutlCommon.TutlInterfaceNoRefCount; | ||||
| {$ENDIF} | {$ENDIF} | ||||
| TengShaderPartLogLevel = ( | |||||
| llInfo, | |||||
| llWarning, | |||||
| llError | |||||
| ); | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //Exceptions//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //Exceptions//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -174,18 +180,12 @@ procedure EengShaderPart.PrintTrace(const aLines: TStrings); | |||||
| else result := result + ' (' + aPart.ClassName + ')'; | else result := result + ' (' + aPart.ClassName + ')'; | ||||
| end; | end; | ||||
| var | |||||
| p: TengShaderPart; | |||||
| begin | begin | ||||
| if not Assigned(Sender) or not | if not Assigned(Sender) or not | ||||
| (Sender is TengShaderPart) then | (Sender is TengShaderPart) then | ||||
| exit; | exit; | ||||
| p := (Sender as TengShaderPart); | |||||
| aLines.Text := Message; | |||||
| while Assigned(p) do begin | |||||
| aLines.Add(Format(' %s (%d:%d): %s', [p.Filename, p.Line+1, p.Col, GetName(p)])); | |||||
| p := p.Parent; | |||||
| end; | |||||
| aLines.Add(Message); | |||||
| (Sender as TengShaderPart).PrintTrace(' ', aLines); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -22,26 +22,67 @@ type | |||||
| TengSearchFlag = ( | TengSearchFlag = ( | ||||
| sfEvaluateIf, // evaluate if statements before search and process with suitable subtree | sfEvaluateIf, // evaluate if statements before search and process with suitable subtree | ||||
| sfSearchAllIf, // search in all if sub trees | sfSearchAllIf, // search in all if sub trees | ||||
| sfIncludeSelf, // add item to search results where search has started | |||||
| sfSearchPrevOnly, // search in previous items only | sfSearchPrevOnly, // search in previous items only | ||||
| sfSearchInherited, // search in inherited | sfSearchInherited, // search in inherited | ||||
| sfSearchChildren, // search in children | sfSearchChildren, // search in children | ||||
| sfSearchChildrenLazy, // set sfSearchChildren in next recursion level | sfSearchChildrenLazy, // set sfSearchChildren in next recursion level | ||||
| sfChildrenFileOnly, // do not leave current file when searching for children | |||||
| sfChildrenGeneratorOnly, // do not leave current generator when searching for children | |||||
| sfChildrenScopeOnly, // do not leave current scope when searching for children | |||||
| sfChildrenOnlyFile, // do not leave current file when searching for children | |||||
| sfChildrenOnlyClass, // do not leave current class when searching for children | |||||
| sfChildrenOnlyGenerator, // do not leave current generator when searching for children | |||||
| sfChildrenOnlyScope, // do not leave current scope when searching for children | |||||
| sfChildrenForceFile, // overwrite sfChildrenOnlyXXX flag when item is a file | |||||
| sfChildrenForceClass, // overwrite sfChildrenOnlyXXX flag when item is a class | |||||
| sfChildrenForceGenerator, // overwrite sfChildrenOnlyXXX flag when item is a generator | |||||
| sfChildrenForceScope, // overwrite sfChildrenOnlyXXX flag when item is a scope | |||||
| sfSearchParents, // search in Parents | sfSearchParents, // search in Parents | ||||
| sfParentsFileOnly, // do not leave current file when searching in parents | |||||
| sfParentsGeneratorOnly, // do not leave current generator when searching in parents | |||||
| sfParentsScopeOnly // do not leave current scope when searching in parents | |||||
| sfParentsOnlyFile, // do not leave current file when searching in parents | |||||
| sfParentsOnlyClass, // do not leave current class when searching in parents | |||||
| sfParentsOnlyGenerator, // do not leave current generator when searching in parents | |||||
| sfParentsOnlyScope, // do not leave current scope when searching in parents | |||||
| sfParentsForceFile, // overwrite sfParentsOnlyXXX flag when item is a file | |||||
| sfParentsForceClass, // overwrite sfParentsOnlyXXX flag when item is a class | |||||
| sfParentsForceGenerator, // overwrite sfParentsOnlyXXX flag when item is a generator | |||||
| sfParentsForceScope // overwrite sfParentsOnlyXXX flag when item is a scope | |||||
| ); | ); | ||||
| TengSearchFlags = set of TengSearchFlag; | TengSearchFlags = set of TengSearchFlag; | ||||
| const | |||||
| SEARCH_FLAG_CURRENT_SCOPE = [ | |||||
| sfSearchPrevOnly, | |||||
| sfSearchInherited, // search in inherited | |||||
| sfSearchChildrenLazy, // set sfSearchChildren in next recursion level | |||||
| sfChildrenOnlyScope, // do not leave current scope when searching for children | |||||
| sfChildrenForceFile, // overwrite sfChildrenOnlyXXX flag when item is a file | |||||
| sfSearchParents, // search in Parents | |||||
| sfParentsOnlyFile // do not leave current file when searching in parents | |||||
| ]; | |||||
| type | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| TengShaderPart = class; | TengShaderPart = class; | ||||
| CengShaderPart = class of TengShaderPart; | CengShaderPart = class of TengShaderPart; | ||||
| TengShaderPartList = specialize TutlSimpleList<TengShaderPart>; | TengShaderPartList = specialize TutlSimpleList<TengShaderPart>; | ||||
| TengSearchResults = class(specialize TutlList<TengShaderPart>) | |||||
| private | |||||
| fFirstOnly: Boolean; | |||||
| fIgnore: TengShaderPart; | |||||
| fTypes: array of CengShaderPart; | |||||
| protected | |||||
| function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; virtual; | |||||
| public | |||||
| property FirstOnly: Boolean read fFirstOnly write fFirstOnly; | |||||
| property Ignore: TengShaderPart read fIgnore write fIgnore; | |||||
| function Add(const aPart: TengShaderPart): Boolean; reintroduce; | |||||
| constructor Create(const aTypes: array of CengShaderPart); | |||||
| end; | |||||
| TengShaderPart = class(TIntfObjNoRefCount) | TengShaderPart = class(TIntfObjNoRefCount) | ||||
| { Nested Types } | { Nested Types } | ||||
| public type | public type | ||||
| @@ -58,26 +99,12 @@ type | |||||
| constructor Create(const aOwner: TengShaderPart; const aReverse: Boolean = false); | constructor Create(const aOwner: TengShaderPart; const aReverse: Boolean = false); | ||||
| end; | end; | ||||
| TSearchResults = class(specialize TutlList<TengShaderPart>) | |||||
| private | |||||
| fFirstOnly: Boolean; | |||||
| fIgnore: TengShaderPart; | |||||
| fTypes: array of CengShaderPart; | |||||
| protected | |||||
| function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; virtual; | |||||
| public | |||||
| property FirstOnly: Boolean read fFirstOnly write fFirstOnly; | |||||
| property Ignore: TengShaderPart read fIgnore write fIgnore; | |||||
| function Add(const aPart: TengShaderPart): Boolean; reintroduce; | |||||
| constructor Create(const aTypes: array of CengShaderPart); | |||||
| end; | |||||
| { Code Loading & Storage } | { Code Loading & Storage } | ||||
| protected { members } | protected { members } | ||||
| fRoot: TengShaderPart; | |||||
| fParent: TengShaderPart; | fParent: TengShaderPart; | ||||
| fLine: Integer; | fLine: Integer; | ||||
| fCol: Integer; | fCol: Integer; | ||||
| 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; | ||||
| @@ -88,8 +115,8 @@ type | |||||
| { General } | { General } | ||||
| protected | protected | ||||
| procedure UpdateCache; virtual; | |||||
| function FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TSearchResults): Boolean; virtual; | |||||
| function FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TengSearchResults): Boolean; virtual; | |||||
| procedure LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); 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; | ||||
| @@ -108,7 +135,9 @@ type | |||||
| function GetParent(const aType: CengShaderPart; out aPart): Boolean; | function GetParent(const aType: CengShaderPart; out aPart): Boolean; | ||||
| function GetParent(const aType: CengShaderPart): TengShaderPart; | function GetParent(const aType: CengShaderPart): TengShaderPart; | ||||
| procedure Find(const aFlags: TengSearchFlags; const aResults: TSearchResults); | |||||
| procedure Find(const aFlags: TengSearchFlags; const aResults: TengSearchResults); | |||||
| procedure PrintTrace(const aPrefix: String; const aLines: TStrings); | |||||
| procedure LogMsg(const aLogLevel: TengShaderPartLogLevel; const aMsg: String); | |||||
| function GetEnumerator: TEnumerator; | function GetEnumerator: TEnumerator; | ||||
| function GetReverseEnumerator: TEnumerator; | function GetReverseEnumerator: TEnumerator; | ||||
| @@ -134,7 +163,7 @@ type | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| uengShaderPartScope, uengShaderCodeGenerator, uengShaderFile, uengShaderFileConstants; | |||||
| uengShaderPartScope, uengShaderCodeGenerator, uengShaderPartClass, uengShaderFile, uengShaderFileConstants; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderPart.TEnumerator//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TengShaderPart.TEnumerator//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -171,9 +200,9 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderPart.TSearchResults///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //TengSearchResults///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderPart.TSearchResults.CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; | |||||
| function TengSearchResults.CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; | |||||
| var | var | ||||
| c: CengShaderPart; | c: CengShaderPart; | ||||
| begin | begin | ||||
| @@ -188,7 +217,7 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderPart.TSearchResults.Add(const aPart: TengShaderPart): Boolean; | |||||
| function TengSearchResults.Add(const aPart: TengShaderPart): Boolean; | |||||
| begin | begin | ||||
| result := true; | result := true; | ||||
| if result and CheckObj(aPart, result) then | if result and CheckObj(aPart, result) then | ||||
| @@ -196,7 +225,7 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| constructor TengShaderPart.TSearchResults.Create(const aTypes: array of CengShaderPart); | |||||
| constructor TengSearchResults.Create(const aTypes: array of CengShaderPart); | |||||
| var | var | ||||
| i: Integer; | i: Integer; | ||||
| begin | begin | ||||
| @@ -252,16 +281,44 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderPart.UpdateCache; | |||||
| var | |||||
| p: TengShaderPart; | |||||
| begin | |||||
| for p in self do | |||||
| p.UpdateCache; | |||||
| end; | |||||
| function TengShaderPart.FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TengSearchResults): Boolean; | |||||
| function VisitChild(const aItem: TengShaderPart): Boolean; | |||||
| begin | |||||
| result := (sfSearchChildren in aFlags); | |||||
| if not result then | |||||
| exit; | |||||
| result := result and | |||||
| Assigned(aItem) and | |||||
| (not (sfChildrenOnlyFile in aFlags) or not (self is TengShaderFile)) and | |||||
| (not (sfChildrenOnlyClass in aFlags) or not (self is TengShaderPartClass)) and | |||||
| (not (sfChildrenOnlyGenerator in aFlags) or not (self is TengShaderCodeGenerator)) and | |||||
| (not (sfChildrenOnlyScope in aFlags) or not (self is TengShaderPartScope)); | |||||
| result := result or | |||||
| ((sfChildrenForceFile in aFlags) and (self is TengShaderFile)) or | |||||
| ((sfChildrenForceClass in aFlags) and (self is TengShaderPartClass)) or | |||||
| ((sfChildrenForceGenerator in aFlags) and (self is TengShaderCodeGenerator)) or | |||||
| ((sfChildrenForceScope in aFlags) and (self is TengShaderPartScope)); | |||||
| end; | |||||
| function VisitParent(const aItem: TengShaderPart): Boolean; | |||||
| begin | |||||
| result := (sfSearchParents in aFlags); | |||||
| if not result then | |||||
| exit; | |||||
| result := result and | |||||
| Assigned(aItem) and | |||||
| (not (sfParentsOnlyFile in aFlags) or not (self is TengShaderFile)) and | |||||
| (not (sfParentsOnlyClass in aFlags) or not (self is TengShaderPartClass)) and | |||||
| (not (sfParentsOnlyGenerator in aFlags) or not (self is TengShaderCodeGenerator)) and | |||||
| (not (sfParentsOnlyScope in aFlags) or not (self is TengShaderPartScope)); | |||||
| result := result or | |||||
| ((sfParentsForceFile in aFlags) and (self is TengShaderFile)) or | |||||
| ((sfParentsForceClass in aFlags) and (self is TengShaderPartClass)) or | |||||
| ((sfParentsForceGenerator in aFlags) and (self is TengShaderCodeGenerator)) or | |||||
| ((sfParentsForceScope in aFlags) and (self is TengShaderPartScope)); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengShaderPart.FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TSearchResults): Boolean; | |||||
| var | var | ||||
| c: TengShaderPart; | c: TengShaderPart; | ||||
| b: Boolean; | b: Boolean; | ||||
| @@ -273,28 +330,27 @@ begin | |||||
| b := b or (c = aChild); | b := b or (c = aChild); | ||||
| if (sfSearchPrevOnly in aFlags) and not b then | if (sfSearchPrevOnly in aFlags) and not b then | ||||
| continue; | continue; | ||||
| if (c <> aChild) and | |||||
| (not (sfChildrenScopeOnly in aFlags) or not (c is TengShaderPartScope)) and | |||||
| (not (sfChildrenGeneratorOnly in aFlags) or not (c is TengShaderCodeGenerator)) and | |||||
| (not (sfChildrenFileOnly in aFlags) or not (c is TengShaderFile)) | |||||
| then | |||||
| result := result and c.FindIntern(aFlags - [sfSearchParents], nil, aResults); | |||||
| if (c <> aChild) and VisitChild(c) then | |||||
| result := result and c.FindIntern(aFlags - [sfSearchParents] + [sfIncludeSelf], nil, aResults); | |||||
| if not result then | if not result then | ||||
| exit; | exit; | ||||
| end; | end; | ||||
| end; | end; | ||||
| result := result and aResults.Add(self); | |||||
| if (sfIncludeSelf in aFlags) then | |||||
| result := result and aResults.Add(self); | |||||
| if (sfSearchChildrenLazy in aFlags) then | if (sfSearchChildrenLazy in aFlags) then | ||||
| aFlags := aFlags + [sfSearchChildren] - [sfSearchChildrenLazy]; | aFlags := aFlags + [sfSearchChildren] - [sfSearchChildrenLazy]; | ||||
| if (sfSearchParents in aFlags) and | |||||
| Assigned(Parent) and | |||||
| (not (sfParentsScopeOnly in aFlags) or not (self is TengShaderPartScope)) and | |||||
| (not (sfParentsGeneratorOnly in aFlags) or not (self is TengShaderCodeGenerator)) and | |||||
| (not (sfParentsFileOnly in aFlags) or not (self is TengShaderFile)) | |||||
| then | |||||
| result := result and Parent.FindIntern(aFlags, self, aResults); | |||||
| if VisitParent(Parent) then | |||||
| result := result and Parent.FindIntern(aFlags + [sfIncludeSelf], self, aResults); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderPart.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); | |||||
| begin | |||||
| if Assigned(Parent) then | |||||
| Parent.LogMsgIntern(aSender, aLogLevel, aMsg); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -309,6 +365,7 @@ end; | |||||
| function TengShaderPart.GetParent(const aType: CengShaderPart; out aPart): Boolean; | function TengShaderPart.GetParent(const aType: CengShaderPart; out aPart): Boolean; | ||||
| begin | begin | ||||
| result := true; | result := true; | ||||
| TengShaderPart(aPart) := nil; | |||||
| if (fParent is aType) then | if (fParent is aType) then | ||||
| TengShaderPart(aPart) := fParent | TengShaderPart(aPart) := fParent | ||||
| else if Assigned(fParent) then | else if Assigned(fParent) then | ||||
| @@ -325,11 +382,38 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderPart.Find(const aFlags: TengSearchFlags; const aResults: TSearchResults); | |||||
| procedure TengShaderPart.Find(const aFlags: TengSearchFlags; const aResults: TengSearchResults); | |||||
| begin | begin | ||||
| FindIntern(aFlags, nil, aResults); | FindIntern(aFlags, nil, aResults); | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderPart.PrintTrace(const aPrefix: String; 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 | |||||
| p := self; | |||||
| while Assigned(p) do begin | |||||
| aLines.Add(Format('%s%s (%d:%d): %s', [aPrefix, p.Filename, p.Line+1, p.Col, GetName(p)])); | |||||
| p := p.Parent; | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderPart.LogMsg(const aLogLevel: TengShaderPartLogLevel; const aMsg: String); | |||||
| begin | |||||
| LogMsgIntern(self, aLogLevel, aMsg); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderPart.GetEnumerator: TEnumerator; | function TengShaderPart.GetEnumerator: TEnumerator; | ||||
| begin | begin | ||||
| @@ -28,8 +28,6 @@ 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 UpdateInherited; override; | |||||
| public | public | ||||
| property Name: String read fName; | property Name: String read fName; | ||||
| property Extends: TStrings read GetExtends; | property Extends: TStrings read GetExtends; | ||||
| @@ -46,7 +44,7 @@ type | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| uengShaderFile, uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartIf; | |||||
| uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderPartClass/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TengShaderPartClass/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -99,36 +97,6 @@ begin | |||||
| result := CheckEndToken(aArgs, self); | result := CheckEndToken(aArgs, self); | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderPartClass.UpdateInherited; | |||||
| var | |||||
| sr: TengShaderPart.TSearchResults; | |||||
| i: Integer; | |||||
| s: String; | |||||
| begin | |||||
| inherited UpdateInherited; | |||||
| fInherited.Clear; | |||||
| sr := TengShaderPart.TSearchResults.Create([TengShaderPartClass]); | |||||
| try | |||||
| sr.Ignore := self; | |||||
| Find([sfSearchChildrenLazy, sfSearchParents, sfParentsFileOnly, sfSearchPrevOnly], sr); | |||||
| for s in fExtends do begin | |||||
| i := 0; | |||||
| while (i >= 0) and (i < sr.Count) do begin | |||||
| if ((sr[i] as TengShaderPartClass).Name = s) then begin | |||||
| fInherited.Add(sr[i]); | |||||
| i := -1; | |||||
| end; | |||||
| inc(i); | |||||
| end; | |||||
| if (i > 0) or (sr.Count = 0) then | |||||
| raise EengUnknownIdentifier.Create(s, self); | |||||
| end; | |||||
| finally | |||||
| FreeAndNil(sr); | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| constructor TengShaderPartClass.Create(const aParent: TengShaderPart); | constructor TengShaderPartClass.Create(const aParent: TengShaderPart); | ||||
| begin | begin | ||||
| @@ -160,12 +128,6 @@ class procedure TengShaderPartClass.Validate(const aArgs: TengParseArgs; const a | |||||
| begin | begin | ||||
| inherited Validate(aArgs, aParent); | 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 | if aParent.HasParent(TengShaderPartClass, true) then | ||||
| RaiseEx(TengShaderPartClass.GetTokenName); | RaiseEx(TengShaderPartClass.GetTokenName); | ||||
| end; | end; | ||||
| @@ -27,8 +27,9 @@ type | |||||
| { General } | { General } | ||||
| protected | protected | ||||
| function FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TSearchResults): Boolean; override; | |||||
| function FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TengSearchResults): Boolean; override; | |||||
| public | public | ||||
| property Expression: TengExpressionItem read fExpression; | |||||
| destructor Destroy; override; | destructor Destroy; override; | ||||
| { Class Methods } | { Class Methods } | ||||
| @@ -137,7 +138,7 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderPartIf.FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TSearchResults): Boolean; | |||||
| function TengShaderPartIf.FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TengSearchResults): Boolean; | |||||
| begin | begin | ||||
| result := true; | result := true; | ||||
| if (sfEvaluateIf in aFlags) and (sfSearchChildren in aFlags) then begin | if (sfEvaluateIf in aFlags) and (sfSearchChildren in aFlags) then begin | ||||
| @@ -51,7 +51,7 @@ type | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartIf; | |||||
| uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderPartKeyValuePair//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TengShaderPartKeyValuePair//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -62,7 +62,7 @@ begin | |||||
| if (fValueName <> '') then | if (fValueName <> '') then | ||||
| result := result + ' ' + fValueName | result := result + ' ' + fValueName | ||||
| else if (fValue <> Unassigned) then | else if (fValue <> Unassigned) then | ||||
| result := result + TOKEN_CHAR_QUOTE + String(fValue) + TOKEN_CHAR_QUOTE; | |||||
| result := result + ' ' + TOKEN_CHAR_QUOTE + String(fValue) + TOKEN_CHAR_QUOTE; | |||||
| result := result + TOKEN_CHAR_END; | result := result + TOKEN_CHAR_END; | ||||
| end; | end; | ||||