AmberVM 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/README +38 -0
  2. data/bin/ambervm +278 -0
  3. data/lib/amber/acts_as_rvm_type.rb +157 -0
  4. data/lib/amber/classes/association.rb +36 -0
  5. data/lib/amber/classes/block.rb +52 -0
  6. data/lib/amber/classes/boolean.rb +40 -0
  7. data/lib/amber/classes/class.rb +50 -0
  8. data/lib/amber/classes/error.rb +22 -0
  9. data/lib/amber/classes/list.rb +96 -0
  10. data/lib/amber/classes/null.rb +35 -0
  11. data/lib/amber/classes/number.rb +95 -0
  12. data/lib/amber/classes/object.rb +56 -0
  13. data/lib/amber/classes/string.rb +79 -0
  14. data/lib/amber/classes.rb +113 -0
  15. data/lib/amber/environment.rb +251 -0
  16. data/lib/amber/fukubukuro/ecma_core.rb +409 -0
  17. data/lib/amber/fukubukuro.rb +866 -0
  18. data/lib/amber/functions/all.rb +3 -0
  19. data/lib/amber/functions/array/append.rb +50 -0
  20. data/lib/amber/functions/array/at.rb +50 -0
  21. data/lib/amber/functions/array/set_at.rb +50 -0
  22. data/lib/amber/functions/array.rb +30 -0
  23. data/lib/amber/functions/association/assoc_get.rb +55 -0
  24. data/lib/amber/functions/association/assoc_set.rb +56 -0
  25. data/lib/amber/functions/bitwise/bitwise_and.rb +41 -0
  26. data/lib/amber/functions/bitwise/bitwise_not.rb +41 -0
  27. data/lib/amber/functions/bitwise/bitwise_or.rb +41 -0
  28. data/lib/amber/functions/bitwise/bitwise_xor.rb +41 -0
  29. data/lib/amber/functions/bitwise.rb +3 -0
  30. data/lib/amber/functions/collection/get.rb +66 -0
  31. data/lib/amber/functions/collection/set.rb +67 -0
  32. data/lib/amber/functions/collection/size.rb +54 -0
  33. data/lib/amber/functions/general/cmp.rb +43 -0
  34. data/lib/amber/functions/general/eq.rb +45 -0
  35. data/lib/amber/functions/general/gt.rb +45 -0
  36. data/lib/amber/functions/general/gte.rb +45 -0
  37. data/lib/amber/functions/general/lt.rb +45 -0
  38. data/lib/amber/functions/general/lte.rb +45 -0
  39. data/lib/amber/functions/general/neq.rb +45 -0
  40. data/lib/amber/functions/general/type.rb +43 -0
  41. data/lib/amber/functions/general.rb +3 -0
  42. data/lib/amber/functions/io/print.rb +45 -0
  43. data/lib/amber/functions/io.rb +3 -0
  44. data/lib/amber/functions/list/align.rb +73 -0
  45. data/lib/amber/functions/list/join.rb +45 -0
  46. data/lib/amber/functions/list/map.rb +58 -0
  47. data/lib/amber/functions/list/split.rb +55 -0
  48. data/lib/amber/functions/list.rb +3 -0
  49. data/lib/amber/functions/logic/and.rb +55 -0
  50. data/lib/amber/functions/logic/not.rb +40 -0
  51. data/lib/amber/functions/logic/or.rb +50 -0
  52. data/lib/amber/functions/logic.rb +3 -0
  53. data/lib/amber/functions/math/abs.rb +39 -0
  54. data/lib/amber/functions/math/acos.rb +39 -0
  55. data/lib/amber/functions/math/add.rb +40 -0
  56. data/lib/amber/functions/math/asin.rb +39 -0
  57. data/lib/amber/functions/math/atan.rb +39 -0
  58. data/lib/amber/functions/math/ceil.rb +39 -0
  59. data/lib/amber/functions/math/cos.rb +39 -0
  60. data/lib/amber/functions/math/dec.rb +39 -0
  61. data/lib/amber/functions/math/div.rb +44 -0
  62. data/lib/amber/functions/math/exp.rb +39 -0
  63. data/lib/amber/functions/math/floor.rb +39 -0
  64. data/lib/amber/functions/math/inc.rb +39 -0
  65. data/lib/amber/functions/math/log.rb +39 -0
  66. data/lib/amber/functions/math/mod.rb +41 -0
  67. data/lib/amber/functions/math/mul.rb +43 -0
  68. data/lib/amber/functions/math/neg.rb +43 -0
  69. data/lib/amber/functions/math/power.rb +43 -0
  70. data/lib/amber/functions/math/rand.rb +36 -0
  71. data/lib/amber/functions/math/round.rb +39 -0
  72. data/lib/amber/functions/math/shl.rb +41 -0
  73. data/lib/amber/functions/math/shr.rb +41 -0
  74. data/lib/amber/functions/math/sin.rb +39 -0
  75. data/lib/amber/functions/math/sub.rb +43 -0
  76. data/lib/amber/functions/math/tan.rb +39 -0
  77. data/lib/amber/functions/math.rb +3 -0
  78. data/lib/amber/functions/objects/send.rb +22 -0
  79. data/lib/amber/functions/rails/print.rb +44 -0
  80. data/lib/amber/functions/rails.rb +3 -0
  81. data/lib/amber/functions/string/ansi.rb +24 -0
  82. data/lib/amber/functions/string/capstr.rb +23 -0
  83. data/lib/amber/functions/string/center.rb +25 -0
  84. data/lib/amber/functions/string/chr.rb +16 -0
  85. data/lib/amber/functions/string/ljust.rb +26 -0
  86. data/lib/amber/functions/string/regmatch.rb +34 -0
  87. data/lib/amber/functions/string/rjust.rb +26 -0
  88. data/lib/amber/functions/string.rb +3 -0
  89. data/lib/amber/functions.rb +103 -0
  90. data/lib/amber/interpreter.rb +1380 -0
  91. data/lib/amber/languages/brainfuck.rb +153 -0
  92. data/lib/amber/languages/ecma/compiler.rb +1661 -0
  93. data/lib/amber/languages/ecma/core-math.js +67 -0
  94. data/lib/amber/languages/ecma/core-objects.js +57 -0
  95. data/lib/amber/languages/ecma.rb +9 -0
  96. data/lib/amber/languages/ecma_fuku/compiler.rb +1622 -0
  97. data/lib/amber/languages/ecma_fuku/core-math.js +67 -0
  98. data/lib/amber/languages/ecma_fuku/core-objects.js +56 -0
  99. data/lib/amber/languages/ecma_fuku.rb +13 -0
  100. data/lib/amber/languages/math/compiler.rb +70 -0
  101. data/lib/amber/languages/math/tokenizer.rb +69 -0
  102. data/lib/amber/languages/math/tree.rb +110 -0
  103. data/lib/amber/languages/math.rb +26 -0
  104. data/lib/amber/languages.rb +99 -0
  105. data/lib/amber/library.rb +79 -0
  106. data/lib/amber/optimisation.rb +299 -0
  107. data/lib/amber/plugin.rb +337 -0
  108. data/lib/amber/rails.rb +90 -0
  109. data/lib/amber.rb +106 -0
  110. data/spec/amber/class_spec.rb +27 -0
  111. data/spec/amber/enviroment_spec.rb +61 -0
  112. data/spec/amber/function_spec.rb +25 -0
  113. data/spec/amber/functions/association/assoc_get_spec.rb +41 -0
  114. data/spec/amber/functions/association/assoc_set_spec.rb +43 -0
  115. data/spec/amber/functions/collection/get_spec.rb +12 -0
  116. data/spec/amber/functions/collection/set_spec.rb +10 -0
  117. data/spec/amber/functions/collection/size_spec.rb +10 -0
  118. data/spec/amber/functions/list/split_spec.rb +47 -0
  119. data/spec/amber/functions/string/ansi_spec.rb +44 -0
  120. data/spec/amber/functions/string/capstr_spec.rb +42 -0
  121. data/spec/amber/functions/string/center_spec.rb +49 -0
  122. data/spec/amber/functions/string/ljust_spec.rb +49 -0
  123. data/spec/amber/functions/string/regmatch_spec.rb +52 -0
  124. data/spec/amber/functions/string/rjust_spec.rb +49 -0
  125. data/spec/amber/interpreter/assignment_spec.rb +22 -0
  126. data/spec/amber/interpreter/condition_spec.rb +103 -0
  127. data/spec/amber/interpreter/constant_spec.rb +31 -0
  128. data/spec/amber/interpreter/core_call_spec.rb +72 -0
  129. data/spec/amber/interpreter/interpreter_spec.rb +11 -0
  130. data/spec/amber/interpreter/parameter_spec.rb +24 -0
  131. data/spec/amber/interpreter/sequence_spec.rb +47 -0
  132. data/spec/amber/interpreter/variable_spec.rb +24 -0
  133. data/spec/amber/plugin_spec.rb +10 -0
  134. data/spec/classes/atom/association_spec.rb +39 -0
  135. data/spec/classes/atom/block_spec.rb +25 -0
  136. data/spec/classes/atom/boolean_spec.rb +67 -0
  137. data/spec/classes/atom/error_spec.rb +43 -0
  138. data/spec/classes/atom/list_spec.rb +68 -0
  139. data/spec/classes/atom/number_spec.rb +132 -0
  140. data/spec/classes/atom/string_spec.rb +175 -0
  141. data/spec/languages/ecma/ecma_array_spec.rb +79 -0
  142. data/spec/languages/ecma/ecma_closure_spec.rb +38 -0
  143. data/spec/languages/ecma/ecma_literals_spec.rb +71 -0
  144. data/spec/languages/ecma/ecma_objects_spec.rb +165 -0
  145. data/spec/languages/ecma/ecma_old_spec.rb +540 -0
  146. data/spec/languages/ecma/ecma_spec.rb +64 -0
  147. data/spec/languages/ecma_fuku/ecma_array_spec.rb +61 -0
  148. data/spec/languages/ecma_fuku/ecma_closure_spec.rb +33 -0
  149. data/spec/languages/ecma_fuku/ecma_function_spec.rb +84 -0
  150. data/spec/languages/ecma_fuku/ecma_literals_spec.rb +55 -0
  151. data/spec/languages/ecma_fuku/ecma_objects_spec.rb +133 -0
  152. data/spec/languages/ecma_fuku/ecma_old_spec.rb +415 -0
  153. data/spec/languages/ecma_fuku/ecma_operator_spec.rb +33 -0
  154. data/spec/languages/ecma_fuku/ecma_spec.rb +52 -0
  155. data/spec/languages/math/compiler_spec.rb +49 -0
  156. data/spec/languages/math/tokenizer_spec.rb +73 -0
  157. data/spec/languages/math/tree_spec.rb +153 -0
  158. metadata +225 -0
@@ -0,0 +1,165 @@
1
+ $: << 'lib'
2
+
3
+ require 'amber'
4
+ require 'amber/languages'
5
+ require 'amber/languages/ecma'
6
+
7
+
8
+ describe AmberVM::Languages::ECMA do
9
+ before(:each) do
10
+ @env = AmberVM::Interpreter.env
11
+ @compiler = AmberVM::Languages::ECMA.new
12
+ end
13
+
14
+ def run code, &tests
15
+ env = @env.dup
16
+ yield(@compiler.compile(code).execute(@env), @env)
17
+ yield(@compiler.compile(code).optimize.execute(env), env)
18
+ end
19
+
20
+ describe "objects" do
21
+ it "should see outer functions" do
22
+ code = <<-CODE
23
+ function a() {
24
+ return 1;
25
+ }
26
+ o = {
27
+ b: function() {
28
+ return a();
29
+ }
30
+ };
31
+ o.b();
32
+ CODE
33
+ run code do
34
+ end
35
+ end
36
+
37
+ it "should not automaticall address it's own variables" do
38
+ code = <<-CODE
39
+ x = 42;
40
+ o = {
41
+ x: 23,
42
+ f: function() {
43
+ return x;
44
+ }
45
+ };
46
+ o.f();
47
+ CODE
48
+ run code do |result, env|
49
+ result.should == 42
50
+ end
51
+ end
52
+
53
+ it "should not make functions closours" do
54
+ code = <<-CODE
55
+ x = 1;
56
+ o = {
57
+ x: 23,
58
+ f: function() {
59
+ return x;
60
+ }
61
+ };
62
+ x = 42;
63
+ o.f();
64
+ CODE
65
+ run code do |result, env|
66
+ result.should == 42
67
+ end
68
+ end
69
+
70
+ it "should see it's own variables with this" do
71
+ code = <<-CODE
72
+ o = {
73
+ x: 23,
74
+ f: function() {
75
+ return this.x;
76
+ }
77
+ };
78
+ o.f();
79
+ CODE
80
+ run code do |result, env|
81
+ result.should == 23
82
+ end
83
+ end
84
+
85
+ it "should switch this correctly" do
86
+ code = <<-CODE
87
+ n = {
88
+ x: 42,
89
+ f: function() {
90
+ return this.x;
91
+ }
92
+ };
93
+ o = {
94
+ x: 23,
95
+ f: function() {
96
+ return n.f();
97
+ }
98
+ };
99
+ o.f();
100
+ CODE
101
+ run code do |result, env|
102
+ result.should == 42
103
+ end
104
+ end
105
+
106
+ it "should switch this back correctly" do
107
+ code = <<-CODE
108
+ n = {
109
+ x: 42,
110
+ f: function() {
111
+ return this.x;
112
+ }
113
+ };
114
+ o = {
115
+ x: 23,
116
+ f: function() {
117
+ n.f();
118
+ return this.x;
119
+ }
120
+ };
121
+ o.f();
122
+ CODE
123
+ run code do |result, env|
124
+ result.should == 23
125
+ end
126
+ end
127
+
128
+ it "should get varibles" do
129
+ object = AmberVM::Classes::Object.new(nil)
130
+ object.variables['variable'] = 42
131
+ @env['obj'] = object
132
+ code = <<-CODE
133
+ obj.variable
134
+ CODE
135
+ run code do |result, env|
136
+ result.should == 42
137
+ end
138
+ end
139
+
140
+ it "should allow to concat objects varibles" do
141
+ object = AmberVM::Classes::Object.new(nil)
142
+ object2 =AmberVM::Classes::Object.new(nil)
143
+ object.variables['obj'] = object2
144
+ object2.variables['variable'] = 42
145
+ @env['obj'] = object
146
+ code = <<-CODE
147
+ obj.obj.variable
148
+ CODE
149
+ run code do |result, env|
150
+ result.should == 42
151
+ end
152
+ end
153
+
154
+ it "should allow to assign literals to variables" do
155
+ code = <<-CODE
156
+ test = 23;
157
+ CODE
158
+ run code do |result, env|
159
+ result.should == 23
160
+ env['test'].val.should == 23
161
+ end
162
+
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,540 @@
1
+ $: << 'lib'
2
+
3
+ require 'amber'
4
+ require 'amber/languages'
5
+ require 'amber/languages/ecma'
6
+
7
+ describe AmberVM::Languages::ECMA do
8
+ before(:each) do
9
+ @compiler = AmberVM::Languages::ECMA.new
10
+ @env = @compiler.env
11
+ end
12
+
13
+
14
+
15
+ def run code, &test
16
+ env = @compiler.env
17
+ @env.data[:locals].each do |k,v|
18
+ env[k] = v.val
19
+ end
20
+ yield(@compiler.compile(code).execute(@env), @env)
21
+ yield(@compiler.compile(code).optimize.execute(env), env)
22
+ end
23
+
24
+ describe "literals" do
25
+ describe "strings" do
26
+ it "should handle string literals" do
27
+ code = <<-EOC
28
+ "Hallo!"
29
+ EOC
30
+ run code do |result, env|
31
+ result.should == "Hallo!"
32
+ end
33
+ end
34
+
35
+ it "should handle newline replacements" do
36
+ code = '"\n"'
37
+ run code do |result, env|
38
+ result.should == "\n"
39
+ end
40
+ end
41
+
42
+ it "should handle newline replacements" do
43
+ code =<<-'EOC'
44
+ "\t"
45
+ EOC
46
+ run code do |result, env|
47
+ result.should == "\t"
48
+ end
49
+ end
50
+ it "should handle newline replacements" do
51
+ code = <<-'EOC'
52
+ "\n"
53
+ EOC
54
+ run code do |result, env|
55
+ result.should == "\n"
56
+ end
57
+ end
58
+
59
+ it "should handle double escapes" do
60
+ code = <<-'EOC'
61
+ "\\t"
62
+ EOC
63
+ run code do |result, env|
64
+ result.should == "\\t"
65
+ end
66
+ end
67
+
68
+ it "should handle double escapes followed by single escapes" do
69
+ code = <<-'EOF'
70
+ "\\\t"
71
+ EOF
72
+ run code do |result, env|
73
+ result.should == "\\\t"
74
+ end
75
+ end
76
+ end
77
+
78
+ it "should handle number literals" do
79
+ code = <<-EOC
80
+ 42
81
+ EOC
82
+ run code do |result, env|
83
+ result.should == 42
84
+ end
85
+ end
86
+
87
+ describe "array" do
88
+ it "should handle array literals with no elements" do
89
+ code = <<-EOC
90
+ []
91
+ EOC
92
+ run code do |result, env|
93
+ result.should == []
94
+ end
95
+ end
96
+
97
+ it "should handle array literals with one element" do
98
+ code = <<-EOC
99
+ ["Kekse!"]
100
+ EOC
101
+ run code do |result, env|
102
+ result.should == ["Kekse!"]
103
+ end
104
+ end
105
+
106
+ it "should handle array literals with arrays in it" do
107
+ code = <<-EOC
108
+ [["Kekse!",2],1]
109
+ EOC
110
+ run code do |result, env|
111
+ result.should == [["Kekse!",2],1]
112
+ end
113
+ end
114
+
115
+ it "should handle array literals with multiple elements" do
116
+ code = <<-EOC
117
+ [42, "Kekse!"]
118
+ EOC
119
+ run code do |result, env|
120
+ result.should == [42, "Kekse!"]
121
+ end
122
+ end
123
+
124
+ it "should allow to set array elements" do
125
+ code = <<-EOC
126
+ array = [];
127
+ array[0] = 42;
128
+ array;
129
+ EOC
130
+ run code do |result, env|
131
+ result.should == [42]
132
+ end
133
+ end
134
+ end
135
+
136
+ describe "Objects array" do
137
+ it "should handle an empty object" do
138
+ code = <<-EOC
139
+ {}
140
+ EOC
141
+ run code do |result, env|
142
+ result.should be_instance_of(AmberVM::Classes::Object)
143
+ end
144
+ end
145
+
146
+ it "should handle an object with variables" do
147
+ code = <<-EOC
148
+ {a: 1}
149
+ EOC
150
+ run code do |result, env|
151
+ result.should be_instance_of(AmberVM::Classes::Object)
152
+ result.variables['a'].val.should == 1
153
+ end
154
+ end
155
+ it "should handle an object with functions" do
156
+ code = <<-EOC
157
+ o = {
158
+ f: function(){
159
+ return 1;
160
+ }
161
+ };
162
+ EOC
163
+ run code do |result, env|
164
+ result.should be_instance_of(AmberVM::Classes::Object)
165
+ result.variables.keys.should include('f')
166
+ end
167
+ end
168
+ end
169
+
170
+ it "should handle true literals" do
171
+ code = <<-EOC
172
+ true
173
+ EOC
174
+ run code do |result, env|
175
+ result.should be_is_true
176
+ end
177
+ end
178
+
179
+ it "should handle false literals" do
180
+ code = <<-EOC
181
+ false
182
+ EOC
183
+ run code do |result, env|
184
+ result.should_not be_is_true
185
+ end
186
+ end
187
+ end
188
+
189
+ describe "array" do
190
+ it "should allow accessing elements" do
191
+ @env['a'] = AmberVM::Classes::List.new([1,2,3])
192
+ code = <<-EOC
193
+ a[0]
194
+ EOC
195
+ run code do |result, env|
196
+ result.should == 1
197
+ end
198
+ end
199
+
200
+ it "should allow setting elements" do
201
+ @env['a'] = AmberVM::Classes::List.new([1,2,3])
202
+ code = <<-EOC
203
+ a[0] = 42;
204
+ EOC
205
+ run code do |result, env|
206
+ result.should == 42
207
+ env['a'].val[0].val.should == 42
208
+ end
209
+ end
210
+
211
+ it "should allow accessing the length" do
212
+ @env['a'] = AmberVM::Classes::List.new([1,2,3])
213
+ code = <<-EOC
214
+ a.length;
215
+ EOC
216
+ run code do |result, env|
217
+ result.should == 3
218
+ end
219
+ end
220
+ end
221
+
222
+ describe "variables" do
223
+ it "should recognize simple assignments" do
224
+ code = <<-EOC
225
+ variable = 'value';
226
+ EOC
227
+ run code do |result, env|
228
+ result.should == 'value'
229
+ env['variable'].val.should == 'value'
230
+ end
231
+ end
232
+
233
+ it "should recognize local assignments" do
234
+ code = <<-EOC
235
+ var variable = 'value';
236
+ EOC
237
+ run code do |result, env|
238
+ result.should == 'value'
239
+ env['variable'].val.should == 'value'
240
+ end
241
+ end
242
+
243
+ it "should recognize multiple local assignments" do
244
+ code = <<-EOC
245
+ var i = 'a', j= 'b';
246
+ EOC
247
+ run code do |result, env|
248
+ result.should == 'b'
249
+ env['i'].val.should == 'a'
250
+ env['j'].val.should == 'b'
251
+ end
252
+ end
253
+
254
+ it "should scope local assignments correctly" do
255
+ code = <<-EOC
256
+ variable = 'outer scope';
257
+ {
258
+ var variable = 'inner scope';
259
+ }
260
+ EOC
261
+ run code do |result, env|
262
+ result.should == 'inner scope'
263
+ env['variable'].val.should == 'inner scope'
264
+ end
265
+ end
266
+ end
267
+
268
+ describe "conditions" do
269
+ describe "true condition" do
270
+ describe "without blocks" do
271
+
272
+ it "should handle conditions without else" do
273
+ code = <<-EOC
274
+ if (true)
275
+ 42
276
+ EOC
277
+ run code do |result, env|
278
+ result.should == 42
279
+ end
280
+ end
281
+
282
+ it "should handle conditions with else" do
283
+ code = <<-EOC
284
+ if (true)
285
+ 42;
286
+ else
287
+ 23;
288
+ EOC
289
+ run code do |result, env|
290
+ result.should == 42
291
+ end
292
+ end
293
+
294
+ it "should handle conditions with else and ugly ';'" do
295
+ code = <<-EOC
296
+ if (true)
297
+ 42;
298
+ else
299
+ 23
300
+ EOC
301
+ run code do |result, env|
302
+ result.should == 42
303
+ end
304
+ end
305
+ end
306
+
307
+ describe "with blocks" do
308
+ it "should handle conditions without else" do
309
+ code = <<-EOC
310
+ if (true) {
311
+ 42;
312
+ }
313
+ EOC
314
+ run code do |result, env|
315
+ result.should == 42
316
+ end
317
+ end
318
+ it "should handle conditions with else" do
319
+ code = <<-EOC
320
+ if (true) {
321
+ 42;
322
+ } else {
323
+ 23;
324
+ }
325
+ EOC
326
+ run code do |result, env|
327
+ result.should == 42
328
+ end
329
+ end
330
+ end
331
+ end
332
+ describe "false condition" do
333
+ describe "without blocks" do
334
+ it "should handle loops without else" do
335
+ code = <<-EOC
336
+ if (false)
337
+ 42;
338
+ EOC
339
+ run code do |result, env|
340
+ result.should be_nil
341
+ end
342
+ end
343
+ it "should handle conditions with else" do
344
+ code = <<-EOC
345
+ if (false)
346
+ 42;
347
+ else
348
+ 23;
349
+ EOC
350
+ run code do |result, env|
351
+ result.should == 23
352
+ end
353
+ end
354
+ end
355
+ describe "with blocks" do
356
+ it "should handle conditions without else" do
357
+ code = <<-EOC
358
+ if (false) {
359
+ 42;
360
+ }
361
+ EOC
362
+ run code do |result, env|
363
+ result.should be_nil
364
+ end
365
+ end
366
+ it "should handle conditions with else" do
367
+ code = <<-EOC
368
+ if (false) {
369
+ 42;
370
+ } else {
371
+ 23;
372
+ }
373
+ EOC
374
+ run code do |result, env|
375
+ result.should == 23
376
+ end
377
+ end
378
+ end
379
+ end
380
+ end
381
+
382
+ describe "loops" do
383
+ it "should handle for loops" do
384
+ code = <<-EOC
385
+ variable = "";
386
+ for (i = 0; i <= 3; i = i + 1) {
387
+ variable = variable + i;
388
+ }
389
+ EOC
390
+ run code do |result, env|
391
+ result.should == 4
392
+ env['variable'].val.should == '0123'
393
+ end
394
+ end
395
+
396
+ it "should handle for loops (bug prevention)" do
397
+ code = <<-EOC
398
+ function test() {for (var i = 1; i <= 2; i+=1) {};};
399
+ test();
400
+ EOC
401
+ (proc{ run(code){} }).should_not raise_error
402
+ end
403
+
404
+ it "should handle while loops" do
405
+ code = <<-EOC
406
+ variable = "";
407
+ i = 0;
408
+ while (i < 3) {
409
+ i = i + 1;
410
+ variable = variable + i;
411
+ }
412
+ EOC
413
+ run code do |result, env|
414
+ result.should == '123'
415
+ env['variable'].val.should == '123'
416
+ end
417
+ end
418
+
419
+ it "should handle do while loops" do
420
+ code = <<-EOC
421
+ variable = "";
422
+ i = 0;
423
+ do {
424
+ i = i + 1;
425
+ variable = variable + i;
426
+ } while (i < 3)
427
+ EOC
428
+ run code do |result, env|
429
+ result.should == '123'
430
+ env['variable'].val.should == '123'
431
+ end
432
+ end
433
+ end
434
+
435
+ it "should execute do while loops at least once" do
436
+ code = <<-EOC
437
+ variable = "";
438
+ i = 0;
439
+ do {
440
+ i = i + 1;
441
+ variable = variable + i;
442
+ } while (i < 0);
443
+ EOC
444
+ run code do |result, env|
445
+ result.should be_nil
446
+ env['variable'].val.should == '1'
447
+ end
448
+ end
449
+
450
+
451
+
452
+ describe "functions" do
453
+ it "should handle function definitions without variables" do
454
+ code = <<-EOC
455
+ function f() {
456
+ 42;
457
+ }
458
+ EOC
459
+ run code do |result, env|
460
+ result.class.should.kind_of? AmberVM::Interpreter::Clousure::Binding
461
+ env['f'].should be
462
+ end
463
+ end
464
+
465
+ it "should handle function definitions with variables" do
466
+ code = <<-EOC
467
+ function g(x) {
468
+ 42 + x;
469
+ }
470
+ EOC
471
+ run code do |result, env|
472
+ result.class.should <= AmberVM::Interpreter::Clousure::Binding
473
+ env['g'].should be
474
+ end
475
+ end
476
+ end
477
+
478
+ describe "objects" do
479
+ it "should handle object variables" do
480
+ obj = mock('object mock')
481
+ varialbes = mock('variables')
482
+ obj.should_receive(:variables).twice.and_return(varialbes)
483
+ varialbes.should_receive(:[]).twice.with('test').and_return(AmberVM::Interpreter::VariableStorage.new('ok'))
484
+ @env['obj'] = obj
485
+ code = <<-EOC
486
+ obj.test;
487
+ EOC
488
+ run code do |result, env|
489
+ result.should == 'ok'
490
+ end
491
+ end
492
+
493
+ end
494
+
495
+
496
+ describe "opperators" do
497
+ it "should recognize ++" do
498
+ @env['i'] = AmberVM::Classes::Number.new(41)
499
+ code = <<-EOC
500
+ i++;
501
+ EOC
502
+ run code do |result, env|
503
+ result.should == 41
504
+ env['i'].val.should == 42
505
+ end
506
+ end
507
+
508
+ it "should recognize --" do
509
+ @env['i'] = AmberVM::Classes::Number.new(43)
510
+ code = <<-EOC
511
+ i--;
512
+ EOC
513
+ run code do |result, env|
514
+ result.should == 43
515
+ env['i'].val.should == 42
516
+ end
517
+ end
518
+
519
+ it "should recognize +=" do
520
+ @env['i'] = AmberVM::Classes::Number.new(40)
521
+ code = <<-EOC
522
+ i += 2;
523
+ EOC
524
+ v = 42
525
+ run code do |result, env|
526
+ result.should == 42
527
+ end
528
+ end
529
+ it "should recognize -=" do
530
+ @env['i'] = AmberVM::Classes::Number.new(44)
531
+ code = <<-EOC
532
+ i -= 2;
533
+ EOC
534
+ v = 42
535
+ run code do |result, env|
536
+ result.should == 42
537
+ end
538
+ end
539
+ end
540
+ end