subtle-lang 0.0.3 → 0.0.4
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.
- data/lib/subtle/evaluator.rb +95 -80
- data/lib/subtle/parser.rb +13 -13
- data/lib/subtle/version.rb +1 -1
- data/spec/subtle/evaluator_spec.rb +73 -0
- metadata +2 -2
data/lib/subtle/evaluator.rb
CHANGED
|
@@ -6,12 +6,10 @@ module Subtle
|
|
|
6
6
|
@transform = Transform.new
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def eval(
|
|
10
|
-
if String ===
|
|
11
|
-
parsed = @parser.parse
|
|
9
|
+
def eval(t)
|
|
10
|
+
if String === t
|
|
11
|
+
parsed = @parser.parse t
|
|
12
12
|
t = @transform.apply parsed
|
|
13
|
-
else
|
|
14
|
-
t = string_or_tree
|
|
15
13
|
end
|
|
16
14
|
|
|
17
15
|
if Hash === t
|
|
@@ -19,12 +17,9 @@ module Subtle
|
|
|
19
17
|
|
|
20
18
|
case type
|
|
21
19
|
when :assignment
|
|
22
|
-
identifier = t[:
|
|
23
|
-
right = try_eval t[:right]
|
|
24
|
-
@state[identifier] = right
|
|
20
|
+
@state[t[:identifier]] = try_eval t[:right]
|
|
25
21
|
when :deassignment
|
|
26
|
-
|
|
27
|
-
@state[identifier]
|
|
22
|
+
@state[t[:identifier]]
|
|
28
23
|
when :function
|
|
29
24
|
t[:function]
|
|
30
25
|
when :function_call
|
|
@@ -64,15 +59,7 @@ module Subtle
|
|
|
64
59
|
verb = "**" if verb == "^"
|
|
65
60
|
|
|
66
61
|
if adverb
|
|
67
|
-
|
|
68
|
-
if right.size < 2
|
|
69
|
-
ae! t, "Need Array of size atleast 2 for a monadic adverb." +
|
|
70
|
-
" Your Array had #{right.size} items."
|
|
71
|
-
end
|
|
72
|
-
else
|
|
73
|
-
ae! t, "Can only apply monadic adverb on Arrays." +
|
|
74
|
-
" You passed in #{right.class}."
|
|
75
|
-
end
|
|
62
|
+
right = [right] unless Array === right
|
|
76
63
|
case adverb
|
|
77
64
|
when "//:"
|
|
78
65
|
right.map do |r|
|
|
@@ -86,36 +73,47 @@ module Subtle
|
|
|
86
73
|
right.map do |r|
|
|
87
74
|
eval type: :monad, verb: verb, right: r
|
|
88
75
|
end
|
|
76
|
+
when "\\" # Scan
|
|
77
|
+
[right.shift].tap do |scan|
|
|
78
|
+
right.each do |r|
|
|
79
|
+
scan << eval({type: :dyad, verb: verb, left: scan.last,
|
|
80
|
+
right: r})
|
|
81
|
+
end
|
|
82
|
+
end
|
|
89
83
|
else
|
|
90
|
-
|
|
84
|
+
ae! t, "Invalid adverb #{adverb} on Monads."
|
|
91
85
|
end
|
|
92
86
|
else
|
|
93
87
|
if Array === right
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
[].tap do |ret|
|
|
101
|
-
right.each_with_index do |r, i|
|
|
102
|
-
r.times { ret << i }
|
|
88
|
+
case verb
|
|
89
|
+
when "&"
|
|
90
|
+
[].tap do |ret|
|
|
91
|
+
right.each_with_index do |r, i|
|
|
92
|
+
r.times { ret << i }
|
|
93
|
+
end
|
|
103
94
|
end
|
|
95
|
+
when "~"
|
|
96
|
+
right.map do |r|
|
|
97
|
+
r == 0 ? 1 : 0
|
|
98
|
+
end
|
|
99
|
+
when "+"
|
|
100
|
+
if Array === right.first
|
|
101
|
+
right.transpose
|
|
102
|
+
else
|
|
103
|
+
right
|
|
104
|
+
end
|
|
105
|
+
when "|"
|
|
106
|
+
right.reverse
|
|
104
107
|
end
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
else
|
|
108
|
+
elsif Numeric === right
|
|
109
|
+
case verb
|
|
110
|
+
when "&"
|
|
111
|
+
right.times.map { 0 }
|
|
112
|
+
when "~"
|
|
113
|
+
right == 0 ? 1 : 0
|
|
114
|
+
when "+", "|"
|
|
113
115
|
right
|
|
114
116
|
end
|
|
115
|
-
when "|"
|
|
116
|
-
right.reverse
|
|
117
|
-
else
|
|
118
|
-
nie! "Verb #{verb} without Adverb not implemented as a Monad"
|
|
119
117
|
end
|
|
120
118
|
end
|
|
121
119
|
when :dyad
|
|
@@ -125,55 +123,67 @@ module Subtle
|
|
|
125
123
|
verb = t[:verb]
|
|
126
124
|
adverb = t[:adverb]
|
|
127
125
|
|
|
128
|
-
# `^` in Subtle is `**` in Ruby
|
|
126
|
+
# `^` in Subtle is `**` in Ruby,
|
|
129
127
|
verb = "**" if verb == "^"
|
|
128
|
+
# `=` is `==`,
|
|
129
|
+
verb = "==" if verb == "="
|
|
130
|
+
# `&` is `min` and `|` is `max.
|
|
131
|
+
verb = "min" if verb == "&"
|
|
132
|
+
verb = "max" if verb == "|"
|
|
130
133
|
|
|
131
134
|
if adverb
|
|
132
135
|
case adverb
|
|
133
136
|
when "/:" # Map each over right
|
|
134
137
|
right.map do |r|
|
|
135
|
-
eval
|
|
138
|
+
eval type: :dyad, left: left, verb: verb, right: r
|
|
136
139
|
end
|
|
137
140
|
when "\\:" # Map each over left
|
|
138
141
|
left.map do |l|
|
|
139
|
-
eval
|
|
142
|
+
eval type: :dyad, left: l, verb: verb, right: right
|
|
140
143
|
end
|
|
141
144
|
else
|
|
142
|
-
|
|
145
|
+
ae! t, "Invalid Adverb #{adverb}"
|
|
143
146
|
end
|
|
144
147
|
else
|
|
145
148
|
case verb
|
|
146
|
-
when "+", "-", "*", "/", "%", "**"
|
|
149
|
+
when "+", "-", "*", "/", "%", "**", "==", "<", ">"
|
|
147
150
|
if Numeric === left && Numeric === right
|
|
148
|
-
left.send(verb, right)
|
|
151
|
+
ret = left.send(verb, right)
|
|
152
|
+
if %w{== < >}.include?(verb)
|
|
153
|
+
ret ? 1 : 0
|
|
154
|
+
else
|
|
155
|
+
ret
|
|
156
|
+
end
|
|
149
157
|
elsif Array === left && Array === right
|
|
150
158
|
if left.size != right.size
|
|
151
159
|
ae! t, "Size of left array must be the same as the size of" +
|
|
152
160
|
" right one, but #{left.size} != #{right.size}."
|
|
153
161
|
end
|
|
154
162
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
left.zip(right).map do |l, r|
|
|
163
|
+
left.zip(right).map do |l, r|
|
|
164
|
+
if Array === l || Array === r
|
|
158
165
|
eval type: :dyad, verb: verb, left: l, right: r
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
(try_eval l).send(verb, try_eval(r))
|
|
166
|
+
else
|
|
167
|
+
ret = (try_eval l).send(verb, try_eval(r))
|
|
168
|
+
if %w{== < >}.include?(verb)
|
|
169
|
+
ret ? 1 : 0
|
|
170
|
+
else
|
|
171
|
+
ret
|
|
172
|
+
end
|
|
167
173
|
end
|
|
168
174
|
end
|
|
169
|
-
|
|
170
175
|
elsif Array === left && Numeric === right
|
|
171
176
|
left.map do |l|
|
|
172
177
|
# Multi-dimensional arrays
|
|
173
178
|
if Array === l
|
|
174
179
|
eval type: :dyad, verb: verb, left: l, right: right
|
|
175
180
|
else
|
|
176
|
-
(try_eval l).send(verb, right)
|
|
181
|
+
ret = (try_eval l).send(verb, right)
|
|
182
|
+
if %w{== < >}.include?(verb)
|
|
183
|
+
ret ? 1 : 0
|
|
184
|
+
else
|
|
185
|
+
ret
|
|
186
|
+
end
|
|
177
187
|
end
|
|
178
188
|
end
|
|
179
189
|
elsif Numeric === left && Array === right
|
|
@@ -182,17 +192,19 @@ module Subtle
|
|
|
182
192
|
if Array === r
|
|
183
193
|
eval type: :dyad, verb: verb, left: left, right: r
|
|
184
194
|
else
|
|
185
|
-
left.send(verb, r)
|
|
195
|
+
ret = left.send(verb, r)
|
|
196
|
+
if %w{== < >}.include?(verb)
|
|
197
|
+
ret ? 1 : 0
|
|
198
|
+
else
|
|
199
|
+
ret
|
|
200
|
+
end
|
|
186
201
|
end
|
|
187
202
|
end
|
|
188
203
|
else
|
|
189
|
-
|
|
204
|
+
ae! t, "Left and Array must be Numeric or Arrays." +
|
|
190
205
|
" You passed in #{left.class} and #{right.class}."
|
|
191
206
|
end
|
|
192
|
-
when "
|
|
193
|
-
verb = "min" if verb == "&"
|
|
194
|
-
verb = "max" if verb == "|"
|
|
195
|
-
|
|
207
|
+
when "max", "min"
|
|
196
208
|
if Numeric === left && Numeric === right
|
|
197
209
|
[left, right].send(verb)
|
|
198
210
|
elsif Array === left && Array === right
|
|
@@ -200,31 +212,38 @@ module Subtle
|
|
|
200
212
|
ae! t, "Size of left array must be the same as the size of" +
|
|
201
213
|
" right one, but #{left.size} != #{right.size}."
|
|
202
214
|
end
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
[x, y].send(verb)
|
|
215
|
+
left.zip(right).map do |l, r|
|
|
216
|
+
eval type: :dyad, verb: verb, left: l, right: r
|
|
206
217
|
end
|
|
207
218
|
elsif Array === left && Numeric === right
|
|
208
219
|
left.map do |l|
|
|
209
|
-
|
|
220
|
+
if Array === l
|
|
221
|
+
eval type: :dyad, verb: verb, left: l, right: right
|
|
222
|
+
else
|
|
223
|
+
[l, right].send(verb)
|
|
224
|
+
end
|
|
210
225
|
end
|
|
211
226
|
elsif Numeric === left && Array === right
|
|
212
227
|
right.map do |r|
|
|
213
|
-
|
|
228
|
+
if Array === r
|
|
229
|
+
eval type: :dyad, verb: verb, left: left, right: r
|
|
230
|
+
else
|
|
231
|
+
[left, r].send(verb)
|
|
232
|
+
end
|
|
214
233
|
end
|
|
215
234
|
else
|
|
216
|
-
|
|
235
|
+
ae! t
|
|
217
236
|
end
|
|
218
237
|
when "!"
|
|
219
238
|
if Numeric === left && Array === right
|
|
239
|
+
right.rotate(left)
|
|
220
240
|
else
|
|
221
241
|
ae! t, "Left must be Numeric and right must be an Array for" +
|
|
222
242
|
" rotate (`!`) dyad. You passed in #{left.class} and" +
|
|
223
243
|
" #{right.class}"
|
|
224
244
|
end
|
|
225
|
-
right.rotate(left)
|
|
226
245
|
else
|
|
227
|
-
|
|
246
|
+
ae! t, "Invalid verb #{verb}."
|
|
228
247
|
end
|
|
229
248
|
end
|
|
230
249
|
when :enumerate
|
|
@@ -232,11 +251,11 @@ module Subtle
|
|
|
232
251
|
if Numeric === last
|
|
233
252
|
(0...last.floor).to_a
|
|
234
253
|
else
|
|
235
|
-
|
|
254
|
+
ae! t, "`last` must be Numeric for type: :enumerate. You passed" +
|
|
236
255
|
" in #{last.class}."
|
|
237
256
|
end
|
|
238
257
|
else
|
|
239
|
-
|
|
258
|
+
ae! t, "Type #{t[:type].inspect} not implemented."
|
|
240
259
|
end
|
|
241
260
|
else
|
|
242
261
|
t
|
|
@@ -250,9 +269,5 @@ module Subtle
|
|
|
250
269
|
def ae!(tree, message = "")
|
|
251
270
|
raise ArgumentError.new message << "\n" << tree.to_yaml
|
|
252
271
|
end
|
|
253
|
-
|
|
254
|
-
def nie!(tree, message = "")
|
|
255
|
-
raise NotImplementedError.new message << "\n" << tree.to_yaml
|
|
256
|
-
end
|
|
257
272
|
end
|
|
258
273
|
end
|
data/lib/subtle/parser.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
module Subtle
|
|
2
2
|
class Parser < Parslet::Parser
|
|
3
3
|
def initialize
|
|
4
|
-
@monadic_verbs = %w{+ - *
|
|
5
|
-
@monadic_adverbs = %w{//: /: /}
|
|
6
|
-
@dyadic_verbs = %w{+ - *
|
|
4
|
+
@monadic_verbs = %w{+ - * / % ^ | & ~}
|
|
5
|
+
@monadic_adverbs = %w{//: /: / \\}
|
|
6
|
+
@dyadic_verbs = %w{+ - * / % ^ | & ! = < >}
|
|
7
7
|
@dyadic_adverbs = %w{/: \:}
|
|
8
8
|
@function_adverbs = %w{/:}
|
|
9
9
|
end
|
|
@@ -17,14 +17,13 @@ module Subtle
|
|
|
17
17
|
rule(:float) { (minus.maybe >> digits >> str(".") >> digits).
|
|
18
18
|
as(:float) >> spaces? }
|
|
19
19
|
rule(:identifier) { (match["a-zA-Z"] >> match["a-zA-Z0-9_"].repeat).
|
|
20
|
-
as(:identifier) }
|
|
21
|
-
rule(:assignment) { (identifier >>
|
|
20
|
+
as(:identifier) >> spaces? }
|
|
21
|
+
rule(:assignment) { (identifier >> str(":") >> spaces? >>
|
|
22
22
|
word.as(:right)).as(:assignment) >> spaces? }
|
|
23
|
-
rule(:deassignment) { identifier.as(:deassignment)
|
|
23
|
+
rule(:deassignment) { identifier.as(:deassignment) }
|
|
24
24
|
|
|
25
25
|
rule(:function) do
|
|
26
|
-
str("{") >> spaces? >> word.as(:function) >>
|
|
27
|
-
spaces?
|
|
26
|
+
str("{") >> spaces? >> word.as(:function) >> str("}") >> spaces?
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
rule :function_adverb do
|
|
@@ -39,7 +38,7 @@ module Subtle
|
|
|
39
38
|
|
|
40
39
|
rule(:variable_call) do
|
|
41
40
|
(identifier >> spaces? >> function_adverb.maybe >>
|
|
42
|
-
(assignment | dyad | noun).as(:arguments)).as(:variable_call)
|
|
41
|
+
(assignment | dyad | noun).as(:arguments)).as(:variable_call) >> spaces?
|
|
43
42
|
end
|
|
44
43
|
|
|
45
44
|
rule(:atom) do
|
|
@@ -48,7 +47,7 @@ module Subtle
|
|
|
48
47
|
end
|
|
49
48
|
|
|
50
49
|
rule :array do
|
|
51
|
-
atom_or_array = (array | (atom >> spaces?).repeat.as(:array))
|
|
50
|
+
atom_or_array = (array | (atom >> spaces?).repeat.as(:array))
|
|
52
51
|
|
|
53
52
|
(str("(") >> spaces? >> atom_or_array >>
|
|
54
53
|
(str(";") >> spaces? >> atom_or_array).repeat >>
|
|
@@ -57,7 +56,7 @@ module Subtle
|
|
|
57
56
|
end
|
|
58
57
|
|
|
59
58
|
rule :enumerate do
|
|
60
|
-
(str("!") >> spaces? >> (word).as(:last)).as(:enumerate)
|
|
59
|
+
(str("!") >> spaces? >> (word).as(:last)).as(:enumerate) >> spaces?
|
|
61
60
|
end
|
|
62
61
|
|
|
63
62
|
rule(:noun) { enumerate | array | atom }
|
|
@@ -82,11 +81,12 @@ module Subtle
|
|
|
82
81
|
|
|
83
82
|
rule :dyad do
|
|
84
83
|
(noun.as(:left) >> dyadic_verb >> dyadic_adverb.maybe >>
|
|
85
|
-
word.as(:right)).as(:dyad)
|
|
84
|
+
word.as(:right)).as(:dyad) >> spaces?
|
|
86
85
|
end
|
|
87
86
|
|
|
88
87
|
rule :monad do
|
|
89
|
-
(monadic_verb >> monadic_adverb.maybe >> word.as(:right)).as(:monad)
|
|
88
|
+
(monadic_verb >> monadic_adverb.maybe >> word.as(:right)).as(:monad) >>
|
|
89
|
+
spaces?
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
rule :word do
|
data/lib/subtle/version.rb
CHANGED
|
@@ -27,10 +27,13 @@ describe Subtle::Evaluator do
|
|
|
27
27
|
describe "on Arrays" do
|
|
28
28
|
e "1 12 & 7 8", [1, 8]
|
|
29
29
|
e "1 12 | 7 8", [7, 12]
|
|
30
|
+
e "(1; 0 1 1 0 0; 1) & (1; 0 1 0 1 0; 1)", [1, [0, 1, 0, 0, 0], 1]
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
describe "on Atoms and Arrays" do
|
|
33
34
|
e "1 | 7 0 & 8 2 | 8 & 6 7 & 1", [7, 1]
|
|
35
|
+
e "1 | (0; 1 0; 0 1 0; (1 0 1 2))", [1, [1, 1], [1, 1, 1], [1, 1, 1, 2]]
|
|
36
|
+
e "(0; 1 0; 0 1 0; (1 0 1 2)) | 1", [1, [1, 1], [1, 1, 1], [1, 1, 1, 2]]
|
|
34
37
|
end
|
|
35
38
|
end
|
|
36
39
|
|
|
@@ -42,6 +45,26 @@ describe Subtle::Evaluator do
|
|
|
42
45
|
e "-2 ! (1 2)", [1, 2]
|
|
43
46
|
e "-2 ! (2 3; 4 5; 8)", [[4, 5], 8, [2, 3]]
|
|
44
47
|
end
|
|
48
|
+
|
|
49
|
+
describe "Comparison (`=`, `<`, `>`)" do
|
|
50
|
+
describe "on Atoms" do
|
|
51
|
+
e "1 > 3", 0
|
|
52
|
+
e "7 < 8", 1
|
|
53
|
+
e "7 = 7", 1
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe "on Arrays" do
|
|
57
|
+
e "1 12 < 7 8", [1, 0]
|
|
58
|
+
e "1 12 > 7 8", [0, 1]
|
|
59
|
+
e "1 12 1 = 7 8 1", [0, 0, 1]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe "on Atoms and Arrays" do
|
|
63
|
+
e "1 2 > 3", [0, 0]
|
|
64
|
+
e "7 < 8 0", [1, 0]
|
|
65
|
+
e "7 = 7 7", [1, 1]
|
|
66
|
+
end
|
|
67
|
+
end
|
|
45
68
|
end
|
|
46
69
|
|
|
47
70
|
describe "Enumerate (`!`)" do
|
|
@@ -87,35 +110,80 @@ describe Subtle::Evaluator do
|
|
|
87
110
|
describe "on Monads" do
|
|
88
111
|
describe "Map over each right (`/:`)" do
|
|
89
112
|
# Where (`&`), Not (`~`), Transpose (`+`) and Reverse (`|`)
|
|
113
|
+
e "&/: 2", [[0, 0]]
|
|
114
|
+
e "&/: 2 1", [[0, 0], [0]]
|
|
90
115
|
e "&/: (0 2; 2 1)", [[1, 1], [0, 0, 1]]
|
|
116
|
+
|
|
117
|
+
e "~/: 1", [0]
|
|
118
|
+
e "~/: 0 1", [1, 0]
|
|
91
119
|
e "~/: (0 1; 0 1)", [[1, 0], [1, 0]]
|
|
120
|
+
|
|
121
|
+
e "+/: 1", [1]
|
|
122
|
+
e "+/: 1 2 3", [1, 2, 3]
|
|
92
123
|
e "+/: ((1 2; 3 4); (5 6; 7 8))", [[[1, 3], [2, 4]], [[5, 7], [6, 8]]]
|
|
124
|
+
|
|
125
|
+
e "|/: 1", [1]
|
|
126
|
+
e "|/: 1 2", [1, 2]
|
|
93
127
|
e "|/: (0 1; 0 2)", [[1, 0], [2, 0]]
|
|
94
128
|
end
|
|
95
129
|
|
|
96
130
|
describe "Map over and fold (`//:`)" do
|
|
131
|
+
e "+//: 1", [1]
|
|
132
|
+
e "+//: 1 2", [1, 2]
|
|
133
|
+
e "+//: (1; 2; 3 4)", [1, 2, 7]
|
|
97
134
|
e "+//: (2 4; 3 1)", [6, 4]
|
|
98
135
|
e "+//:+(2 4; 3 1)", [5, 5]
|
|
99
136
|
end
|
|
137
|
+
|
|
138
|
+
describe "Scan (`\`)" do
|
|
139
|
+
e "+\\2", [2]
|
|
140
|
+
e "-\\2", [2]
|
|
141
|
+
e "*\\2", [2]
|
|
142
|
+
e "/\\2", [2]
|
|
143
|
+
e "%\\2", [2]
|
|
144
|
+
e "^\\2", [2]
|
|
145
|
+
|
|
146
|
+
e "+\\1 2 3 4 5", [1, 3, 6, 10, 15]
|
|
147
|
+
e "-\\1 2 3 4 5", [1, -1, -4, -8, -13]
|
|
148
|
+
e "*\\1 2 3 4 5", [1, 2, 6, 24, 120]
|
|
149
|
+
e "/\\8 4 3 2", [8, 2, 0, 0]
|
|
150
|
+
e "%\\8 6 3 1", [8, 2, 2, 0]
|
|
151
|
+
e "^\\2 1 3 4", [2, 2, 8, 4096]
|
|
152
|
+
|
|
153
|
+
e "+\\(1 2; 3 4; 5)", [[1, 2], [4, 6], [9, 11]]
|
|
154
|
+
e "-\\(1 2; 3 4; 5)", [[1, 2], [-2, -2], [-7, -7]]
|
|
155
|
+
e "*\\(1 2; 3 4; 5)", [[1, 2], [3, 8], [15, 40]]
|
|
156
|
+
e "/\\(8 4; 3; 2)", [[8, 4], [2, 1], [1, 0]]
|
|
157
|
+
e "%\\(8 6; 3; 1)", [[8, 6], [2, 0], [0, 0]]
|
|
158
|
+
e "^\\(2 1; 3; 4)", [[2, 1], [8, 1], [4096, 1]]
|
|
159
|
+
end
|
|
100
160
|
end
|
|
101
161
|
end
|
|
102
162
|
|
|
103
163
|
describe "Monads" do
|
|
104
164
|
describe "Where (`&`)" do
|
|
165
|
+
e "&1", [0]
|
|
166
|
+
e "&2", [0, 0]
|
|
105
167
|
e "&1 0 1", [0, 2]
|
|
106
168
|
e "&1 3 2", [0, 1, 1, 1, 2, 2]
|
|
107
169
|
end
|
|
108
170
|
|
|
109
171
|
describe "Not (`~`)" do
|
|
172
|
+
e "~0", 1
|
|
173
|
+
e "~1", 0
|
|
174
|
+
e "~4", 0
|
|
110
175
|
e "~1 0 -1 1 7 8 0 0", [0, 1, 0, 0, 0, 0, 1, 1]
|
|
111
176
|
end
|
|
112
177
|
|
|
113
178
|
describe "Transpose (`+`)" do
|
|
179
|
+
e "+0", 0
|
|
180
|
+
e "+1", 1
|
|
114
181
|
e "+1 2 3", [1, 2, 3]
|
|
115
182
|
e "+(1 2; 3 4; 5 6)", [[1, 3, 5], [2, 4, 6]]
|
|
116
183
|
end
|
|
117
184
|
|
|
118
185
|
describe "Reverse (`|`)" do
|
|
186
|
+
e "|1", 1
|
|
119
187
|
e "|1 2", [2, 1]
|
|
120
188
|
e "|(1 2; 3; (6 7; 8))", [[[6, 7], 8], 3, [1, 2]]
|
|
121
189
|
end
|
|
@@ -136,6 +204,7 @@ describe Subtle::Evaluator do
|
|
|
136
204
|
e "2 ^ ((5 6; 0 1);1 2; 3 4)", [[[32, 64], [1, 2]], [2, 4], [8, 16]]
|
|
137
205
|
e "(;1 2; 3 4) - 1", [[], [0, 1], [2, 3]]
|
|
138
206
|
e "((5 6; 0 1);1 2; 3 4) ^ 2", [[[25, 36], [0, 1]], [1, 4], [9, 16]]
|
|
207
|
+
e "(1; 2 3; 4 5) + (1; 2 3; 4 5)", [2, [4, 6], [8, 10]]
|
|
139
208
|
end
|
|
140
209
|
|
|
141
210
|
describe "on 1D/2D/3D Arrays with 2D/3D Arrays" do
|
|
@@ -216,5 +285,9 @@ describe Subtle::Evaluator do
|
|
|
216
285
|
ae! "1 2 ! 2 3"
|
|
217
286
|
ae! "2 ! 1"
|
|
218
287
|
end
|
|
288
|
+
|
|
289
|
+
describe "on Scan adverb" do
|
|
290
|
+
ae! "+\\(1 2; 3; 4 5 6)"
|
|
291
|
+
end
|
|
219
292
|
end
|
|
220
293
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: subtle-lang
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.4
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-12-
|
|
12
|
+
date: 2012-12-15 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: parslet
|