25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

219 satır
8.9 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. else
  114. result := nil;
  115. end;
  116. end;
  117. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  118. function TengShaderPartIf.GetText: String;
  119. begin
  120. result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + fExpression.Text + TOKEN_CHAR_END + fIfPart.Text;
  121. if Assigned(fElsePart) then
  122. result := result + fElsePart.Text;
  123. result := result + TOKEN_CHAR_BEGIN + TOKEN_END + TOKEN_CHAR_END;
  124. end;
  125. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  126. function TengShaderPartIf.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  127. begin
  128. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  129. raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
  130. if (aParams.Count < 2) then
  131. raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);
  132. fExpression := ParseExpression(self, aParams, 1);
  133. fIfPart := TengShaderPartIfCntr.Create(self);
  134. result := fIfPart.ParseText(aArgs);
  135. result := HandleToken(result, aArgs);
  136. end;
  137. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  138. procedure TengShaderPartIf.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
  139. var
  140. b: Boolean;
  141. p: TengShaderCodePart;
  142. begin
  143. b := fExpression.GetValue;
  144. if b
  145. then p := fIfPart
  146. else p := fElsePart;
  147. if Assigned(p) then begin
  148. p.GenerateCodeIntern(aArgs);
  149. aArgs.AppendToPrevLine;
  150. end else
  151. aArgs.AddToken(GetTokenName);
  152. end;
  153. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  154. destructor TengShaderPartIf.Destroy;
  155. begin
  156. FreeAndNil(fExpression);
  157. FreeAndNil(fIfPart);
  158. FreeAndNil(fElsePart);
  159. inherited Destroy;
  160. end;
  161. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  162. //TengShaderPartElIf////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  163. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  164. function TengShaderPartElIf.HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String;
  165. begin
  166. result := aToken;
  167. if (result <> TOKEN_END) then
  168. raise EengUnexpectedToken.Create(aToken, TOKEN_END, aArgs.Col, aArgs.Line, Filename, self);
  169. end;
  170. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  171. class function TengShaderPartElIf.GetTokenName: String;
  172. begin
  173. result := TOKEN_ELIF;
  174. end;
  175. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  176. //TengShaderPartElse////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  177. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  178. function TengShaderPartElse.GetText: String;
  179. begin
  180. result := TOKEN_CHAR_BEGIN + GetTokenName + TOKEN_CHAR_END + inherited GetText;
  181. end;
  182. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  183. class function TengShaderPartElse.GetTokenName: String;
  184. begin
  185. result := TOKEN_ELSE;
  186. end;
  187. end.