spitewaste 0.2.01 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ce4494399350d9afb01a0c84aef1ce504da4a24349b33a45de83d6b6f4fa10b
4
- data.tar.gz: 330b14a9eb241ff0ac8986956c8f790dd88ce87db4823e08ff19edfc7db0aee1
3
+ metadata.gz: f039f7e3e393fc05321b8eec880b0596320a5a2bf6edc5bd6690502db221fd25
4
+ data.tar.gz: d2e137737cf57c865637b0ab44a9fe2546c141e8dec624865c7932553b81ceee
5
5
  SHA512:
6
- metadata.gz: 04d8acb9a1ed8e1617447407ee511b38b35d2f15a0ef2cc836690138f67f1e036712eb912d3c1dc7331e4d4d2d8694b4fad67be4a0fdefec55515144c9b4a9ce
7
- data.tar.gz: 3161a39f4f7b364a5204d4174bbe7f1aa3ac43c530c86d6273b3fe61a04a93eb450688c882d9709f06a105bed35e37479310183cdb39d1509cf90049f2f0fcf7
6
+ metadata.gz: 34cc5fa69d331f4d227b0c7a4263b64fd87464bc52d5aae87bd41012e8d92b825891e779b7620aa8e885c39178d7f983f4e8dc7beb7b6e23d22e834dba08b8f7
7
+ data.tar.gz: 92b0baacda3b6030e41f49c8915598bfb3d40e7f7fc13ee204aa0a9c8f2696840cea36e834f765fcba8fcbdaaf872cedf65689f6804580847b6e08cbe6387271
@@ -21,6 +21,10 @@ module Spitewaste
21
21
  return :whitespace if white > black
22
22
  program[/import|[^-\w\s]/] ? :spitewaste : :assembly
23
23
  end
24
+
25
+ def strpack s
26
+ s.bytes.zip(0..).sum { |b, e| b * 128 ** e }
27
+ end
24
28
  end
25
29
 
26
30
  require 'spitewaste/assembler'
@@ -112,7 +112,7 @@ module Spitewaste
112
112
  flow: %i[jump jz jn ret exit],
113
113
  math: %i[add sub mul div mod],
114
114
  heap: %i[store load],
115
- io: %i[ichr inum ochr onum],
115
+ io: %i[ichr inum ochr onum shell],
116
116
  calls: %i[call label]
117
117
  }.flat_map { |type, insns| insns.map { |i| [i, type] } }.to_h
118
118
 
@@ -219,11 +219,10 @@ _sorted_yes: push 1 slide 3 ret
219
219
  ; [1 2 3 3] => [3 2 1 3]
220
220
  ; [7 1] => [7 1]
221
221
  ; [5 4 3 2 1 5] => [1 2 3 4 5 5]
222
- aryrev: push -3 copy 1 store
223
- _aryrev_loop:
224
- swap copy 1 :bury $--
225
- push 0 copy 1 sub jn _aryrev_loop
226
- push 3 sub load ret
222
+ aryrev:
223
+ push -10 :aryheap push -10
224
+ @-9 times (dup load swap $--)
225
+ pop @-9 ret
227
226
 
228
227
  ; returns the array A replicated N times
229
228
  ; ! N must be greater than 1
@@ -1455,6 +1455,53 @@
1455
1455
  }
1456
1456
  },
1457
1457
  "fun": {
1458
+ "ROT13": {
1459
+ "full": "applies the ROT13 \"cipher\" to the string S\n[S] => [S']\n\n[\"gnat\"] => [\"tang\"]\n[\"purely\"] => [\"cheryl\"]\n[\"cat.PNG\"] => [\"png.CAT\"]\n[\"Hello, world.\"] => [\"Uryyb, jbeyq.\"]\n[\"a123z\"] => [\"n123m\"]\n",
1460
+ "desc": "applies the ROT13 \"cipher\" to the string S",
1461
+ "effect": "[S] => [S']",
1462
+ "cases": [
1463
+ [
1464
+ [
1465
+ 244873063
1466
+ ],
1467
+ [
1468
+ 217821428
1469
+ ]
1470
+ ],
1471
+ [
1472
+ [
1473
+ 4186733066992
1474
+ ],
1475
+ [
1476
+ 3743573177443
1477
+ ]
1478
+ ],
1479
+ [
1480
+ [
1481
+ 314962935099619
1482
+ ],
1483
+ [
1484
+ 371687373272944
1485
+ ]
1486
+ ],
1487
+ [
1488
+ [
1489
+ 905009539406525881141375688
1490
+ ],
1491
+ [
1492
+ 906989270706565425435408725
1493
+ ]
1494
+ ],
1495
+ [
1496
+ [
1497
+ 32856905953
1498
+ ],
1499
+ [
1500
+ 29367245038
1501
+ ]
1502
+ ]
1503
+ ]
1504
+ },
1458
1505
  "anagrams?": {
1459
1506
  "full": "returns whether the strings S and T are composed of the same characters\n[S T] => [0 | 1]\n\n[\"allergy\" \"gallery\"] => [1]\n[\"largely\" \"regally\"] => [1]\n[\"foo\" \"bar\"] => [0]\n",
1460
1507
  "desc": "returns whether the strings S and T are composed of the same characters",
@@ -1699,33 +1746,49 @@
1699
1746
  },
1700
1747
  "io": {
1701
1748
  "getline": {
1702
- "full": "reads a line of input onto the top of the stack as a packed string\n",
1703
- "desc": "",
1704
- "effect": "reads a line of input onto the top of the stack as a packed string",
1749
+ "full": "reads a line of input onto the top of the stack as a packed string\n[] => [L]\n",
1750
+ "desc": "reads a line of input onto the top of the stack as a packed string",
1751
+ "effect": "[] => [L]",
1705
1752
  "cases": [
1706
1753
 
1707
1754
  ]
1708
1755
  },
1709
1756
  "print": {
1710
- "full": "prints the character at the top of the stack until terminating zero\n",
1711
- "desc": "",
1712
- "effect": "prints the character at the top of the stack until terminating zero",
1757
+ "full": "prints the character at the top of the stack until terminating zero\n[0 ... C] => []\n",
1758
+ "desc": "prints the character at the top of the stack until terminating zero",
1759
+ "effect": "[0 ... C] => []",
1713
1760
  "cases": [
1714
1761
 
1715
1762
  ]
1716
1763
  },
1717
1764
  "println": {
1718
- "full": "print with newline\n",
1719
- "desc": "",
1720
- "effect": "print with newline",
1765
+ "full": "print with newline\n[0 ... C] => []\n",
1766
+ "desc": "print with newline",
1767
+ "effect": "[0 ... C] => []",
1768
+ "cases": [
1769
+
1770
+ ]
1771
+ },
1772
+ "prompt": {
1773
+ "full": "displays the string S then reads a line of input\n[S] => [L]\n",
1774
+ "desc": "displays the string S then reads a line of input",
1775
+ "effect": "[S] => [L]",
1721
1776
  "cases": [
1722
1777
 
1723
1778
  ]
1724
1779
  },
1725
1780
  "readall": {
1726
- "full": "consume stdin until EOF\n",
1727
- "desc": "",
1728
- "effect": "consume stdin until EOF",
1781
+ "full": "consume stdin until EOF into the string S\n[] => [S]\n",
1782
+ "desc": "consume stdin until EOF into the string S",
1783
+ "effect": "[] => [S]",
1784
+ "cases": [
1785
+
1786
+ ]
1787
+ },
1788
+ "readfile": {
1789
+ "full": "returns the contents C of the file at path P (a string)\nNON-STANDARD! This function makes use of the `shell` instruction, which is\nonly(?) available in the Spiceweight Whitespace interpreter.\n[P] => [C]\n",
1790
+ "desc": "returns the contents C of the file at path P (a string)\nNON-STANDARD! This function makes use of the `shell` instruction, which is\nonly(?) available in the Spiceweight Whitespace interpreter.",
1791
+ "effect": "[P] => [C]",
1729
1792
  "cases": [
1730
1793
 
1731
1794
  ]
@@ -2564,6 +2627,14 @@
2564
2627
  }
2565
2628
  },
2566
2629
  "random": {
2630
+ "bogosort": {
2631
+ "full": "sorts the array A if you're lucky\n[A] => [A']\n",
2632
+ "desc": "sorts the array A if you're lucky",
2633
+ "effect": "[A] => [A']",
2634
+ "cases": [
2635
+
2636
+ ]
2637
+ },
2567
2638
  "dice": {
2568
2639
  "full": "returns an array A of N random integers between 1 and D (inclusive)\n[N D] => [A]\n",
2569
2640
  "desc": "returns an array A of N random integers between 1 and D (inclusive)",
@@ -3668,6 +3739,93 @@
3668
3739
  ]
3669
3740
  ]
3670
3741
  },
3742
+ "swapary": {
3743
+ "full": "swaps the two arrays at the top of the stack\n[A B] => [B A]\n\n[1 2 3 3 3 2 1 3] => [3 2 1 3 1 2 3 3]\n[5 6 2 9 7 5 3 1 5] => [9 7 5 3 1 5 5 6 2]\n[0 0 2 4 2 0 3] => [4 2 0 3 0 0 2]\n[1 1 2 1] => [2 1 1 1]\n",
3744
+ "desc": "swaps the two arrays at the top of the stack",
3745
+ "effect": "[A B] => [B A]",
3746
+ "cases": [
3747
+ [
3748
+ [
3749
+ 1,
3750
+ 2,
3751
+ 3,
3752
+ 3,
3753
+ 3,
3754
+ 2,
3755
+ 1,
3756
+ 3
3757
+ ],
3758
+ [
3759
+ 3,
3760
+ 2,
3761
+ 1,
3762
+ 3,
3763
+ 1,
3764
+ 2,
3765
+ 3,
3766
+ 3
3767
+ ]
3768
+ ],
3769
+ [
3770
+ [
3771
+ 5,
3772
+ 6,
3773
+ 2,
3774
+ 9,
3775
+ 7,
3776
+ 5,
3777
+ 3,
3778
+ 1,
3779
+ 5
3780
+ ],
3781
+ [
3782
+ 9,
3783
+ 7,
3784
+ 5,
3785
+ 3,
3786
+ 1,
3787
+ 5,
3788
+ 5,
3789
+ 6,
3790
+ 2
3791
+ ]
3792
+ ],
3793
+ [
3794
+ [
3795
+ 0,
3796
+ 0,
3797
+ 2,
3798
+ 4,
3799
+ 2,
3800
+ 0,
3801
+ 3
3802
+ ],
3803
+ [
3804
+ 4,
3805
+ 2,
3806
+ 0,
3807
+ 3,
3808
+ 0,
3809
+ 0,
3810
+ 2
3811
+ ]
3812
+ ],
3813
+ [
3814
+ [
3815
+ 1,
3816
+ 1,
3817
+ 2,
3818
+ 1
3819
+ ],
3820
+ [
3821
+ 2,
3822
+ 1,
3823
+ 1,
3824
+ 1
3825
+ ]
3826
+ ]
3827
+ ]
3828
+ },
3671
3829
  "to_a": {
3672
3830
  "full": "pops elements off the stack until it hits the specified sentinel value S,\npushing them to the resulting pseudo-array. It's often more convenient to\nbuild up a collection in reverse order, and we often don't know in advance\nhow many elements we'll meet, but we do know to stop at the sentinel.\n[S En ... E1 S] => [E1 ... En n]\n\n[-1 9 8 7 -1] => [7 8 9 3]\n[0 'c' 'b' 'a' 0] => ['a' 'b' 'c' 3]\n",
3673
3831
  "desc": "pops elements off the stack until it hits the specified sentinel value S,\npushing them to the resulting pseudo-array. It's often more convenient to\nbuild up a collection in reverse order, and we often don't know in advance\nhow many elements we'll meet, but we do know to stop at the sentinel.",
@@ -4103,6 +4261,49 @@
4103
4261
  ]
4104
4262
  ]
4105
4263
  },
4264
+ "strbegins?": {
4265
+ "full": "returns 1 if the string S begins with substring T, 0 otherwise\n[S T] => [0 | 1]\n\n[\"foobar\" \"foo\"] => [1]\n[\"foobar\" \"boo\"] => [0]\n[\"abc123\" \"123\"] => [0]\n[\" foo\" \" \"] = [1]\n",
4266
+ "desc": "returns 1 if the string S begins with substring T, 0 otherwise",
4267
+ "effect": "[S T] => [0 | 1]",
4268
+ "cases": [
4269
+ [
4270
+ [
4271
+ 3943255767014,
4272
+ 1832934
4273
+ ],
4274
+ [
4275
+ 1
4276
+ ]
4277
+ ],
4278
+ [
4279
+ [
4280
+ 3943255767014,
4281
+ 1832930
4282
+ ],
4283
+ [
4284
+ 0
4285
+ ]
4286
+ ],
4287
+ [
4288
+ [
4289
+ 1765872824673,
4290
+ 842033
4291
+ ],
4292
+ [
4293
+ 0
4294
+ ]
4295
+ ],
4296
+ [
4297
+ [
4298
+ 234615584,
4299
+ 32
4300
+ ],
4301
+ [
4302
+ 1
4303
+ ]
4304
+ ]
4305
+ ]
4306
+ },
4106
4307
  "strcat": {
4107
4308
  "full": "takes two packed strings and returns their concatenation (as a packed string)\n[S T] => [S+T]\n\n[\"foo\" \"\"] => [\"foo\"]\n[\"\" \"foo\"] => [\"foo\"]\n[\"foo\" \"bar\"] => [\"foobar\"]\n",
4108
4309
  "desc": "takes two packed strings and returns their concatenation (as a packed string)",
@@ -4314,6 +4515,49 @@
4314
4515
  ]
4315
4516
  ]
4316
4517
  },
4518
+ "strends?": {
4519
+ "full": "returns 1 if the string S ends with substring T, 0 otherwise\n[S T] => [0 | 1]\n\n[\"foobar\" \"bar\"] => [1]\n[\"foobar\" \"foo\"] => [0]\n[\"abc123\" \"abc\"] => [0]\n[\"foo \" \" \"] = [1]\n",
4520
+ "desc": "returns 1 if the string S ends with substring T, 0 otherwise",
4521
+ "effect": "[S T] => [0 | 1]",
4522
+ "cases": [
4523
+ [
4524
+ [
4525
+ 3943255767014,
4526
+ 1880290
4527
+ ],
4528
+ [
4529
+ 1
4530
+ ]
4531
+ ],
4532
+ [
4533
+ [
4534
+ 3943255767014,
4535
+ 1832934
4536
+ ],
4537
+ [
4538
+ 0
4539
+ ]
4540
+ ],
4541
+ [
4542
+ [
4543
+ 1765872824673,
4544
+ 1634657
4545
+ ],
4546
+ [
4547
+ 0
4548
+ ]
4549
+ ],
4550
+ [
4551
+ [
4552
+ 68941798,
4553
+ 32
4554
+ ],
4555
+ [
4556
+ 1
4557
+ ]
4558
+ ]
4559
+ ]
4560
+ },
4317
4561
  "strexpand": {
4318
4562
  "full": "expands the length-2 string S to contain the intervening ASCII characters\n[S] => [S']\n\n[\"CJ\"] => [\"CDEFGHIJ\"]\n[\"DA\"] => [\"DCBA\"]\n[\"af\"] => [\"abcdef\"]\n[\"09\"] => [\"0123456789\"]\n[\"90\"] => [\"9876543210\"]\n[\"(1\"] => [\"()*+,-./01\"]\n",
4319
4563
  "desc": "expands the length-2 string S to contain the intervening ASCII characters",
@@ -5035,6 +5279,14 @@
5035
5279
 
5036
5280
  ]
5037
5281
  },
5282
+ "aryheap": {
5283
+ "full": "stashes the array A in negative heap space starting at index I\n[A I] => []\n",
5284
+ "desc": "stashes the array A in negative heap space starting at index I",
5285
+ "effect": "[A I] => []",
5286
+ "cases": [
5287
+
5288
+ ]
5289
+ },
5038
5290
  "between?": {
5039
5291
  "full": "returns 1 if the number N is between A and B (inclusive), 0 otherwise\n[N A B]\n\n[5 0 10] => [1]\n[11 0 10] => [0]\n[4 0 4] => [1]\n[-1 0 4] => [0]\n[-5 -10 0] => [1]\n[3 4 2] => [0]\n",
5040
5292
  "desc": "returns 1 if the number N is between A and B (inclusive), 0 otherwise",
@@ -5315,7 +5567,7 @@
5315
5567
  ]
5316
5568
  ]
5317
5569
  },
5318
- "heap_seeking_missile": {
5570
+ "heap-seeking_missile": {
5319
5571
  "full": "Though extremely rare, it's possible that we know a particular value is\nstored in the heap at some key, just not which one. This subroutine takes\na value V to search for and a starting index I, and either returns the first\nkey associated with that value or loops forever. Probably don't touch.\n[V I]\n",
5320
5572
  "desc": "Though extremely rare, it's possible that we know a particular value is\nstored in the heap at some key, just not which one. This subroutine takes\na value V to search for and a starting index I, and either returns the first\nkey associated with that value or loops forever. Probably don't touch.",
5321
5573
  "effect": "[V I]",
@@ -5323,6 +5575,22 @@
5323
5575
 
5324
5576
  ]
5325
5577
  },
5578
+ "heapary": {
5579
+ "full": "restores the heaped array starting at index I\n[I] => [A]\n",
5580
+ "desc": "restores the heaped array starting at index I",
5581
+ "effect": "[I] => [A]",
5582
+ "cases": [
5583
+
5584
+ ]
5585
+ },
5586
+ "heapswap": {
5587
+ "full": "swaps the elements in the heap at indices I and J\n[I J] => []\n",
5588
+ "desc": "swaps the elements in the heap at indices I and J",
5589
+ "effect": "[I J] => []",
5590
+ "cases": [
5591
+
5592
+ ]
5593
+ },
5326
5594
  "hex2rgb": {
5327
5595
  "full": "converts the #RRGGBB (leading '#' optional) color string S to\nits individual RGB components as integers in the range 0-255\n[S] => [R G B]\n\n[\"#000000\"] => [0 0 0]\n[\"ffffff\"] => [255 255 255]\n[\"#102030\"] => [16 32 48]\n[\"c0ffee\"] => [192 255 238]\n",
5328
5596
  "desc": "converts the #RRGGBB (leading '#' optional) color string S to\nits individual RGB components as integers in the range 0-255",
@@ -5998,6 +6266,14 @@
5998
6266
  ]
5999
6267
  ]
6000
6268
  ]
6269
+ },
6270
+ "time": {
6271
+ "full": "returns the number of nanoseconds N since the Unix epoch\n[] => [N]\n",
6272
+ "desc": "returns the number of nanoseconds N since the Unix epoch",
6273
+ "effect": "[] => [N]",
6274
+ "cases": [
6275
+
6276
+ ]
6001
6277
  }
6002
6278
  }
6003
6279
  }
@@ -94,3 +94,17 @@ to_roman: push -2,0 store
94
94
  $_to_roman("X", 10) $_to_roman("IX", 9)
95
95
  $_to_roman("V", 5) $_to_roman("IV", 4)
96
96
  $_to_roman("I", 1) push 2 sub load ret
97
+
98
+ ; applies the ROT13 "cipher" to the string S
99
+ ; [S] => [S']
100
+ ;
101
+ ; ["gnat"] => ["tang"]
102
+ ; ["purely"] => ["cheryl"]
103
+ ; ["cat.PNG"] => ["png.CAT"]
104
+ ; ["Hello, world."] => ["Uryyb, jbeyq."]
105
+ ; ["a123z"] => ["n123m"]
106
+ ROT13:
107
+ push "AZ" :strexpand push "az" :strexpand :strcat
108
+ push "NZ" :strexpand push "AM" :strexpand
109
+ push "nz" :strexpand push "am" :strexpand
110
+ :strcat :strcat :strcat :strtrans ret
@@ -1,6 +1,7 @@
1
1
  import string ; strcat, strpack, strrev, strunpack
2
2
 
3
3
  ; prints the character at the top of the stack until terminating zero
4
+ ; [0 ... C] => []
4
5
  print: :strunpack
5
6
  _print_loop:
6
7
  dup jz _print_done
@@ -8,34 +9,35 @@ _print_loop:
8
9
  _print_done: pop ret
9
10
 
10
11
  ; print with newline
12
+ ; [0 ... C] => []
11
13
  println: :print push 10 ochr ret
12
14
 
13
- ;;;
14
-
15
15
  ; reads a line of input onto the top of the stack as a packed string
16
16
  ; ! clobbers heap address -1
17
+ ; [] => [L]
17
18
  getline: push 0 ; terminator for strpack
18
-
19
- ; read characters onto the stack until newline (10) or EOF (-1)
20
19
  _getline_loop:
21
20
  push -1 dup ichr load
22
21
  dup jn _getline_eof
23
22
  dup push 10 sub jz _getline_done
24
23
  jump _getline_loop
25
-
26
24
  _getline_eof: pop
27
25
  _getline_done: :strpack :strrev ret
28
26
 
29
- ;;;
30
-
27
+ ; displays the string S then reads a line of input
28
+ ; [S] => [L]
31
29
  prompt: :print :getline ret
32
30
 
33
- ;;;
34
-
35
- ; consume stdin until EOF
31
+ ; consume stdin until EOF into the string S
32
+ ; [] => [S]
36
33
  readall: push 0 ; accumulated string
37
34
  _readall_loop:
38
35
  :getline dup jz _readall_done
39
36
  :strcat jump _readall_loop
40
-
41
37
  _readall_done: pop ret
38
+
39
+ ; returns the contents C of the file at path P (a string)
40
+ ; NON-STANDARD! This function makes use of the `shell` instruction, which is
41
+ ; only(?) available in the Spiceweight Whitespace interpreter.
42
+ ; [P] => [C]
43
+ readfile: push "cat " swap :strcat shell ret
@@ -1,3 +1,4 @@
1
+ import array ; sorted?
1
2
  import math ; pow
2
3
  import string ; strtoa
3
4
 
@@ -32,3 +33,7 @@ _shuffle_loop:
32
33
  ; shuffles the characters of the string S, producing a random anagram
33
34
  ; [S] => [S']
34
35
  strfry: :strtoa :shuffle pop :strpack ret
36
+
37
+ ; sorts the array A if you're lucky
38
+ ; [A] => [A']
39
+ bogosort: :shuffle :arydup :sorted? jz bogosort ret
@@ -104,3 +104,14 @@ _ncopy_restore:
104
104
  dup push 9 add jz _ncopy_done
105
105
  dup load swap push 1 add jump _ncopy_restore
106
106
  _ncopy_done: pop ret
107
+
108
+ ; swaps the two arrays at the top of the stack
109
+ ; [A B] => [B A]
110
+ ;
111
+ ; [1 2 3 3 3 2 1 3] => [3 2 1 3 1 2 3 3]
112
+ ; [5 6 2 9 7 5 3 1 5] => [9 7 5 3 1 5 5 6 2]
113
+ ; [0 0 2 4 2 0 3] => [4 2 0 3 0 0 2]
114
+ ; [1 1 2 1] => [2 1 1 1]
115
+ swapary:
116
+ push -10 :aryheap push -11 @-9 sub :aryheap
117
+ push -10 :heapary push -11 @-9 sub :heapary ret
@@ -399,3 +399,25 @@ strtoa: dup :strlen pop :strunpack @-1 $++ ret
399
399
  ; ["foobar"] => ["LEEHKX"]
400
400
  ; ["LEEHKX"] => ["foobar"]
401
401
  memfrob: :strtoa map (push 42 :bxor) pop :strpack ret
402
+
403
+ ; returns 1 if the string S begins with substring T, 0 otherwise
404
+ ; [S T] => [0 | 1]
405
+ ;
406
+ ; ["foobar" "foo"] => [1]
407
+ ; ["foobar" "boo"] => [0]
408
+ ; ["abc123" "123"] => [0]
409
+ ; [" foo" " "] = [1]
410
+ strbegins?:
411
+ dup :strlen copy 2 swap push 0 swap
412
+ :strslice :eq slide 1 ret
413
+
414
+ ; returns 1 if the string S ends with substring T, 0 otherwise
415
+ ; [S T] => [0 | 1]
416
+ ;
417
+ ; ["foobar" "bar"] => [1]
418
+ ; ["foobar" "foo"] => [0]
419
+ ; ["abc123" "abc"] => [0]
420
+ ; ["foo " " "] = [1]
421
+ strends?:
422
+ :strrev dup :strlen copy 2 :strrev swap push 0 swap
423
+ :strslice :eq slide 1 ret
@@ -215,8 +215,8 @@ between?: copy 2 :gte swap copy 2 :lte mul slide 1 ret
215
215
  ; a value V to search for and a starting index I, and either returns the first
216
216
  ; key associated with that value or loops forever. Probably don't touch.
217
217
  ; [V I]
218
- heap_seeking_missile:
219
- $++ dup load copy 2 :eq jz heap_search
218
+ heap-seeking_missile:
219
+ $++ dup load copy 2 :eq jz heap-seeking_missile
220
220
  slide 1 ret
221
221
 
222
222
  ; converts the #RRGGBB (leading '#' optional) color string S to
@@ -246,3 +246,31 @@ rgb2hex:
246
246
  copy 2 push 256 mul add add
247
247
  slide 2 :to_hex push 6,48 :rjustc ret
248
248
  _rgb2hex_invalid: push "(rgb2hex) invalid RGB" :die!
249
+
250
+ ; stashes the array A in negative heap space starting at index I
251
+ ; [A I] => []
252
+ aryheap:
253
+ $++ dup copy 2 store
254
+ swap times ($-- swap copy 1 swap store) pop ret
255
+
256
+ ; restores the heaped array starting at index I
257
+ ; [I] => [A]
258
+ heapary:
259
+ $++ dup load swap copy 1 sub swap
260
+ times (dup load swap $++) load ret
261
+
262
+ ; swaps the elements in the heap at indices I and J
263
+ ; ! TODO: make heap effects doctest-able
264
+ ; [I J] => []
265
+ heapswap: dup load swap copy 2 load store store ret
266
+
267
+ ; returns the number of nanoseconds N since the Unix epoch
268
+ ; [] => [N]
269
+ time: push "date +%s%N" shell :to_i ret
270
+
271
+ $bench(insns) {
272
+ #insns :println
273
+ :time ^0 `insns` :time @0 sub
274
+ push 10,9 :pow :divmod swap onum
275
+ push '.' ochr :to_s push 9,48 :rjustc :println
276
+ }
@@ -148,11 +148,13 @@ module Spitewaste
148
148
  params, body = @macros[$1]
149
149
  raise "no macro function '#$1'" unless body
150
150
  map = parse[params].zip(parse[$2]).to_h
151
- body.gsub(/`(.+?)`/) { map[$1] }
151
+ body
152
+ .gsub(/`(.+?)`/) { map[$1] }
153
+ .gsub(/#(\S+)/) { "push #{Spitewaste.strpack map[$1]}" }
152
154
  }
153
155
 
154
156
  @src.gsub!(/(\$\S+)\s*=\s*(.+)/) { @macros[$1] ||= $2; '' }
155
- @src.gsub!(/(\$\S+)/) { @macros[$1] || raise("no macro '#$1'") }
157
+ @src.gsub!(/(\$[^)\s]+)/) { @macros[$1] || raise("no macro '#$1'") }
156
158
  end
157
159
 
158
160
  def eliminate_dead_code!
@@ -1,3 +1,3 @@
1
1
  module Spitewaste
2
- VERSION = '0.2.01'
2
+ VERSION = '0.2.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spitewaste
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.01
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Collided Scope (collidedscope)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-03 00:00:00.000000000 Z
11
+ date: 2021-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake