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.

243 line
9.5 KiB

  1. unit uengShaderPartProc;
  2. {$mode objfpc}{$H+}
  3. {$I uengShaderFile.inc}
  4. interface
  5. uses
  6. Classes, SysUtils,
  7. uengShaderPart, uengShaderPartScope, uengShaderFileParser
  8. {$IFDEF USE_BITSPACE_UTILS}
  9. , uutlGenerics;
  10. {$ELSE}
  11. , fgl;
  12. {$ENDIF}
  13. type
  14. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  15. TengShaderPartProcParam = packed record
  16. Typ: String;
  17. Name: String;
  18. end;
  19. TengShaderPartProcParamList = specialize TutlSimpleList<TengShaderPartProcParam>;
  20. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  21. TengShaderPartProc = class(TengShaderPartScope)
  22. { Code Loading & Storage }
  23. private
  24. fName: String;
  25. fIsInline: Boolean;
  26. fParameters: TengShaderPartProcParamList;
  27. protected
  28. function GetHeaderText: String; virtual;
  29. function GetText: String; override;
  30. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  31. { General }
  32. public
  33. property Name: String read fName;
  34. property IsInline: Boolean read fIsInline;
  35. constructor Create(const aParent: TengShaderPart); override;
  36. destructor Destroy; override;
  37. { Class Members }
  38. public
  39. class function GetTokenName: String; override;
  40. end;
  41. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  42. TengShaderPartMain = class(TengShaderPartProc)
  43. { Code Loading & Storage }
  44. protected
  45. function GetHeaderText: String; override;
  46. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  47. { General }
  48. public
  49. class function GetTokenName: String; override;
  50. end;
  51. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  52. TengShaderPartFunc = class(TengShaderPartProc)
  53. { Code Loading & Storage }
  54. private
  55. fReturnType: String;
  56. protected
  57. function GetHeaderText: String; override;
  58. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  59. { Class Methods }
  60. public
  61. class function GetTokenName: String; override;
  62. end;
  63. implementation
  64. uses
  65. uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;
  66. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  67. //TengShaderPartProc////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  68. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. function TengShaderPartProc.GetHeaderText: String;
  70. var
  71. p: TengShaderPartProcParam;
  72. begin
  73. result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + TOKEN_CHAR_QUOTE + fName + TOKEN_CHAR_QUOTE;
  74. for p in fParameters do begin
  75. result := result + ' ' + TOKEN_CHAR_QUOTE + p.Typ + TOKEN_CHAR_QUOTE +
  76. ' ' + TOKEN_CHAR_QUOTE + p.Name + TOKEN_CHAR_QUOTE;
  77. end;
  78. result := result + TOKEN_CHAR_END;
  79. end;
  80. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  81. function TengShaderPartProc.GetText: String;
  82. begin
  83. result := GetHeaderText +
  84. inherited GetText +
  85. TOKEN_CHAR_BEGIN + TOKEN_END + TOKEN_CHAR_END;
  86. end;
  87. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  88. function TengShaderPartProc.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  89. type
  90. TParseArgsState = (pasType, pasName);
  91. var
  92. i: Integer;
  93. state: TParseArgsState;
  94. param: TengShaderPartProcParam;
  95. begin
  96. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  97. raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
  98. if (aParams.Count < 2) then
  99. raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);
  100. i := 2;
  101. result := '';
  102. fName := aParams[1].Name;
  103. state := pasType;
  104. fParameters.Clear;
  105. while (i < aParams.Count) do begin
  106. case state of
  107. pasType: begin
  108. if (aParams[i].Name <> TOKEN_INLINE) then begin
  109. param.Typ := aParams[i].Name;
  110. state := pasName;
  111. end else
  112. fIsInline := true;
  113. end;
  114. pasName: begin
  115. if (aParams[i].Name = TOKEN_INLINE) then begin
  116. with aParams[i] do
  117. raise EengInvalidParamter.Create('expected parameter name (found ' + TOKEN_INLINE + ')', Line, Col, Filename, self);
  118. end else begin
  119. param.Name := aParams[i].Name;
  120. fParameters.Add(param);
  121. state := pasType;
  122. end;
  123. end;
  124. end;
  125. inc(i);
  126. end;
  127. if (state <> pasType) then
  128. raise EengInvalidParamterCount.Create('invalid parameter count in ' + GetTokenName + '(expected multiple of 2)', self);
  129. inherited ParseIntern(aArgs, aParams);
  130. result := CheckEndToken(aArgs, self);
  131. end;
  132. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  133. constructor TengShaderPartProc.Create(const aParent: TengShaderPart);
  134. begin
  135. inherited Create(aParent);
  136. fParameters := TengShaderPartProcParamList.Create(true);
  137. end;
  138. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  139. destructor TengShaderPartProc.Destroy;
  140. begin
  141. FreeAndNil(fParameters);
  142. inherited Destroy;
  143. end;
  144. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  145. class function TengShaderPartProc.GetTokenName: String;
  146. begin
  147. result := TOKEN_PROC;
  148. end;
  149. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  150. //TengShaderPartMain////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  151. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  152. function TengShaderPartMain.GetHeaderText: String;
  153. begin
  154. result := TOKEN_CHAR_BEGIN + GetTokenName + TOKEN_CHAR_END;
  155. end;
  156. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  157. function TengShaderPartMain.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  158. var
  159. p: TengTokenParameter;
  160. begin
  161. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  162. raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
  163. if (aParams.Count <> 1) then
  164. raise EengInvalidParamterCount.Create(GetTokenName, 1, self);
  165. result := '';
  166. p.Name := 'main';
  167. p.Quoted := false;
  168. p.Line := Line;
  169. p.Col := Col + Length(GetTokenName);
  170. aParams.Add(p);
  171. inherited ParseIntern(aArgs, aParams);
  172. end;
  173. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  174. class function TengShaderPartMain.GetTokenName: String;
  175. begin
  176. result := TOKEN_MAIN;
  177. end;
  178. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  179. //TengShaderPartFunc////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  180. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  181. function TengShaderPartFunc.GetHeaderText: String;
  182. var
  183. p: TengShaderPartProcParam;
  184. begin
  185. result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' +
  186. TOKEN_CHAR_QUOTE + fReturnType + TOKEN_CHAR_QUOTE + ' ' +
  187. TOKEN_CHAR_QUOTE + fName + TOKEN_CHAR_QUOTE;
  188. for p in fParameters do
  189. result := result + ' ' + TOKEN_CHAR_QUOTE + p.Typ + TOKEN_CHAR_QUOTE
  190. + ' ' + TOKEN_CHAR_QUOTE + p.Name + TOKEN_CHAR_QUOTE;
  191. result := result + TOKEN_CHAR_END;
  192. end;
  193. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  194. function TengShaderPartFunc.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  195. begin
  196. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  197. raise EengInvalidToken.Create(ClassName, aParams[0].Name, Line, Col, Filename, self);
  198. if (aParams.Count < 3) then
  199. raise EengInvalidParamterCount.Create(GetTokenName, 3, self);
  200. fReturnType := aParams[1].Name;
  201. aParams.Delete(1);
  202. result := inherited ParseIntern(aArgs, aParams);
  203. end;
  204. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  205. class function TengShaderPartFunc.GetTokenName: String;
  206. begin
  207. result := TOKEN_FUNC;
  208. end;
  209. end.