spitewaste 0.1.010 → 0.1.011

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.
@@ -56,3 +56,24 @@ _collatz_done: pop ret
56
56
 
57
57
  ; ruby:
58
58
  ; push "'" :strcat push "ruby -e 'p " swap :strcat shell ret
59
+
60
+ $_to_roman(r, v) {
61
+ push `v` :divmod swap push `r` swap :strrep
62
+ push -2 load swap :strcat push -2 swap store
63
+ }
64
+
65
+ ; converts the number N to a string of roman numerals R
66
+ ; [N] => [R]
67
+ ;
68
+ ; [2020] => ["MMXX"]
69
+ ; [1666] => ["MDCLXVI"]
70
+ ; [1337] => ["MCCCXXXVII"]
71
+ ; [94] => ["XCIV"]
72
+ to_roman: push -2,0 store
73
+ $_to_roman("M", 1000) $_to_roman("CM", 900)
74
+ $_to_roman("D", 500) $_to_roman("CD", 400)
75
+ $_to_roman("C", 100) $_to_roman("XC", 90)
76
+ $_to_roman("L", 50) $_to_roman("XL", 40)
77
+ $_to_roman("X", 10) $_to_roman("IX", 9)
78
+ $_to_roman("V", 5) $_to_roman("IV", 4)
79
+ $_to_roman("I", 1) push 2 sub load ret
@@ -10,3 +10,7 @@ rand:
10
10
 
11
11
  rand_range: ; [a b]
12
12
  copy 1 sub :rand swap mod add ret
13
+
14
+ dice:
15
+ push -2 swap store push 1 :aryfill
16
+ map (push -2 load :rand_range) ret
@@ -293,7 +293,7 @@ strcount:
293
293
  reduce (add) ret
294
294
 
295
295
  ; translates all characters in A to the corresponding characters in B
296
- ; in stirng S, ; similar to the `tr` utility in Unix. A and B must be
296
+ ; in string S, ; similar to the `tr` utility in Unix. A and B must be
297
297
  ; of the same length. TODO: make this smarter (ranges, length mismatch)
298
298
  ; ! clobbers heap addresses -1, -2, and -3
299
299
  ; [S A B] => [S']
@@ -343,6 +343,25 @@ _strsqueeze_loop: ; [s]
343
343
  _strsqueeze_skip: pop jump _strsqueeze_loop
344
344
  _strsqueeze_done: pop :strpack :strrev ret
345
345
 
346
+ $_strdel(cmp) {
347
+ :strunpack push -1 load :strlen
348
+ select (push -2 load swap :strindex `cmp`)
349
+ pop :strpack ret
350
+ }
351
+
352
+ ; returns the string S with all characters in string T removed, like `tr -d`.
353
+ ; If the first character of T is '^', instead only those characters are kept.
354
+ ; [S T] => [S']
355
+ ;
356
+ ; ["abc123" "abc"] => ["123"]
357
+ ; ["abc123" "123"] => ["abc"]
358
+ ; ["abcba12321" "abc"] => ["12321"]
359
+ ; ["abc12321cba" "^2ac"] => ["ac22ca"]
360
+ ; ["facetious" "^aeiou"] => ["aeiou"]
361
+ strdel: push -1 copy 2 store push -2 copy 1 store
362
+ push 0 :charat push '^' :neq jz _strdel_comp $_strdel(:neg?)
363
+ _strdel_comp: $_strdel(:pos?)
364
+
346
365
  ; returns the sum of the ordinal values of the characters in string S
347
366
  ; [S] => [N]
348
367
  ;
@@ -0,0 +1,14 @@
1
+ ;;; Miscellaneous terminal-based functionality
2
+
3
+ import util ; hex2rgb
4
+
5
+ $_setg(code) {
6
+ push 91,27 ochr ochr
7
+ push `code` onum push 50,59 ochr ochr
8
+ :hex2rgb each (push 59 ochr onum)
9
+ push 109 ochr ret
10
+ }
11
+
12
+ setfg: $_setg(38)
13
+ setbg: $_setg(48)
14
+ reset: push 109,91,27 ochr ochr ochr ret
@@ -15,22 +15,24 @@ import string ; charat, strcat, strindex, strlen
15
15
  ; [0 -2] => [0 -1 -2]
16
16
  ; [-3 3] => [-3 -2 -1 0 1 2 3]
17
17
  ; [3 -3] => [3 2 1 0 -1 -2 -3]
18
- ; [4 4] => [4 5] TODO: bug
19
- range: dup copy 2 sub jn _range_down
18
+ ; [4 4] => [4]
19
+ range: dup copy 2 sub jz _range_one dup copy 2 sub jn _range_down
20
20
  copy 1 push 1 add swap
21
21
  copy 1 copy 1 sub jn range pop ret
22
+ _range_one: pop ret
22
23
  _range_down:
23
24
  copy 1 push 1 sub swap
24
25
  dup copy 2 sub jn _range_down pop ret
25
26
 
26
27
  $range_loop(fn, cmp) {
27
28
  `fn`:
28
- copy 1 copy 1 add swap dup
29
- copy 2 add push -1 load `cmp` jz `fn` pop ret
29
+ dup copy 2 add push -1 load `cmp` jz _`fn`_done
30
+ copy 1 copy 1 add swap jump `fn`
31
+ _`fn`_done: pop ret
30
32
  }
31
33
 
32
- ; inserts between the top two stack values the intervening consecutive elements,
33
- ; counting by `step` up/down to (but never beyond) J
34
+ ; inserts between I and J the intervening consecutive elements, counting by
35
+ ; step S up/down to (but never beyond) J
34
36
  ; [I J S] => [I I±S ... ~J]
35
37
  ;
36
38
  ; [1 4 1] => [1 2 3 4]
@@ -41,10 +43,12 @@ $range_loop(fn, cmp) {
41
43
  ; [25 -5 -10] => [25 15 5 -5]
42
44
  ; [4 20 3] => [4 7 10 13 16 19]
43
45
  ; [20 4 -3] => [20 17 14 11 8 5]
46
+ ; [3 9 7] => [3]
47
+ ; [9 3 -7] => [9]
44
48
  steprange: swap push -1 copy 1 store copy 2 sub
45
49
  jn _steprange_down_loop jump _steprange_loop ; prevent DCE
46
- $range_loop(_steprange_loop, :gt)
47
- $range_loop(_steprange_down_loop, :lt)
50
+ $range_loop(_steprange_loop, :lte)
51
+ $range_loop(_steprange_down_loop, :gte)
48
52
 
49
53
  ; prints the string at the top of the stack and halts execution
50
54
  die!: :println exit
@@ -92,11 +96,13 @@ hex: push 16 :stoi ret
92
96
  ; [N B]
93
97
  ;
94
98
  ; [42 2] => ["101010"]
99
+ ; [-42 2] => ["-101010"]
95
100
  ; [511 8] => ["777"]
96
101
  ; [12345 10] => ["12345"]
102
+ ; [-54321 10] => ["-54321"]
97
103
  ; [57005 16] => ["dead"]
98
104
  ; [81699 17] => ["gabe"]
99
- itos: swap push 0 ; accumulator
105
+ itos: swap push -2 copy 1 :neg? store :abs push 0
100
106
  _itos_loop:
101
107
  swap dup jz _itos_done
102
108
  swap copy 1 copy 3 mod
@@ -104,7 +110,7 @@ _itos_loop:
104
110
  swap :strcat
105
111
  swap copy 2 div
106
112
  swap jump _itos_loop
107
- _itos_done: swap slide 2 ret
113
+ _itos_done: swap slide 2 push 45,-2 load mul swap :strcat ret
108
114
 
109
115
  ; creature comforts
110
116
  to_bin: push 2 :itos ret
@@ -190,6 +196,18 @@ lte: swap ; intentionally flow into gte
190
196
  gte: sub jn _gte_no push 1 ret
191
197
  _gte_no: push 0 ret
192
198
 
199
+ ; returns 1 if the number N is between A and B (inclusive), 0 otherwise
200
+ ; ! A must be <= B for sensible results TODO: bug?
201
+ ; [N A B]
202
+ ;
203
+ ; [5 0 10] => [1]
204
+ ; [11 0 10] => [0]
205
+ ; [4 0 4] => [1]
206
+ ; [-1 0 4] => [0]
207
+ ; [-5 -10 0] => [1]
208
+ ; [3 4 2] => [0]
209
+ between?: copy 2 :gte swap copy 2 :lte mul slide 1 ret
210
+
193
211
  ; Though extremely rare, it's possible that we know a particular value is
194
212
  ; stored in the heap at some key, just not which one. This subroutine takes
195
213
  ; a value V to search for and a starting index I, and either returns the first
@@ -198,3 +216,31 @@ _gte_no: push 0 ret
198
216
  heap_seeking_missile:
199
217
  $++ dup load copy 2 :eq jz heap_search
200
218
  slide 1 ret
219
+
220
+ ; converts the #RRGGBB (leading '#' optional) color string S to
221
+ ; its individual RGB components as integers in the range 0-255
222
+ ; [S] => [R G B]
223
+ ;
224
+ ; ["#000000"] => [0 0 0]
225
+ ; ["ffffff"] => [255 255 255]
226
+ ; ["#102030"] => [16 32 48]
227
+ ; ["c0ffee"] => [192 255 238]
228
+ hex2rgb:
229
+ dup push 0 :charat push '#' :eq push 127 mul $++ div
230
+ push 128,2 :pow :divmod :hex swap
231
+ push 128,2 :pow :divmod :hex swap :hex ret
232
+
233
+ ; converts R, G, and B components to length-6 hexadecimal string S
234
+ ; ! dies if any of the values to convert aren't between 0 and 255
235
+ ; [R G B] => [S]
236
+ ;
237
+ ; [0 0 0] => ["000000"]
238
+ ; [255 255 255] => ["ffffff"]
239
+ ; [16 32 48] => ["102030"]
240
+ ; [192 255 238] => ["c0ffee"]
241
+ rgb2hex:
242
+ push 3 :arydup all (push 0,255 :between?) jz _rgb2hex_invalid
243
+ pop copy 2 push 256,2 :pow mul
244
+ copy 2 push 256 mul add add
245
+ slide 2 :to_hex push 6,48 :rjustc ret
246
+ _rgb2hex_invalid: push "(rgb2hex) invalid RGB" :die!
@@ -64,9 +64,13 @@ maxby_lesser_%1$s: swap jump maxby_resume_%1$s
64
64
  maxby_done_%1$s:
65
65
  SPW
66
66
 
67
- 'minby' => 'maxby (%2$s push -1 mul)',
68
- 'each' => 'dup times (dup call roll %2$s push 1 sub) pop',
69
- 'count' => 'select (%2$s) dup call nslide',
67
+ 'minby' => 'maxby (%2$s push -1 mul)',
68
+ 'each' => 'dup times (dup call roll %2$s push 1 sub) pop',
69
+ 'all' => 'map (%2$s) reduce (add) push -11 load call eq',
70
+ # TODO: optimize any to stop early if possible
71
+ 'any' => 'map (%2$s) reduce (add) push 0 call gt',
72
+ 'none' => 'map (%2$s) reduce (add) push 0 call eq',
73
+ 'count' => 'select (%2$s) dup call nslide',
70
74
  'select' => generate_filter_spw('select', 0, 1),
71
75
  'reject' => generate_filter_spw('reject', 1, 0),
72
76
  }
@@ -61,10 +61,10 @@ module Spitewaste
61
61
  resolve_imports
62
62
  seed_prng if @seen.include? 'random'
63
63
  resolve_strings
64
- remove_comments
65
64
  add_sugar
66
- fucktionalize
65
+ remove_comments
67
66
  propagate_macros
67
+ fucktionalize
68
68
  end
69
69
 
70
70
  def resolve_imports
@@ -1,3 +1,3 @@
1
1
  module Spitewaste
2
- VERSION = '0.1.010'
2
+ VERSION = '0.1.011'
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.1.010
4
+ version: 0.1.011
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: 2020-12-18 00:00:00.000000000 Z
11
+ date: 2020-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -110,6 +110,7 @@ files:
110
110
  - lib/spitewaste/libspw/stack.spw
111
111
  - lib/spitewaste/libspw/string.spw
112
112
  - lib/spitewaste/libspw/syntax.spw
113
+ - lib/spitewaste/libspw/terminal.spw
113
114
  - lib/spitewaste/libspw/test.spw
114
115
  - lib/spitewaste/libspw/util.spw
115
116
  - lib/spitewaste/parsers/assembly.rb