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.

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