AmberVM 0.0.19

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.
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