spitewaste 0.1.010 → 0.1.011

Sign up to get free protection for your applications and to get access to all the features.
@@ -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