You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
7.5 KiB

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