Guest User

list.asm

a guest
Apr 22nd, 2021
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.38 KB | None | 0 0
  1. ; These affect the name of lists' length constants
  2. def list_length_prefix equs "LENGTH_"
  3. def list_length_suffix equs ""
  4.  
  5. ; __list_length LIST, length
  6. ; For internal use only!
  7. ;
  8. MACRO __list_length
  9. if def({list_length_prefix}\1{list_length_suffix})
  10. purge {list_length_prefix}\1{list_length_suffix}
  11. endc
  12. def {list_length_prefix}\1{list_length_suffix} equ \2
  13. ENDM
  14.  
  15. ; list LIST, items...
  16. ; Create a new list.
  17. ;
  18. ; \1: symbol - The list to create
  19. ; \2+: number... - The initial items, if any
  20. ;
  21. ; list SQUARES, 1, 4, 9
  22. ; assert LENGTH_SQUARES == 3
  23. ; assert SQUARES#2 == 4
  24. ;
  25. ; list_item items...
  26. ; Append items to the previously created list.
  27. ;
  28. ; \1+: number... - The items to append, if any
  29. ;
  30. ; list SQUARES
  31. ; list_item 1
  32. ; list_item 4, 9
  33. ; assert LENGTH_MONS == 3
  34. ; assert SQUARES#3 == 9
  35. ;
  36. MACRO list
  37. assert !def({list_length_prefix}\1{list_length_suffix}), \
  38. "list: list \1 is already defined"
  39. __list_length \1, 0
  40. list_append \#
  41. redef list_item equs "list_append \1,"
  42. ENDM
  43.  
  44. ; list_print LIST
  45. ; Print a list.
  46. ;
  47. ; \1: symbol - The list to print
  48. ;
  49. ; list SQUARES, 1, 4, 9
  50. ; ; Prints [$1, $4, $9]
  51. ; list_print SQUARES
  52. ;
  53. MACRO list_print
  54. assert def({list_length_prefix}\1{list_length_suffix}), \
  55. "list_print: list \1 is not defined"
  56. print "["
  57. for __i, 1, {list_length_prefix}\1{list_length_suffix} + 1
  58. if __i > 1
  59. print ", "
  60. endc
  61. print {\1#{d:__i}}
  62. endr
  63. purge __i
  64. print "]"
  65. ENDM
  66.  
  67. ; list_println LIST
  68. ; Print a list followed by a newline.
  69. ;
  70. ; \1: symbol - The list to print
  71. ;
  72. ; list SQUARES, 1, 4, 9
  73. ; ; Prints [$1, $4, $9]
  74. ; list_println SQUARES
  75. ;
  76. MACRO list_println
  77. assert def({list_length_prefix}\1{list_length_suffix}), \
  78. "list_println: list \1 is not defined"
  79. list_print \1
  80. println
  81. ENDM
  82.  
  83. ; list_append LIST, items...
  84. ; Append items to a list.
  85. ;
  86. ; \1: symbol - The list to update
  87. ; \2+: number... - The items to append, if any
  88. ;
  89. ; list SQUARES
  90. ; list_append SQUARES, 1, 4, 9
  91. ; assert LENGTH_SQUARES == 3
  92. ; assert SQUARES#1 == 1
  93. ;
  94. MACRO list_append
  95. assert def({list_length_prefix}\1{list_length_suffix}), \
  96. "list_append: list \1 is not defined"
  97. def __n = {list_length_prefix}\1{list_length_suffix}
  98. for __i, 2, _NARG + 1
  99. def __j = __n + __i - 1
  100. def \1#{d:__j} equ \<__i>
  101. purge __j
  102. endr
  103. purge __i
  104. __list_length \1, __n + {_NARG} - 1
  105. purge __n
  106. ENDM
  107.  
  108. ; list_extend LIST1, LIST2
  109. ; Append items to a list from another.
  110. ;
  111. ; \1: symbol - The list to update
  112. ; \2: symbol - The list to append from
  113. ;
  114. ; list SQUARES, 1, 4, 9
  115. ; list MORESQUARES, 16, 25
  116. ; list_extend SQUARES, MORESQUARES
  117. ; assert LENGTH_SQUARES == 5
  118. ;
  119. MACRO list_extend
  120. assert def({list_length_prefix}\1{list_length_suffix}), \
  121. "list_extend: list \1 is not defined"
  122. assert def({list_length_prefix}\2{list_length_suffix}), \
  123. "list_extend: list \2 is not defined"
  124. for __i, 1, {list_length_prefix}\2{list_length_suffix} + 1
  125. list_append \1, {\2#{d:__i}}
  126. endr
  127. purge __i
  128. ENDM
  129.  
  130. ; list_copy LIST1, LIST2
  131. ; Create a new list as a copy of another list.
  132. ;
  133. ; \1: symbol - The list to create
  134. ; \2: symbol - The list to copy
  135. ;
  136. ; list SQUARES, 1, 4, 9
  137. ; list_copy DIMS, SQUARES
  138. ; ; Prints [$1, $4, $9]
  139. ; list_print DIMS
  140. ;
  141. MACRO list_copy
  142. assert !def({list_length_prefix}\1{list_length_suffix}), \
  143. "list_copy: list \1 is already defined"
  144. assert def({list_length_prefix}\2{list_length_suffix}), \
  145. "list_copy: list \2 is not defined"
  146. __list_length \1, {list_length_prefix}\2{list_length_suffix}
  147. for __i, 1, {list_length_prefix}\2{list_length_suffix} + 1
  148. def \1#{d:__i} equ {\2#{d:__i}}
  149. endr
  150. purge __i
  151. ENDM
  152.  
  153. ; list_clear LIST
  154. ; Clear a list.
  155. ;
  156. ; \1: symbol - The list to clear
  157. ;
  158. ; list SQUARES, 1, 4, 9
  159. ; list_clear SQUARES
  160. ; assert LENGTH_SQUARES == 0
  161. ;
  162. MACRO list_clear
  163. assert def({list_length_prefix}\1{list_length_suffix}), \
  164. "list_clear: list \1 is not defined"
  165. for __i, 1, {list_length_prefix}\1{list_length_suffix} + 1
  166. purge \1#{d:__i}
  167. endr
  168. purge __i
  169. __list_length \1, 0
  170. ENDM
  171.  
  172. ; list_purge LIST
  173. ; Purge a list.
  174. ;
  175. ; \1: symbol - The list to purge
  176. ;
  177. ; list SQUARES, 1, 4, 9
  178. ; list_purge SQUARES
  179. ; assert !DEF(LENGTH_SQUARES)
  180. ;
  181. MACRO list_purge
  182. assert def({list_length_prefix}\1{list_length_suffix}), \
  183. "list_purge: list \1 is not defined"
  184. list_clear \1
  185. purge {list_length_prefix}\1{list_length_suffix}
  186. ENDM
  187.  
  188. ; list_set LIST, index, item
  189. ; Set an index of a list to an item.
  190. ;
  191. ; \1: symbol - The list to update
  192. ; \2: number - The index to be set
  193. ; \3: number - The item to set
  194. ;
  195. ; list SQUARES, 1, 3, 9
  196. ; list_set SQUARES, 2, 4
  197. ; assert SQUARES#2 == 4
  198. ;
  199. MACRO list_set
  200. assert def({list_length_prefix}\1{list_length_suffix}), \
  201. "list_set: list \1 is not defined"
  202. def __idx = \2
  203. assert 1 <= __idx && __idx <= {list_length_prefix}\1{list_length_suffix}, \
  204. "list_set: invalid index for list \1: {d:__idx}"
  205. purge \1#{d:__idx}
  206. def \1#{d:__idx} equ \3
  207. purge __idx
  208. ENDM
  209.  
  210. ; list_insert LIST, index, item
  211. ; Insert an item into a list before an index.
  212. ;
  213. ; \1: symbol - The list to update
  214. ; \2: number - The index to insert before
  215. ; \3: number - The item to insert
  216. ;
  217. ; list SQUARES, 1, 9
  218. ; list_insert SQUARES, 2, 4
  219. ; assert SQUARES#2 == 4
  220. ;
  221. MACRO list_insert
  222. assert def({list_length_prefix}\1{list_length_suffix}), \
  223. "list_insert: list \1 is not defined"
  224. def __n = {list_length_prefix}\1{list_length_suffix}
  225. def __idx = \2
  226. assert 1 <= __idx && __idx <= __n, \
  227. "list_insert: invalid index for list \1: {d:__idx}"
  228. for __i, __n + 1, __idx, -1
  229. def __j = __i - 1
  230. def \1#{d:__i} equ {\1#{d:__j}}
  231. purge \1#{d:__j}, __j
  232. endr
  233. purge __i
  234. def \1#{d:__idx} equ \3
  235. purge __idx
  236. __list_length \1, __n + 1
  237. purge __n
  238. ENDM
  239.  
  240. ; list_delete LIST, index
  241. ; Delete an index from a list.
  242. ;
  243. ; \1: symbol - The list to update
  244. ; \2: number - The index to delete
  245. ;
  246. ; list SQUARES, 1, 4, 9
  247. ; list_delete SQUARES, 1
  248. ; assert LENGTH_SQUARES == 2
  249. ; assert SQUARES#1 == 4
  250. ;
  251. MACRO list_delete
  252. assert def({list_length_prefix}\1{list_length_suffix}), \
  253. "list_delete: list \1 is not defined"
  254. def __n = {list_length_prefix}\1{list_length_suffix}
  255. def __idx = \2
  256. assert 1 <= __idx && __idx <= __n, \
  257. "list_delete: invalid index for list \1: {d:__idx}"
  258. purge \1#{d:__idx}
  259. for __i, __idx, __n
  260. def __j = __i + 1
  261. def \1#{d:__i} equ {\1#{d:__j}}
  262. purge \1#{d:__j}, __j
  263. endr
  264. purge __i, __idx
  265. __list_length \1, __n - 1
  266. purge __n
  267. ENDM
  268.  
  269. ; list_find INDEX, LIST, item
  270. ; Find the first index of an item in a list.
  271. ;
  272. ; \1: symbol - The index to define
  273. ; \2: symbol - The list to use
  274. ; \3: number - The item to search for
  275. ;
  276. ; list SQUARES, 1, 4, 9
  277. ; list_find N, SQUARES, 4
  278. ; assert N == 2
  279. ; list_find N, SQUARES, 100
  280. ; assert N == 0
  281. ;
  282. MACRO list_find
  283. assert def({list_length_prefix}\2{list_length_suffix}), \
  284. "list_find: list \2 is not defined"
  285. def \1 = 0
  286. for __i, 1, {list_length_prefix}\2{list_length_suffix} + 1
  287. if (\3) == {\2#{d:__i}}
  288. def \1 = __i
  289. break
  290. endc
  291. endr
  292. purge __i
  293. ENDM
  294.  
  295. ; list_rfind INDEX, LIST, item
  296. ; Find the last index of an item in a list.
  297. ;
  298. ; \1: symbol - The index to define
  299. ; \2: symbol - The list to use
  300. ; \3: number - The item to search for
  301. ;
  302. ; list VALUES, 6, 4, 6
  303. ; list_rfind N, VALUES, 6
  304. ; assert N == 3
  305. ;
  306. MACRO list_rfind
  307. assert def({list_length_prefix}\2{list_length_suffix}), \
  308. "list_rfind: list \2 is not defined"
  309. def \1 = 0
  310. for __i, {list_length_prefix}\2{list_length_suffix}, 0, -1
  311. if (\3) == {\2#{d:__i}}
  312. def \1 = __i
  313. break
  314. endc
  315. endr
  316. purge __i
  317. ENDM
  318.  
  319. ; list_count NUM, LIST, item
  320. ; Count the occurrences of an item in a list.
  321. ;
  322. ; \1: symbol - The quantity to define
  323. ; \2: symbol - The list to use
  324. ; \3: number - The item to count
  325. ;
  326. ; list ROW, 1, 1, 2, 3, 1
  327. ; list_count N, ROW, 1
  328. ; assert N == 3
  329. ;
  330. MACRO list_count
  331. assert def({list_length_prefix}\2{list_length_suffix}), \
  332. "list_count: list \2 is not defined"
  333. def \1 = 0
  334. for __i, 1, {list_length_prefix}\2{list_length_suffix} + 1
  335. if (\3) == {\2#{d:__i}}
  336. def \1 = \1 + 1
  337. endc
  338. endr
  339. purge __i
  340. ENDM
  341.  
  342. ; list_replace LIST, old, new
  343. ; Replace each occurrence of an item in a list.
  344. ;
  345. ; \1: symbol - The list to update
  346. ; \2: number - The old number to be replaced
  347. ; \3: number - The new number to replace with
  348. ;
  349. ; list VALUES, 6, 4, 6
  350. ; list_replace VALUES, 6, 3
  351. ; ; Prints [$3, $4, $3]
  352. ; list_println VALUES
  353. ;
  354. MACRO list_replace
  355. assert def({list_length_prefix}\1{list_length_suffix}), \
  356. "list_replace: list \1 is not defined"
  357. for __i, 1, {list_length_prefix}\1{list_length_suffix} + 1
  358. if (\2) == {\1#{d:__i}}
  359. purge \1#{d:__i}
  360. def \1#{d:__i} equ \3
  361. endc
  362. endr
  363. purge __i
  364. ENDM
  365.  
  366. ; list_remove LIST, item
  367. ; Remove the first occurrence of an item in a list.
  368. ;
  369. ; \1: symbol - The list to update
  370. ; \2: number - The number to be removed
  371. ;
  372. ; list VALUES, 1, 2, 3, 1
  373. ; list_remove VALUES, 1
  374. ; ; Prints [$2, $3, $1]
  375. ; list_println VALUES
  376. ;
  377. MACRO list_remove
  378. assert def({list_length_prefix}\1{list_length_suffix}), \
  379. "list_remove: list \1 is not defined"
  380. list_find ___idx\@, \1, \2
  381. if ___idx\@ > 0
  382. list_delete \1, ___idx\@
  383. endc
  384. purge ___idx\@
  385. ENDM
  386.  
  387. ; list_remove_all LIST, item
  388. ; Remove each occurrence of an item in a list.
  389. ;
  390. ; \1: symbol - The list to update
  391. ; \2: number - The number to be removed
  392. ;
  393. ; list VALUES, 1, 2, 3, 1
  394. ; list_remove_all VALUES, 1
  395. ; ; Prints [$2, $3]
  396. ; list_println VALUES
  397. ;
  398. MACRO list_remove_all
  399. assert def({list_length_prefix}\1{list_length_suffix}), \
  400. "list_remove_all: list \1 is not defined"
  401. list_count ___num\@, \1, \2
  402. rept ___num\@
  403. list_remove \1, \2
  404. endr
  405. purge ___num\@
  406. ENDM
  407.  
  408. ; list_sort LIST
  409. ; Sort a list.
  410. ;
  411. ; \1: symbol - The list to sort
  412. ;
  413. ; list SQUARES, 4, 9, 1
  414. ; list_sort SQUARES
  415. ; ; Prints [$1, $4, $9]
  416. ; list_println SQUARES
  417. ;
  418. MACRO list_sort
  419. assert def({list_length_prefix}\1{list_length_suffix}), \
  420. "list_sort: list \1 is not defined"
  421. def __n = {list_length_prefix}\1{list_length_suffix}
  422. for __p, ceil(log(__n << 16, 2.0)) >> 16
  423. def __w = 2 ** __p
  424. for __i, 1, __n + 1, 2 * __w
  425. if __i + __w > __n
  426. break
  427. endc
  428. def __l1 = __i
  429. def __r1 = __l1 + __w - 1
  430. def __l2 = __r1 + 1
  431. def __r2 = __l2 + __w - 1
  432. if __r2 > __n
  433. def __r2 = __n
  434. endc
  435. for __t, __n
  436. if __l1 > __r1 || __l2 > __r2
  437. break
  438. endc
  439. if {\1#{d:__l1}} <= {\1#{d:__l2}}
  440. def __tmp{d:__t} equ {\1#{d:__l1}}
  441. def __l1 = __l1 + 1
  442. else
  443. def __tmp{d:__t} equ {\1#{d:__l2}}
  444. def __l2 = __l2 + 1
  445. endc
  446. endr
  447. for __j, __l1, __r1 + 1
  448. def __tmp{d:__t} equ {\1#{d:__j}}
  449. def __t = __t + 1
  450. endr
  451. for __j, __l2, __r2 + 1
  452. def __tmp{d:__t} equ {\1#{d:__j}}
  453. def __t = __t + 1
  454. endr
  455. purge __l1, __r1, __l2, __r2
  456. for __j, __t
  457. def __k = __i + __j
  458. purge \1#{d:__k}
  459. def \1#{d:__k} equ {__tmp{d:__j}}
  460. purge __k, __tmp{d:__j}
  461. endr
  462. purge __j, __t
  463. endr
  464. purge __i, __w
  465. endr
  466. purge __p, __n
  467. ENDM
  468.  
  469. ; list_reverse LIST
  470. ; Reverse a list.
  471. ;
  472. ; \1: symbol - The list to reverse
  473. ;
  474. ; list SQUARES, 9, 4, 1
  475. ; list_reverse SQUARES
  476. ; ; Prints [$1, $4, $9]
  477. ; list_println SQUARES
  478. ;
  479. MACRO list_reverse
  480. assert def({list_length_prefix}\1{list_length_suffix}), \
  481. "list_reverse: list \1 is not defined"
  482. def __n = {list_length_prefix}\1{list_length_suffix}
  483. for __i, 1, __n / 2 + 1
  484. def __j = __n - __i + 1
  485. def __tmp equ {\1#{d:__i}}
  486. purge \1#{d:__i}
  487. def \1#{d:__i} equ {\1#{d:__j}}
  488. purge \1#{d:__j}
  489. def \1#{d:__j} equ {__tmp}
  490. purge __tmp, __j
  491. endr
  492. purge __i, __n
  493. ENDM
  494.  
  495. list SQUARES
  496. list_item 4
  497. list_item 9
  498. list_item 1
  499. list_sort SQUARES
  500.  
  501. list_println SQUARES ; [$1, $4, $9]
  502. println LENGTH_SQUARES ; $3
  503.  
  504. list_copy VALUES, SQUARES
  505. list_append VALUES, 10, 20
  506.  
  507. list_println VALUES ; [$1, $4, $9, $A, $14]
  508. list_replace VALUES, 10, 11
  509. println VALUES#4 ; $B
  510.  
  511. list SEQUENCE, 16, 25, 36
  512. list_delete VALUES, 4
  513. list_remove VALUES, 20
  514. list_extend VALUES, SEQUENCE
  515. list_purge SEQUENCE
  516. list_println VALUES ; [$1, $4, $9, $10, $19, $24]
  517.  
  518. list_purge VALUES
  519. assert !DEF(LENGTH_VALUES)
  520. list VALUES, 11, 22, 22, 33, 22, 33
  521. list_find N, VALUES, 22
  522. println N ; $2
  523. list_rfind N, VALUES, 22
  524. println N ; $5
  525. list_count N, VALUES, 22
  526. println N ; $3
  527. list_remove_all VALUES, 22
  528. list_set VALUES, 2, 44
  529. list_insert VALUES, 3, 55
  530. list_reverse VALUES
  531. list_println VALUES ; [$21, $37, $2C, $B]
  532.  
Advertisement
Add Comment
Please, Sign In to add comment