Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

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