spitewaste 0.2.0 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8cd3201a4c8647de4fb29c8529c45fb379c2633cd660a4155e28720931202f94
4
- data.tar.gz: 3ba703110341a406d476aa8afa8d89c8a57b9d6e136f319956f28f7d311b16e7
3
+ metadata.gz: dd82c27931f053688f5ce4b0406bfb1a87448dd14be21deaaf75d6faf4c7353d
4
+ data.tar.gz: f08502018fb3474f708d2adbeac4df57db03a7a38d86d00c1a0ecd17182c8336
5
5
  SHA512:
6
- metadata.gz: d103c80be7025cca6d784127444702460394e4d0f137f124581212b6d92523b80c7e95e15642f9c0036b26545e821dcee206686818d0728dbe57c7b57a388ef0
7
- data.tar.gz: 39f473d86a4df1a125a6edae3ff1e29c5a069da2aa72862834097b7151bd11c4fdfe93f8119b60c7009468e4f5c2a05ef60a92d99a9b9198485f79c42411f33d
6
+ metadata.gz: 3cee6b9e82a342c672f5c4ecc8c3ca3820c160ddb286f22fd59ab35c5b74c961b856077798a7238ff2966c0477d31f54e48797fcff480b8fe7a3e081a37e91d0
7
+ data.tar.gz: 2b7c2e45a492defe0236641d26fe830e40a88983387caeda1490dd561ee73465d0ad915b57450aa00a776f5b2e1675aa698fb5a4a838c9d91a0afb44a905bc6b
data/Rakefile CHANGED
@@ -15,9 +15,8 @@ task :docs do |t|
15
15
 
16
16
  Dir.chdir('lib/spitewaste/libspw') do |d|
17
17
  Dir['*.spw'].sort.each do |path|
18
- next if path['random']
19
- lib = File.basename path, '.spw'
20
- docs[lib] = extract_docs path
18
+ mod = File.basename path, '.spw'
19
+ docs[mod] = extract_docs path
21
20
  end
22
21
 
23
22
  File.open('docs.json', ?w) { |f|
data/bin/spw CHANGED
@@ -7,5 +7,6 @@ require 'spitewaste/cli/exec'
7
7
  require 'spitewaste/cli/compile'
8
8
  require 'spitewaste/cli/convert'
9
9
  require 'spitewaste/cli/image'
10
+ require 'spitewaste/cli/version'
10
11
 
11
12
  SpitewasteCLI.start ARGV
data/lib/spitewaste.rb CHANGED
@@ -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'
@@ -85,7 +85,7 @@ module Spitewaste
85
85
  @ip = 0
86
86
  while @instructions[@ip]
87
87
  next @ip -= 1 if optimize_constant_pow
88
- next if optimize_constant_strpack
88
+ # next if optimize_constant_strpack
89
89
  @ip += 1
90
90
  end
91
91
  end
@@ -0,0 +1,9 @@
1
+ require 'spitewaste/version'
2
+
3
+ class SpitewasteCLI
4
+ desc 'version', 'Display the current version of Spitewaste and exit.'
5
+
6
+ def version
7
+ puts "spw version #{Spitewaste::VERSION}"
8
+ end
9
+ end
@@ -4,7 +4,8 @@ require 'yaml'
4
4
 
5
5
  module Spitewaste
6
6
  class ImageEmitter < Emitter
7
- SCHEMES = YAML.load_file(File.join __dir__, 'schemes.yaml')['schemes']
7
+ schemes = File.read File.join __dir__, 'schemes.yaml'
8
+ SCHEMES = YAML.safe_load(schemes, aliases: true)['schemes']
8
9
  LINEFEED = ChunkyPNG::Image.from_file File.join __dir__, 'linefeed.png'
9
10
  DEFAULTS = {
10
11
  colors: 'gruvbox_dark',
@@ -112,7 +113,7 @@ module Spitewaste
112
113
  flow: %i[jump jz jn ret exit],
113
114
  math: %i[add sub mul div mod],
114
115
  heap: %i[store load],
115
- io: %i[ichr inum ochr onum],
116
+ io: %i[ichr inum ochr onum shell],
116
117
  calls: %i[call label]
117
118
  }.flat_map { |type, insns| insns.map { |i| [i, type] } }.to_h
118
119
 
@@ -599,6 +599,52 @@ schemes:
599
599
  cyan: '0x99faf2'
600
600
  white: '0xffffff'
601
601
 
602
+ konsole_linux: &konsole_linux
603
+ primary:
604
+ foreground: '0xe3e3e3'
605
+ bright_foreground: '0xffffff'
606
+ dim_foreground: '0xe3e3e3'
607
+ background: '0x1f1f1f'
608
+ bright_background: '0x686868' # not sure
609
+ dim_background: '0x1f1f1f' # not sure
610
+ cursor:
611
+ text: '0x191622'
612
+ cursor: '0xf8f8f2'
613
+ search:
614
+ matches:
615
+ foreground: '0xb2b2b2'
616
+ background: '0xb26818'
617
+ focused_match:
618
+ foreground: CellBackground
619
+ background: CellForeground
620
+ normal:
621
+ black: '0x000000'
622
+ red: '0xb21818'
623
+ green: '0x18b218'
624
+ yellow: '0xb26818'
625
+ blue: '0x1818b2'
626
+ magenta: '0xb218b2'
627
+ cyan: '0x18b2b2'
628
+ white: '0xb2b2b2'
629
+ bright:
630
+ black: '0x686868'
631
+ red: '0xff5454'
632
+ green: '0x54ff54'
633
+ yellow: '0xffff54'
634
+ blue: '0x5454ff'
635
+ magenta: '0xff54ff'
636
+ cyan: '0x54ffff'
637
+ white: '0xffffff'
638
+ dim:
639
+ black: '0x000000'
640
+ red: '0xb21818'
641
+ green: '0x18b218'
642
+ yellow: '0xb26818'
643
+ blue: '0x1818b2'
644
+ magenta: '0xb218b2'
645
+ cyan: '0x18b2b2'
646
+ white: '0xb2b2b2'
647
+
602
648
  low_contrast: &low_contrast
603
649
  primary:
604
650
  background: '0x333333'
@@ -717,6 +763,41 @@ schemes:
717
763
  cyan: '0x5fb3b3'
718
764
  white: '0xadb5c0'
719
765
 
766
+ omni: &omni
767
+ primary:
768
+ background: '0x191622'
769
+ foreground: '0xe1e1e6'
770
+ cursor:
771
+ text: '0x191622'
772
+ cursor: '0xf8f8f2'
773
+ normal:
774
+ black: '0x000000'
775
+ red: '0xff5555'
776
+ green: '0x50fa7b'
777
+ yellow: '0xeffa78'
778
+ blue: '0xbd93f9'
779
+ magenta: '0xff79c6'
780
+ cyan: '0x8d79ba'
781
+ white: '0xbfbfbf'
782
+ bright:
783
+ black: '0x4d4d4d'
784
+ red: '0xff6e67'
785
+ green: '0x5af78e'
786
+ yellow: '0xeaf08d'
787
+ blue: '0xcaa9fa'
788
+ magenta: '0xff92d0'
789
+ cyan: '0xaa91e3'
790
+ white: '0xe6e6e6'
791
+ dim:
792
+ black: '0x000000'
793
+ red: '0xa90000'
794
+ green: '0x049f2b'
795
+ yellow: '0xa3b106'
796
+ blue: '0x530aba'
797
+ magenta: '0xbb006b'
798
+ cyan: '0x433364'
799
+ white: '0x5f5f5f'
800
+
720
801
  one_dark: &one_dark
721
802
  primary:
722
803
  background: '0x1e2127'
@@ -740,6 +821,29 @@ schemes:
740
821
  cyan: '0x56b6c2'
741
822
  white: '0xffffff'
742
823
 
824
+ palenight: &palenight
825
+ primary:
826
+ background: '0x292d3e'
827
+ foreground: '0xd0d0d0'
828
+ normal:
829
+ black: '0x292d3e'
830
+ red: '0xf07178'
831
+ green: '0xc3e88d'
832
+ yellow: '0xffcb6b'
833
+ blue: '0x82aaff'
834
+ magenta: '0xc792ea'
835
+ cyan: '0x89ddff'
836
+ white: '0xd0d0d0'
837
+ bright:
838
+ black: '0x434758'
839
+ red: '0xff8b92'
840
+ green: '0xddffa7'
841
+ yellow: '0xffe585'
842
+ blue: '0x9cc4ff'
843
+ magenta: '0xe1acff'
844
+ cyan: '0xa3f7ff'
845
+ white: '0xffffff'
846
+
743
847
  papercolor_light: &papercolor_light
744
848
  primary:
745
849
  background: '0xeeeeee'
@@ -812,6 +916,29 @@ schemes:
812
916
  cyan: '0x4fb8cc'
813
917
  white: '0xf1f1f1'
814
918
 
919
+ remedy_dark: &remedy_dark
920
+ primary:
921
+ background: '0x2c2b2a'
922
+ foreground: '0xf9e7c4'
923
+ normal:
924
+ black: '0x282a2e'
925
+ blue: '0x5f819d'
926
+ cyan: '0x5e8d87'
927
+ green: '0x8c9440'
928
+ magenta: '0x85678f'
929
+ red: '0xa54242'
930
+ white: '0x707880'
931
+ yellow: '0xde935f'
932
+ bright:
933
+ black: '0x373b41'
934
+ blue: '0x81a2be'
935
+ cyan: '0x8abeb7'
936
+ green: '0xb5bd68'
937
+ magenta: '0xb294bb'
938
+ red: '0xcc6666'
939
+ white: '0xc5c8c6'
940
+ yellow: '0xf0c674'
941
+
815
942
  snazzy: &snazzy
816
943
  primary:
817
944
  background: '0x282a36'
@@ -10,6 +10,12 @@ import util ; dec, die!, eq
10
10
 
11
11
  $amax = 1000
12
12
 
13
+ ; prints the array A to stdout in the form [e1,e2,...]
14
+ ; [A] => []
15
+ aryprint:
16
+ map (:to_s) push ',' :strjoinc
17
+ push '[' ochr :print push ']' ochr ret
18
+
13
19
  ; places an array of N elements E at the top of the stack
14
20
  ; [N E] => [A]
15
21
  ;
@@ -36,7 +42,23 @@ arysum: reduce (add) ret
36
42
  ; [7 50 10 2] => [7 50 10 2 50 10 2]
37
43
  arydup:
38
44
  dup $++ push -2 copy 1 store
39
- times (push -2 load $-- :ncopy) ret
45
+ times (@-2 $-- :ncopy) ret
46
+
47
+ ; returns 1 if the arrays A1 and A2 have the same length and
48
+ ; contain the same elements in the same order, 0 otherwise
49
+ ; [A1 A2] => [0 | 1]
50
+ ;
51
+ ; [1 2 3 3 1 2 3 3] => [1]
52
+ ; [1 2 3 3 3 2 1 3] => [0]
53
+ ; [1 2 2 1 2 3 3] => [0]
54
+ ; [1 2 3 3 1 2 2] => [0]
55
+ ; [7 10 2 7 10 2] => [1]
56
+ ; [6 1 9 1] => [0]
57
+ aryeq: dup $++ :roll copy 1 copy 1 :eq jz _aryeq_difflen ; length mismatch
58
+ ^-1 times (@-1 :ncopy :eq jz _aryeq_no)
59
+ push 1 @-1 :nslide ret
60
+ _aryeq_no: push 0 @-1 @-5 sub $-- :nslide ret ; ! -5 is magic from times()
61
+ _aryeq_difflen: add push 0 swap :nslide ret
40
62
 
41
63
  ; places the element E at the end of the array A, increasing its length by 1
42
64
  ; [A E] => [A']
@@ -99,15 +121,15 @@ arycat: dup $++ :roll add ret
99
121
  ;;;
100
122
 
101
123
  arypack:
102
- :arydup reduce (:max) $++ push -1 swap store
103
- $-- times (push -1 load mul add)
104
- push $amax mul push -1 load add
105
- push $amax mul push -10 load add ret
124
+ :arydup reduce (:max) $++ ^-1
125
+ $-- times (@-1 mul add)
126
+ push $amax mul @-1 add
127
+ push $amax mul @-10 add ret
106
128
 
107
129
  aryunpack:
108
- push $amax :divmod push -2 swap store
109
- push $amax :divmod push -1 swap store
110
- push -2 load times (push -1 load :divmod swap)
130
+ push $amax :divmod ^-2
131
+ push $amax :divmod ^-1
132
+ @-2 times (@-1 :divmod swap)
111
133
  push 2 sub load ret
112
134
 
113
135
  arylen: push $amax mod ret
@@ -161,8 +183,8 @@ _aryswap_noop: pop pop ret
161
183
  ; [6 8 -3 4 0 5] => [-3 8]
162
184
  ; [7 1] => [7 7]
163
185
  minmax:
164
- :arydup reduce (:max) push -1 swap store
165
- reduce (:min) push -1 load ret
186
+ :arydup reduce (:max) ^-1
187
+ reduce (:min) @-1 ret
166
188
 
167
189
  ;;; TODO: make sort not atrociously inefficient
168
190
 
@@ -170,22 +192,37 @@ sort: push -3 copy 1 store ; preserve length
170
192
  _sort_loop:
171
193
  :arydup reduce (:min)
172
194
  push -1 copy 1 store copy 1 $++ :bury ; stash minimum element
173
- :arydup push -1 load :aryindex
195
+ :arydup @-1 :aryindex
174
196
  copy 1 swap sub :dig $-- ; remove minimum element from array
175
197
  push 0 copy 1 sub jn _sort_loop
176
198
  push 3 sub load ret
177
199
 
200
+ ; returns 0 if any of the elements in array A is
201
+ ; strictly less than the one before it, 1 otherwise
202
+ ; [A] => [0 | 1]
203
+ ;
204
+ ; [1 2 3 3] => [1]
205
+ ; [3 2 1 3] => [0]
206
+ ; [1 1 2 2 4] => [1]
207
+ ; [1 2 3 4 3 5] => [0]
208
+ sorted?: $--
209
+ _sorted_loop:
210
+ copy 1 copy 3 sub jn _sorted_no
211
+ $-- dup jz _sorted_yes
212
+ slide 1 jump _sorted_loop
213
+ _sorted_no: $++ push 0 swap :nslide ret
214
+ _sorted_yes: push 1 slide 3 ret
215
+
178
216
  ; reverses the array A
179
217
  ; [A] => [A']
180
218
  ;
181
219
  ; [1 2 3 3] => [3 2 1 3]
182
220
  ; [7 1] => [7 1]
183
221
  ; [5 4 3 2 1 5] => [1 2 3 4 5 5]
184
- aryrev: push -3 copy 1 store
185
- _aryrev_loop:
186
- swap copy 1 :bury $--
187
- push 0 copy 1 sub jn _aryrev_loop
188
- push 3 sub load ret
222
+ aryrev:
223
+ push -10 :aryheap push -10
224
+ @-9 times (dup load swap $--)
225
+ pop @-9 ret
189
226
 
190
227
  ; returns the array A replicated N times
191
228
  ; ! N must be greater than 1
@@ -196,4 +233,4 @@ aryrep: push -1 swap push -3 copy 1 store store
196
233
  _aryrep_loop:
197
234
  push -1 dup :dec load jz _aryrep_done
198
235
  :arydup jump _aryrep_loop
199
- _aryrep_done: push -3 load $-- times (:arycat) ret
236
+ _aryrep_done: @-3 $-- times (:arycat) ret
@@ -12,8 +12,8 @@ $bitfun(op, bit, done) {
12
12
  push -2,1,-1,0 store store
13
13
  _`op`_loop: push -1
14
14
  copy 2 push 2 mod copy 2 push 2 mod `bit`
15
- push -1 load swap push -2 load dup push 2 mul
16
- push -2 swap store mul add store
15
+ @-1 swap @-2 dup push 2 mul
16
+ ^-2 mul add store
17
17
  push 2 div swap push 2 div
18
18
  dup copy 2 mul jz _`op`_done swap jump _`op`_loop
19
19
  _`op`_done: `done` ret
@@ -35,7 +35,7 @@ band: $bitfun(band, mul, mul $-- load)
35
35
  ; [61 77] => [125] [93 65] => [93]
36
36
  ; [14 87] => [95] [71 37] => [103]
37
37
  ; [7 19] => [23] [38 92] => [126]
38
- bor: $bitfun(bor, add $++ push 2 div, add push -2 load mul push -1 load add)
38
+ bor: $bitfun(bor, add $++ push 2 div, add @-2 mul @-1 add)
39
39
 
40
40
  ; returns the bitwise XOR of A and B
41
41
  ; [A B] => [A ^ B]
@@ -44,7 +44,7 @@ bor: $bitfun(bor, add $++ push 2 div, add push -2 load mul push -1 load add)
44
44
  ; [51 5] => [54] [97 77] => [44]
45
45
  ; [39 65] => [102] [12 26] => [22]
46
46
  ; [44 36] => [8] [6 21] => [19]
47
- bxor: $bitfun(bxor, :neq, add push -2 load mul push -1 load add)
47
+ bxor: $bitfun(bxor, :neq, add @-2 mul @-1 add)
48
48
 
49
49
  ; returns the infinite-precision bitwise NOT of N by inverting all of its bits
50
50
  ; [N] => [~N]
@@ -135,6 +135,95 @@
135
135
  ]
136
136
  ]
137
137
  },
138
+ "aryeq": {
139
+ "full": "returns 1 if the arrays A1 and A2 have the same length and\ncontain the same elements in the same order, 0 otherwise\n[A1 A2] => [0 | 1]\n\n[1 2 3 3 1 2 3 3] => [1]\n[1 2 3 3 3 2 1 3] => [0]\n[1 2 2 1 2 3 3] => [0]\n[1 2 3 3 1 2 2] => [0]\n[7 10 2 7 10 2] => [1]\n[6 1 9 1] => [0]\n",
140
+ "desc": "returns 1 if the arrays A1 and A2 have the same length and\ncontain the same elements in the same order, 0 otherwise",
141
+ "effect": "[A1 A2] => [0 | 1]",
142
+ "cases": [
143
+ [
144
+ [
145
+ 1,
146
+ 2,
147
+ 3,
148
+ 3,
149
+ 1,
150
+ 2,
151
+ 3,
152
+ 3
153
+ ],
154
+ [
155
+ 1
156
+ ]
157
+ ],
158
+ [
159
+ [
160
+ 1,
161
+ 2,
162
+ 3,
163
+ 3,
164
+ 3,
165
+ 2,
166
+ 1,
167
+ 3
168
+ ],
169
+ [
170
+ 0
171
+ ]
172
+ ],
173
+ [
174
+ [
175
+ 1,
176
+ 2,
177
+ 2,
178
+ 1,
179
+ 2,
180
+ 3,
181
+ 3
182
+ ],
183
+ [
184
+ 0
185
+ ]
186
+ ],
187
+ [
188
+ [
189
+ 1,
190
+ 2,
191
+ 3,
192
+ 3,
193
+ 1,
194
+ 2,
195
+ 2
196
+ ],
197
+ [
198
+ 0
199
+ ]
200
+ ],
201
+ [
202
+ [
203
+ 7,
204
+ 10,
205
+ 2,
206
+ 7,
207
+ 10,
208
+ 2
209
+ ],
210
+ [
211
+ 1
212
+ ]
213
+ ],
214
+ [
215
+ [
216
+ 6,
217
+ 1,
218
+ 9,
219
+ 1
220
+ ],
221
+ [
222
+ 0
223
+ ]
224
+ ]
225
+ ]
226
+ },
138
227
  "aryfill": {
139
228
  "full": "places an array of N elements E at the top of the stack\n[N E] => [A]\n\n[3 0] => [0 0 0 3]\n[5 1] => [1 1 1 1 1 5]\n[4 -2] => [-2 -2 -2 -2 4]\n",
140
229
  "desc": "places an array of N elements E at the top of the stack",
@@ -338,6 +427,14 @@
338
427
  ]
339
428
  ]
340
429
  },
430
+ "aryprint": {
431
+ "full": "prints the array A to stdout in the form [e1,e2,...]\n[A] => []\n",
432
+ "desc": "prints the array A to stdout in the form [e1,e2,...]",
433
+ "effect": "[A] => []",
434
+ "cases": [
435
+
436
+ ]
437
+ },
341
438
  "arypush": {
342
439
  "full": "places the element E at the end of the array A, increasing its length by 1\n[A E] => [A']\n\n[3 2 1 3 7] => [3 2 1 7 4]\n[4 2 2 0] => [4 2 0 3]\n[6 1 9] => [6 9 2]\n[7 5 8 2 4] => [7 5 8 4 3]\n",
343
440
  "desc": "places the element E at the end of the array A, increasing its length by 1",
@@ -794,6 +891,60 @@
794
891
  ]
795
892
  ]
796
893
  ]
894
+ },
895
+ "sorted?": {
896
+ "full": "returns 0 if any of the elements in array A is\nstrictly less than the one before it, 1 otherwise\n[A] => [0 | 1]\n\n[1 2 3 3] => [1]\n[3 2 1 3] => [0]\n[1 1 2 2 4] => [1]\n[1 2 3 4 3 5] => [0]\n",
897
+ "desc": "returns 0 if any of the elements in array A is\nstrictly less than the one before it, 1 otherwise",
898
+ "effect": "[A] => [0 | 1]",
899
+ "cases": [
900
+ [
901
+ [
902
+ 1,
903
+ 2,
904
+ 3,
905
+ 3
906
+ ],
907
+ [
908
+ 1
909
+ ]
910
+ ],
911
+ [
912
+ [
913
+ 3,
914
+ 2,
915
+ 1,
916
+ 3
917
+ ],
918
+ [
919
+ 0
920
+ ]
921
+ ],
922
+ [
923
+ [
924
+ 1,
925
+ 1,
926
+ 2,
927
+ 2,
928
+ 4
929
+ ],
930
+ [
931
+ 1
932
+ ]
933
+ ],
934
+ [
935
+ [
936
+ 1,
937
+ 2,
938
+ 3,
939
+ 4,
940
+ 3,
941
+ 5
942
+ ],
943
+ [
944
+ 0
945
+ ]
946
+ ]
947
+ ]
797
948
  }
798
949
  },
799
950
  "bits": {
@@ -1304,6 +1455,53 @@
1304
1455
  }
1305
1456
  },
1306
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
+ },
1307
1505
  "anagrams?": {
1308
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",
1309
1507
  "desc": "returns whether the strings S and T are composed of the same characters",
@@ -1405,6 +1603,45 @@
1405
1603
  ]
1406
1604
  ]
1407
1605
  },
1606
+ "collatz_len": {
1607
+ "full": "returns the length L of the Collatz sequence for integer N\n[N] => [L]\n\n[1] => [1]\n[4] => [3]\n[7] => [17]\n[189] => [107]\n",
1608
+ "desc": "returns the length L of the Collatz sequence for integer N",
1609
+ "effect": "[N] => [L]",
1610
+ "cases": [
1611
+ [
1612
+ [
1613
+ 1
1614
+ ],
1615
+ [
1616
+ 1
1617
+ ]
1618
+ ],
1619
+ [
1620
+ [
1621
+ 4
1622
+ ],
1623
+ [
1624
+ 3
1625
+ ]
1626
+ ],
1627
+ [
1628
+ [
1629
+ 7
1630
+ ],
1631
+ [
1632
+ 17
1633
+ ]
1634
+ ],
1635
+ [
1636
+ [
1637
+ 189
1638
+ ],
1639
+ [
1640
+ 107
1641
+ ]
1642
+ ]
1643
+ ]
1644
+ },
1408
1645
  "isop": {
1409
1646
  "full": "returns the sum of the alphabetical characters in string S where A=1, B=2...\n[S] => [sum]\n\n[\"Math\"] => [42]\n[\"wizards\"] => [100]\n[\"AbCd\"] => [10]\n",
1410
1647
  "desc": "returns the sum of the alphabetical characters in string S where A=1, B=2...",
@@ -1509,33 +1746,49 @@
1509
1746
  },
1510
1747
  "io": {
1511
1748
  "getline": {
1512
- "full": "reads a line of input onto the top of the stack as a packed string\n",
1513
- "desc": "",
1514
- "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]",
1515
1752
  "cases": [
1516
1753
 
1517
1754
  ]
1518
1755
  },
1519
1756
  "print": {
1520
- "full": "prints the character at the top of the stack until terminating zero\n",
1521
- "desc": "",
1522
- "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] => []",
1523
1760
  "cases": [
1524
1761
 
1525
1762
  ]
1526
1763
  },
1527
1764
  "println": {
1528
- "full": "print with newline\n",
1529
- "desc": "",
1530
- "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]",
1531
1776
  "cases": [
1532
1777
 
1533
1778
  ]
1534
1779
  },
1535
1780
  "readall": {
1536
- "full": "consume stdin until EOF\n",
1537
- "desc": "",
1538
- "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]",
1539
1792
  "cases": [
1540
1793
 
1541
1794
  ]
@@ -2373,6 +2626,64 @@
2373
2626
  ]
2374
2627
  }
2375
2628
  },
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
+ },
2638
+ "dice": {
2639
+ "full": "returns an array A of N random integers between 1 and D (inclusive)\n[N D] => [A]\n",
2640
+ "desc": "returns an array A of N random integers between 1 and D (inclusive)",
2641
+ "effect": "[N D] => [A]",
2642
+ "cases": [
2643
+
2644
+ ]
2645
+ },
2646
+ "rand": {
2647
+ "full": "returns the next number N in the linear congruential generator (better MINSTD)\n[] => [N]\n",
2648
+ "desc": "returns the next number N in the linear congruential generator (better MINSTD)",
2649
+ "effect": "[] => [N]",
2650
+ "cases": [
2651
+
2652
+ ]
2653
+ },
2654
+ "rand_range": {
2655
+ "full": "returns a random integer I between A and B (inclusive)\n[A B] => [I]\n",
2656
+ "desc": "returns a random integer I between A and B (inclusive)",
2657
+ "effect": "[A B] => [I]",
2658
+ "cases": [
2659
+
2660
+ ]
2661
+ },
2662
+ "shuffle": {
2663
+ "full": "shuffles the array A in-place using the modern Fisher-Yates algorithm\n[A] => [A']\n",
2664
+ "desc": "shuffles the array A in-place using the modern Fisher-Yates algorithm",
2665
+ "effect": "[A] => [A']",
2666
+ "cases": [
2667
+
2668
+ ]
2669
+ },
2670
+ "srand": {
2671
+ "full": "seeds the random number generator with integer S\n[S] => []\n",
2672
+ "desc": "seeds the random number generator with integer S",
2673
+ "effect": "[S] => []",
2674
+ "cases": [
2675
+
2676
+ ]
2677
+ },
2678
+ "strfry": {
2679
+ "full": "shuffles the characters of the string S, producing a random anagram\n[S] => [S']\n",
2680
+ "desc": "shuffles the characters of the string S, producing a random anagram",
2681
+ "effect": "[S] => [S']",
2682
+ "cases": [
2683
+
2684
+ ]
2685
+ }
2686
+ },
2376
2687
  "rational": {
2377
2688
  "from_r": {
2378
2689
  "full": "decomposes the rational number R into its numerator N and denominator D\n[R] => [N D]\n\n[R(22,7)] => [22 7]\n[R(-3,4)] => [-3 4]\n[R(3,-4)] => [-3 4]\n[R(4,8)] => [4 8] ; no implicit simplification\n",
@@ -3428,6 +3739,93 @@
3428
3739
  ]
3429
3740
  ]
3430
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
+ },
3431
3829
  "to_a": {
3432
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",
3433
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.",
@@ -3863,6 +4261,49 @@
3863
4261
  ]
3864
4262
  ]
3865
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
+ },
3866
4307
  "strcat": {
3867
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",
3868
4309
  "desc": "takes two packed strings and returns their concatenation (as a packed string)",
@@ -4074,6 +4515,49 @@
4074
4515
  ]
4075
4516
  ]
4076
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
+ },
4077
4561
  "strexpand": {
4078
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",
4079
4563
  "desc": "expands the length-2 string S to contain the intervening ASCII characters",
@@ -4686,6 +5170,25 @@
4686
5170
  ]
4687
5171
  ]
4688
5172
  },
5173
+ "strtoa": {
5174
+ "full": "gets the characters of the string S onto the stack as a pseudo-array, but\nwith a leading 0 on the assumption that it'll eventually be repacked\n\n[\"abc\"] => [0 99 98 97 3]\n",
5175
+ "desc": "gets the characters of the string S onto the stack as a pseudo-array, but",
5176
+ "effect": "with a leading 0 on the assumption that it'll eventually be repacked",
5177
+ "cases": [
5178
+ [
5179
+ [
5180
+ 1634657
5181
+ ],
5182
+ [
5183
+ 0,
5184
+ 99,
5185
+ 98,
5186
+ 97,
5187
+ 3
5188
+ ]
5189
+ ]
5190
+ ]
5191
+ },
4689
5192
  "strtrans": {
4690
5193
  "full": "translates all characters in A to the corresponding characters in B\nin string S, ; similar to the `tr` utility in Unix. A and B must be\nof the same length. TODO: make this smarter (ranges, length mismatch)\n[S A B] => [S']\n\n[\"abcd\" \"abc\" \"xyz\"] => [\"xyzd\"]\n[\"foobar\" \"oba\" \"ele\"] => [\"feeler\"]\n[\"abcdcba\" \"abcd\" \"xyz|\"] => [\"xyz|zyx\"]\n",
4691
5194
  "desc": "translates all characters in A to the corresponding characters in B\nin string S, ; similar to the `tr` utility in Unix. A and B must be\nof the same length. TODO: make this smarter (ranges, length mismatch)",
@@ -4776,6 +5279,14 @@
4776
5279
 
4777
5280
  ]
4778
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
+ },
4779
5290
  "between?": {
4780
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",
4781
5292
  "desc": "returns 1 if the number N is between A and B (inclusive), 0 otherwise",
@@ -4852,9 +5363,9 @@
4852
5363
  ]
4853
5364
  },
4854
5365
  "die!": {
4855
- "full": "prints the string at the top of the stack and halts execution\n",
4856
- "desc": "",
4857
- "effect": "prints the string at the top of the stack and halts execution",
5366
+ "full": "prints the string at the top of the stack and halts execution after pushing\nsomething onto the stack to signal abnormal termination/unclean exit\n[...] => [... 1]\n",
5367
+ "desc": "prints the string at the top of the stack and halts execution after pushing\nsomething onto the stack to signal abnormal termination/unclean exit",
5368
+ "effect": "[...] => [... 1]",
4858
5369
  "cases": [
4859
5370
 
4860
5371
  ]
@@ -5056,7 +5567,7 @@
5056
5567
  ]
5057
5568
  ]
5058
5569
  },
5059
- "heap_seeking_missile": {
5570
+ "heap-seeking_missile": {
5060
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",
5061
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.",
5062
5573
  "effect": "[V I]",
@@ -5064,6 +5575,22 @@
5064
5575
 
5065
5576
  ]
5066
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
+ },
5067
5594
  "hex2rgb": {
5068
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",
5069
5596
  "desc": "converts the #RRGGBB (leading '#' optional) color string S to\nits individual RGB components as integers in the range 0-255",
@@ -5739,6 +6266,14 @@
5739
6266
  ]
5740
6267
  ]
5741
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
+ ]
5742
6277
  }
5743
6278
  }
5744
6279
  }