spitewaste 0.1.012 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,3 +8,6 @@ assert_eq:
8
8
  push ", got " :print onum
9
9
  push " for test " swap :strcat :die!
10
10
  _assert_eq_yes: pop pop pop ret
11
+
12
+ assert_nz: jz _assert_nz_no pop ret
13
+ _assert_nz_no: push "expected nonzero for test " swap :strcat :die!
@@ -26,7 +26,7 @@ _range_down:
26
26
 
27
27
  $range_loop(fn, cmp) {
28
28
  `fn`:
29
- dup copy 2 add push -1 load `cmp` jz _`fn`_done
29
+ dup copy 2 add @-1 `cmp` jz _`fn`_done
30
30
  copy 1 copy 1 add swap jump `fn`
31
31
  _`fn`_done: pop ret
32
32
  }
@@ -50,8 +50,10 @@ steprange: swap push -1 copy 1 store copy 2 sub
50
50
  $range_loop(_steprange_loop, :lte)
51
51
  $range_loop(_steprange_down_loop, :gte)
52
52
 
53
- ; prints the string at the top of the stack and halts execution
54
- die!: :println exit
53
+ ; prints the string at the top of the stack and halts execution after pushing
54
+ ; something onto the stack to signal abnormal termination/unclean exit
55
+ ; [...] => [... 1]
56
+ die!: :println push 1 exit
55
57
 
56
58
  ; for stoi and itos
57
59
  alpha: push "0123456789abcdefghijklmnopqrstuvwxyz" ret
@@ -72,7 +74,7 @@ alpha: push "0123456789abcdefghijklmnopqrstuvwxyz" ret
72
74
  ; ["-123" 10] => [-123]
73
75
  ; ["-ff" 16] => [-255]
74
76
  stoi: swap dup :_stoi_sign swap copy 1 :eq
75
- push 2 mul $-- push -2 swap store push 0
77
+ push 2 mul $-- ^-2 push 0
76
78
  _stoi_loop: ; [b s a]
77
79
  swap dup jz _stoi_done
78
80
  swap copy 2 copy 2
@@ -83,8 +85,8 @@ _stoi_loop: ; [b s a]
83
85
  mul add swap push 128 div swap
84
86
  jump _stoi_loop
85
87
  _stoi_sign: dup push 0 :charat push '-' :eq copy 1 :strlen :strslice ret
86
- _stoi_invalid: pop pop slide 1 swap div push -2 load mul ret
87
- _stoi_done: swap slide 2 push -2 load mul ret
88
+ _stoi_invalid: pop pop slide 1 swap div @-2 mul ret
89
+ _stoi_done: swap slide 2 @-2 mul ret
88
90
 
89
91
  ; creature comforts
90
92
 
@@ -111,7 +113,7 @@ _itos_loop:
111
113
  swap :strcat
112
114
  swap copy 2 div
113
115
  swap jump _itos_loop
114
- _itos_done: swap slide 2 push 45,-2 load mul swap :strcat ret
116
+ _itos_done: swap slide 2 push 45 @-2 mul swap :strcat ret
115
117
 
116
118
  ; creature comforts
117
119
 
@@ -129,12 +131,10 @@ to_hex: push 16 :itos ret
129
131
  ; [256 16] => [1 0 0 3]
130
132
  digits:
131
133
  copy 1 jz _digits_zero ; special case
132
- push -1 swap store
133
- push -1 swap ; sentinel value
134
+ ^-1 push -1 swap ; sentinel value
134
135
  _digits_loop:
135
136
  dup jz _digits_done
136
- push -1 load :divmod
137
- swap jump _digits_loop
137
+ @-1 :divmod swap jump _digits_loop
138
138
  _digits_zero: dup div ret
139
139
  _digits_done: push 1 sub :to_a ret
140
140
 
@@ -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
+ }
@@ -117,6 +117,10 @@ module Spitewaste
117
117
  @src.gsub!(/'(.)'/) { $1.ord }
118
118
  # quick push (`push 1,2,3` desugars to individual pushes)
119
119
  @src.gsub!(/push \S+/) { |m| m.split(?,) * ' push ' }
120
+ # quick store (`^2` = `push 2 swap store`)
121
+ @src.gsub!(/\^(\S+)/, 'push \1 swap store')
122
+ # quick load (`@2` = `push 2 load`)
123
+ @src.gsub!(/@(\S+)/, 'push \1 load')
120
124
  end
121
125
 
122
126
  def gensym
@@ -137,18 +141,20 @@ module Spitewaste
137
141
  parse = -> s { s.split(?,).map &:strip }
138
142
 
139
143
  # Macro "functions" get handled first.
140
- @src.gsub!(/(\$\S+?)\(([^)]+)\)\s*{(.+?)}/m) {
144
+ @src.gsub!(/(\$\S+?)\(([^)]*)\)\s*{(.+?)}/m) {
141
145
  @macros[$1] ||= [$2, $3]; ''
142
146
  }
143
- @src.gsub!(/(\$\S+?)\(([^)]+)\)/) {
147
+ @src.gsub!(/(\$\S+?)\(([^)]*)\)/) {
144
148
  params, body = @macros[$1]
145
149
  raise "no macro function '#$1'" unless body
146
150
  map = parse[params].zip(parse[$2]).to_h
147
- body.gsub(/`(.+?)`/) { map[$1] }
151
+ body
152
+ .gsub(/`(.+?)`/) { map[$1] }
153
+ .gsub(/#(\S+)/) { "push #{Spitewaste.strpack map[$1]}" }
148
154
  }
149
155
 
150
156
  @src.gsub!(/(\$\S+)\s*=\s*(.+)/) { @macros[$1] ||= $2; '' }
151
- @src.gsub!(/(\$\S+)/) { @macros[$1] || raise("no macro '#$1'") }
157
+ @src.gsub!(/(\$[^)\s]+)/) { @macros[$1] || raise("no macro '#$1'") }
152
158
  end
153
159
 
154
160
  def eliminate_dead_code!
@@ -1,3 +1,3 @@
1
1
  module Spitewaste
2
- VERSION = '0.1.012'
2
+ VERSION = '0.2.4'
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.012
4
+ version: 0.2.4
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-01 00:00:00.000000000 Z
11
+ date: 2021-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -138,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
138
  - !ruby/object:Gem::Version
139
139
  version: '0'
140
140
  requirements: []
141
- rubygems_version: 3.1.4
141
+ rubygems_version: 3.2.18
142
142
  signing_key:
143
143
  specification_version: 4
144
144
  summary: Make programming in Whitespace even better.