Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

216 lignes
8.8 KiB

  1. unit uengShaderPartIf;
  2. {$mode objfpc}{$H+}
  3. {$I uengShaderFile.inc}
  4. interface
  5. uses
  6. Classes, SysUtils,
  7. uengShaderPart, uengShaderCodePart, uengShaderPartScope, uengShaderFileExpression,
  8. uengShaderFileParser, uengShaderGeneratorArgs;
  9. type
  10. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  11. TengShaderPartIfCntr = class(TengShaderPartScope)
  12. { Class Methods }
  13. public
  14. class function GetTokenName: String; override;
  15. end;
  16. TengShaderPartIf = class(TengShaderPartIfCntr)
  17. { Code Loading & Storage }
  18. private
  19. fExpression: TengExpressionItem;
  20. fIfPart: TengShaderPartScope;
  21. fElsePart: TengShaderPartScope;
  22. function HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
  23. protected
  24. function HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; virtual;
  25. function GetCount: Integer; override;
  26. function GetChild(const aIndex: Integer): TengShaderPart; override;
  27. function GetText: String; override;
  28. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  29. { Code Generation }
  30. public
  31. procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;
  32. { General }
  33. public
  34. property Expression: TengExpressionItem read fExpression;
  35. property IfPart: TengShaderPartScope read fIfPart;
  36. property ElsePart: TengShaderPartScope read fElsePart;
  37. destructor Destroy; override;
  38. end;
  39. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  40. TengShaderPartElIf = class(TengShaderPartIf)
  41. { Code Loading & Storage }
  42. protected
  43. function HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; override;
  44. { Class Methods }
  45. public
  46. class function GetTokenName: String; override;
  47. end;
  48. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  49. TengShaderPartElse = class(TengShaderPartScope)
  50. { Code Loading & Storage }
  51. protected
  52. function GetText: String; override;
  53. { Class Methods }
  54. public
  55. class function GetTokenName: String; override;
  56. end;
  57. implementation
  58. uses
  59. uengShaderFileTypes, uengShaderFileConstants, uengShaderFileHelper;
  60. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  61. //TengShaderPartIfCntr//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  62. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. class function TengShaderPartIfCntr.GetTokenName: String;
  64. begin
  65. result := TOKEN_IF;
  66. end;
  67. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  68. //TengShaderPartIf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  70. function TengShaderPartIf.HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
  71. type
  72. CengShaderPartScope = class of TengShaderPartScope;
  73. const
  74. TOKEN_CLASSES: array[0..1] of CengShaderPartScope = (
  75. TengShaderPartElse,
  76. TengShaderPartElIf
  77. );
  78. var
  79. c: CengShaderPartScope;
  80. begin
  81. for c in TOKEN_CLASSES do begin
  82. if c.CheckToken(aToken) then begin
  83. c.Validate(aArgs, self);
  84. fElsePart := c.Create(self);
  85. break;
  86. end;
  87. end;
  88. result := aToken;
  89. if Assigned(fElsePart) then
  90. result := fElsePart.ParseText(aArgs);
  91. result := HandeEndToken(result, aArgs);
  92. end;
  93. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  94. function TengShaderPartIf.HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String;
  95. begin
  96. result := CheckEndToken(aToken, aArgs, self);
  97. end;
  98. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  99. function TengShaderPartIf.GetCount: Integer;
  100. begin
  101. result := 1;
  102. if Assigned(fElsePart) then
  103. inc(result, 1);
  104. end;
  105. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  106. function TengShaderPartIf.GetChild(const aIndex: Integer): TengShaderPart;
  107. begin
  108. if (aIndex < 0) or (aIndex >= Count) then
  109. raise EengOutOfRange.Create(0, Count-1, aIndex, self);
  110. case aIndex of
  111. 0: result := fIfPart;
  112. 1: result := fElsePart;
  113. end;
  114. end;
  115. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  116. function TengShaderPartIf.GetText: String;
  117. begin
  118. result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + fExpression.Text + TOKEN_CHAR_END + fIfPart.Text;
  119. if Assigned(fElsePart) then
  120. result := result + fElsePart.Text;
  121. result := result + TOKEN_CHAR_BEGIN + TOKEN_END + TOKEN_CHAR_END;
  122. end;
  123. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  124. function TengShaderPartIf.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  125. begin
  126. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  127. raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
  128. if (aParams.Count < 2) then
  129. raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);
  130. fExpression := ParseExpression(self, aParams, 1);
  131. fIfPart := TengShaderPartIfCntr.Create(self);
  132. result := fIfPart.ParseText(aArgs);
  133. result := HandleToken(result, aArgs);
  134. end;
  135. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  136. procedure TengShaderPartIf.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
  137. var
  138. b: Boolean;
  139. p: TengShaderCodePart;
  140. begin
  141. b := fExpression.GetValue;
  142. if b
  143. then p := fIfPart
  144. else p := fElsePart;
  145. if Assigned(p) then begin
  146. p.GenerateCodeIntern(aArgs);
  147. aArgs.AppendToPrevLine;
  148. end;
  149. end;
  150. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  151. destructor TengShaderPartIf.Destroy;
  152. begin
  153. FreeAndNil(fExpression);
  154. FreeAndNil(fIfPart);
  155. FreeAndNil(fElsePart);
  156. inherited Destroy;
  157. end;
  158. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  159. //TengShaderPartElIf////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  160. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  161. function TengShaderPartElIf.HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String;
  162. begin
  163. result := aToken;
  164. if (result <> TOKEN_END) then
  165. raise EengUnexpectedToken.Create(aToken, TOKEN_END, aArgs.Col, aArgs.Line, Filename, self);
  166. end;
  167. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  168. class function TengShaderPartElIf.GetTokenName: String;
  169. begin
  170. result := TOKEN_ELIF;
  171. end;
  172. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  173. //TengShaderPartElse////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  174. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  175. function TengShaderPartElse.GetText: String;
  176. begin
  177. result := TOKEN_CHAR_BEGIN + GetTokenName + TOKEN_CHAR_END + inherited GetText;
  178. end;
  179. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  180. class function TengShaderPartElse.GetTokenName: String;
  181. begin
  182. result := TOKEN_ELSE;
  183. end;
  184. end.