queue.tin 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. #nop vim: set filetype=tt:;
  2. /*
  3. 本文件属于 PaoTin++ 的一部分。
  4. PaoTin++ © 2020~2023 的所有版权均由担子炮(dzp <danzipao@gmail.com>) 享有并保留一切法律权利
  5. 你可以在遵照 GPLv3 协议的基础之上使用、修改及重新分发本程序。
  6. */
  7. #nop 本文件是 xtintin 的一部分,实现了一些队列处理函数;
  8. ///=== {
  9. ///// 队列处理函数:
  10. /////
  11. // #@ queue.Size <队列名称>
  12. // 返回队列的长度。
  13. //
  14. // EXAMPLE:
  15. // #local q {};
  16. // #local size \@queue.Size{q};
  17. //
  18. // ASSERT: {\$size} === {0}
  19. //
  20. // EXAMPLE:
  21. // #local q {};
  22. // #local _ \@queue.Push{q;foo};
  23. // #local _ \@queue.Push{q;bar};
  24. // #local _ \@queue.Push{q;baz};
  25. // #local size \@queue.Size{q};
  26. //
  27. // ASSERT: {\$size} === {3}
  28. // };
  29. #func {queue.Size} {
  30. #local queue.local.queue {%1};
  31. #local queue.local.size {0};
  32. #list {$queue.local.queue} {size} queue.local.size;
  33. #return {$queue.local.size};
  34. };
  35. ///=== {
  36. // #@ queue.IsEmpty <队列名称>
  37. // 如果队列为空,则返回真,否则返回假。
  38. //
  39. // EXAMPLE:
  40. // #local q {};
  41. // #local b \@queue.IsEmpty{q};
  42. //
  43. // ASSERT: {\$b} === {1}
  44. //
  45. // EXAMPLE:
  46. // #local q {};
  47. // #local _ \@queue.Push{q;foo};
  48. // #local _ \@queue.Push{q;bar};
  49. // #local _ \@queue.Push{q;baz};
  50. // #local b \@queue.IsEmpty{q};
  51. //
  52. // ASSERT: {\$b} === {0}
  53. // };
  54. #func {queue.IsEmpty} {
  55. #if { @queue.Size{%1} > 0 } {
  56. #return 0;
  57. };
  58. #else {
  59. #return 1;
  60. };
  61. };
  62. ///=== {
  63. // #@ queue.First <队列名称>
  64. // 返回队列的第一个元素。如果队列为空则返回空。
  65. //
  66. // EXAMPLE:
  67. // #local q {};
  68. // #local v \@queue.First{q};
  69. //
  70. // ASSERT: {\$v} === {}
  71. //
  72. // EXAMPLE:
  73. // #local q {};
  74. // #local _ \@queue.Push{q;foo};
  75. // #local _ \@queue.Push{q;bar};
  76. // #local _ \@queue.Push{q;baz};
  77. // #local v \@queue.First{q};
  78. //
  79. // ASSERT: {\$v} === {foo}
  80. // };
  81. #func {queue.First} {
  82. #local queue.local.queue {%1};
  83. #local queue.local.value {${${queue.local.queue}[1]}};
  84. #return {$queue.local.value};
  85. };
  86. ///=== {
  87. // #@ queue.Last <队列名称>
  88. // 返回队列的最后一个元素。如果队列为空则返回空。
  89. //
  90. // EXAMPLE:
  91. // #local q {};
  92. // #local v \@queue.Last{q};
  93. //
  94. // ASSERT: {\$v} === {}
  95. //
  96. // EXAMPLE:
  97. // #local q {};
  98. // #local _ \@queue.Push{q;foo};
  99. // #local _ \@queue.Push{q;bar};
  100. // #local _ \@queue.Push{q;baz};
  101. // #local v \@queue.Last{q};
  102. //
  103. // ASSERT: {\$v} === {baz}
  104. // };
  105. #func {queue.Last} {
  106. #local queue.local.queue {%1};
  107. #local queue.local.value {${${queue.local.queue}[-1]}};
  108. #return {$queue.local.value};
  109. };
  110. ///=== {
  111. // #@ queue.Push <队列名称> <元素>
  112. // 将元素推入队列末尾。没有返回值。
  113. //
  114. // EXAMPLE:
  115. // #local q {};
  116. // #local _ \@queue.Push{q;foo};
  117. // #local _ \@queue.Push{q;bar};
  118. // #local _ \@queue.Push{q;baz};
  119. //
  120. // ASSERT: {\$q} === {{1}{foo}{2}{bar}{3}{baz}}
  121. //
  122. // EXAMPLE:
  123. // #local q {};
  124. // #local _ \@queue.Push{q; {f;o;o}};
  125. // #local _ \@queue.Push{q; {b;a;r}};
  126. // #local _ \@queue.Push{q; {b;a;z}};
  127. //
  128. // ASSERT: {\$q} === {{1}{f;o;o}{2}{b;a;r}{3}{b;a;z}}
  129. //
  130. // EXAMPLE:
  131. // #local q {};
  132. // #local _ \@queue.Push{q; { {1}{f} {2}{o} {3}{o} }};
  133. // #local _ \@queue.Push{q; { {1}{b} {2}{a} {3}{r} }};
  134. // #local _ \@queue.Push{q; { {1}{b} {2}{a} {3}{z} }};
  135. //
  136. // ASSERT: {\$q} === {{1}{{1}{f}{2}{o}{3}{o}}{2}{{1}{b}{2}{a}{3}{r}}{3}{{1}{b}{2}{a}{3}{z}}}
  137. // };
  138. #func {queue.Push} {queue.Push {%1} {%2}; #return {}};
  139. ///=== {
  140. // #@ queue.Pop <队列名称>
  141. // 从队列末尾取出元素。返回取出的元素。
  142. //
  143. // EXAMPLE:
  144. // #local q {};
  145. // #local _ \@queue.Push{q;foo};
  146. // #local _ \@queue.Push{q;bar};
  147. // #local _ \@queue.Push{q;baz};
  148. // #local v {\@queue.Pop{q}};
  149. //
  150. // ASSERT: {v=\$v, q=\$q} === {v=baz, q={1}{foo}{2}{bar}}
  151. //
  152. // EXAMPLE:
  153. // #local q {};
  154. // #local _ \@queue.Push{q; {f;o;o}};
  155. // #local _ \@queue.Push{q; {b;a;r}};
  156. // #local _ \@queue.Push{q; {b;a;z}};
  157. // #local v {\@queue.Pop{q}};
  158. //
  159. // ASSERT: {v={\$v}, q=\$q} === {v={b;a;z}, q={1}{f;o;o}{2}{b;a;r}}
  160. //
  161. // EXAMPLE:
  162. // #local q {};
  163. // #local _ \@queue.Push{q; { {1}{f} {2}{o} {3}{o} }};
  164. // #local _ \@queue.Push{q; { {1}{b} {2}{a} {3}{r} }};
  165. // #local _ \@queue.Push{q; { {1}{b} {2}{a} {3}{z} }};
  166. // #local v {\@queue.Pop{q}};
  167. //
  168. // ASSERT: {v={\$v}, q=\$q} === {v={{1}{b}{2}{a}{3}{z}}, q={1}{{1}{f}{2}{o}{3}{o}}{2}{{1}{b}{2}{a}{3}{r}}}
  169. // };
  170. #func {queue.Pop} {
  171. #local queue.local.queue {%1};
  172. #if { @queue.Size{$queue.local.queue} == 0 } {
  173. #return {};
  174. };
  175. #local queue.local.value {${${queue.local.queue}[-1]}};
  176. #list {$queue.local.queue} delete {-1};
  177. #return {$queue.local.value};
  178. };
  179. ///=== {
  180. // #@ queue.Shift <队列名称>
  181. // 从队列开头取出元素。返回取出的元素。
  182. //
  183. // EXAMPLE:
  184. // #local q {};
  185. // #local _ \@queue.Push{q;foo};
  186. // #local _ \@queue.Push{q;bar};
  187. // #local _ \@queue.Push{q;baz};
  188. // #local v {\@queue.Shift{q}};
  189. //
  190. // ASSERT: {v=\$v, q=\$q} === {v=foo, q={1}{bar}{2}{baz}}
  191. //
  192. // EXAMPLE:
  193. // #local q {};
  194. // #local _ \@queue.Push{q; {f;o;o}};
  195. // #local _ \@queue.Push{q; {b;a;r}};
  196. // #local _ \@queue.Push{q; {b;a;z}};
  197. // #local v {\@queue.Shift{q}};
  198. //
  199. // ASSERT: {v={\$v}, q=\$q} === {v={f;o;o}, q={1}{b;a;r}{2}{b;a;z}}
  200. //
  201. // EXAMPLE:
  202. // #local q {};
  203. // #local _ \@queue.Push{q; { {1}{f} {2}{o} {3}{o} }};
  204. // #local _ \@queue.Push{q; { {1}{b} {2}{a} {3}{r} }};
  205. // #local _ \@queue.Push{q; { {1}{b} {2}{a} {3}{z} }};
  206. // #local v {\@queue.Shift{q}};
  207. //
  208. // ASSERT: {v={\$v}, q=\$q} === {v={{1}{f}{2}{o}{3}{o}}, q={1}{{1}{b}{2}{a}{3}{r}}{2}{{1}{b}{2}{a}{3}{z}}}
  209. // };
  210. #func {queue.Shift} {
  211. #local queue.local.queue {%1};
  212. #if { @queue.Size{$queue.local.queue} == 0 } {
  213. #return {};
  214. };
  215. #local queue.local.value {${${queue.local.queue}[+1]}};
  216. #list {$queue.local.queue} delete {1};
  217. #return {$queue.local.value};
  218. };
  219. ///=== {
  220. // #@ queue.Unshift <队列名称> <元素>
  221. // 将元素推入队列开头。没有返回值。
  222. //
  223. // EXAMPLE:
  224. // #local q {};
  225. // #local _ \@queue.Push{q;foo};
  226. // #local _ \@queue.Push{q;bar};
  227. // #local _ \@queue.Push{q;baz};
  228. //
  229. // ASSERT: {\$q} === {{1}{foo}{2}{bar}{3}{baz}}
  230. //
  231. // EXAMPLE:
  232. // #local q {};
  233. // #local _ \@queue.Push{q; {f;o;o}};
  234. // #local _ \@queue.Push{q; {b;a;r}};
  235. // #local _ \@queue.Push{q; {b;a;z}};
  236. //
  237. // ASSERT: {\$q} === {{1}{f;o;o}{2}{b;a;r}{3}{b;a;z}}
  238. //
  239. // EXAMPLE:
  240. // #local q {};
  241. // #local _ \@queue.Push{q; { {1}{f} {2}{o} {3}{o} }};
  242. // #local _ \@queue.Push{q; { {1}{b} {2}{a} {3}{r} }};
  243. // #local _ \@queue.Push{q; { {1}{b} {2}{a} {3}{z} }};
  244. //
  245. // ASSERT: {\$q} === {{1}{{1}{f}{2}{o}{3}{o}}{2}{{1}{b}{2}{a}{3}{r}}{3}{{1}{b}{2}{a}{3}{z}}}
  246. // };
  247. #func {queue.Unshift} {queue.Unshift {%1} {%2}; #return {}};
  248. ///=== {
  249. ///// 别名版队列处理:
  250. //
  251. // ## queue.Push <队列名称> <元素>
  252. // 将元素推入队列末尾。
  253. //
  254. // EXAMPLE:
  255. // #local q {};
  256. // queue.Push q foo;
  257. // queue.Push q bar;
  258. // queue.Push q baz;
  259. //
  260. // ASSERT: {\$q} === {{1}{foo}{2}{bar}{3}{baz}}
  261. //
  262. // EXAMPLE:
  263. // #local q {};
  264. // queue.Push q {f;o;o};
  265. // queue.Push q {b;a;r};
  266. // queue.Push q {b;a;z};
  267. //
  268. // ASSERT: {\$q} === {{1}{f;o;o}{2}{b;a;r}{3}{b;a;z}}
  269. //
  270. // EXAMPLE:
  271. // #local q {};
  272. // queue.Push q { {1}{f} {2}{o} {3}{o} };
  273. // queue.Push q { {1}{b} {2}{a} {3}{r} };
  274. // queue.Push q { {1}{b} {2}{a} {3}{z} };
  275. //
  276. // ASSERT: {\$q} === {{1}{{1}{f}{2}{o}{3}{o}}{2}{{1}{b}{2}{a}{3}{r}}{3}{{1}{b}{2}{a}{3}{z}}}
  277. //
  278. // ## queue.Pop <队列名称>
  279. // 从队列末尾取出元素,并丢弃。
  280. //
  281. // EXAMPLE:
  282. // #local q {};
  283. // queue.Push q foo;
  284. // queue.Push q bar;
  285. // queue.Push q baz;
  286. // queue.Pop q;
  287. //
  288. // ASSERT: {\$q} === {{1}{foo}{2}{bar}}
  289. //
  290. // EXAMPLE:
  291. // #local q {};
  292. // queue.Push q {f;o;o};
  293. // queue.Push q {b;a;r};
  294. // queue.Push q {b;a;z};
  295. // queue.Pop q;
  296. //
  297. // ASSERT: {\$q} === {{1}{f;o;o}{2}{b;a;r}}
  298. //
  299. // EXAMPLE:
  300. // #local q {};
  301. // queue.Push q { {1}{f} {2}{o} {3}{o} };
  302. // queue.Push q { {1}{b} {2}{a} {3}{r} };
  303. // queue.Push q { {1}{b} {2}{a} {3}{z} };
  304. // queue.Pop q;
  305. //
  306. // ASSERT: {\$q} === {{1}{{1}{f}{2}{o}{3}{o}}{2}{{1}{b}{2}{a}{3}{r}}}
  307. //
  308. // ## queue.Shift <队列名称>
  309. // 从队列开头取出元素,并丢弃。
  310. //
  311. // EXAMPLE:
  312. // #local q {};
  313. // queue.Push q foo;
  314. // queue.Push q bar;
  315. // queue.Push q baz;
  316. // queue.Shift q;
  317. //
  318. // ASSERT: {\$q} === {{1}{bar}{2}{baz}}
  319. //
  320. // EXAMPLE:
  321. // #local q {};
  322. // queue.Push q {f;o;o};
  323. // queue.Push q {b;a;r};
  324. // queue.Push q {b;a;z};
  325. // queue.Shift q;
  326. //
  327. // ASSERT: {\$q} === {{1}{b;a;r}{2}{b;a;z}}
  328. //
  329. // EXAMPLE:
  330. // #local q {};
  331. // queue.Push q { {1}{f} {2}{o} {3}{o} };
  332. // queue.Push q { {1}{b} {2}{a} {3}{r} };
  333. // queue.Push q { {1}{b} {2}{a} {3}{z} };
  334. // queue.Shift q;
  335. //
  336. // ASSERT: {\$q} === {{1}{{1}{b}{2}{a}{3}{r}}{2}{{1}{b}{2}{a}{3}{z}}}
  337. //
  338. // ## queue.Unshift <队列名称> <元素>
  339. // 将元素推入队列开头。
  340. //
  341. // EXAMPLE:
  342. // #local q {};
  343. // queue.Unshift q baz;
  344. // queue.Unshift q bar;
  345. // queue.Unshift q foo;
  346. //
  347. // ASSERT: {\$q} === {{1}{foo}{2}{bar}{3}{baz}}
  348. //
  349. // EXAMPLE:
  350. // #local q {};
  351. // queue.Unshift q {b;a;z};
  352. // queue.Unshift q {b;a;r};
  353. // queue.Unshift q {f;o;o};
  354. //
  355. // ASSERT: {\$q} === {{1}{f;o;o}{2}{b;a;r}{3}{b;a;z}}
  356. //
  357. // EXAMPLE:
  358. // #local q {};
  359. // queue.Unshift q { {1}{b} {2}{a} {3}{z} };
  360. // queue.Unshift q { {1}{b} {2}{a} {3}{r} };
  361. // queue.Unshift q { {1}{f} {2}{o} {3}{o} };
  362. //
  363. // ASSERT: {\$q} === {{1}{{1}{f}{2}{o}{3}{o}}{2}{{1}{b}{2}{a}{3}{r}}{3}{{1}{b}{2}{a}{3}{z}}}
  364. // };
  365. #alias {queue.Push} {
  366. #local queue.local.queue {%1};
  367. #local queue.local.value {%2};
  368. #list {$queue.local.queue} add {{$queue.local.value}};
  369. };
  370. #alias {queue.Pop} {#local _ @queue.Pop{{%1}}};
  371. #alias {queue.Shift} {#local _ @queue.Shift{{%1}}};
  372. #alias {queue.Unshift} {
  373. #local queue.local.queue {%1};
  374. #local queue.local.value {%2};
  375. #list {$queue.local.queue} insert {1} {$queue.local.value};
  376. };