spitewaste 0.1.004 → 0.1.009
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/Rakefile +4 -3
- data/bin/spw +1 -0
- data/lib/spitewaste.rb +2 -0
- data/lib/spitewaste/assembler.rb +51 -6
- data/lib/spitewaste/cli.rb +21 -19
- data/lib/spitewaste/cli/asm.rb +2 -0
- data/lib/spitewaste/cli/compile.rb +2 -0
- data/lib/spitewaste/cli/convert.rb +2 -0
- data/lib/spitewaste/cli/docs.rb +51 -0
- data/lib/spitewaste/cli/exec.rb +2 -0
- data/lib/spitewaste/cli/image.rb +2 -0
- data/lib/spitewaste/libspw/array.spw +69 -18
- data/lib/spitewaste/libspw/bits.spw +70 -70
- data/lib/spitewaste/libspw/case.spw +34 -28
- data/lib/spitewaste/libspw/docs.json +1 -0
- data/lib/spitewaste/libspw/fun.spw +34 -22
- data/lib/spitewaste/libspw/math.spw +7 -3
- data/lib/spitewaste/libspw/prime.spw +33 -33
- data/lib/spitewaste/libspw/rational.spw +23 -0
- data/lib/spitewaste/libspw/string.spw +20 -19
- data/lib/spitewaste/libspw/test.spw +2 -3
- data/lib/spitewaste/libspw/util.spw +66 -20
- data/lib/spitewaste/parsers/spitewaste.rb +17 -3
- data/lib/spitewaste/version.rb +1 -1
- metadata +4 -2
@@ -4,18 +4,44 @@ import stack ; to_a
|
|
4
4
|
import string ; charat, strcat, strindex, strlen
|
5
5
|
|
6
6
|
; inserts between the top two stack values the intervening consecutive elements
|
7
|
-
;
|
8
|
-
; [I J] => [I I
|
7
|
+
; supports counting up or down
|
8
|
+
; [I J] => [I I±1 ... J]
|
9
9
|
;
|
10
10
|
; [2 5] => [2 3 4 5]
|
11
|
+
; [5 2] => [5 4 3 2]
|
11
12
|
; [0 4] => [0 1 2 3 4]
|
13
|
+
; [4 0] => [4 3 2 1 0]
|
12
14
|
; [-2 0] => [-2 -1 0]
|
15
|
+
; [0 -2] => [0 -1 -2]
|
13
16
|
; [-3 3] => [-3 -2 -1 0 1 2 3]
|
17
|
+
; [3 -3] => [3 2 1 0 -1 -2 -3]
|
14
18
|
; [4 4] => [4 5] TODO: bug
|
15
|
-
range:
|
19
|
+
range: dup copy 2 sub jn _range_down
|
16
20
|
copy 1 push 1 add swap
|
17
|
-
copy 1 copy 1 sub jn range
|
18
|
-
|
21
|
+
copy 1 copy 1 sub jn range pop ret
|
22
|
+
_range_down:
|
23
|
+
copy 1 push 1 sub swap
|
24
|
+
dup copy 2 sub jn _range_down pop ret
|
25
|
+
|
26
|
+
$range_loop(fn, cmp) {
|
27
|
+
`fn`:
|
28
|
+
copy 1 copy 1 add swap dup
|
29
|
+
copy 2 add push -1 load `cmp` jz `fn` pop ret
|
30
|
+
}
|
31
|
+
|
32
|
+
; inserts between the top two stack values the intervening consecutive elements,
|
33
|
+
; counting by `step` up/down to (but never beyond) J
|
34
|
+
; [I J S] => [I I±S ... ~J]
|
35
|
+
;
|
36
|
+
; [1 4 1] => [1 2 3 4]
|
37
|
+
; [4 1 -1] => [4 3 2 1]
|
38
|
+
; [2 10 3] => [2 5 8]
|
39
|
+
; [10 2 -3] => [10 7 4]
|
40
|
+
; [-5 25 10] => [-5 5 15 25]
|
41
|
+
; [25 -5 -10] => [25 15 5 -5]
|
42
|
+
steprange: swap push -1 swap store dup copy 2 sub jn _steprange_down_loop
|
43
|
+
$range_loop(_steprange_loop, :gt)
|
44
|
+
$range_loop(_steprange_down_loop, :lt)
|
19
45
|
|
20
46
|
; prints the string at the top of the stack and halts execution
|
21
47
|
die!: :println exit
|
@@ -34,7 +60,12 @@ alpha: push "0123456789abcdefghijklmnopqrstuvwxyz" ret
|
|
34
60
|
; ["123____" 10] => [123000] ; TODO: bug
|
35
61
|
; ["dead" 16] => [57005]
|
36
62
|
; ["gabe" 17] => [81699]
|
37
|
-
|
63
|
+
; ["0" 10] => [0] ["-0" 10] => [0]
|
64
|
+
; ["-10001" 2] => [-17]
|
65
|
+
; ["-123" 10] => [-123]
|
66
|
+
; ["-ff" 16] => [-255]
|
67
|
+
stoi: swap dup :_stoi_sign swap copy 1 :eq
|
68
|
+
push 2 mul $-- push -2 swap store push 0
|
38
69
|
_stoi_loop: ; [b s a]
|
39
70
|
swap dup jz _stoi_done
|
40
71
|
swap copy 2 copy 2
|
@@ -44,10 +75,11 @@ _stoi_loop: ; [b s a]
|
|
44
75
|
dup jn _stoi_invalid ; found something non-alphanumeric
|
45
76
|
mul add swap push 128 div swap
|
46
77
|
jump _stoi_loop
|
47
|
-
|
48
|
-
|
78
|
+
_stoi_sign: dup push 0 :charat push '-' :eq copy 1 :strlen :strslice ret
|
79
|
+
_stoi_invalid: pop pop slide 1 swap div push -2 load mul ret
|
80
|
+
_stoi_done: swap slide 2 push -2 load mul ret
|
49
81
|
|
50
|
-
|
82
|
+
; creature comforts
|
51
83
|
bin: push 2 :stoi ret
|
52
84
|
oct: push 8 :stoi ret
|
53
85
|
to_i: push 10 :stoi ret
|
@@ -71,11 +103,14 @@ _itos_loop:
|
|
71
103
|
swap jump _itos_loop
|
72
104
|
_itos_done: swap slide 2 ret
|
73
105
|
|
74
|
-
; creature
|
75
|
-
|
106
|
+
; creature comforts
|
107
|
+
to_bin: push 2 :itos ret
|
108
|
+
to_oct: push 8 :itos ret
|
109
|
+
to_s: push 10 :itos ret
|
110
|
+
to_hex: push 16 :itos ret
|
76
111
|
|
77
112
|
; puts the digits of N in base B on the stack as a pseudo-array
|
78
|
-
; [N B]
|
113
|
+
; [N B] => [Dn ...D0 n]
|
79
114
|
;
|
80
115
|
; [42 2] => [1 0 1 0 1 0 6]
|
81
116
|
; [12345 10] => [1 2 3 4 5 5]
|
@@ -125,22 +160,33 @@ _neq_no: push 0 ret
|
|
125
160
|
; pops A and B and pushes 1 if A is greater than B, 0 otherwise
|
126
161
|
; [A B] => [A > B]
|
127
162
|
;
|
128
|
-
; [4 3] => [1]
|
129
|
-
; [
|
130
|
-
; [2 2] => [0]
|
131
|
-
; [2 1] => [1]
|
163
|
+
; [4 3] => [1] [3 4] => [0]
|
164
|
+
; [2 2] => [0] [2 1] => [1]
|
132
165
|
gt: swap ; intentionally flow into lt
|
133
166
|
|
134
167
|
; pops A and B and pushes 1 if A is less than than B, 0 otherwise
|
135
168
|
; [A B] => [A < B]
|
136
169
|
;
|
137
|
-
; [3 4] => [1]
|
138
|
-
; [
|
139
|
-
; [2 2] => [0]
|
140
|
-
; [1 2] => [1]
|
170
|
+
; [3 4] => [1] [4 3] => [0]
|
171
|
+
; [2 2] => [0] [1 2] => [1]
|
141
172
|
lt: sub jn _lt_yes push 0 ret
|
142
173
|
_lt_yes: push 1 ret
|
143
174
|
|
175
|
+
; pops A and B and pushes 1 if A is less than or equal to B, 0 otherwise
|
176
|
+
; [A B] => [A > B]
|
177
|
+
;
|
178
|
+
; [2 2] => [1] [2 1] => [0]
|
179
|
+
; [4 3] => [0] [3 4] => [1]
|
180
|
+
lte: swap ; intentionally flow into gte
|
181
|
+
|
182
|
+
; pops A and B and pushes 1 if A is greater than or equal to B, 0 otherwise
|
183
|
+
; [A B] => [A > B]
|
184
|
+
;
|
185
|
+
; [2 2] => [1] [1 2] => [0]
|
186
|
+
; [3 4] => [0] [4 3] => [1]
|
187
|
+
gte: sub jn _gte_no push 1 ret
|
188
|
+
_gte_no: push 0 ret
|
189
|
+
|
144
190
|
; Though extremely rare, it's possible that we know a particular value is
|
145
191
|
; stored in the heap at some key, just not which one. This subroutine takes
|
146
192
|
; a value V to search for and a starting index I, and either returns the first
|
@@ -11,7 +11,7 @@ module Spitewaste
|
|
11
11
|
INSTRUCTIONS = /(\S+):|(\b(#{OPERATORS_M2T.keys * ?|})\s+(-?\d\S*)?)/
|
12
12
|
SPECIAL_INSN = /(call|jump|jz|jn)\s+(\S+)/
|
13
13
|
|
14
|
-
attr_reader :src, :instructions, :error
|
14
|
+
attr_reader :src, :instructions, :error, :symbol_table
|
15
15
|
|
16
16
|
def initialize program, **options
|
17
17
|
@src = program.dup
|
@@ -127,8 +127,22 @@ module Spitewaste
|
|
127
127
|
def propagate_macros
|
128
128
|
# Macros are write-once, allowing user code to customize the special
|
129
129
|
# values that get used to drive certain behavior in the standard library.
|
130
|
+
|
131
|
+
parse = -> s { s.split(?,).map &:strip }
|
132
|
+
|
133
|
+
# Macro "functions" get handled first.
|
134
|
+
@src.gsub!(/(\$\S+?)\(([^)]+)\)\s*{(.+?)}/m) {
|
135
|
+
@macros[$1] ||= [$2, $3]; ''
|
136
|
+
}
|
137
|
+
@src.gsub!(/(\$\S+?)\(([^)]+)\)/) {
|
138
|
+
params, body = @macros[$1]
|
139
|
+
raise "no macro function '#$1'" unless body
|
140
|
+
map = parse[params].zip(parse[$2]).to_h
|
141
|
+
body.gsub(/`(.+?)`/) { map[$1] }
|
142
|
+
}
|
143
|
+
|
130
144
|
@src.gsub!(/(\$\S+)\s*=\s*(.+)/) { @macros[$1] ||= $2; '' }
|
131
|
-
@src.gsub!(/(\$\S+)/) { @macros[$1] || raise("no macro '
|
145
|
+
@src.gsub!(/(\$\S+)/) { @macros[$1] || raise("no macro '#$1'") }
|
132
146
|
end
|
133
147
|
|
134
148
|
def eliminate_dead_code!
|
@@ -146,7 +160,7 @@ module Spitewaste
|
|
146
160
|
subroutines = {}
|
147
161
|
while label = tokens.shift
|
148
162
|
sublen = tokens.index { |t| t[/:$/] } || tokens.size
|
149
|
-
subroutines[label.chop]
|
163
|
+
subroutines[label.chop] ||= tokens.shift sublen
|
150
164
|
end
|
151
165
|
|
152
166
|
# A subroutine may indirectly depend on the one immediately after by
|
data/lib/spitewaste/version.rb
CHANGED
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.
|
4
|
+
version: 0.1.009
|
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-
|
11
|
+
date: 2020-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- lib/spitewaste/cli/asm.rb
|
87
87
|
- lib/spitewaste/cli/compile.rb
|
88
88
|
- lib/spitewaste/cli/convert.rb
|
89
|
+
- lib/spitewaste/cli/docs.rb
|
89
90
|
- lib/spitewaste/cli/exec.rb
|
90
91
|
- lib/spitewaste/cli/image.rb
|
91
92
|
- lib/spitewaste/emitter.rb
|
@@ -99,6 +100,7 @@ files:
|
|
99
100
|
- lib/spitewaste/libspw/array.spw
|
100
101
|
- lib/spitewaste/libspw/bits.spw
|
101
102
|
- lib/spitewaste/libspw/case.spw
|
103
|
+
- lib/spitewaste/libspw/docs.json
|
102
104
|
- lib/spitewaste/libspw/fun.spw
|
103
105
|
- lib/spitewaste/libspw/io.spw
|
104
106
|
- lib/spitewaste/libspw/math.spw
|