Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

213 linhas
8.7 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. if Assigned(fElsePart) then
  89. result := fElsePart.ParseText(aArgs);
  90. result := HandeEndToken(result, aArgs);
  91. end;
  92. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  93. function TengShaderPartIf.HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String;
  94. begin
  95. result := CheckEndToken(aArgs, self);
  96. end;
  97. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  98. function TengShaderPartIf.GetCount: Integer;
  99. begin
  100. result := 1;
  101. if Assigned(fElsePart) then
  102. inc(result, 1);
  103. end;
  104. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  105. function TengShaderPartIf.GetChild(const aIndex: Integer): TengShaderPart;
  106. begin
  107. if (aIndex < 0) or (aIndex >= Count) then
  108. raise EengOutOfRange.Create(0, Count-1, aIndex, self);
  109. case aIndex of
  110. 0: result := fIfPart;
  111. 1: result := fElsePart;
  112. end;
  113. end;
  114. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  115. function TengShaderPartIf.GetText: String;
  116. begin
  117. result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + fExpression.Text + TOKEN_CHAR_END + fIfPart.Text;
  118. if Assigned(fElsePart) then
  119. result := result + fElsePart.Text;
  120. result := result + TOKEN_CHAR_BEGIN + TOKEN_END + TOKEN_CHAR_END;
  121. end;
  122. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  123. function TengShaderPartIf.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  124. begin
  125. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  126. raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
  127. if (aParams.Count < 2) then
  128. raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);
  129. fExpression := ParseExpression(self, aParams, 1);
  130. fIfPart := TengShaderPartIfCntr.Create(self);
  131. result := fIfPart.ParseText(aArgs);
  132. result := HandleToken(result, aArgs);
  133. end;
  134. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  135. procedure TengShaderPartIf.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
  136. var
  137. b: Boolean;
  138. p: TengShaderCodePart;
  139. begin
  140. b := fExpression.GetValue;
  141. if b
  142. then p := fIfPart
  143. else p := fElsePart;
  144. if Assigned(p) then
  145. p.GenerateCodeIntern(aArgs);
  146. end;
  147. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  148. destructor TengShaderPartIf.Destroy;
  149. begin
  150. FreeAndNil(fExpression);
  151. FreeAndNil(fIfPart);
  152. FreeAndNil(fElsePart);
  153. inherited Destroy;
  154. end;
  155. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  156. //TengShaderPartElIf////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  157. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  158. function TengShaderPartElIf.HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String;
  159. begin
  160. result := aToken;
  161. if (result <> TOKEN_END) then
  162. raise EengInvalidToken.Create(ClassName, result, aArgs.Line, aArgs.Col, Filename, self);
  163. end;
  164. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  165. class function TengShaderPartElIf.GetTokenName: String;
  166. begin
  167. result := TOKEN_ELIF;
  168. end;
  169. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  170. //TengShaderPartElse////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  171. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  172. function TengShaderPartElse.GetText: String;
  173. begin
  174. result := TOKEN_CHAR_BEGIN + GetTokenName + TOKEN_CHAR_END + inherited GetText;
  175. end;
  176. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  177. class function TengShaderPartElse.GetTokenName: String;
  178. begin
  179. result := TOKEN_ELSE;
  180. end;
  181. end.