| @@ -23,7 +23,7 @@ uses | |||||
| type | type | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| TengShaderFileLogEvent = procedure(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String) of object; | TengShaderFileLogEvent = procedure(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String) of object; | ||||
| TengShaderFile = class(TengShaderCodeGenerator) | |||||
| TengShaderFile = class(TengShaderGenerator) | |||||
| { Code Loading & Storage } | { Code Loading & Storage } | ||||
| private | private | ||||
| fFilename: String; | fFilename: String; | ||||
| @@ -31,7 +31,7 @@ type | |||||
| fFileWriter: IutlFileWriter; | fFileWriter: IutlFileWriter; | ||||
| fClasses: TengShaderPartClassMap; | fClasses: TengShaderPartClassMap; | ||||
| private | private | ||||
| function GetGenerator(const aName: String): TengShaderCodeGenerator; | |||||
| function GetGenerator(const aName: String): TengShaderGenerator; | |||||
| function GetGeneratorCount: Integer; | function GetGeneratorCount: Integer; | ||||
| function GetGeneratorNames(const aIndex: Integer): String; | function GetGeneratorNames(const aIndex: Integer): String; | ||||
| procedure UpdateClasses; | procedure UpdateClasses; | ||||
| @@ -54,7 +54,7 @@ type | |||||
| protected | protected | ||||
| procedure LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); 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]: TengShaderGenerator 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; | property OnLog: TengShaderFileLogEvent read fOnLog write fOnLog; | ||||
| @@ -67,12 +67,12 @@ type | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| uengShaderPartInclude, uengShaderPartKeyValuePair, uengShaderFileHelper; | |||||
| uengShaderPartInclude, uengShaderPartKeyValuePair, uengShaderFileHelper, uengShaderPartProc; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderFile//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TengShaderFile//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderFile.GetGenerator(const aName: String): TengShaderCodeGenerator; | |||||
| function TengShaderFile.GetGenerator(const aName: String): TengShaderGenerator; | |||||
| begin | begin | ||||
| result := fClasses[aName]; | result := fClasses[aName]; | ||||
| if not Assigned(result) then | if not Assigned(result) then | ||||
| @@ -170,7 +170,7 @@ begin | |||||
| walker.Owner := self; | walker.Owner := self; | ||||
| walker.SearchFlags := [sfSearchChildren, sfIgnoreOwner]; | walker.SearchFlags := [sfSearchChildren, sfIgnoreOwner]; | ||||
| walker.ResultTypes := CengShaderPartArr.Create(TengShaderFile); | walker.ResultTypes := CengShaderPartArr.Create(TengShaderFile); | ||||
| walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderCodeGenerator); | |||||
| walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderGenerator); | |||||
| walker.Run(self); | walker.Run(self); | ||||
| for p in sr do | for p in sr do | ||||
| (p as TengShaderFile).CopyProperties(self); | (p as TengShaderFile).CopyProperties(self); | ||||
| @@ -260,10 +260,34 @@ end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderFile.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | procedure TengShaderFile.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | ||||
| var | |||||
| sr: TengSearchResults; | |||||
| walker: TengSearchWalker; | |||||
| main: TengShaderPartMain; | |||||
| begin | begin | ||||
| inherited GenerateCodeIntern(aArgs); | inherited GenerateCodeIntern(aArgs); | ||||
| if (aArgs.Root = self) then begin | if (aArgs.Root = self) then begin | ||||
| // TODO generate main routine code (if exists) | |||||
| sr := TengSearchResults.Create; | |||||
| walker := TengSearchWalker.Create(sr); | |||||
| try | |||||
| walker.SearchFlags := [sfSearchChildren, sfEvaluateIf]; | |||||
| walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartMain); | |||||
| walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderGenerator); | |||||
| walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile); | |||||
| walker.Run(self); | |||||
| main := (ExtractSearchResult(self, TengShaderPartMain.GetTokenName, sr, []) as TengShaderPartMain); | |||||
| if Assigned(main) then begin | |||||
| aArgs.PushFlags((aArgs.Flags * [gfAddProcedureItem, gfAddParameterItem]) + [gfGenerateProcedureCode]); | |||||
| try | |||||
| main.GenerateCodeIntern(aArgs); | |||||
| finally | |||||
| aArgs.PopFlags; | |||||
| end; | |||||
| end; | |||||
| finally | |||||
| FreeAndNil(walker); | |||||
| FreeAndNil(sr); | |||||
| end; | |||||
| end; | end; | ||||
| end; | end; | ||||
| @@ -25,7 +25,7 @@ const | |||||
| TOKEN_CLASS = TOKEN_CHAR_IDENT + 'CLASS'; //{$CLASS PhongLight $EXTENDS Normal Glow} | TOKEN_CLASS = TOKEN_CHAR_IDENT + 'CLASS'; //{$CLASS PhongLight $EXTENDS Normal Glow} | ||||
| TOKEN_EXTENDS = TOKEN_CHAR_IDENT + 'EXTENDS'; | TOKEN_EXTENDS = TOKEN_CHAR_IDENT + 'EXTENDS'; | ||||
| TOKEN_INHERITED = TOKEN_CHAR_IDENT + 'INHERITED'; //{$INHERITED} {$INHERITED BaseClass} | |||||
| TOKEN_INHERITED = TOKEN_CHAR_IDENT + 'INHERITED'; //{$INHERITED BaseClassMethod 'param1' 'param2'} | |||||
| TOKEN_INCLUDE = TOKEN_CHAR_IDENT + 'INCLUDE'; //{$INCLUDE 'Normal.frag'} | TOKEN_INCLUDE = TOKEN_CHAR_IDENT + 'INCLUDE'; //{$INCLUDE 'Normal.frag'} | ||||
| @@ -85,6 +85,7 @@ const | |||||
| TOKEN_SPLIT_CHARS = [' ', #9, TOKEN_OP_GROUP_BEGIN, TOKEN_OP_GROUP_END]; | TOKEN_SPLIT_CHARS = [' ', #9, TOKEN_OP_GROUP_BEGIN, TOKEN_OP_GROUP_END]; | ||||
| COMMAND_END_TOKENS = [TOKEN_CHAR_COMMANT_END, TOKEN_CHAR_SCOPE_BEGIN, TOKEN_CHAR_SCOPE_END]; | COMMAND_END_TOKENS = [TOKEN_CHAR_COMMANT_END, TOKEN_CHAR_SCOPE_BEGIN, TOKEN_CHAR_SCOPE_END]; | ||||
| LAYOUT_MIN_VERSION = 150; | |||||
| VERSION_EXTRA_COMPAT = 'compatibility'; //{$META $VERSION 'compatibility'} | VERSION_EXTRA_COMPAT = 'compatibility'; //{$META $VERSION 'compatibility'} | ||||
| implementation | implementation | ||||
| @@ -692,14 +692,14 @@ begin | |||||
| sr := TengSearchResults.Create; | sr := TengSearchResults.Create; | ||||
| walker := TengKeyValuePairSearchWalker.Create(sr); | walker := TengKeyValuePairSearchWalker.Create(sr); | ||||
| try | try | ||||
| walker.Name := param.Name; | |||||
| walker.SearchFlags := [sfSearchChildrenLazy, sfSearchParents]; | |||||
| walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty, TengShaderPartStatic); | |||||
| walker.Name := param.Name; | |||||
| walker.SearchFlags := [sfSearchChildrenLazy, sfSearchParents]; | |||||
| walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty, TengShaderPartStatic); | |||||
| walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope); | walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope); | ||||
| walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile); | |||||
| walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile); | |||||
| walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile); | walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile); | ||||
| walker.Run(fParent); | walker.Run(fParent); | ||||
| tmp := ExtractSearchResult(fParent, param.Name, sr, param.Line, param.Col); | |||||
| tmp := ExtractSearchResult(fParent, param.Name, sr, [ifWarning, ifRaiseEx], param.Line, param.Col); | |||||
| result := TengExpressionVariable.Create(param.Name, (tmp as TengShaderPartKeyValuePair), param.Line, param.Col); | result := TengExpressionVariable.Create(param.Name, (tmp as TengShaderPartKeyValuePair), param.Line, param.Col); | ||||
| finally | finally | ||||
| FreeAndNil(walker); | FreeAndNil(walker); | ||||
| @@ -8,15 +8,33 @@ interface | |||||
| uses | uses | ||||
| uengShaderPart, uengShaderFileParser; | uengShaderPart, uengShaderFileParser; | ||||
| type | |||||
| TInfoFlag = ( | |||||
| ifWarning, | |||||
| ifRaiseEx | |||||
| ); | |||||
| TInfoFlags = set of TInfoFlag; | |||||
| 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; | |||||
| function CheckType(const aShaderPart: TengShaderPart; const aTypes: array of CengShaderPart): Boolean; | |||||
| function ExtractSearchResult( | |||||
| const aSender: TengShaderPart; | |||||
| const aIdent: String; | |||||
| const aList: TengShaderPartList; | |||||
| const aFlags: TInfoFlags = [ifWarning, ifRaiseEx]; | |||||
| aLine: Integer = -1; | |||||
| aCol: Integer = -1; | |||||
| aFilename: String = ''): TengShaderPart; | |||||
| type | type | ||||
| TengSearchFlag = ( | TengSearchFlag = ( | ||||
| sfSearchChildren, // search in children | sfSearchChildren, // search in children | ||||
| sfEvaluateIf, // evaluate if and search in suitable subtree | |||||
| sfIgnoreIf, // do not search in if items | |||||
| sfSearchChildrenLazy, // set sfSearchChildren in next recursion level | sfSearchChildrenLazy, // set sfSearchChildren in next recursion level | ||||
| sfSearchParents, // search in Parents | sfSearchParents, // search in Parents | ||||
| sfSearchInherited, // search in inherited classes | |||||
| sfIgnoreOwner // ignore owner of search walker | sfIgnoreOwner // ignore owner of search walker | ||||
| ); | ); | ||||
| TengSearchFlags = set of TengSearchFlag; | TengSearchFlags = set of TengSearchFlag; | ||||
| @@ -65,11 +83,21 @@ type | |||||
| property Name: String read fName write fName; | property Name: String read fName write fName; | ||||
| end; | end; | ||||
| TengProcSearchWalker = class(TengSearchWalker) | |||||
| private | |||||
| fName: String; | |||||
| protected | |||||
| function Check(const aPart: TengShaderPart): Boolean; override; | |||||
| public | |||||
| property Name: String read fName write fName; | |||||
| constructor Create(const aResults: TengSearchResults); | |||||
| end; | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| sysutils, | sysutils, | ||||
| uengShaderFileConstants, uengShaderFileTypes, uengShaderPartKeyValuePair; | |||||
| uengShaderFileConstants, uengShaderFileTypes, uengShaderPartKeyValuePair, uengShaderPartProc, uengShaderPartIf; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function IsValidIdentifier(const aIdent: String): Boolean; | function IsValidIdentifier(const aIdent: String): Boolean; | ||||
| @@ -106,9 +134,21 @@ begin | |||||
| end; | end; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function CheckType(const aShaderPart: TengShaderPart; const aTypes: array of CengShaderPart): Boolean; | |||||
| var | |||||
| t: CengShaderPart; | |||||
| begin | |||||
| result := true; | |||||
| for t in aTypes do | |||||
| if (aShaderPart is t) then | |||||
| exit; | |||||
| result := (Length(aTypes) = 0); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function ExtractSearchResult(const aSender: TengShaderPart; const aIdent: String; const aList: TengShaderPartList; | function ExtractSearchResult(const aSender: TengShaderPart; const aIdent: String; const aList: TengShaderPartList; | ||||
| aLine: Integer; aCol: Integer; aFilename: String): TengShaderPart; | |||||
| const aFlags: TInfoFlags; aLine: Integer; aCol: Integer; aFilename: String): TengShaderPart; | |||||
| var | var | ||||
| s: String; | s: String; | ||||
| i: Integer; | i: Integer; | ||||
| @@ -122,10 +162,13 @@ begin | |||||
| if (aFilename = '') then | if (aFilename = '') then | ||||
| aFilename := aSender.Filename; | aFilename := aSender.Filename; | ||||
| end; | end; | ||||
| if (aList.Count <= 0) then | |||||
| raise EengUnknownIdentifier.Create(aIdent, aLine, aCol, aFilename, aSender); | |||||
| if (aList.Count <= 0) then begin | |||||
| if (ifRaiseEx in aFlags) then | |||||
| raise EengUnknownIdentifier.Create(aIdent, aLine, aCol, aFilename, aSender); | |||||
| exit; | |||||
| end; | |||||
| result := aList[aList.Count-1]; | result := aList[aList.Count-1]; | ||||
| if (aList.Count > 1) and Assigned(aSender) then begin | |||||
| if (aList.Count > 1) and Assigned(aSender) and (ifWarning in aFlags) then begin | |||||
| s := Format('use of duplicate identifier: %s (%s %d:%d)', [aIdent, result.Filename, result.Line + 1, result.Col]) + sLineBreak + | s := Format('use of duplicate identifier: %s (%s %d:%d)', [aIdent, result.Filename, result.Line + 1, result.Col]) + sLineBreak + | ||||
| 'previously declared here:' + sLineBreak; | 'previously declared here:' + sLineBreak; | ||||
| i := aList.Count - 2; | i := aList.Count - 2; | ||||
| @@ -183,7 +226,7 @@ var | |||||
| end; | end; | ||||
| var | var | ||||
| c: TengShaderPart; | |||||
| p: TengShaderPart; | |||||
| nextArgs: TArgs; | nextArgs: TArgs; | ||||
| begin | begin | ||||
| if not Assigned(aPart) then | if not Assigned(aPart) then | ||||
| @@ -193,6 +236,7 @@ begin | |||||
| else | else | ||||
| args.Flags := fSearchFlags; | args.Flags := fSearchFlags; | ||||
| // visit parent | |||||
| nextArgs := args; | nextArgs := args; | ||||
| if (sfSearchChildrenLazy in nextArgs.Flags) then | if (sfSearchChildrenLazy in nextArgs.Flags) then | ||||
| nextArgs.Flags := nextArgs.Flags + [sfSearchChildren] - [sfSearchChildrenLazy]; | nextArgs.Flags := nextArgs.Flags + [sfSearchChildren] - [sfSearchChildrenLazy]; | ||||
| @@ -201,12 +245,25 @@ begin | |||||
| if VisitParent then | if VisitParent then | ||||
| Visit(aPart.Parent, aPart, @nextArgs); | Visit(aPart.Parent, aPart, @nextArgs); | ||||
| // visit children | |||||
| if (sfSearchChildren in args.Flags) then begin | if (sfSearchChildren in args.Flags) then begin | ||||
| for c in aPart do begin | |||||
| if Check(c) then | |||||
| fResults.Add(c); | |||||
| if VisitChild(c) then | |||||
| Visit(c, aPart, @args); | |||||
| if (aPart is TengShaderPartIf) then with (aPart as TengShaderPartIf) do begin | |||||
| if (sfEvaluateIf in args.Flags) then begin | |||||
| if Expression.GetValue | |||||
| then p := IfPart | |||||
| else p := ElsePart; | |||||
| if Assigned(p) then | |||||
| Visit(p, aPart, @args); | |||||
| exit; | |||||
| end else if (sfIgnoreIf in args.Flags) then | |||||
| exit; | |||||
| end; | |||||
| for p in aPart do begin | |||||
| if Check(p) then | |||||
| fResults.Add(p); | |||||
| if VisitChild(p) then | |||||
| Visit(p, aPart, @args); | |||||
| end; | end; | ||||
| end; | end; | ||||
| end; | end; | ||||
| @@ -242,5 +299,23 @@ begin | |||||
| ((aPart as TengShaderPartKeyValuePair).Name = fName); | ((aPart as TengShaderPartKeyValuePair).Name = fName); | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //TengProcSearchWalker////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengProcSearchWalker.Check(const aPart: TengShaderPart): Boolean; | |||||
| begin | |||||
| result := | |||||
| inherited Check(aPart) and | |||||
| (aPart is TengShaderPartProc) and | |||||
| ((aPart as TengShaderPartProc).Name = fName); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| constructor TengProcSearchWalker.Create(const aResults: TengSearchResults); | |||||
| begin | |||||
| inherited Create(aResults); | |||||
| ResultTypes := CengShaderPartArr.Create(TengShaderPartProc); | |||||
| end; | |||||
| end. | end. | ||||
| @@ -9,7 +9,7 @@ uses | |||||
| Classes, SysUtils | Classes, SysUtils | ||||
| {$IFDEF USE_BITSPACE_UTILS} | {$IFDEF USE_BITSPACE_UTILS} | ||||
| , uutlSerialization, uutlCommon | |||||
| , uutlSerialization, uutlCommon, uutlGenerics | |||||
| {$ENDIF} | {$ENDIF} | ||||
| ; | ; | ||||
| @@ -36,6 +36,33 @@ type | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| TengMetaType = ( | |||||
| metaUnknown, | |||||
| metaNormal, | |||||
| metaVersion, | |||||
| metaExtension, | |||||
| metaLayout); | |||||
| TengMetaData = class(TObject) | |||||
| private | |||||
| fMetaType: TengMetaType; | |||||
| fName: String; | |||||
| fValues: TStringList; | |||||
| function GetCount: Integer; | |||||
| function GetValues: TStrings; | |||||
| public | |||||
| property MetaType: TengMetaType read fMetaType; | |||||
| property Name: String read fName; | |||||
| property Count: Integer read GetCount; | |||||
| property Values: TStrings read GetValues; | |||||
| procedure Assign(const aValues: TengMetaData); | |||||
| constructor Create(const aName: String; const aType: TengMetaType); | |||||
| destructor Destroy; override; | |||||
| end; | |||||
| TengMetaDataList = specialize TutlSimpleList<TengMetaData>; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //Exceptions//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //Exceptions//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -159,6 +186,45 @@ implementation | |||||
| uses | uses | ||||
| uengShaderPart; | uengShaderPart; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //TengMetaData////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengMetaData.GetCount: Integer; | |||||
| begin | |||||
| result := fValues.Count; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengMetaData.GetValues: TStrings; | |||||
| begin | |||||
| result := fValues; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengMetaData.Assign(const aValues: TengMetaData); | |||||
| begin | |||||
| fName := aValues.Name; | |||||
| fMetaType := aValues.MetaType; | |||||
| fValues.Clear; | |||||
| fValues.AddStrings(aValues.Values); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| constructor TengMetaData.Create(const aName: String; const aType: TengMetaType); | |||||
| begin | |||||
| inherited Create; | |||||
| fName := aName; | |||||
| fMetaType := aType; | |||||
| fValues := TStringList.Create; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| destructor TengMetaData.Destroy; | |||||
| begin | |||||
| FreeAndNil(fValues); | |||||
| inherited Destroy; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //EengExpressionInternal//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //EengExpressionInternal//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -12,7 +12,7 @@ uses | |||||
| type | type | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| TengShaderCodeGenerator = class(TengShaderPartScope) | |||||
| TengShaderGenerator = class(TengShaderPartScope) | |||||
| { Code Loading & Storage } | { Code Loading & Storage } | ||||
| private | private | ||||
| fPropertyMap: TengShaderPartPropertyMap; | fPropertyMap: TengShaderPartPropertyMap; | ||||
| @@ -26,7 +26,7 @@ type | |||||
| procedure SetPropertyByName(const aName: String; aValue: Variant); | procedure SetPropertyByName(const aName: String; aValue: Variant); | ||||
| protected | protected | ||||
| procedure AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean = true); | procedure AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean = true); | ||||
| procedure CopyProperties(const aGen: TengShaderCodeGenerator); | |||||
| procedure CopyProperties(const aGen: TengShaderGenerator); | |||||
| procedure UpdateProperties; virtual; | procedure UpdateProperties; virtual; | ||||
| function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; | function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; | ||||
| public | public | ||||
| @@ -48,15 +48,15 @@ type | |||||
| implementation | implementation | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderCodeGenerator/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //TengShaderGenerator/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderCodeGenerator.GetPropertyByIndex(const aIndex: Integer): Variant; | |||||
| function TengShaderGenerator.GetPropertyByIndex(const aIndex: Integer): Variant; | |||||
| begin | begin | ||||
| result := fPropertyMap.ValueAt[aIndex].Value; | result := fPropertyMap.ValueAt[aIndex].Value; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderCodeGenerator.GetPropertyByName(const aName: String): Variant; | |||||
| function TengShaderGenerator.GetPropertyByName(const aName: String): Variant; | |||||
| var | var | ||||
| l: TengShaderPartPropertyList; | l: TengShaderPartPropertyList; | ||||
| begin | begin | ||||
| @@ -67,25 +67,25 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderCodeGenerator.GetPropertyCount: Integer; | |||||
| function TengShaderGenerator.GetPropertyCount: Integer; | |||||
| begin | begin | ||||
| result := fPropertyMap.Count; | result := fPropertyMap.Count; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderCodeGenerator.GetPropertyNames(const aIndex: Integer): String; | |||||
| function TengShaderGenerator.GetPropertyNames(const aIndex: Integer): String; | |||||
| begin | begin | ||||
| result := fPropertyMap.KeyValuePairs[aIndex].Key; | result := fPropertyMap.KeyValuePairs[aIndex].Key; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderCodeGenerator.SetPropertyByIndex(const aIndex: Integer; aValue: Variant); | |||||
| procedure TengShaderGenerator.SetPropertyByIndex(const aIndex: Integer; aValue: Variant); | |||||
| begin | begin | ||||
| fPropertyMap.ValueAt[aIndex].Value := aValue; | fPropertyMap.ValueAt[aIndex].Value := aValue; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderCodeGenerator.SetPropertyByName(const aName: String; aValue: Variant); | |||||
| procedure TengShaderGenerator.SetPropertyByName(const aName: String; aValue: Variant); | |||||
| var | var | ||||
| l: TengShaderPartPropertyList; | l: TengShaderPartPropertyList; | ||||
| begin | begin | ||||
| @@ -96,7 +96,7 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderCodeGenerator.AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean); | |||||
| procedure TengShaderGenerator.AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean); | |||||
| var | var | ||||
| l: TengShaderPartPropertyList; | l: TengShaderPartPropertyList; | ||||
| p: TengShaderPartProperty; | p: TengShaderPartProperty; | ||||
| @@ -121,7 +121,7 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderCodeGenerator.CopyProperties(const aGen: TengShaderCodeGenerator); | |||||
| procedure TengShaderGenerator.CopyProperties(const aGen: TengShaderGenerator); | |||||
| var | var | ||||
| l: TengShaderPartPropertyList; | l: TengShaderPartPropertyList; | ||||
| p: TengShaderPartProperty; | p: TengShaderPartProperty; | ||||
| @@ -132,26 +132,27 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderCodeGenerator.UpdateProperties; | |||||
| procedure TengShaderGenerator.UpdateProperties; | |||||
| begin | begin | ||||
| fPropertyMap.Clear; | fPropertyMap.Clear; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderCodeGenerator.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; | |||||
| function TengShaderGenerator.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; | |||||
| begin | begin | ||||
| result := inherited ParseIntern(aArgs, aParams); | result := inherited ParseIntern(aArgs, aParams); | ||||
| UpdateProperties; | UpdateProperties; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderCodeGenerator.GenerateCode(const aCode: TengShaderCode); | |||||
| procedure TengShaderGenerator.GenerateCode(const aCode: TengShaderCode); | |||||
| var | var | ||||
| args: TengShaderGeneratorArgs; | args: TengShaderGeneratorArgs; | ||||
| begin | begin | ||||
| args := TengShaderGeneratorArgs.Create(self); | args := TengShaderGeneratorArgs.Create(self); | ||||
| try | try | ||||
| inherited GenerateCodeIntern(args); | |||||
| fPropertyMap.ApplyValues; | |||||
| GenerateCodeIntern(args); | |||||
| args.GenerateCode(aCode); | args.GenerateCode(aCode); | ||||
| finally | finally | ||||
| FreeAndNil(args); | FreeAndNil(args); | ||||
| @@ -159,14 +160,14 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| constructor TengShaderCodeGenerator.Create(const aParent: TengShaderPart); | |||||
| constructor TengShaderGenerator.Create(const aParent: TengShaderPart); | |||||
| begin | begin | ||||
| inherited Create(aParent); | inherited Create(aParent); | ||||
| fPropertyMap := TengShaderPartPropertyMap.Create(true); | fPropertyMap := TengShaderPartPropertyMap.Create(true); | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| destructor TengShaderCodeGenerator.Destroy; | |||||
| destructor TengShaderGenerator.Destroy; | |||||
| begin | begin | ||||
| FreeAndNil(fPropertyMap); | FreeAndNil(fPropertyMap); | ||||
| inherited Destroy; | inherited Destroy; | ||||
| @@ -17,33 +17,52 @@ uses | |||||
| type | type | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| TengGenerateFlag = ( | TengGenerateFlag = ( | ||||
| gfGenerateParameterItemCode, // generate code for parameter items | |||||
| gfAddParameterItem // add parameter items to generator args | |||||
| gfGenerateProcedureCode, // generate procedure code | |||||
| gfGenerateProcedureCall, // generate procedure call | |||||
| gfGenerateInlineCode, // generate procedure as inline code | |||||
| gfGenerateParameterCode, // generate code for parameter items | |||||
| gfAddProcedureItem, // add procedure item to generator args | |||||
| gfAddParameterItem // add parameter items to generator args | |||||
| ); | ); | ||||
| TengGenerateFlags = set of TengGenerateFlag; | TengGenerateFlags = set of TengGenerateFlag; | ||||
| TengGenerateFlagsStack = specialize TutlSimpleList<TengGenerateFlags>; | |||||
| TengPopCodeFlag = ( | |||||
| pcfAppend, | |||||
| pcfPrepend, | |||||
| pcfAddEmptyLine | |||||
| ); | |||||
| TengPopCodeFlags = set of TengPopCodeFlag; | |||||
| TengShaderGeneratorArgs = class(TObject) | TengShaderGeneratorArgs = class(TObject) | ||||
| private type | private type | ||||
| TengGeneratorToken = ( | TengGeneratorToken = ( | ||||
| gtNormal, // normal text | |||||
| gtLineBreak, // line break | |||||
| gtCommandEnd, // command end (like ';') | |||||
| gtBlockBegin, // code block begin (to calculate indent) | |||||
| gtBlockEnd, // code block end (to calculate indent) | |||||
| gtToken // code token (like '$INCLUDE' or '$IF') | |||||
| gtNormal = 0, // normal text | |||||
| gtLineBreak = 1, // line break | |||||
| gtCommandEnd = 2, // command end (like ';') | |||||
| gtBlockBegin = 3, // code block begin (to calculate indent) | |||||
| gtBlockEnd = 4, // code block end (to calculate indent) | |||||
| gtToken = 5 // code token (like '$INCLUDE' or '$IF') | |||||
| ); | ); | ||||
| TCodePart = class(TObject) | TCodePart = class(TObject) | ||||
| private | private | ||||
| fText: String; | fText: String; | ||||
| fIndent: Integer; | |||||
| fToken: TengGeneratorToken; | fToken: TengGeneratorToken; | ||||
| function GetText: String; | |||||
| function GetDebugText: String; | |||||
| function GetCode: String; | |||||
| public | public | ||||
| property Text: String read GetText; | |||||
| property Token: TengGeneratorToken read fToken; | |||||
| constructor Create(const aToken: TengGeneratorToken; const aText: String); | |||||
| property Text: String read fText write fText; | |||||
| property Code: String read GetCode; | |||||
| property DebugText: String read GetDebugText; | |||||
| property Indent: Integer read fIndent; | |||||
| property Token: TengGeneratorToken read fToken; | |||||
| constructor Create(const aToken: TengGeneratorToken; const aText: String; const aIndent: Integer = 0); | |||||
| end; | end; | ||||
| TCodePartList = specialize TutlSimpleList<TCodePart>; | TCodePartList = specialize TutlSimpleList<TCodePart>; | ||||
| public type | |||||
| TCodeStackItem = class(TObject) | TCodeStackItem = class(TObject) | ||||
| private | private | ||||
| fItems: TCodePartList; | fItems: TCodePartList; | ||||
| @@ -53,33 +72,64 @@ type | |||||
| property IsEmpty: Boolean read GetIsEmpty; | property IsEmpty: Boolean read GetIsEmpty; | ||||
| procedure GenerateCode(const aCode: TengShaderCode); | procedure GenerateCode(const aCode: TengShaderCode); | ||||
| procedure Merge(const aItem: TCodeStackItem; aIndex: Integer); | |||||
| constructor Create; | constructor Create; | ||||
| destructor Destroy; override; | destructor Destroy; override; | ||||
| end; | end; | ||||
| private type | |||||
| TCodeStack = specialize TutlSimpleList<TCodeStackItem>; | TCodeStack = specialize TutlSimpleList<TCodeStackItem>; | ||||
| TParameterMap = specialize TutlMap<string, TengShaderPart>; | |||||
| TProcedureList = specialize TutlSimpleList<TengShaderPart>; | |||||
| TProcParamStack = specialize TutlSimpleList<TStrings>; | |||||
| private | private | ||||
| fInlineReturnCounter: Integer; | |||||
| fCode: TCodeStack; | fCode: TCodeStack; | ||||
| fRoot: TengShaderPart; | fRoot: TengShaderPart; | ||||
| fFlags: TengGenerateFlags; | |||||
| fFlagStack: TengGenerateFlagsStack; | |||||
| fMetaDataList: TengMetaDataList; | |||||
| fParameters: TParameterMap; | |||||
| fProcedures: TProcedureList; | |||||
| fProcParams: TProcParamStack; | |||||
| fMaxParameterLength: Integer; | |||||
| function GetFlags: TengGenerateFlags; | |||||
| function GetProcParams: TStrings; | |||||
| procedure GenerateParameterCode(const aTypes: CengShaderPartArr); | |||||
| procedure GenerateProcedureCode; | |||||
| procedure GenerateMetaCode; | |||||
| public | public | ||||
| property Root: TengShaderPart read fRoot; | |||||
| property Flags: TengGenerateFlags read fFlags; | |||||
| property Root: TengShaderPart read fRoot; | |||||
| property Flags: TengGenerateFlags read GetFlags; | |||||
| property ProcParams: TStrings read GetProcParams; | |||||
| property MaxParameterLength: Integer read fMaxParameterLength; | |||||
| procedure PushCode; | procedure PushCode; | ||||
| procedure PopCode; | |||||
| procedure PushFlags(const aFlags: TengGenerateFlags); | |||||
| procedure PushProcParams(const aParams: TStrings); | |||||
| procedure PopCode(const aFlags: TengPopCodeFlags); | |||||
| procedure PopFlags; | |||||
| procedure PopProcParams; | |||||
| function AddText(const aText: String): TengShaderGeneratorArgs; | |||||
| function AddToken(const aToken: String): TengShaderGeneratorArgs; | |||||
| function AddCommandEnd(const aToken: String): TengShaderGeneratorArgs; | |||||
| function AddLineBreak: TengShaderGeneratorArgs; | |||||
| function BeginBlock(const aIndent: Integer = 0): TengShaderGeneratorArgs; | |||||
| function EndBlock: TengShaderGeneratorArgs; | |||||
| procedure AddText(const aText: String); | |||||
| procedure AddToken(const aToken: String); | |||||
| procedure AddCommandEnd(const aToken: String); | |||||
| procedure AddLineBreak; | |||||
| procedure BeginBlock; | |||||
| procedure EndBlock; | |||||
| procedure AddMeta(const aMeta: TengMetaData); | |||||
| procedure AddParameter(const aParam: TengShaderPart); | |||||
| procedure AddProcedure(const aProc: TengShaderPart); | |||||
| procedure AddMeta(const aMeta: TengShaderPart); | |||||
| procedure AddParam(const aParam: TengShaderPart); | |||||
| function ExtractCurrentCommand(const aCommand: TCodeStackItem): Integer; | |||||
| procedure ReplaceIdents(const aOld, aNew: TStrings); | |||||
| procedure ReplaceReturns(const aCommand: TCodeStackItem; const aRetType, aName: String); | |||||
| procedure GenerateCode(const aCode: TengShaderCode); | procedure GenerateCode(const aCode: TengShaderCode); | ||||
| @@ -90,12 +140,16 @@ type | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| Math; | |||||
| Math, RegExpr, | |||||
| uengShaderFileHelper, uengShaderFileConstants, uengShaderPartParameter, uengShaderPartProc; | |||||
| const | |||||
| WHITESPACES = [' ', #9]; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderGeneratorArgs.TCodePart/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TengShaderGeneratorArgs.TCodePart/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderGeneratorArgs.TCodePart.GetText: String; | |||||
| function TengShaderGeneratorArgs.TCodePart.GetCode: String; | |||||
| begin | begin | ||||
| case fToken of | case fToken of | ||||
| gtNormal, | gtNormal, | ||||
| @@ -109,11 +163,27 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| constructor TengShaderGeneratorArgs.TCodePart.Create(const aToken: TengGeneratorToken; const aText: String); | |||||
| function TengShaderGeneratorArgs.TCodePart.GetDebugText: String; | |||||
| begin | |||||
| case fToken of | |||||
| gtNormal: result := '[N]' + fText; | |||||
| gtLineBreak: result := sLineBreak; | |||||
| gtCommandEnd: result := '[C]' + fText; | |||||
| gtBlockBegin: result := format('[B%d]', [fIndent]); | |||||
| gtBlockEnd: result := '[E]'; | |||||
| gtToken: result := '[T' + fText + ']'; | |||||
| else | |||||
| result := '[' + IntToStr(Integer(fToken)) + ']' + fText | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| constructor TengShaderGeneratorArgs.TCodePart.Create(const aToken: TengGeneratorToken; const aText: String; const aIndent: Integer); | |||||
| begin | begin | ||||
| inherited Create; | inherited Create; | ||||
| fToken := aToken; | |||||
| fText := aText; | |||||
| fToken := aToken; | |||||
| fText := aText; | |||||
| fIndent := aIndent; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -131,15 +201,10 @@ type | |||||
| gfToken, // current line has a token in it | gfToken, // current line has a token in it | ||||
| gfTokenOnly, // current line has only a token (or whitespaces) in it | gfTokenOnly, // current line has only a token (or whitespaces) in it | ||||
| gfPrevIsEmpty, // previouse line was empty (or whitespaces only) | gfPrevIsEmpty, // previouse line was empty (or whitespaces only) | ||||
| gfCodeIsEmpty, // nothing has added to code | |||||
| gfAddToPrevLine, // add current line to previous line | |||||
| gfAddNextLine // add next line to current line (set gfAddToPrevLine on linebreak) | |||||
| gfCodeIsEmpty // nothing has added to code | |||||
| ); | ); | ||||
| TGenFlags = set of TGenFlag; | TGenFlags = set of TGenFlag; | ||||
| const | |||||
| WHITESPACES = [' ', #9]; | |||||
| var | var | ||||
| i: Integer; | i: Integer; | ||||
| f: TGenFlags; | f: TGenFlags; | ||||
| @@ -171,7 +236,7 @@ var | |||||
| inc(aStartIndex); | inc(aStartIndex); | ||||
| end; | end; | ||||
| if (result >= High(Integer)) then | if (result >= High(Integer)) then | ||||
| result := -1; | |||||
| result := 0; | |||||
| end; | end; | ||||
| function TrimLeftLen(const aStr: String; aLen: Integer): String; | function TrimLeftLen(const aStr: String; aLen: Integer): String; | ||||
| @@ -189,23 +254,22 @@ var | |||||
| function PrepareStr(const aStr: String; const aOffset: Integer): String; | function PrepareStr(const aStr: String; const aOffset: Integer): String; | ||||
| begin | begin | ||||
| if (aOffset < 0) | |||||
| then result := StringOfChar(' ', -aOffset) + aStr | |||||
| else result := TrimLeftLen(aStr, aOffset); | |||||
| if (aOffset > 0) | |||||
| then result := StringOfChar(' ', aOffset) + aStr | |||||
| else result := TrimLeftLen(aStr, -aOffset); | |||||
| end; | end; | ||||
| procedure IndentBlock(aStartIndex: Integer; const aIndent: Integer); | procedure IndentBlock(aStartIndex: Integer; const aIndent: Integer); | ||||
| var | var | ||||
| o: Integer; | o: Integer; | ||||
| begin | begin | ||||
| o := GetMinOffset(aStartIndex) - aIndent; | |||||
| if (o <= 0) then | |||||
| exit; | |||||
| o := aIndent - GetMinOffset(aStartIndex); | |||||
| while (aStartIndex < aCode.Count) do begin | while (aStartIndex < aCode.Count) do begin | ||||
| aCode[aStartIndex] := PrepareStr(aCode[aStartIndex], o); | aCode[aStartIndex] := PrepareStr(aCode[aStartIndex], o); | ||||
| inc(aStartIndex); | inc(aStartIndex); | ||||
| end; | end; | ||||
| line := PrepareStr(line, o); | |||||
| if (Trim(line) <> '') then | |||||
| line := PrepareStr(line, o); | |||||
| end; | end; | ||||
| procedure ProgressBlock(const aIndent: Integer); | procedure ProgressBlock(const aIndent: Integer); | ||||
| @@ -221,33 +285,18 @@ var | |||||
| case cp.Token of | case cp.Token of | ||||
| gtLineBreak: begin | gtLineBreak: begin | ||||
| // line has whitespaces only | |||||
| if (Trim(line) = '') then begin | if (Trim(line) = '') then begin | ||||
| if (f * [gfToken, gfPrevIsEmpty] = []) then begin | |||||
| if (f * [gfTokenOnly, gfPrevIsEmpty] = []) then begin | |||||
| aCode.Add(line); | aCode.Add(line); | ||||
| Include(f, gfPrevIsEmpty); | Include(f, gfPrevIsEmpty); | ||||
| end; | end; | ||||
| if not (gfTokenOnly in f) then | |||||
| Exclude(f, gfAddToPrevLine); | |||||
| // line has text | |||||
| end else begin | end else begin | ||||
| if (gfAddToPrevLine in f) and not (gfCodeIsEmpty in f) then begin | |||||
| aCode[aCode.Count-1] := aCode[aCode.Count-1] + TrimLeft(line) | |||||
| end else begin | |||||
| aCode.Add(line); | |||||
| Exclude(f, gfPrevIsEmpty); | |||||
| Exclude(f, gfCodeIsEmpty); | |||||
| end; | |||||
| Exclude(f, gfAddToPrevLine); | |||||
| aCode.Add(line); | |||||
| Exclude(f, gfPrevIsEmpty); | |||||
| Exclude(f, gfCodeIsEmpty); | |||||
| end; | end; | ||||
| Exclude(f, gfToken); | Exclude(f, gfToken); | ||||
| Exclude(f, gfTokenOnly); | Exclude(f, gfTokenOnly); | ||||
| if (gfAddNextLine in f) then begin | |||||
| Exclude(f, gfAddNextLine); | |||||
| Include(f, gfAddToPrevLine); | |||||
| end; | |||||
| line := ''; | line := ''; | ||||
| end; | end; | ||||
| @@ -258,35 +307,59 @@ var | |||||
| end; | end; | ||||
| gtBlockBegin: begin | gtBlockBegin: begin | ||||
| if (Trim(line) <> '') then | |||||
| Include(f, gfAddNextLine); | |||||
| Include(f, gfPrevIsEmpty); | Include(f, gfPrevIsEmpty); | ||||
| ProgressBlock(GetOffset(cp)); | |||||
| ProgressBlock(GetStrOffset(line) + cp.Indent); | |||||
| end; | end; | ||||
| gtBlockEnd: begin | gtBlockEnd: begin | ||||
| if (Trim(line) = '') then | |||||
| Include(f, gfAddToPrevLine); | |||||
| IndentBlock(FirstLineIndex, aIndent); | IndentBlock(FirstLineIndex, aIndent); | ||||
| exit; | exit; | ||||
| end; | end; | ||||
| else | else | ||||
| s := cp.GetText; | |||||
| if (gfAddNextLine in f) and (Trim(s) <> '') then | |||||
| Exclude(f, gfAddNextLine); | |||||
| s := cp.Code; | |||||
| line := line + s; | line := line + s; | ||||
| end; | end; | ||||
| end; | end; | ||||
| end; | end; | ||||
| procedure GenerateDebugCode; | |||||
| var | |||||
| cp: TCodePart; | |||||
| s: String; | |||||
| sl: TStringList; | |||||
| begin | |||||
| s := ''; | |||||
| for cp in fItems do | |||||
| s := s + cp.DebugText; | |||||
| sl := TStringList.Create; | |||||
| try | |||||
| sl.Text := s; | |||||
| sl.SaveToFile('C:\Users\Erik\Desktop\tmp\debug.txt'); | |||||
| finally | |||||
| FreeAndNil(sl); | |||||
| end; | |||||
| end; | |||||
| begin | begin | ||||
| i := 0; | i := 0; | ||||
| f := [gfPrevIsEmpty, gfCodeIsEmpty]; | f := [gfPrevIsEmpty, gfCodeIsEmpty]; | ||||
| line := ''; | line := ''; | ||||
| GenerateDebugCode; | |||||
| ProgressBlock(0); | ProgressBlock(0); | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderGeneratorArgs.TCodeStackItem.Merge(const aItem: TCodeStackItem; aIndex: Integer); | |||||
| begin | |||||
| if (aIndex < 0) then | |||||
| aIndex := 0; | |||||
| if (aIndex > fItems.Count) then | |||||
| aIndex := fItems.Count; | |||||
| while (aItem.Items.Count > 0) do | |||||
| fItems.Insert(aIndex, aItem.Items.PopLast(false)); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| constructor TengShaderGeneratorArgs.TCodeStackItem.Create; | constructor TengShaderGeneratorArgs.TCodeStackItem.Create; | ||||
| begin | begin | ||||
| @@ -302,7 +375,126 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderGeneratorArgs///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //TengShaderGeneratorArgs/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengShaderGeneratorArgs.GetFlags: TengGenerateFlags; | |||||
| begin | |||||
| result := fFlagStack.Last; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengShaderGeneratorArgs.GetProcParams: TStrings; | |||||
| begin | |||||
| result := fProcParams.Last; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderGeneratorArgs.GenerateParameterCode(const aTypes: CengShaderPartArr); | |||||
| var | |||||
| m: TParameterMap; | |||||
| p: TengShaderPart; | |||||
| begin | |||||
| PushCode; | |||||
| PushFlags(Flags + [gfGenerateParameterCode] - [gfAddParameterItem]); | |||||
| m := TParameterMap.Create(false); | |||||
| try | |||||
| fMaxParameterLength := 0; | |||||
| for p in fParameters do begin | |||||
| if CheckType(p, aTypes) then with (p as TengShaderPartParameter) do begin | |||||
| fMaxParameterLength := Max(fMaxParameterLength, Length(Typ)); | |||||
| m.Add(Typ+Name, p); | |||||
| end; | |||||
| end; | |||||
| for p in m do begin | |||||
| (p as TengShaderPartParameter).GenerateCodeIntern(self); | |||||
| AddLineBreak; | |||||
| end; | |||||
| finally | |||||
| FreeAndNil(m); | |||||
| PopFlags; | |||||
| PopCode([pcfPrepend, pcfAddEmptyLine]); | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderGeneratorArgs.GenerateProcedureCode; | |||||
| var | |||||
| i: Integer; | |||||
| begin | |||||
| i := 0; | |||||
| while (i < fProcedures.Count) do begin | |||||
| PushCode; | |||||
| PushFlags([gfGenerateProcedureCode, gfAddParameterItem]); | |||||
| try | |||||
| (fProcedures[i] as TengShaderPartProc).GenerateCodeIntern(self); | |||||
| finally | |||||
| PopFlags; | |||||
| PopCode([pcfPrepend, pcfAddEmptyLine]); | |||||
| end; | |||||
| inc(i); | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderGeneratorArgs.GenerateMetaCode; | |||||
| var | |||||
| layouts: TStringList; | |||||
| m: TengMetaData; | |||||
| vCompat: Boolean; | |||||
| vMax, i: Integer; | |||||
| s: String; | |||||
| begin | |||||
| PushCode; | |||||
| vMax := 0; | |||||
| vCompat := false; | |||||
| layouts := TStringList.Create; | |||||
| try | |||||
| for m in fMetaDataList do begin | |||||
| case m.MetaType of | |||||
| metaVersion: begin | |||||
| if (m.Values[0] = VERSION_EXTRA_COMPAT) then | |||||
| vCompat := true | |||||
| else if TryStrToInt(m.Values[0], i) then | |||||
| vMax := max(vMax, i); | |||||
| if (m.Count > 1) and (m.Values[1] = VERSION_EXTRA_COMPAT) then | |||||
| vCompat := true; | |||||
| end; | |||||
| metaExtension: begin | |||||
| AddText(format('#extension %s : %s', [m.Values[0], m.Values[1]])); | |||||
| AddLineBreak; | |||||
| end; | |||||
| metaLayout: begin | |||||
| layouts.Add('layout' + m.Values[0] + ';'); | |||||
| end; | |||||
| end; | |||||
| end; | |||||
| if (vMax >= LAYOUT_MIN_VERSION) then begin | |||||
| for s in layouts do begin | |||||
| AddText(s); | |||||
| AddLineBreak; | |||||
| end; | |||||
| end; | |||||
| if (vMax > 0) then begin | |||||
| PushCode; | |||||
| try | |||||
| AddText('#version ' + IntToStr(vMax)); | |||||
| if vCompat then | |||||
| AddText(' ' + VERSION_EXTRA_COMPAT); | |||||
| AddLineBreak; | |||||
| finally | |||||
| PopCode([pcfPrepend]); | |||||
| end; | |||||
| end; | |||||
| finally | |||||
| PopCode([pcfPrepend, pcfAddEmptyLine]); | |||||
| FreeAndNil(layouts); | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.PushCode; | procedure TengShaderGeneratorArgs.PushCode; | ||||
| begin | begin | ||||
| @@ -310,69 +502,269 @@ begin | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.PopCode; | |||||
| procedure TengShaderGeneratorArgs.PushFlags(const aFlags: TengGenerateFlags); | |||||
| begin | |||||
| fFlagStack.PushLast(aFlags); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderGeneratorArgs.PushProcParams(const aParams: TStrings); | |||||
| begin | |||||
| fProcParams.PushLast(aParams); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderGeneratorArgs.PopCode(const aFlags: TengPopCodeFlags); | |||||
| var | var | ||||
| csi: TCodeStackItem; | csi: TCodeStackItem; | ||||
| begin | begin | ||||
| csi := fCode.PopLast(false); | csi := fCode.PopLast(false); | ||||
| try | try | ||||
| // TODO merge | |||||
| if csi.IsEmpty then | |||||
| exit; | |||||
| if (pcfPrepend in aFlags) then begin | |||||
| if (pcfAddEmptyLine in aFlags) then | |||||
| csi.Items.Add(TCodePart.Create(gtLineBreak, '')); | |||||
| fCode.Last.Merge(csi, 1); | |||||
| end else if (pcfAppend in aFlags) then begin | |||||
| if (pcfAddEmptyLine in aFlags) then | |||||
| fCode.Last.Items.Add(TCodePart.Create(gtLineBreak, '')); | |||||
| fCode.Last.Merge(csi, fCode.Last.Items.Count); | |||||
| end; | |||||
| finally | finally | ||||
| FreeAndNil(csi); | FreeAndNil(csi); | ||||
| end; | end; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.AddText(const aText: String); | |||||
| procedure TengShaderGeneratorArgs.PopFlags; | |||||
| begin | |||||
| fFlagStack.PopLast(true); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderGeneratorArgs.PopProcParams; | |||||
| begin | |||||
| fProcParams.PopLast; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengShaderGeneratorArgs.AddText(const aText: String): TengShaderGeneratorArgs; | |||||
| begin | begin | ||||
| fCode.Last.Items.Add(TCodePart.Create(gtNormal, aText)); | fCode.Last.Items.Add(TCodePart.Create(gtNormal, aText)); | ||||
| result := self; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.AddToken(const aToken: String); | |||||
| function TengShaderGeneratorArgs.AddToken(const aToken: String): TengShaderGeneratorArgs; | |||||
| begin | begin | ||||
| fCode.Last.Items.Add(TCodePart.Create(gtToken, aToken)); | fCode.Last.Items.Add(TCodePart.Create(gtToken, aToken)); | ||||
| result := self; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.AddCommandEnd(const aToken: String); | |||||
| function TengShaderGeneratorArgs.AddCommandEnd(const aToken: String): TengShaderGeneratorArgs; | |||||
| begin | begin | ||||
| fCode.Last.Items.Add(TCodePart.Create(gtCommandEnd, aToken)); | fCode.Last.Items.Add(TCodePart.Create(gtCommandEnd, aToken)); | ||||
| result := self; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.AddLineBreak; | |||||
| function TengShaderGeneratorArgs.AddLineBreak: TengShaderGeneratorArgs; | |||||
| begin | begin | ||||
| fCode.Last.Items.Add(TCodePart.Create(gtLineBreak, '')); | fCode.Last.Items.Add(TCodePart.Create(gtLineBreak, '')); | ||||
| result := self; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.BeginBlock; | |||||
| function TengShaderGeneratorArgs.BeginBlock(const aIndent: Integer): TengShaderGeneratorArgs; | |||||
| begin | begin | ||||
| fCode.Last.Items.Add(TCodePart.Create(gtBlockBegin, '')); | |||||
| fCode.Last.Items.Add(TCodePart.Create(gtBlockBegin, '', aIndent)); | |||||
| result := self; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.EndBlock; | |||||
| function TengShaderGeneratorArgs.EndBlock: TengShaderGeneratorArgs; | |||||
| begin | begin | ||||
| fCode.Last.Items.Add(TCodePart.Create(gtBlockEnd, '')); | fCode.Last.Items.Add(TCodePart.Create(gtBlockEnd, '')); | ||||
| result := self; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.AddMeta(const aMeta: TengShaderPart); | |||||
| procedure TengShaderGeneratorArgs.AddMeta(const aMeta: TengMetaData); | |||||
| begin | begin | ||||
| // TODO | |||||
| fMetaDataList.Add(aMeta); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.AddParam(const aParam: TengShaderPart); | |||||
| procedure TengShaderGeneratorArgs.AddParameter(const aParam: TengShaderPart); | |||||
| var | |||||
| p: TengShaderPart; | |||||
| s: String; | |||||
| begin | |||||
| if not (aParam is TengShaderPartParameter) then | |||||
| raise EengShaderPartInternal.Create('parameter (' + aParam.ClassName + ') is not a ' + TengShaderPartParameter.ClassName, aParam); | |||||
| with (aParam as TengShaderPartParameter) do begin | |||||
| p := fParameters[Name]; | |||||
| if Assigned(p) then begin | |||||
| s := Format('use of duplicate identifier: %s (%s %d:%d)', [Name, Filename, Line + 1, Col]) + sLineBreak + | |||||
| 'previously declared here:' + sLineBreak + | |||||
| Format(' %s %d:%d', [p.Filename, p.Line + 1, p.Col]) + sLineBreak; | |||||
| fRoot.LogMsg(llWarning, s); | |||||
| fParameters[Name] := aParam; | |||||
| end else | |||||
| fParameters.Add(Name, aParam); | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderGeneratorArgs.AddProcedure(const aProc: TengShaderPart); | |||||
| begin | |||||
| if not (aProc is TengShaderPartProc) then | |||||
| raise EengShaderPartInternal.Create('parameter (' + aProc.ClassName + ') is not a ' + TengShaderPartProc.ClassName, aProc); | |||||
| fProcedures.Add(aProc); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengShaderGeneratorArgs.ExtractCurrentCommand(const aCommand: TCodeStackItem): Integer; | |||||
| var | |||||
| csi: TCodeStackItem; | |||||
| i, len: Integer; | |||||
| s: String; | |||||
| begin | |||||
| csi := fCode.Last; | |||||
| if not Assigned(aCommand) then | |||||
| exit; | |||||
| // find last command end token | |||||
| while (csi.Items.Last.Token <> gtCommandEnd) do | |||||
| aCommand.Items.PushFirst(csi.Items.PopLast(false)); | |||||
| // move forward to first code part with text | |||||
| while (aCommand.Items.First.Token <> gtNormal) or (Trim(aCommand.Items.First.Text) = '') do | |||||
| csi.Items.PushLast(aCommand.Items.PopFirst(false)); | |||||
| // extract leading whitespaces | |||||
| i := 1; | |||||
| s := aCommand.Items.First.Text; | |||||
| len := Length(s); | |||||
| while (s[i] in WHITESPACES) and (i <= len) do | |||||
| inc(i); | |||||
| csi.Items.PushLast(TCodePart.Create(gtNormal, Copy(s, 1, i-1))); | |||||
| aCommand.Items.First.Text := copy(s, i, len-i+1); | |||||
| result := i - 1; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderGeneratorArgs.ReplaceIdents(const aOld, aNew: TStrings); | |||||
| var | |||||
| rx: TRegExpr; | |||||
| i: Integer; | |||||
| cp: TCodePart; | |||||
| begin | begin | ||||
| // TODO | |||||
| if (aOld.Count <> aNew.Count) then | |||||
| raise EengShaderPartInternal.Create('old and new ident must have the same size'); | |||||
| rx := TRegExpr.Create; | |||||
| try | |||||
| for i := 0 to aOld.Count-1 do begin | |||||
| rx.Expression := '([^A-z0-9_]+|^)' + aOld[i] + '([^A-z0-9_]+|$)'; | |||||
| for cp in fCode.Last.Items do | |||||
| cp.Text := rx.Replace(cp.Text, '$1' + aNew[i] + '$2', true); | |||||
| end; | |||||
| finally | |||||
| FreeAndNil(rx); | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderGeneratorArgs.ReplaceReturns(const aCommand: TCodeStackItem; const aRetType, aName: String); | |||||
| var | |||||
| rx: TRegExpr; | |||||
| RetCount, i, j: Integer; | |||||
| csi: TCodeStackItem; | |||||
| cp: TCodePart; | |||||
| s: String; | |||||
| begin | |||||
| rx := TRegExpr.Create; | |||||
| try | |||||
| rx.Expression := '([^A-z0-9_]+|^)return([^A-z0-9_]+|$)'; | |||||
| csi := fCode.Last; | |||||
| // find number of "return" in code | |||||
| RetCount := 0; | |||||
| for cp in csi.Items do begin | |||||
| s := cp.Code; | |||||
| if rx.Exec(s) then | |||||
| inc(RetCount); | |||||
| end; | |||||
| // no "return" found | |||||
| if (RetCount = 0) then begin | |||||
| raise EengShaderPartInternal.Create('expected "return" token in function'); | |||||
| // more than one "return" | |||||
| end else if (RetCount > 1) then begin | |||||
| // find block begin | |||||
| i := 0; | |||||
| while (csi.Items[i].Token <> gtBlockBegin) and (i < csi.Items.Count) do | |||||
| inc(i); | |||||
| if (i < csi.Items.Count) | |||||
| then inc(i) | |||||
| else i := 0; | |||||
| // insert temp variable | |||||
| s := Format('%s_ret%.4d', [aName, fInlineReturnCounter]); | |||||
| inc(fInlineReturnCounter); | |||||
| csi.Items.Insert(i, TCodePart.Create(gtLineBreak, '')); | |||||
| csi.Items.Insert(i+1, TCodePart.Create(gtNormal, aRetType + ' ' + s)); | |||||
| csi.Items.Insert(i+2, TCodePart.Create(gtCommandEnd, ';')); | |||||
| csi.Items.Insert(i+3, TCodePart.Create(gtLineBreak, '')); | |||||
| // replace "return" with temp variable | |||||
| for cp in csi.Items do | |||||
| cp.Text := rx.Replace(cp.Text, '$1' + s + ' =$2', true); | |||||
| // merge code | |||||
| csi.Merge(aCommand, csi.Items.Count); | |||||
| AddText(s); | |||||
| // exact one "return" | |||||
| end else begin | |||||
| i := csi.Items.Count-1; | |||||
| while (i > 0) do begin | |||||
| cp := csi.Items[i]; | |||||
| if rx.Exec(cp.Text) then begin | |||||
| csi.Items.Insert(i, TCodePart.Create(gtNormal, rx.Match[1])); | |||||
| cp.Text := rx.Replace(cp.Text, '(', true); | |||||
| // replace last gtCommandEnd with ')' and delete everything behind | |||||
| j := csi.Items.Count-1; | |||||
| while (j > i) and not (csi.Items[j].Token = gtCommandEnd) do | |||||
| dec(j); | |||||
| if (j > i) then | |||||
| csi.Items[j] := TCodePart.Create(gtNormal, ')'); | |||||
| while (csi.Items.Count-1 > j) do | |||||
| csi.Items.PopLast(true); | |||||
| // merge | |||||
| csi.Merge(aCommand, i+1); | |||||
| end; | |||||
| dec(i); | |||||
| end; | |||||
| end; | |||||
| finally | |||||
| FreeAndNil(rx); | |||||
| end; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderGeneratorArgs.GenerateCode(const aCode: TengShaderCode); | procedure TengShaderGeneratorArgs.GenerateCode(const aCode: TengShaderCode); | ||||
| begin | begin | ||||
| GenerateProcedureCode; | |||||
| GenerateParameterCode(CengShaderPartArr.Create(TengShaderPartVar)); | |||||
| GenerateParameterCode(CengShaderPartArr.Create(TengShaderPartVarying)); | |||||
| GenerateParameterCode(CengShaderPartArr.Create(TengShaderPartUniform)); | |||||
| GenerateMetaCode; | |||||
| fCode.Last.GenerateCode(aCode); | fCode.Last.GenerateCode(aCode); | ||||
| end; | end; | ||||
| @@ -380,14 +772,26 @@ end; | |||||
| constructor TengShaderGeneratorArgs.Create(const aRoot: TengShaderPart); | constructor TengShaderGeneratorArgs.Create(const aRoot: TengShaderPart); | ||||
| begin | begin | ||||
| inherited Create; | inherited Create; | ||||
| fCode := TCodeStack.Create(true); | |||||
| fRoot := aRoot; | |||||
| fCode := TCodeStack.Create(true); | |||||
| fFlagStack := TengGenerateFlagsStack.Create(); | |||||
| fMetaDataList := TengMetaDataList.Create(false); | |||||
| fParameters := TParameterMap.Create(false); | |||||
| fProcedures := TProcedureList.Create(false); | |||||
| fProcParams := TProcParamStack.Create(false); | |||||
| fRoot := aRoot; | |||||
| fInlineReturnCounter := 0; | |||||
| PushCode; | PushCode; | ||||
| PushFlags([ gfAddParameterItem, gfAddProcedureItem ]); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| destructor TengShaderGeneratorArgs.Destroy; | destructor TengShaderGeneratorArgs.Destroy; | ||||
| begin | begin | ||||
| FreeAndNil(fProcParams); | |||||
| FreeAndNil(fProcedures); | |||||
| FreeAndNil(fParameters); | |||||
| FreeAndNil(fMetaDataList); | |||||
| FreeAndNil(fFlagStack); | |||||
| FreeAndNil(fCode); | FreeAndNil(fCode); | ||||
| inherited Destroy; | inherited Destroy; | ||||
| end; | end; | ||||
| @@ -226,7 +226,7 @@ end; | |||||
| function TengShaderPart.GetParent(const aType: CengShaderPart): TengShaderPart; | function TengShaderPart.GetParent(const aType: CengShaderPart): TengShaderPart; | ||||
| begin | begin | ||||
| if not GetParent(aType, result) then | if not GetParent(aType, result) then | ||||
| raise EengShaderPartInternal.Create(GetTokenName + ' ha sno parent of type ' + aType.GetTokenName, self); | |||||
| raise EengShaderPartInternal.Create(GetTokenName + ' has no parent of type ' + aType.GetTokenName, self); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -44,6 +44,12 @@ type | |||||
| { Class Methods } | { Class Methods } | ||||
| protected | protected | ||||
| function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; | function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; | ||||
| { Code Generation } | |||||
| public | |||||
| procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override; | |||||
| { Class Methods } | |||||
| public | public | ||||
| class function GetTokenName: String; override; | class function GetTokenName: String; override; | ||||
| class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); override; | class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); override; | ||||
| @@ -52,7 +58,8 @@ type | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| uengShaderPartProc, uengShaderPartClass, uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper; | |||||
| uengShaderPartProc, uengShaderPartClass, uengShaderFileConstants, uengShaderFileTypes, | |||||
| uengShaderFileHelper, uengShaderGenerator, uengShaderFile; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderPartCall//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TengShaderPartCall//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -95,9 +102,34 @@ end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| procedure TengShaderPartCall.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | procedure TengShaderPartCall.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | ||||
| var | |||||
| sr: TengSearchResults; | |||||
| walker: TengProcSearchWalker; | |||||
| proc: TengShaderPartProc; | |||||
| begin | begin | ||||
| inherited GenerateCodeIntern(aArgs); | inherited GenerateCodeIntern(aArgs); | ||||
| // TODO | |||||
| sr := TengSearchResults.Create; | |||||
| walker := TengProcSearchWalker.Create(sr); | |||||
| try | |||||
| walker.Name := Name; | |||||
| walker.SearchFlags := [sfEvaluateIf, sfSearchChildren, sfSearchInherited]; | |||||
| walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderGenerator); | |||||
| walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile); | |||||
| walker.Run(aArgs.Root); | |||||
| proc := (ExtractSearchResult(self, walker.Name, sr) as TengShaderPartProc); | |||||
| aArgs.PushProcParams(fParameters); | |||||
| aArgs.PushFlags(aArgs.Flags - [gfGenerateProcedureCode, gfGenerateInlineCode] + [gfGenerateProcedureCall]); | |||||
| try | |||||
| proc.GenerateCodeIntern(aArgs); | |||||
| finally | |||||
| aArgs.PopFlags; | |||||
| aArgs.PopProcParams; | |||||
| end; | |||||
| finally | |||||
| FreeAndNil(walker); | |||||
| FreeAndNil(sr); | |||||
| end; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -149,6 +181,69 @@ begin | |||||
| result := ''; | result := ''; | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderPartInherited.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | |||||
| function FindProc: TengShaderPartProc; | |||||
| var | |||||
| sr: TengSearchResults; | |||||
| walker: TengProcSearchWalker; | |||||
| ParentProc: TengShaderPartProc; | |||||
| begin | |||||
| sr := TengSearchResults.Create; | |||||
| walker := TengProcSearchWalker.Create(sr); | |||||
| try | |||||
| ParentProc := (GetParent(TengShaderPartProc) as TengShaderPartProc); | |||||
| walker.Name := Name; | |||||
| if (walker.Name = '') then | |||||
| walker.Name := ParentProc.Name; | |||||
| walker.Owner := ParentProc; | |||||
| walker.SearchFlags := [sfEvaluateIf, sfIgnoreOwner, sfSearchChildrenLazy, sfSearchInherited, sfSearchParents]; | |||||
| walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderPartClass); | |||||
| walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartClass); | |||||
| walker.Run(ParentProc); | |||||
| result := (ExtractSearchResult(self, walker.Name, sr) as TengShaderPartProc); | |||||
| finally | |||||
| FreeAndNil(walker); | |||||
| FreeAndNil(sr); | |||||
| end; | |||||
| end; | |||||
| procedure GenCode(const aProc: TengShaderPartProc; const aParams: TStrings); | |||||
| begin | |||||
| aArgs.PushFlags(aArgs.Flags + [gfGenerateInlineCode]); | |||||
| aArgs.PushProcParams(aParams); | |||||
| try | |||||
| aProc.GenerateCodeIntern(aArgs); | |||||
| finally | |||||
| aArgs.PopProcParams; | |||||
| aArgs.PopFlags; | |||||
| end; | |||||
| end; | |||||
| var | |||||
| proc: TengShaderPartProc; | |||||
| i: Integer; | |||||
| params: TStringList; | |||||
| begin | |||||
| aArgs.AddToken(GetTokenName); | |||||
| proc := FindProc; | |||||
| if (fParameters.Count > 0) then begin | |||||
| if (fParameters.Count <> proc.ParameterCount) then | |||||
| raise EengInvalidParamterCount.Create(proc.name + ' expexts ' + IntToStr(proc.ParameterCount) + ' parameters', self); | |||||
| GenCode(proc, fParameters); | |||||
| end else begin | |||||
| params := TStringList.Create; | |||||
| try | |||||
| for i := 0 to proc.ParameterCount-1 do | |||||
| params.Add(proc.Parameters[i].Name); | |||||
| GenCode(proc, params); | |||||
| finally | |||||
| FreeAndNil(params); | |||||
| end; | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| class function TengShaderPartInherited.GetTokenName: String; | class function TengShaderPartInherited.GetTokenName: String; | ||||
| begin | begin | ||||
| @@ -18,7 +18,7 @@ type | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| TengShaderPartClass = class; | TengShaderPartClass = class; | ||||
| TengShaderPartClassList = specialize TutlSimpleList<TengShaderPartClass>; | TengShaderPartClassList = specialize TutlSimpleList<TengShaderPartClass>; | ||||
| TengShaderPartClass = class(TengShaderCodeGenerator) | |||||
| TengShaderPartClass = class(TengShaderGenerator) | |||||
| { Code Loading & Storage } | { Code Loading & Storage } | ||||
| private { member } | private { member } | ||||
| fName: String; | fName: String; | ||||
| @@ -54,7 +54,8 @@ type | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartKeyValuePair, uengShaderPartScope, uengShaderFile; | |||||
| uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartKeyValuePair, | |||||
| uengShaderPartScope, uengShaderFile, uengShaderPartProc; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderPartClass/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TengShaderPartClass/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -173,7 +174,7 @@ begin | |||||
| walker := TengSearchWalker.Create(sr); | walker := TengSearchWalker.Create(sr); | ||||
| try | try | ||||
| walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty); | walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty); | ||||
| walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderCodeGenerator); | |||||
| walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderGenerator); | |||||
| walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile); | walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile); | ||||
| walker.Run(self); | walker.Run(self); | ||||
| for p in sr.GetReverseEnumerator do | for p in sr.GetReverseEnumerator do | ||||
| @@ -188,6 +189,9 @@ end; | |||||
| procedure TengShaderPartClass.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | procedure TengShaderPartClass.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | ||||
| var | var | ||||
| c: TengShaderPartClass; | c: TengShaderPartClass; | ||||
| sr: TengSearchResults; | |||||
| walker: TengSearchWalker; | |||||
| main: TengShaderPartMain; | |||||
| begin | begin | ||||
| if (aArgs.Root <> self) then | if (aArgs.Root <> self) then | ||||
| exit; | exit; | ||||
| @@ -195,7 +199,23 @@ begin | |||||
| c.GenerateCodeIntern(aArgs); | c.GenerateCodeIntern(aArgs); | ||||
| inherited GenerateCodeIntern(aArgs); | inherited GenerateCodeIntern(aArgs); | ||||
| // TODO generate main routine | |||||
| sr := TengSearchResults.Create; | |||||
| walker := TengSearchWalker.Create(sr); | |||||
| try | |||||
| walker.SearchFlags := [sfSearchChildren, sfEvaluateIf]; | |||||
| walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartMain); | |||||
| walker.Run(self); | |||||
| main := (ExtractSearchResult(self, TengShaderPartMain.GetTokenName, sr) as TengShaderPartMain); | |||||
| aArgs.PushFlags([gfGenerateProcedureCode]); | |||||
| try | |||||
| main.GenerateCodeIntern(aArgs); | |||||
| finally | |||||
| aArgs.PopFlags; | |||||
| end; | |||||
| finally | |||||
| FreeAndNil(walker); | |||||
| FreeAndNil(sr); | |||||
| end; | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -154,8 +154,12 @@ end; | |||||
| procedure TengShaderPartCntr.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | procedure TengShaderPartCntr.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | ||||
| var | var | ||||
| p: TengShaderCodePart; | p: TengShaderCodePart; | ||||
| s: String; | |||||
| begin | begin | ||||
| aArgs.AddToken(GetTokenName); | |||||
| s := GetTokenName; | |||||
| if (s = '') then | |||||
| s := ClassName; | |||||
| aArgs.AddToken(s); | |||||
| try | try | ||||
| for p in fChildren do | for p in fChildren do | ||||
| p.GenerateCodeIntern(aArgs); | p.GenerateCodeIntern(aArgs); | ||||
| @@ -7,33 +7,9 @@ interface | |||||
| uses | uses | ||||
| Classes, SysUtils, | Classes, SysUtils, | ||||
| uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs; | |||||
| uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs, uengShaderFileTypes; | |||||
| type | type | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| TengMetaType = ( | |||||
| metaUnknown, | |||||
| metaNormal, | |||||
| metaVersion, | |||||
| metaExtension, | |||||
| metaLayout); | |||||
| TengMetaData = class(TObject) | |||||
| private | |||||
| fMetaType: TengMetaType; | |||||
| fName: String; | |||||
| fValues: TStringList; | |||||
| function GetValues: TStrings; | |||||
| public | |||||
| property MetaType: TengMetaType read fMetaType; | |||||
| property Name: String read fName; | |||||
| property Values: TStrings read GetValues; | |||||
| procedure Assign(const aValues: TengMetaData); | |||||
| constructor Create(const aName: String; const aType: TengMetaType); | |||||
| destructor Destroy; override; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| TengShaderPartMeta = class(TengShaderCodePart) | TengShaderPartMeta = class(TengShaderCodePart) | ||||
| { Code Loading & Storage } | { Code Loading & Storage } | ||||
| @@ -61,40 +37,7 @@ type | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| uengShaderFileConstants, uengShaderFileTypes; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //TengMetaData////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengMetaData.GetValues: TStrings; | |||||
| begin | |||||
| result := fValues; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengMetaData.Assign(const aValues: TengMetaData); | |||||
| begin | |||||
| fName := aValues.Name; | |||||
| fMetaType := aValues.MetaType; | |||||
| fValues.Clear; | |||||
| fValues.AddStrings(aValues.Values); | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| constructor TengMetaData.Create(const aName: String; const aType: TengMetaType); | |||||
| begin | |||||
| inherited Create; | |||||
| fName := aName; | |||||
| fMetaType := aType; | |||||
| fValues := TStringList.Create; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| destructor TengMetaData.Destroy; | |||||
| begin | |||||
| FreeAndNil(fValues); | |||||
| inherited Destroy; | |||||
| end; | |||||
| uengShaderFileConstants; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderPartMeta//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TengShaderPartMeta//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -170,7 +113,7 @@ end; | |||||
| procedure TengShaderPartMeta.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | procedure TengShaderPartMeta.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | ||||
| begin | begin | ||||
| inherited GenerateCodeIntern(aArgs); | inherited GenerateCodeIntern(aArgs); | ||||
| aArgs.AddMeta(self); | |||||
| aArgs.AddMeta(fData); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -129,7 +129,7 @@ procedure TengShaderPartParameter.GenerateCodeIntern(const aArgs: TengShaderGene | |||||
| begin | begin | ||||
| if (gfAddParameterItem in aArgs.Flags) then begin | if (gfAddParameterItem in aArgs.Flags) then begin | ||||
| inherited GenerateCodeIntern(aArgs); | inherited GenerateCodeIntern(aArgs); | ||||
| aArgs.AddParam(self); | |||||
| aArgs.AddParameter(self); | |||||
| end; | end; | ||||
| end; | end; | ||||
| @@ -167,8 +167,11 @@ end; | |||||
| procedure TengShaderPartVar.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | procedure TengShaderPartVar.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | ||||
| begin | begin | ||||
| inherited GenerateCodeIntern(aArgs); | inherited GenerateCodeIntern(aArgs); | ||||
| if (gfGenerateParameterItemCode in aArgs.Flags) then begin | |||||
| // TODO | |||||
| if (gfGenerateParameterCode in aArgs.Flags) then begin | |||||
| aArgs.AddText(format('%*s %s', [aArgs.MaxParameterLength, fType, fName])); | |||||
| if (fDefaultValue <> '') then | |||||
| aArgs.AddText(' = ' + fDefaultValue); | |||||
| aArgs.AddCommandEnd(';'); | |||||
| end; | end; | ||||
| end; | end; | ||||
| @@ -184,9 +187,8 @@ end; | |||||
| procedure TengShaderPartVarying.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | procedure TengShaderPartVarying.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | ||||
| begin | begin | ||||
| inherited GenerateCodeIntern(aArgs); | inherited GenerateCodeIntern(aArgs); | ||||
| if (gfGenerateParameterItemCode in aArgs.Flags) then begin | |||||
| // TODO | |||||
| end; | |||||
| if (gfGenerateParameterCode in aArgs.Flags) then | |||||
| aArgs.AddText(Format('varying %*s %s;', [aArgs.MaxParameterLength, fType, fName])); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -201,9 +203,8 @@ end; | |||||
| procedure TengShaderPartUniform.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | procedure TengShaderPartUniform.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | ||||
| begin | begin | ||||
| inherited GenerateCodeIntern(aArgs); | inherited GenerateCodeIntern(aArgs); | ||||
| if (gfGenerateParameterItemCode in aArgs.Flags) then begin | |||||
| // TODO | |||||
| end; | |||||
| if (gfGenerateParameterCode in aArgs.Flags) then | |||||
| aArgs.AddText(Format('uniform %*s %s;', [aArgs.MaxParameterLength, fType, fName])); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -242,9 +243,8 @@ end; | |||||
| procedure TengShaderPartConst.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | procedure TengShaderPartConst.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | ||||
| begin | begin | ||||
| inherited GenerateCodeIntern(aArgs); | inherited GenerateCodeIntern(aArgs); | ||||
| if (gfGenerateParameterItemCode in aArgs.Flags) then begin | |||||
| // TODO | |||||
| end; | |||||
| if (gfGenerateParameterCode in aArgs.Flags) then | |||||
| aArgs.AddText(Format('const %*s %s;', [aArgs.MaxParameterLength, fType, fName])); | |||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -7,7 +7,7 @@ interface | |||||
| uses | uses | ||||
| Classes, SysUtils, | Classes, SysUtils, | ||||
| uengShaderPart, uengShaderPartScope, uengShaderFileParser | |||||
| uengShaderPart, uengShaderPartScope, uengShaderFileParser, uengShaderGeneratorArgs | |||||
| {$IFDEF USE_BITSPACE_UTILS} | {$IFDEF USE_BITSPACE_UTILS} | ||||
| , uutlGenerics; | , uutlGenerics; | ||||
| @@ -30,15 +30,26 @@ type | |||||
| fName: String; | fName: String; | ||||
| fIsInline: Boolean; | fIsInline: Boolean; | ||||
| fParameters: TengShaderPartProcParamList; | fParameters: TengShaderPartProcParamList; | ||||
| function GetParameter(const aIndex: Integer): TengShaderPartProcParam; | |||||
| function GetParameterCount: Integer; | |||||
| protected | protected | ||||
| function GetHeaderText: String; virtual; | function GetHeaderText: String; virtual; | ||||
| 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; | ||||
| { Code Generation } | |||||
| protected | |||||
| function GenerateHeaderCode: String; virtual; | |||||
| procedure GenerateInlineCode(const aArgs: TengShaderGeneratorArgs); virtual; | |||||
| public | |||||
| procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override; | |||||
| { General } | { General } | ||||
| public | public | ||||
| property Name: String read fName; | |||||
| property IsInline: Boolean read fIsInline; | |||||
| property Name: String read fName; | |||||
| property IsInline: Boolean read fIsInline; | |||||
| property ParameterCount: Integer read GetParameterCount; | |||||
| property Parameters[const aIndex: Integer]: TengShaderPartProcParam read GetParameter; | |||||
| constructor Create(const aParent: TengShaderPart); override; | constructor Create(const aParent: TengShaderPart); override; | ||||
| destructor Destroy; override; | destructor Destroy; override; | ||||
| @@ -55,6 +66,10 @@ type | |||||
| function GetHeaderText: String; override; | function GetHeaderText: String; override; | ||||
| function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; | function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; | ||||
| { Code Generation } | |||||
| protected | |||||
| function GenerateHeaderCode: String; override; | |||||
| { General } | { General } | ||||
| public | public | ||||
| class function GetTokenName: String; override; | class function GetTokenName: String; override; | ||||
| @@ -69,6 +84,11 @@ type | |||||
| function GetHeaderText: String; override; | function GetHeaderText: String; override; | ||||
| function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; | function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; | ||||
| { Code Generation } | |||||
| protected | |||||
| function GenerateHeaderCode: String; override; | |||||
| procedure GenerateInlineCode(const aArgs: TengShaderGeneratorArgs); override; | |||||
| { Class Methods } | { Class Methods } | ||||
| public | public | ||||
| class function GetTokenName: String; override; | class function GetTokenName: String; override; | ||||
| @@ -77,10 +97,23 @@ type | |||||
| implementation | implementation | ||||
| uses | uses | ||||
| RegExpr, | |||||
| uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper; | uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //TengShaderPartProc//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //TengShaderPartProc//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengShaderPartProc.GetParameter(const aIndex: Integer): TengShaderPartProcParam; | |||||
| begin | |||||
| result := fParameters[aIndex]; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengShaderPartProc.GetParameterCount: Integer; | |||||
| begin | |||||
| result := fParameters.Count; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| function TengShaderPartProc.GetHeaderText: String; | function TengShaderPartProc.GetHeaderText: String; | ||||
| var | var | ||||
| @@ -150,6 +183,102 @@ begin | |||||
| result := CheckEndToken(aArgs, self); | result := CheckEndToken(aArgs, self); | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengShaderPartProc.GenerateHeaderCode: String; | |||||
| var | |||||
| p: TengShaderPartProcParam; | |||||
| begin | |||||
| result := ''; | |||||
| for p in fParameters do begin | |||||
| if (result <> '') then | |||||
| result := result + ', '; | |||||
| result := result + p.Typ + ' ' + p.Name; | |||||
| end; | |||||
| if (result = '') then | |||||
| result := 'void'; | |||||
| result := 'void ' + fName + '(' + result + ')'; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderPartProc.GenerateInlineCode(const aArgs: TengShaderGeneratorArgs); | |||||
| var | |||||
| p: TengShaderPartProcParam; | |||||
| old, new: TStringList; | |||||
| rx: TRegExpr; | |||||
| s: String; | |||||
| begin | |||||
| aArgs.PushCode; | |||||
| rx := TRegExpr.Create; | |||||
| old := TStringList.Create; | |||||
| new := TStringList.Create; | |||||
| try | |||||
| inherited GenerateCodeIntern(aArgs); | |||||
| // prepare old parameters | |||||
| for p in fParameters do | |||||
| old.Add(p.Name); | |||||
| // prepate new paramaters | |||||
| rx.Expression := '[^A-z0-9_]+'; | |||||
| for s in aArgs.ProcParams do begin | |||||
| if rx.Exec(s) | |||||
| then new.Add('(' + s + ')') | |||||
| else new.Add(s); | |||||
| end; | |||||
| // replace parameters | |||||
| aArgs.ReplaceIdents(old, new); | |||||
| finally | |||||
| FreeAndNil(rx); | |||||
| FreeAndNil(old); | |||||
| FreeAndNil(new); | |||||
| aArgs.PopCode([pcfAppend]); | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderPartProc.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); | |||||
| var | |||||
| s, params: String; | |||||
| begin | |||||
| // generate inline code | |||||
| if (aArgs.Flags * [gfGenerateProcedureCall, gfGenerateProcedureCode] <> []) and | |||||
| ((gfGenerateInlineCode in aArgs.Flags) or fIsInline) then | |||||
| begin | |||||
| GenerateInlineCode(aArgs); | |||||
| // TODO: ignore next command end?! | |||||
| // generate code | |||||
| end else if (gfGenerateProcedureCode in aArgs.Flags) then begin | |||||
| aArgs | |||||
| .AddLineBreak | |||||
| .AddText(GenerateHeaderCode) | |||||
| .AddLineBreak | |||||
| .AddCommandEnd('{') | |||||
| .AddLineBreak | |||||
| .BeginBlock(4); | |||||
| try | |||||
| inherited GenerateCodeIntern(aArgs); | |||||
| finally | |||||
| aArgs | |||||
| .EndBlock | |||||
| .AddCommandEnd('}') | |||||
| .AddLineBreak; | |||||
| end; | |||||
| // generate call | |||||
| end else if (gfGenerateProcedureCall in aArgs.Flags) then begin | |||||
| params := ''; | |||||
| for s in aArgs.ProcParams do begin | |||||
| if (params <> '') then | |||||
| params := params + ', '; | |||||
| params := params + s; | |||||
| end; | |||||
| aArgs.AddText(fName + '(' + params + ')'); | |||||
| aArgs.AddProcedure(self); | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| constructor TengShaderPartProc.Create(const aParent: TengShaderPart); | constructor TengShaderPartProc.Create(const aParent: TengShaderPart); | ||||
| begin | begin | ||||
| @@ -197,6 +326,12 @@ begin | |||||
| inherited ParseIntern(aArgs, aParams); | inherited ParseIntern(aArgs, aParams); | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengShaderPartMain.GenerateHeaderCode: String; | |||||
| begin | |||||
| result := 'void main(void)'; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| class function TengShaderPartMain.GetTokenName: String; | class function TengShaderPartMain.GetTokenName: String; | ||||
| begin | begin | ||||
| @@ -232,6 +367,46 @@ begin | |||||
| result := inherited ParseIntern(aArgs, aParams); | result := inherited ParseIntern(aArgs, aParams); | ||||
| end; | end; | ||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| function TengShaderPartFunc.GenerateHeaderCode: String; | |||||
| var | |||||
| p: TengShaderPartProcParam; | |||||
| begin | |||||
| result := ''; | |||||
| for p in fParameters do begin | |||||
| if (result <> '') then | |||||
| result := result + ', '; | |||||
| result := result + p.Typ + ' ' + p.Name; | |||||
| end; | |||||
| if (result = '') then | |||||
| result := 'void'; | |||||
| result := fReturnType + ' ' + fName + '(' + result + ')'; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||||
| procedure TengShaderPartFunc.GenerateInlineCode(const aArgs: TengShaderGeneratorArgs); | |||||
| var | |||||
| csi: TengShaderGeneratorArgs.TCodeStackItem; | |||||
| indent: Integer; | |||||
| begin | |||||
| csi := TengShaderGeneratorArgs.TCodeStackItem.Create; | |||||
| try | |||||
| indent := aArgs.ExtractCurrentCommand(csi); | |||||
| aArgs.PushCode; | |||||
| aArgs.BeginBlock; | |||||
| try | |||||
| inherited GenerateInlineCode(aArgs); | |||||
| finally | |||||
| aArgs.EndBlock; | |||||
| aArgs.AddText(StringOfChar(' ', indent)); | |||||
| aArgs.ReplaceReturns(csi, fReturnType, fName); | |||||
| aArgs.PopCode([pcfAppend]); | |||||
| end; | |||||
| finally | |||||
| FreeAndNil(csi); | |||||
| end; | |||||
| end; | |||||
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| class function TengShaderPartFunc.GetTokenName: String; | class function TengShaderPartFunc.GetTokenName: String; | ||||
| begin | begin | ||||