trxl 0.1.5

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.
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --loadby random
3
+ --format specdoc
4
+ --backtrace
@@ -0,0 +1,28 @@
1
+ require "rubygems"
2
+ require "treetop"
3
+ require "pathname"
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+
8
+ SPEC_ROOT = Pathname(__FILE__).dirname.expand_path
9
+
10
+ require SPEC_ROOT.parent + 'lib/trxl'
11
+
12
+ module Trxl
13
+ module SpecHelper
14
+
15
+ # raise unless successful
16
+ def parse(expression)
17
+ @parser.parse(expression)
18
+ end
19
+
20
+ # raise if an exception is raised during parsing
21
+ # raise if an exception is raised during evaluation
22
+ def eval(expression, env = Environment.new)
23
+ env = Trxl::Environment.new(env) if env.is_a?(Hash)
24
+ ast = parse(expression)
25
+ ast.eval(env)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,391 @@
1
+ require 'spec_helper'
2
+
3
+ Infinity = 1.0 / 0
4
+
5
+ describe "When evaluating addition expressions, the language" do
6
+
7
+ include Trxl::SpecHelper
8
+
9
+ before(:each) do
10
+ @parser = Trxl::Calculator.new
11
+ end
12
+
13
+ it "should allow integers as operands" do
14
+ eval("0+0").should == 0 + 0
15
+ eval("0+1").should == 0 + 1
16
+ eval("1+0").should == 1 + 0
17
+ eval("1+1").should == 1 + 1
18
+ eval("2+2").should == 2 + 2
19
+ eval("2+-2").should == 2 + -2
20
+ end
21
+
22
+ it "should allow floats as operands" do
23
+ eval("0.0+0.0").should == 0.0 + 0.0
24
+ eval("0.1+1").should == 0.1 + 1
25
+ eval("1.34+0.23456789").should == 1.34 + 0.23456789
26
+ eval("1.000+1.87").should == 1.000 + 1.87
27
+ eval("2.0+2.01").should == 2.0 + 2.01
28
+ eval("2.0+-2.01").should == 2.0 + -2.01
29
+ end
30
+
31
+ it "should allow arbitrary spacing" do
32
+ eval("4 + 2").should == 4 + 2
33
+ eval("4 +2").should == 4 + 2
34
+ eval("4+ 2").should == 4 + 2
35
+ eval(" 4 + 2").should == 4 + 2
36
+ eval("4 + 2 ").should == 4 + 2
37
+ eval(" 4 + 2 ").should == 4 + 2
38
+ end
39
+
40
+ it "should allow chained expressions" do
41
+ eval("1 + 1 + 1").should == 1 + 1 + 1
42
+ eval("1 + 1 + 1 + 1").should == 1 + 1 + 1 + 1
43
+ end
44
+
45
+ end
46
+
47
+
48
+ describe "When evaluating subtraction expressions, the language" do
49
+
50
+ include Trxl::SpecHelper
51
+
52
+ before(:each) do
53
+ @parser = Trxl::Calculator.new
54
+ end
55
+
56
+ it "should allow integers as operands" do
57
+ eval("0-0").should == 0 - 0
58
+ eval("0-2").should == 0 - 2
59
+ eval("2-2").should == 2 - 2
60
+ eval("5-2").should == 5 - 2
61
+ eval("5--2").should == 5--2
62
+ end
63
+
64
+
65
+ it "should allow floats as operands" do
66
+ eval("0.0-0.0").should == 0.0 - 0.0
67
+ eval("0.1-2.34").should == 0.1 - 2.34
68
+ eval("2.12-2.34").should == 2.12 - 2.34
69
+ eval("5.45678-2.456789").should == 5.45678 - 2.456789
70
+ eval("5.45678--2.456789").should == 5.45678 - -2.456789
71
+ end
72
+
73
+ it "should allow arbitrary spacing" do
74
+ eval("4 - 2").should == 4 - 2
75
+ eval("4 -2").should == 4 - 2
76
+ eval("4- 2").should == 4 - 2
77
+ eval(" 4 - 2").should == 4 - 2
78
+ eval("4 - 2 ").should == 4 - 2
79
+ eval(" 4 - 2 ").should == 4 - 2
80
+ end
81
+
82
+ it "should perform left associative evaluation in chained expressions" do
83
+ eval("16 - 4 - 2").should == (16 - 4 - 2)
84
+ eval("16 - 4 - 2 - 2").should == (16 - 4 - 2 - 2)
85
+ end
86
+
87
+ it "should allow to override operator precedence with parentheses" do
88
+ eval("(16 - 4) - 2").should == (16 - 4) - 2
89
+ eval("16 - (4 - 2)").should == 16 - (4 - 2)
90
+ eval("(16 - 4) - (2 - 2)").should == (16 - 4) - (2 - 2)
91
+ eval("16 - (4 - 2) - 2").should == 16 - (4 - 2) - 2
92
+ end
93
+
94
+ end
95
+
96
+
97
+ describe "When evaluating multiplication expressions, the language" do
98
+
99
+ include Trxl::SpecHelper
100
+
101
+ before(:each) do
102
+ @parser = Trxl::Calculator.new
103
+ end
104
+
105
+ it "should allow integers as operands" do
106
+ eval("0*0").should == 0 * 0
107
+ eval("0*1").should == 0 * 1
108
+ eval("1*0").should == 1 * 0
109
+ eval("1*1").should == 1 * 1
110
+ eval("2*2").should == 2 * 2
111
+ eval("3*4").should == 3 * 4
112
+ eval("3*-4").should == 3 * -4
113
+ end
114
+
115
+
116
+ it "should allow floats as operands" do
117
+ eval("0.0*0.0").should == 0.0 * 0.0
118
+ eval("0.1*1.0").should == 0.1 * 1.0
119
+ eval("1.345*0.987").should == 1.345 * 0.987
120
+ eval("1.23*1.45").should == 1.23 * 1.45
121
+ eval("2.5*2").should == 2.5 * 2
122
+ eval("3.45*4.45").should == 3.45 * 4.45
123
+ eval("3.45*-4.45").should == 3.45 * -4.45
124
+ end
125
+
126
+ it "should allow arbitrary spacing" do
127
+ eval("4 * 2").should == 4 * 2
128
+ eval("4 *2").should == 4 * 2
129
+ eval("4* 2").should == 4 * 2
130
+ eval(" 4 * 2").should == 4 * 2
131
+ eval("4 * 2 ").should == 4 * 2
132
+ eval(" 4 * 2 ").should == 4 * 2
133
+ end
134
+
135
+ it "should allow chained expressions" do
136
+ eval("1 * 2 * 3").should == 1 * 2 * 3
137
+ eval("1 * 2 * 3 * 4").should == 1 * 2 * 3 * 4
138
+ end
139
+
140
+ end
141
+
142
+
143
+ describe "When evaluating division expressions, the language" do
144
+
145
+ include Trxl::SpecHelper
146
+
147
+ before(:each) do
148
+ @parser = Trxl::Calculator.new
149
+ end
150
+
151
+ it "should allow integers as operands" do
152
+ eval("1/1").should == 1.0 / 1
153
+ eval("0/1").should == 0.0 / 1
154
+ eval("1/2").should == 1.0 / 2
155
+ eval("4/2").should == 4.0 / 2
156
+ eval("3/2").should == 3.0 / 2
157
+ eval("3/-2").should == 3.0 / -2
158
+
159
+ # test division by zero
160
+ lambda { eval("1/0") }.should raise_error(Trxl::DivisionByZeroError)
161
+ end
162
+
163
+ it "should allow floats as operands" do
164
+ eval("1.0/1.0").should == 1.0 / 1.0
165
+ eval("0.0/1.0").should == 0.0 / 1.0
166
+ eval("1.23/2.34").should == 1.23 / 2.34
167
+ eval("4.2345678/2").should == 4.2345678 / 2
168
+ eval("3/2.123456").should == 3 / 2.123456
169
+ eval("3/-2.123456").should == 3 / -2.123456
170
+
171
+ # TODO think about DivisonByZero vs. Infinity
172
+ end
173
+
174
+ it "should allow arbitrary spacing" do
175
+ eval("4 / 2").should == 4 / 2
176
+ eval("4 /2").should == 4 / 2
177
+ eval("4/ 2").should == 4 / 2
178
+ eval(" 4 / 2").should == 4 / 2
179
+ eval("4 / 2 ").should == 4 / 2
180
+ eval(" 4 / 2 ").should == 4 / 2
181
+ end
182
+
183
+ it "should perform left associative evaluation in chained expressions" do
184
+ eval("16 / 4 / 2").should == (16 / 4 / 2)
185
+ eval("16 / 4 / 2 / 2").should == (16 / 4 / 2 / 2)
186
+ end
187
+
188
+ it "should allow to override operator precedence with parentheses" do
189
+ eval("(16 / 4) / 2").should == (16 / 4) / 2
190
+ eval("16 / (4 / 2)").should == 16 / (4 / 2)
191
+ eval("(16 / 4) / (2 / 2)").should == (16 / 4) / (2 / 2)
192
+ eval("16 / (4 / 2) / 2").should == 16 / (4 / 2) / 2
193
+ end
194
+
195
+ end
196
+
197
+
198
+ describe "When evaluating modulo expressions, the language" do
199
+
200
+ include Trxl::SpecHelper
201
+
202
+ before(:each) do
203
+ @parser = Trxl::Calculator.new
204
+ end
205
+
206
+ it "should allow integers as operands" do
207
+ eval("1%1").should == 1 % 1
208
+ eval("4%2").should == 4 % 2
209
+ eval("8%3").should == 8 % 3
210
+ eval("8%-3").should == 8 % -3
211
+
212
+ # test division by zero
213
+ lambda { eval("1%0") }.should raise_error(Trxl::DivisionByZeroError)
214
+ end
215
+
216
+
217
+ it "should allow floats as operands" do
218
+ eval("1.0%1.0").should == 1.0 % 1.0
219
+ eval("4.0%2.0").should == 4.0 % 2.0
220
+ eval("8.0%3.2").should == 8.0 % 3.2
221
+ eval("8.0%-3.2").should == 8.0 % -3.2
222
+
223
+ # TODO think about DivisonByZero vs. Infinity
224
+ end
225
+
226
+ it "should allow arbitrary spacing" do
227
+ eval("4 % 2").should == 4 % 2
228
+ eval("4 %2").should == 4 % 2
229
+ eval("4% 2").should == 4 % 2
230
+ eval(" 4 % 2").should == 4 % 2
231
+ eval("4 % 2 ").should == 4 % 2
232
+ eval(" 4 % 2 ").should == 4 % 2
233
+ end
234
+
235
+ it "should perform left associative evaluation in chained expressions" do
236
+ eval("15 % 5 % 3").should == (15 % 5 % 3)
237
+ eval("16 % 9 % 4 % 2").should == (16 % 9 % 4 % 2)
238
+ end
239
+
240
+ it "should allow to override operator precedence with parentheses" do
241
+ eval("(16 % 4) % 2").should == (16 % 4) % 2
242
+ eval("16 % (5 % 3)").should == 16 % (5 % 3)
243
+ eval("(16 % 4) % (5 % 3)").should == (16 % 4) % (5 % 3)
244
+ eval("16 % (5 % 3) % 2").should == 16 % (5 % 3) % 2
245
+ end
246
+
247
+ end
248
+
249
+ describe "When evaluating exponential expressions, the language" do
250
+
251
+ include Trxl::SpecHelper
252
+
253
+ before(:each) do
254
+ @parser = Trxl::Calculator.new
255
+ end
256
+
257
+ it "should allow integers as operands" do
258
+ eval("1^1").should == 1 ** 1
259
+ eval("4^2").should == 4 ** 2
260
+ eval("8^3").should == 8 ** 3
261
+ eval("8^-3").should == 8 ** -3
262
+ end
263
+
264
+
265
+ it "should allow floats as operands" do
266
+ eval("1.0^1.0").should == 1.0 ** 1.0
267
+ eval("4.0^2.0").should == 4.0 ** 2.0
268
+ eval("8.0^3.2").should == 8.0 ** 3.2
269
+ eval("8.0^-3.2").should == 8.0 ** -3.2
270
+ end
271
+
272
+ it "should allow arbitrary spacing" do
273
+ eval("4 ^ 2").should == 4 ** 2
274
+ eval("4 ^2").should == 4 ** 2
275
+ eval("4^ 2").should == 4 ** 2
276
+ eval(" 4 ^ 2").should == 4 ** 2
277
+ eval("4 ^ 2 ").should == 4 ** 2
278
+ eval(" 4 ^ 2 ").should == 4 ** 2
279
+ end
280
+
281
+ it "should perform left associative evaluation in chained expressions" do
282
+ eval("2 ^ 2 ^ 2").should == (2 ** 2 ** 2)
283
+ eval("2 ^ 2 ^ 2 ^ 2").should == (2 ** 2 ** 2 ** 2)
284
+ end
285
+
286
+ end
287
+
288
+
289
+ describe "When evaluating arbitrary arithmetic expressions, the language" do
290
+
291
+ include Trxl::SpecHelper
292
+
293
+ before(:each) do
294
+ @parser = Trxl::Calculator.new
295
+ end
296
+
297
+ it "should respect arithmetic operator precedence" do
298
+ eval("2 + 4 * 2 + 2").should == 2 + 4 * 2 + 2
299
+ eval("2 + 4 / 2 + 2").should == 2 + 4 / 2 + 2
300
+ eval("2 + 5 % 3 + 2").should == 2 + 5 % 3 + 2
301
+ eval("2 + 4 ^ 2 + 2").should == 2 + 4 ** 2 + 2
302
+
303
+ eval("2 - 4 * 2 - 2").should == 2 - 4 * 2 - 2
304
+ eval("2 - 4 / 2 - 2").should == 2 - 4 / 2 - 2
305
+ eval("2 - 5 % 3 - 2").should == 2 - 5 % 3 - 2
306
+ eval("2 - 4 ^ 2 - 2").should == 2 - 4 ** 2 - 2
307
+
308
+ eval("2 * 4 * 2 - 2").should == 2 * 4 * 2 - 2
309
+ eval("8 / 4 / 2 - 2").should == 8 / 4 / 2 - 2
310
+ eval("8 % 4 % 2 - 2").should == 8 % 4 % 2 - 2
311
+ eval("2 ^ 2 ^ 2 - 2").should == 2 ** 2 ** 2 - 2
312
+
313
+ eval("2 * 4 * 2 - 2 * 3").should == 2 * 4 * 2 - 2 * 3
314
+ eval("8 / 4 / 2 - 4 / 2").should == 8 / 4 / 2 - 4 / 2
315
+ eval("8 % 4 % 2 - 5 % 3").should == 8 % 4 % 2 - 5 % 3
316
+ eval("2 ^ 2 ^ 2 - 2 ^ 2").should == 2 ** 2 ** 2 - 2 ** 2
317
+
318
+ eval("4 / 2 + 2 * 4 * 2 - 2 * 3").should == 4 / 2 + 2 * 4 * 2 - 2 * 3
319
+ eval("2 * 2 + 8 / 4 / 2 - 4 / 2").should == 2 * 2 + 8 / 4 / 2 - 4 / 2
320
+ eval("2 + 4 + 8 % 4 % 2 - 5 % 3").should == 2 + 4 + 8 % 4 % 2 - 5 % 3
321
+ eval("2 * 2 + 2 ^ 2 ^ 2 - 2 ^ 2").should == 2 * 2 + 2 ** 2 ** 2 - 2 ** 2
322
+
323
+ eval("4 + 2 - 2").should == 4 + 2 - 2
324
+ eval("4 * 2 / 2").should == 4 * 2 / 2
325
+ eval("4 * 2 % 2").should == 4 * 2 % 2
326
+
327
+ eval("4 - 2 + 2").should == 4 - 2 + 2
328
+ eval("4 / 2 * 2").should == 4 / 2 * 2
329
+ eval("4 % 2 * 2").should == 4 % 2 * 2
330
+ eval("4 ^ 2 * 2").should == 4 ** 2 * 2
331
+
332
+ end
333
+
334
+ it "should allow to override operator precedence using parentheses" do
335
+ eval("(2 + 4) * (2 + 2)").should == (2 + 4) * (2 + 2)
336
+ eval("(2 + 4) / (2 + 2)").should == (2 + 4).to_f / (2 + 2)
337
+ eval("(2 + 4) % (2 + 2)").should == (2 + 4) % (2 + 2)
338
+ eval("(2 + 4) ^ (2 + 2)").should == (2 + 4) ** (2 + 2)
339
+
340
+ eval("(2 - 4) * (2 - 2)").should == (2 - 4) * (2 - 2)
341
+ eval("(2 - 4) / (4 - 2)").should == (2 - 4).to_f / (4 - 2)
342
+ eval("(2 - 4) % (4 - 2)").should == (2 - 4) % (4 - 2)
343
+ eval("(2 - 4) ^ (2 - 2)").should == (2 - 4) ** (2 - 2)
344
+
345
+ eval("2 * 4 * (2 - 2)").should == 2 * 4 * (2 - 2)
346
+ eval("8 / (4 / 2) - 2").should == 8 / (4 / 2) - 2
347
+ eval("8 / (8 / 2 - 2)").should == 8 / (8 / 2 - 2)
348
+ eval("8 % (5 % 3) - 2").should == 8 % (5 % 3) - 2
349
+ eval("8 % (4 % 2 - 2)").should == 8 % (4 % 2 - 2)
350
+ eval("2 ^ (2 ^ 2) - 2").should == 2 ** (2 ** 2) - 2
351
+ eval("2 ^ (2 ^ 2 - 2)").should == 2 ** (2 ** 2 - 2)
352
+
353
+ eval("2 * 4 * (2 - 2) * 3").should == 2 * 4 * (2 - 2) * 3
354
+ eval("2 * 4 * (2 - 2 * 3)").should == 2 * 4 * (2 - 2 * 3)
355
+ eval("8 / 4 / (2 - 4) / 2").should == 8.0 / 4 / (2 - 4) / 2
356
+ eval("8 / 4 / (2 - 8 / 2)").should == 8.0 / 4 / (2 - 8 / 2)
357
+ eval("8 % 4 % (2 - 6) % 3").should == 8 % 4 % (2 - 6) % 3
358
+ eval("8 % 4 % (2 - 6 % 3)").should == 8 % 4 % (2 - 6 % 3)
359
+ eval("2 ^ 2 ^ (2 - 2) ^ 2").should == 2 ** 2 ** (2 - 2) ** 2
360
+ eval("2 ^ 2 ^ (2 - 2 ^ 2)").should == 2 ** 2 ** (2 - 2 ** 2)
361
+
362
+ eval("4 / (2 + 2 * 4) * (2 - 2) * 3").should == 4 / (2 + 2 * 4) * (2 - 2) * 3
363
+ eval("2 * (2 + 8 / 4 / 2 - 4) / 2").should == 2 * (2 + 8 / 4 / 2 - 4) / 2
364
+ eval("(2 + 4 + 8 % 4) % 2 - (5 % 3)").should == (2 + 4 + 8 % 4) % 2 - (5 % 3)
365
+ eval("(2 * 2 + 2) ^ (2 ^ 2) - 2 ^ 2").should == (2 * 2 + 2) ** (2 ** 2) - 2 ** 2
366
+ end
367
+
368
+
369
+ it "should allow to use variables as operands" do
370
+ env = { :a => 5, :b => 2, :foo => 3 }
371
+ eval("(((1 + 2 * a) - b * foo) * 2 + a) / foo", env).should == (((1 + 2 * env[:a]) - env[:b] * env[:foo]) * 2 + env[:a]) / env[:foo]
372
+ end
373
+
374
+ it "should allow to use function applications as operands" do
375
+ program = <<-PROGRAM
376
+ sum = fun(a,b) { a + b };
377
+ (2 * 2 + sum(2,4)) / 2
378
+ PROGRAM
379
+ eval(program).should == 5
380
+ end
381
+
382
+ it "should allow to use function applications and variables as operands" do
383
+ program = <<-PROGRAM
384
+ x = 2; y = 4;
385
+ sum = fun(a,b) { a + b };
386
+ (x * 2 + sum(x,y)) / 2
387
+ PROGRAM
388
+ eval(program).should == 5
389
+ end
390
+
391
+ end
@@ -0,0 +1,163 @@
1
+ require 'spec_helper'
2
+
3
+ describe "For working with Arrays, the language" do
4
+
5
+ include Trxl::SpecHelper
6
+
7
+ before(:each) do
8
+ @parser = Trxl::Calculator.new
9
+ end
10
+
11
+
12
+ it "should resolve positive offsets within arrays" do
13
+ env = { :foo => [ 1, 2, 3 ] }
14
+ eval("foo[0]", env).should == 1
15
+ eval("foo[1]", env).should == 2
16
+ eval("foo[2]", env).should == 3
17
+ eval("foo[3]", env).should be_nil
18
+ end
19
+
20
+ it "should recognize primary expressions as offset specifiers" do
21
+ env = { :foo => [ 1, 2, 3 ] }
22
+ eval("a = 0; foo[a]", env).should == 1
23
+ eval("foo[fun(x){x}(0)]", env).should == 1
24
+ end
25
+
26
+ it "should resolve negative offsets within arrays" do
27
+ env = { :foo => [ 1, 2, 3 ] }
28
+ eval("foo[-1]", env).should == 3
29
+ eval("foo[-2]", env).should == 2
30
+ eval("foo[-3]", env).should == 1
31
+ eval("foo[-4]", env).should be_nil
32
+ end
33
+
34
+ it "should resolve exact matching expressions" do
35
+ env = { :foo => [ 1, 2, 2, 3, 3, 3 ] }
36
+
37
+ eval("foo[=1]", env).should == [1]
38
+ eval("foo[=2]", env).should == [2,2]
39
+ eval("foo[=3]", env).should == [3,3,3]
40
+ eval("foo[=4]", env).should == []
41
+
42
+ env = { :foo => [ "foo", "foo", "bar" ] }
43
+
44
+ eval("foo[='foo']", env).should == [ "foo", "foo" ]
45
+ eval("foo[='bar']", env).should == [ "bar" ]
46
+ eval("foo[='baz']", env).should == []
47
+
48
+ env = { :foo => [ "foo", "foo", "bar" ], :a => "foo", :b => "bar", :c => "baz" }
49
+
50
+ eval("foo[=a]", env).should == [ "foo", "foo" ]
51
+ eval("foo[=b]", env).should == [ "bar" ]
52
+ eval("foo[=c]", env).should == []
53
+ end
54
+
55
+ it "should resolve exact matching expressions followed by offset access expressions" do
56
+ env = { :foo => [ 1, 2, 2, 3, 3, 3 ] }
57
+ eval("foo[=1][0]", env).should == 1
58
+ eval("foo[=2][0]", env).should == 2
59
+ eval("foo[=2][1]", env).should == 2
60
+ eval("foo[=3][0]", env).should == 3
61
+ eval("foo[=3][1]", env).should == 3
62
+ eval("foo[=3][2]", env).should == 3
63
+ eval("foo[=4][0]", env).should be_nil
64
+ end
65
+
66
+ it "should allow array variable definitions" do
67
+ eval("a = []").should == []
68
+ eval("a = []; a;").should == []
69
+ eval("a = [ 1, 2, 3 ]").should == [ 1, 2, 3 ]
70
+ eval("a = [ 1, 2, 3 ]; a;").should == [ 1, 2, 3 ]
71
+ end
72
+
73
+ it "should allow nested array variable definitions" do
74
+ eval("a = [[]]").should == [[]]
75
+ eval("a = [[]]; a;").should == [[]]
76
+ eval("a = [ [1, 2], [3, 4] ]").should == [ [1, 2], [3, 4] ]
77
+ eval("a = [ [1, 2], [3, 4] ]; a;").should == [ [1, 2], [3, 4] ]
78
+ end
79
+
80
+ it "should allow arbitrary expressions in array literal" do
81
+ eval("x = 1; foo = fun(x) {x}; arr = [ x, fun(){2}(), foo(3) ]").should == [ 1, 2, 3 ]
82
+ end
83
+
84
+ it "should be able to perform offset access expressions on user defined array variables" do
85
+ eval("a = [1,2,3]; a[0]").should == 1
86
+ eval("a = [1,2,3]; a[1]").should == 2
87
+ eval("a = [1,2,3]; a[2]").should == 3
88
+
89
+ eval("a = []; a[0]").should be_nil
90
+ eval("a = [[]]; a[0]").should == []
91
+ end
92
+
93
+ it "should be able to perform multiple offset access expressions on nested array variables" do
94
+ eval("a = [[]][0]").should == []
95
+ eval("a = [ [1, 2], [3, 4] ]; a[0]").should == [1, 2]
96
+ eval("a = [ [1, 2], [3, 4] ]; a[0][0];").should == 1
97
+ eval("a = [ [1, 2], [3, 4] ]; a[0][1];").should == 2
98
+ end
99
+
100
+ it "should return arrays for array literal expressions" do
101
+ eval("[1,2,3]").should == [ 1, 2, 3 ]
102
+ eval("[ 1, fun(){2}(), fun(x){x}(3) ]").should == [ 1, 2, 3 ]
103
+ end
104
+
105
+ it "should be able to perform offset access expressions on array literals" do
106
+ eval("[1,2,3][0]").should == 1
107
+ eval("[1,2,3][1]").should == 2
108
+ eval("[1,2,3][2]").should == 3
109
+ eval("[1,2,3][-1]").should == 3
110
+ eval("[1,2,3][-2]").should == 2
111
+ eval("[1,2,3][-3]").should == 1
112
+ end
113
+
114
+ it "should be able to calculate the size of any given Array or String" do
115
+ eval("a = [ 1, 2, 3 ]; SIZE(a);").should == 3
116
+ eval("SIZE(a = [ 1, 2, 3 ])").should == 3
117
+ eval("SIZE([ 1, 2, 3 ])").should == 3
118
+
119
+ eval("s = 'Test String'; SIZE(s);").should == "Test String".size
120
+ eval("SIZE(a = 'Test String')").should == "Test String".size
121
+ eval("SIZE('Test String')").should == "Test String".size
122
+
123
+ lambda { eval("SIZE(1)") }.should raise_error(Trxl::InvalidOperationException)
124
+ lambda { eval("SIZE(fun(){3}())") }.should raise_error(Trxl::InvalidOperationException)
125
+ end
126
+
127
+ it "should allow to push values into an already existing Array" do
128
+ eval("a = []; a << 1;").should == [ 1 ]
129
+ eval("a = []; a << 1; a;").should == [ 1 ]
130
+ eval("a = [1]; a << 2;").should == [ 1, 2 ]
131
+ eval("a = [1]; a << 2; a;").should == [ 1, 2 ]
132
+ lambda { eval("a = 1; a << 2;") }.should raise_error(Trxl::InvalidOperationException)
133
+
134
+ #eval("a = [[]]; a[0] << 1;").should == [ [1] ]
135
+ eval("a = [[]]; a[0] << 1; a;").should == [ [1] ]
136
+ eval("a = [1]; a << [2];").should == [ 1, [ 2 ] ]
137
+ eval("a = [1]; a << [2]; a;").should == [ 1, [ 2 ] ]
138
+ lambda { eval("a = [1]; a[0] << 2;") }.should raise_error(Trxl::InvalidOperationException)
139
+ end
140
+
141
+ it "should allow to add two Arrays" do
142
+ eval("[1,2,3] + []").should == [1,2,3]
143
+ eval("[] + [4,5,6]").should == [4,5,6]
144
+ eval("[1,2,3] + [4,5,6]").should == [1,2,3,4,5,6]
145
+
146
+ eval("[[1,2],3] + []").should == [[1,2],3]
147
+ eval("[[]] + [4,5,6]").should == [[],4,5,6]
148
+ eval("[[1,2],3] + [[4,5],6]").should == [[1,2],3,[4,5],6]
149
+ end
150
+
151
+ it "should allow to subtract two Arrays" do
152
+ eval("[1,2,3] - []").should == [1,2,3]
153
+ eval("[] - [4,5,6]").should == []
154
+ eval("[1,2,3] - [4,5,6]").should == [1,2,3]
155
+ eval("[1,2,3,4,5,6] - [4,5,6]").should == [1,2,3]
156
+
157
+ eval("[[1,2],3] - []").should == [[1,2],3]
158
+ eval("[[]] - [4,5,6]").should == [[]]
159
+ eval("[[1,2],3] - [4,5,6]").should == [[1,2],3]
160
+ eval("[1,2,3,[4],5,[6]] - [4,5,6]").should == [1,2,3,[4],[6]]
161
+ end
162
+
163
+ end