選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

438 行
21 KiB

  1. unit uengShaderFileTypes;
  2. {$mode objfpc}{$H+}
  3. {$I uengShaderFile.inc}
  4. interface
  5. uses
  6. Classes, SysUtils
  7. {$IFDEF USE_BITSPACE_UTILS}
  8. , uutlSerialization, uutlCommon
  9. {$ENDIF}
  10. ;
  11. type
  12. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  13. {$IFDEF USE_BITSPACE_UTILS}
  14. IengShaderFileWriter = uutlSerialization.IutlFileWriter;
  15. IengShaderFileReader = uutlSerialization.IutlFileReader;
  16. TengShaderFileReader = uutlSerialization.TutlSimpleFileReader;
  17. TengShaderFileWriter = uutlSerialization.TutlSimpleFileWriter;
  18. TIntfObjNoRefCount = uutlCommon.TutlInterfaceNoRefCount;
  19. {$ENDIF}
  20. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  21. //Exceptions////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  22. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  23. EengShaderPart = class(Exception)
  24. protected
  25. function GenerateMessage: String; virtual;
  26. public
  27. Sender: TObject;
  28. Line: Integer;
  29. Col: Integer;
  30. Filename: String;
  31. procedure PrintTrace(const aLines: TStrings);
  32. function PrintTrace: String;
  33. constructor Create(const aSender: TObject); overload;
  34. constructor Create(const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
  35. constructor Create(const aMsg: String; const aSender: TObject); overload;
  36. constructor Create(const aMsg: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
  37. end;
  38. EengShaderPartInternal = class(EengShaderPart);
  39. EengExpression = class(EengShaderPart);
  40. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  41. EengInvalidToken = class(EengShaderPartInternal)
  42. protected
  43. function GenerateMessage: String; override;
  44. public
  45. SenderClassName: String;
  46. Token: String;
  47. constructor Create(const aSenderClassName: String; const aToken: String; const aSender: TObject); overload;
  48. constructor Create(const aSenderClassName: String; const aToken: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
  49. end;
  50. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  51. EengUnexpectedToken = class(EengShaderPart)
  52. protected
  53. function GenerateMessage: String; override;
  54. public
  55. Token: String;
  56. Expected: String;
  57. constructor Create(const aToken, aExpected: String; const aSender: TObject); overload;
  58. constructor Create(const aToken, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
  59. end;
  60. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  61. EengInvalidParamter = class(EengShaderPart)
  62. protected
  63. function GenerateMessage: String; override;
  64. public
  65. Param: String;
  66. Expected: String;
  67. constructor Create(const aParam, aExpected: String; const aSender: TObject); overload;
  68. constructor Create(const aParam, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
  69. end;
  70. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  71. EengInvalidParamterCount = class(EengShaderPart)
  72. protected
  73. function GenerateMessage: String; override;
  74. public
  75. Token: String;
  76. ExpectedMin: Integer;
  77. ExpectedMax: Integer;
  78. constructor Create(const aToken: String; const aExpected: Integer; const aSender: TObject); overload;
  79. constructor Create(const aToken: String; const aExpectedMin, aExpectedMax: Integer; const aSender: TObject); overload;
  80. constructor Create(const aToken: String; const aExpected, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
  81. constructor Create(const aToken: String; const aExpectedMin, aExpectedMax, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
  82. end;
  83. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  84. EengInvalidIdentifier = class(EengShaderPart)
  85. protected
  86. function GenerateMessage: String; override;
  87. public
  88. Identifier: String;
  89. constructor Create(const aIdentifier: String; const aSender: TObject); overload;
  90. constructor Create(const aIdentifier: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
  91. end;
  92. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  93. EengOutOfRange = class(EengShaderPartInternal)
  94. protected
  95. function GenerateMessage: String; override;
  96. public
  97. Min: Integer;
  98. Max: Integer;
  99. Index: Integer;
  100. constructor Create(const aMin, aMax, aIndex: Integer; const aSender: TObject); overload;
  101. constructor Create(const aMin, aMax, aIndex, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
  102. end;
  103. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. EengDuplicateIdentifier = class(EengShaderPart)
  105. protected
  106. function GenerateMessage: String; override;
  107. public
  108. Name: String;
  109. New: TObject;
  110. Old: TObject;
  111. constructor Create(const aName: String; const aNew, aOld, aSender: TObject); overload;
  112. constructor Create(const aName: String; const aNew, aOld: TObject; aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload;
  113. end;
  114. implementation
  115. uses
  116. uengShaderPart;
  117. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  118. //EengShaderPart////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  119. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  120. function EengShaderPart.GenerateMessage: String;
  121. begin
  122. result := ''; // DUMMY
  123. end;
  124. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  125. procedure EengShaderPart.PrintTrace(const aLines: TStrings);
  126. function GetName(const aPart: TengShaderPart): String;
  127. begin
  128. result := aPart.GetTokenName;
  129. if (result = '')
  130. then result := aPart.ClassName
  131. else result := result + ' (' + aPart.ClassName + ')';
  132. end;
  133. var
  134. p: TengShaderPart;
  135. begin
  136. if not Assigned(Sender) or not
  137. (Sender is TengShaderPart) then
  138. exit;
  139. p := (Sender as TengShaderPart);
  140. aLines.Text := Message;
  141. while Assigned(p) do begin
  142. aLines.Add(Format('%s (%d:%d): %s', [p.Filename, p.Line, p.Col, GetName(p)]));
  143. p := p.Parent;
  144. end;
  145. end;
  146. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  147. function EengShaderPart.PrintTrace: String;
  148. var
  149. sl: TStringList;
  150. begin
  151. sl := TStringList.Create;
  152. try
  153. PrintTrace(sl);
  154. result := sl.Text;
  155. finally
  156. FreeAndNil(sl);
  157. end;
  158. end;
  159. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  160. constructor EengShaderPart.Create(const aSender: TObject);
  161. begin
  162. Create(GenerateMessage, aSender);
  163. end;
  164. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  165. constructor EengShaderPart.Create(const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
  166. begin
  167. Create(GenerateMessage, aLine, aCol, aFilename, aSender);
  168. end;
  169. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  170. constructor EengShaderPart.Create(const aMsg: String; const aSender: TObject);
  171. begin
  172. Sender := nil;
  173. if Assigned(aSender)
  174. then Create(
  175. aMsg,
  176. (aSender as TengShaderPart).Line,
  177. (aSender as TengShaderPart).Col,
  178. (aSender as TengShaderPart).Filename,
  179. aSender)
  180. else inherited Create(Format('%s: %s', [
  181. ClassName,
  182. aMsg]));
  183. end;
  184. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  185. constructor EengShaderPart.Create(const aMsg: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
  186. begin
  187. Sender := aSender;
  188. Line := aLine;
  189. Col := aCol;
  190. Filename := aFilename;
  191. inherited Create(Format('%s (%s %d:%d): %s',[
  192. ClassName,
  193. ExtractFileName(Filename),
  194. Line+1,
  195. Col,
  196. aMsg]))
  197. end;
  198. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  199. //EengInvalidToken//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  200. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  201. function EengInvalidToken.GenerateMessage: String;
  202. begin
  203. result := 'invalid token: ' + SenderClassName + ' <> '+ Token;
  204. end;
  205. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  206. constructor EengInvalidToken.Create(const aSenderClassName: String; const aToken: String; const aSender: TObject);
  207. begin
  208. SenderClassName := aSenderClassName;
  209. Token := aToken;
  210. inherited Create(aSender);
  211. end;
  212. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  213. constructor EengInvalidToken.Create(const aSenderClassName: String; const aToken: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
  214. begin
  215. SenderClassName := aSenderClassName;
  216. Token := aToken;
  217. inherited Create(aLine, aCol, aFilename, aSender);
  218. end;
  219. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  220. //EengUnexpectedToken///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  221. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  222. function EengUnexpectedToken.GenerateMessage: String;
  223. begin
  224. result := 'unexpected token: ' + Token;
  225. if (Expected <> '') then
  226. result := result + '(expected ' + Expected + ')';
  227. end;
  228. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  229. constructor EengUnexpectedToken.Create(const aToken, aExpected: String; const aSender: TObject);
  230. begin
  231. Token := aToken;
  232. Expected := aExpected;
  233. inherited Create(aSender);
  234. end;
  235. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  236. constructor EengUnexpectedToken.Create(const aToken, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
  237. begin
  238. Token := aToken;
  239. Expected := aExpected;
  240. inherited Create(aLine, aCol, aFilename, aSender);
  241. end;
  242. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  243. //EengInvalidParamter///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  244. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  245. function EengInvalidParamter.GenerateMessage: String;
  246. begin
  247. result := 'invalid parameter: ' + Param;
  248. if (Expected <> '') then
  249. result := result + '(expected ' + Expected + ')';
  250. end;
  251. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  252. constructor EengInvalidParamter.Create(const aParam, aExpected: String; const aSender: TObject);
  253. begin
  254. Param := aParam;
  255. Expected := aExpected;
  256. inherited Create(aSender);
  257. end;
  258. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  259. constructor EengInvalidParamter.Create(const aParam, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
  260. begin
  261. Param := aParam;
  262. Expected := aExpected;
  263. inherited Create(aLine, aCol, aFilename, aSender);
  264. end;
  265. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  266. //EengInvalidParamterCount//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  267. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  268. function EengInvalidParamterCount.GenerateMessage: String;
  269. begin
  270. result := 'invalid parameter count in ' + Token + '(expected ';
  271. if (ExpectedMin = ExpectedMax) then
  272. result := result + IntToStr(ExpectedMin)
  273. else if (ExpectedMax < 0) then
  274. result := result + ' at least ' + IntToStr(ExpectedMin)
  275. else
  276. result := IntToStr(ExpectedMin) + ' to ' + IntToStr(ExpectedMax);
  277. result := result + 'parameter)';
  278. end;
  279. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  280. constructor EengInvalidParamterCount.Create(const aToken: String; const aExpected: Integer; const aSender: TObject);
  281. begin
  282. Token := aToken;
  283. ExpectedMin := aExpected;
  284. ExpectedMax := aExpected;
  285. inherited Create(aSender);
  286. end;
  287. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  288. constructor EengInvalidParamterCount.Create(const aToken: String; const aExpectedMin, aExpectedMax: Integer; const aSender: TObject);
  289. begin
  290. Token := aToken;
  291. ExpectedMin := aExpectedMin;
  292. ExpectedMax := aExpectedMax;
  293. inherited Create(aSender);
  294. end;
  295. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  296. constructor EengInvalidParamterCount.Create(const aToken: String; const aExpected, aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
  297. begin
  298. Token := aToken;
  299. ExpectedMin := aExpected;
  300. ExpectedMax := aExpected;
  301. inherited Create(aLine, aCol, aFilename, aSender);
  302. end;
  303. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  304. constructor EengInvalidParamterCount.Create(const aToken: String; const aExpectedMin, aExpectedMax, aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
  305. begin
  306. Token := aToken;
  307. ExpectedMin := aExpectedMin;
  308. ExpectedMax := aExpectedMax;
  309. inherited Create(aLine, aCol, aFilename, aSender);
  310. end;
  311. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  312. //EengInvalidIdentifier/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  313. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  314. function EengInvalidIdentifier.GenerateMessage: String;
  315. begin
  316. result := 'invalid identifier: ' + Identifier;
  317. end;
  318. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  319. constructor EengInvalidIdentifier.Create(const aIdentifier: String; const aSender: TObject);
  320. begin
  321. Identifier := aIdentifier;
  322. inherited Create(aSender);
  323. end;
  324. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  325. constructor EengInvalidIdentifier.Create(const aIdentifier: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
  326. begin
  327. Identifier := aIdentifier;
  328. inherited Create(aLine, aCol, aFilename, aSender);
  329. end;
  330. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  331. //EengOutOfRange////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  332. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  333. function EengOutOfRange.GenerateMessage: String;
  334. begin
  335. result := format('index (%d) out of range (%d:%d)', [Index, Min, Max])
  336. end;
  337. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  338. constructor EengOutOfRange.Create(const aMin, aMax, aIndex: Integer; const aSender: TObject);
  339. begin
  340. Min := aMin;
  341. Max := aMax;
  342. Index := aIndex;
  343. inherited Create(aSender);
  344. end;
  345. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  346. constructor EengOutOfRange.Create(const aMin, aMax, aIndex, aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
  347. begin
  348. Min := aMin;
  349. Max := aMax;
  350. Index := aIndex;
  351. inherited Create(aLine, aCol, aFilename, aSender);
  352. end;
  353. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  354. //EengDuplicateIdentifier///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  355. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  356. function EengDuplicateIdentifier.GenerateMessage: String;
  357. begin
  358. result := 'duplicate identifier: ' + Name;
  359. if (New is TengShaderPart) then
  360. result := result + Format('(%s %d:%d)', [
  361. (New as TengShaderPart).Filename,
  362. (New as TengShaderPart).Line,
  363. (New as TengShaderPart).Col]);
  364. if (Old is TengShaderPart) then
  365. result := result + Format('(previously declared here %s %d:%d)', [
  366. (Old as TengShaderPart).Filename,
  367. (Old as TengShaderPart).Line,
  368. (Old as TengShaderPart).Col]);
  369. end;
  370. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  371. constructor EengDuplicateIdentifier.Create(const aName: String; const aNew, aOld, aSender: TObject);
  372. begin
  373. Name := aName;
  374. New := aNew;
  375. Old := aOld;
  376. inherited Create(aSender);
  377. end;
  378. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  379. constructor EengDuplicateIdentifier.Create(const aName: String; const aNew, aOld: TObject; aLine, aCol: Integer; const aFilename: String; const aSender: TObject);
  380. begin
  381. Name := aName;
  382. New := aNew;
  383. Old := aOld;
  384. inherited Create(aLine, aCol, aFilename, aSender);
  385. end;
  386. end.