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.

252 regels
10 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. class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); override;
  41. end;
  42. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  43. TengShaderPartMain = class(TengShaderPartProc)
  44. { Code Loading & Storage }
  45. protected
  46. function GetHeaderText: String; override;
  47. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  48. { General }
  49. public
  50. class function GetTokenName: String; override;
  51. end;
  52. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. TengShaderPartFunc = class(TengShaderPartProc)
  54. { Code Loading & Storage }
  55. private
  56. fReturnType: String;
  57. protected
  58. function GetHeaderText: String; override;
  59. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  60. { Class Methods }
  61. public
  62. class function GetTokenName: String; override;
  63. end;
  64. implementation
  65. uses
  66. uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;
  67. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  68. //TengShaderPartProc////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  70. function TengShaderPartProc.GetHeaderText: String;
  71. var
  72. p: TengShaderPartProcParam;
  73. begin
  74. result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + TOKEN_CHAR_QUOTE + fName + TOKEN_CHAR_QUOTE;
  75. for p in fParameters do begin
  76. result := result + ' ' + TOKEN_CHAR_QUOTE + p.Typ + TOKEN_CHAR_QUOTE +
  77. ' ' + TOKEN_CHAR_QUOTE + p.Name + TOKEN_CHAR_QUOTE;
  78. end;
  79. result := result + TOKEN_CHAR_END;
  80. end;
  81. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  82. function TengShaderPartProc.GetText: String;
  83. begin
  84. result := GetHeaderText +
  85. inherited GetText +
  86. TOKEN_CHAR_BEGIN + TOKEN_END + TOKEN_CHAR_END;
  87. end;
  88. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  89. function TengShaderPartProc.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  90. type
  91. TParseArgsState = (pasType, pasName);
  92. var
  93. i: Integer;
  94. state: TParseArgsState;
  95. param: TengShaderPartProcParam;
  96. begin
  97. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  98. raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename);
  99. if (aParams.Count < 2) then
  100. raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, Line, Col, Filename);
  101. i := 2;
  102. result := '';
  103. fName := aParams[1].Name;
  104. state := pasType;
  105. fParameters.Clear;
  106. while (i < aParams.Count) do begin
  107. case state of
  108. pasType: begin
  109. if (aParams[i].Name <> TOKEN_INLINE) then begin
  110. param.Typ := aParams[i].Name;
  111. state := pasName;
  112. end else
  113. fIsInline := true;
  114. end;
  115. pasName: begin
  116. if (aParams[i].Name = TOKEN_INLINE) then begin
  117. with aParams[i] do
  118. raise EengInvalidParamter.Create('expected parameter name (found ' + TOKEN_INLINE + ')', Line, Col, Filename);
  119. end else begin
  120. param.Name := aParams[i].Name;
  121. fParameters.Add(param);
  122. state := pasType;
  123. end;
  124. end;
  125. end;
  126. inc(i);
  127. end;
  128. if (state <> pasType) then
  129. raise EengInvalidParamterCount.Create('invalid parameter count in ' + GetTokenName + '(expected multiple of 2)', Line, Col, Filename);
  130. inherited ParseIntern(aArgs, aParams);
  131. result := CheckEndToken(aArgs, self);
  132. end;
  133. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  134. constructor TengShaderPartProc.Create(const aParent: TengShaderPart);
  135. begin
  136. inherited Create(aParent);
  137. fParameters := TengShaderPartProcParamList.Create(true);
  138. end;
  139. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  140. destructor TengShaderPartProc.Destroy;
  141. begin
  142. FreeAndNil(fParameters);
  143. inherited Destroy;
  144. end;
  145. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  146. class function TengShaderPartProc.GetTokenName: String;
  147. begin
  148. result := TOKEN_PROC;
  149. end;
  150. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  151. class procedure TengShaderPartProc.Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart);
  152. begin
  153. if (aParent.HasParent(TengShaderPartProc, true)) then with aArgs do
  154. raise EengShaderPart.Create('token ' + GetTokenName + ' is not allowed inside ' +
  155. TOKEN_PROC + ', ' + TOKEN_FUNC + ' or + ' + TOKEN_MAIN, Line, Col, aParent.Filename);
  156. end;
  157. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  158. //TengShaderPartMain////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  159. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  160. function TengShaderPartMain.GetHeaderText: String;
  161. begin
  162. result := TOKEN_CHAR_BEGIN + GetTokenName + TOKEN_CHAR_END;
  163. end;
  164. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  165. function TengShaderPartMain.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  166. var
  167. p: TengTokenParameter;
  168. begin
  169. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  170. raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename);
  171. if (aParams.Count <> 1) then
  172. raise EengInvalidParamterCount.Create(GetTokenName, 1, Line, Col, Filename);
  173. result := '';
  174. p.Name := 'main';
  175. p.Quoted := false;
  176. p.Line := Line;
  177. p.Col := Col + Length(GetTokenName);
  178. aParams.Add(p);
  179. inherited ParseIntern(aArgs, aParams);
  180. end;
  181. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  182. class function TengShaderPartMain.GetTokenName: String;
  183. begin
  184. result := TOKEN_MAIN;
  185. end;
  186. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  187. //TengShaderPartFunc////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  188. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  189. function TengShaderPartFunc.GetHeaderText: String;
  190. var
  191. p: TengShaderPartProcParam;
  192. begin
  193. result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' +
  194. TOKEN_CHAR_QUOTE + fReturnType + TOKEN_CHAR_QUOTE + ' ' +
  195. TOKEN_CHAR_QUOTE + fName + TOKEN_CHAR_QUOTE;
  196. for p in fParameters do
  197. result := result + ' ' + TOKEN_CHAR_QUOTE + p.Typ + TOKEN_CHAR_QUOTE
  198. + ' ' + TOKEN_CHAR_QUOTE + p.Name + TOKEN_CHAR_QUOTE;
  199. result := result + TOKEN_CHAR_END;
  200. end;
  201. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  202. function TengShaderPartFunc.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  203. begin
  204. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  205. raise EengInvalidToken.Create(ClassName, aParams[0].Name, Line, Col, Filename);
  206. if (aParams.Count < 3) then
  207. raise EengInvalidParamterCount.Create(GetTokenName, 3, Line, Col, Filename);
  208. fReturnType := aParams[1].Name;
  209. aParams.Delete(1);
  210. result := inherited ParseIntern(aArgs, aParams);
  211. end;
  212. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  213. class function TengShaderPartFunc.GetTokenName: String;
  214. begin
  215. result := TOKEN_FUNC;
  216. end;
  217. end.