spitewaste 0.2.0 → 0.2.5

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: 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
  }