rVM 0.0.14 → 0.0.17

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 (113) hide show
  1. data/README +4 -4
  2. data/bin/rvm +229 -0
  3. data/lib/rvm.rb +6 -6
  4. data/lib/rvm/acts_as_rvm_type.rb +26 -3
  5. data/lib/rvm/classes.rb +9 -15
  6. data/lib/rvm/classes/block.rb +8 -3
  7. data/lib/rvm/classes/class.rb +2 -2
  8. data/lib/rvm/classes/list.rb +1 -1
  9. data/lib/rvm/classes/null.rb +31 -0
  10. data/lib/rvm/classes/number.rb +4 -0
  11. data/lib/rvm/classes/object.rb +1 -1
  12. data/lib/rvm/classes/string.rb +6 -1
  13. data/lib/rvm/environment.rb +256 -0
  14. data/lib/rvm/functions.rb +9 -4
  15. data/lib/rvm/functions/array.rb +26 -2
  16. data/lib/rvm/functions/array/append.rb +31 -1
  17. data/lib/rvm/functions/array/at.rb +29 -1
  18. data/lib/rvm/functions/array/set_at.rb +29 -0
  19. data/lib/rvm/functions/association/assoc_get.rb +34 -0
  20. data/lib/rvm/functions/association/assoc_set.rb +32 -0
  21. data/lib/rvm/functions/bitwise.rb +3 -0
  22. data/lib/rvm/functions/bitwise/bitwise_and.rb +41 -0
  23. data/lib/rvm/functions/bitwise/bitwise_or.rb +41 -0
  24. data/lib/rvm/functions/bitwise/bitwise_xor.rb +41 -0
  25. data/lib/rvm/functions/collection/get.rb +37 -4
  26. data/lib/rvm/functions/collection/set.rb +37 -3
  27. data/lib/rvm/functions/collection/size.rb +33 -1
  28. data/lib/rvm/functions/general/cmp.rb +35 -7
  29. data/lib/rvm/functions/general/eq.rb +29 -0
  30. data/lib/rvm/functions/general/gt.rb +29 -0
  31. data/lib/rvm/functions/general/gte.rb +29 -0
  32. data/lib/rvm/functions/general/lt.rb +29 -0
  33. data/lib/rvm/functions/general/lte.rb +29 -0
  34. data/lib/rvm/functions/general/neq.rb +5 -0
  35. data/lib/rvm/functions/io/print.rb +38 -8
  36. data/lib/rvm/functions/list/align.rb +25 -1
  37. data/lib/rvm/functions/list/join.rb +27 -0
  38. data/lib/rvm/functions/list/map.rb +34 -0
  39. data/lib/rvm/functions/list/split.rb +31 -0
  40. data/lib/rvm/functions/logic/and.rb +36 -2
  41. data/lib/rvm/functions/logic/not.rb +27 -0
  42. data/lib/rvm/functions/logic/or.rb +32 -2
  43. data/lib/rvm/functions/math/add.rb +25 -0
  44. data/lib/rvm/functions/math/cos.rb +39 -0
  45. data/lib/rvm/functions/math/div.rb +25 -0
  46. data/lib/rvm/functions/math/mod.rb +41 -0
  47. data/lib/rvm/functions/math/mul.rb +25 -0
  48. data/lib/rvm/functions/math/neg.rb +25 -0
  49. data/lib/rvm/functions/math/power.rb +25 -0
  50. data/lib/rvm/functions/math/shl.rb +41 -0
  51. data/lib/rvm/functions/math/shr.rb +41 -0
  52. data/lib/rvm/functions/math/sin.rb +39 -0
  53. data/lib/rvm/functions/math/sub.rb +25 -0
  54. data/lib/rvm/functions/math/tan.rb +39 -0
  55. data/lib/rvm/functions/rails/print.rb +33 -3
  56. data/lib/rvm/interpreter.rb +405 -272
  57. data/lib/rvm/languages.rb +45 -11
  58. data/lib/rvm/languages/brainfuck.rb +15 -16
  59. data/lib/rvm/languages/ecma.rb +4 -1257
  60. data/lib/rvm/languages/ecma/compiler.rb +1353 -0
  61. data/lib/rvm/languages/ecma/core-math.js +84 -0
  62. data/lib/rvm/languages/math.rb +9 -16
  63. data/lib/rvm/languages/math/compiler.rb +9 -9
  64. data/lib/rvm/languages/math/tokenizer.rb +1 -1
  65. data/lib/rvm/languages/math/tree.rb +14 -14
  66. data/lib/rvm/library.rb +26 -18
  67. data/lib/rvm/optimisation.rb +109 -0
  68. data/lib/rvm/plugin.rb +109 -45
  69. data/lib/rvm/rails.rb +79 -54
  70. data/spec/classes/atom/association_spec.rb +8 -8
  71. data/spec/classes/atom/block_spec.rb +8 -5
  72. data/spec/classes/atom/boolean_spec.rb +1 -1
  73. data/spec/classes/atom/error_spec.rb +1 -1
  74. data/spec/classes/atom/list_spec.rb +1 -1
  75. data/spec/classes/atom/number_spec.rb +2 -2
  76. data/spec/classes/atom/string_spec.rb +1 -1
  77. data/spec/languages/ecma/ecma_spec.rb +94 -38
  78. data/spec/languages/ecma/json_spec.rb +4 -4
  79. data/spec/languages/math/compiler_spec.rb +5 -5
  80. data/spec/languages/math/tokenizer_spec.rb +1 -1
  81. data/spec/languages/math/tree_spec.rb +1 -1
  82. data/spec/{base → rvm}/class_spec.rb +2 -2
  83. data/spec/{base/interpreter → rvm}/enviroment_spec.rb +19 -9
  84. data/spec/{base → rvm}/function_spec.rb +2 -2
  85. data/spec/{functions → rvm/functions}/association/assoc_get_spec.rb +2 -2
  86. data/spec/{functions → rvm/functions}/association/assoc_set_spec.rb +2 -2
  87. data/spec/rvm/functions/collection/get_spec.rb +12 -0
  88. data/spec/rvm/functions/collection/set_spec.rb +10 -0
  89. data/spec/rvm/functions/collection/size_spec.rb +10 -0
  90. data/spec/{functions → rvm/functions}/list/split_spec.rb +3 -3
  91. data/spec/{functions → rvm/functions}/string/ansi_spec.rb +3 -3
  92. data/spec/{functions → rvm/functions}/string/capstr_spec.rb +3 -3
  93. data/spec/{functions → rvm/functions}/string/center_spec.rb +3 -3
  94. data/spec/{functions → rvm/functions}/string/ljust_spec.rb +3 -3
  95. data/spec/{functions → rvm/functions}/string/regmatch_spec.rb +3 -3
  96. data/spec/{functions → rvm/functions}/string/rjust_spec.rb +3 -3
  97. data/spec/{base → rvm}/interpreter/assignment_spec.rb +1 -1
  98. data/spec/rvm/interpreter/condition_spec.rb +103 -0
  99. data/spec/{base → rvm}/interpreter/constant_spec.rb +1 -1
  100. data/spec/rvm/interpreter/core_call_spec.rb +72 -0
  101. data/spec/{base → rvm}/interpreter/interpreter_spec.rb +1 -1
  102. data/spec/{base → rvm}/interpreter/parameter_spec.rb +1 -1
  103. data/spec/rvm/interpreter/sequence_spec.rb +47 -0
  104. data/spec/{base → rvm}/interpreter/variable_spec.rb +1 -1
  105. data/spec/{base → rvm}/plugin_spec.rb +2 -2
  106. metadata +66 -35
  107. data/lib/rake/helpers/code_statistics.rb +0 -167
  108. data/spec/base/interpreter/condition_spec.rb +0 -47
  109. data/spec/base/interpreter/function_call_spec.rb +0 -72
  110. data/spec/base/interpreter/sequence_spec.rb +0 -20
  111. data/spec/functions/collection/get_spec.rb +0 -12
  112. data/spec/functions/collection/set_spec.rb +0 -10
  113. data/spec/functions/collection/size_spec.rb +0 -10
@@ -1,4 +1,28 @@
1
- require File.dirname(__FILE__) +'/acts_as_rvm_type.rb'
1
+ =begin
2
+ The MIT License
3
+
4
+ Copyright (c) 2008 Heinz N. 'Licenser' Gies
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Ruby Mush"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
+ =end
24
+
25
+ require 'rvm/acts_as_rvm_type.rb'
2
26
 
3
27
  # Inlcude the RVM::ACtsAsRVMType into active record so functions like
4
28
  # +acts_as_rvm_type+ and comparable
@@ -6,60 +30,61 @@ ActiveRecord::Base.class_eval do
6
30
  include RVM::ActsAsRVMType
7
31
  end
8
32
 
9
- class ActionView::Base
10
-
11
- # This function allows to render code that gets compiled by rvm. The first
12
- # parameter passed is the code to compile, a string most likely, the second
13
- # is a hash that is passed to the render function, see the Rails API doc for
14
- # details on what to put there.
15
- #
16
- # In addition to those rails specifc parameters rvm_render accepts 4 additioal
17
- # parameters.They are the same as used in +rvm_execute+.
18
- def rvm_reder code, options = {}
19
- render options.merge({:text => rvm_execute(code, options)})
20
- end
21
-
22
-
23
- # The rvm_execute executes a string of code with a certein behavior and
24
- # returns not the result but what was written in the special :render variable
25
- # of the enviroment.
26
- #
27
- # The folowing options can be passed to it to influence it's behaviro.
28
- #
29
- # :language:: The language that should be used to compile the code, be adwised
30
- # that it is nessessary to load this prior to executing it.
31
- #
32
- # :enviroment:: This allows to pass a own enviroment, for example to publish
33
- # variables or to maintain state between executions.
34
- #
35
- # :object:: If this is set the code will be executed in the context of the
36
- # object passed, this using it's local variable storage and it's
37
- # functions. Be aware that when using :object and :enviroment
38
- # togehter, variables set in the code will NOT go in the enviroment
39
- # as they are local in the object.
40
- #
41
- # :timeout:: This is used to limit the execution time of the code, it can be
42
- # used to prevent runaway processes beeing executed. Very helpfull
43
- # when the code executed isn't 100% trunstworty.
44
- def rvm_execute code, options = {}
45
- options = {
46
- :language => :ecma,
47
- :enviroment => RVM::Interpreter.env
48
- }.merge(options)
49
- compiler = RVM::Languages[options[:language]].new
50
- code = compiler.compile(code)
51
- code = RVM::Interpreter::ObjectContext.new(RVM::Interpreter::Constant.new(options[:object]), code) if options[:object]
52
- if options[:enviroment][:render].is_a? RVM::Classes::Error or options[:enviroment][:render].nil?
53
- options[:enviroment][:render] = ""
33
+ module ActionController #:nodoc:
34
+ class Base
35
+ # This function allows to render code that gets compiled by rvm. The first
36
+ # parameter passed is the code to compile, a string most likely, the second
37
+ # is a hash that is passed to the render function, see the Rails API doc for
38
+ # details on what to put there.
39
+ #
40
+ # In addition to those rails specifc parameters rvm_render accepts 4 additioal
41
+ # parameters.They are the same as used in +rvm_execute+.
42
+ def rvm_reder code, options = {}
43
+ render options.merge({:text => rvm_execute(code, options)})
54
44
  end
55
- puts options[:enviroment][:render].inspect
56
- if options[:timeout]
57
- s = RVM::Safety.new :timeout => options[:timeout]
58
- s.execute(code, options[:enviroment])
59
- else
60
- code.execute(options[:enviroment])
45
+
46
+
47
+ # The rvm_execute executes a string of code with a certein behavior and
48
+ # returns not the result but what was written in the special :render variable
49
+ # of the environment.
50
+ #
51
+ # The folowing options can be passed to it to influence it's behaviro.
52
+ #
53
+ # :language:: The language that should be used to compile the code, be adwised
54
+ # that it is nessessary to load this prior to executing it.
55
+ #
56
+ # :environment:: This allows to pass a own environment, for example to publish
57
+ # variables or to maintain state between executions.
58
+ #
59
+ # :object:: If this is set the code will be executed in the context of the
60
+ # object passed, this using it's local variable storage and it's
61
+ # functions. Be aware that when using :object and :environment
62
+ # togehter, variables set in the code will NOT go in the environment
63
+ # as they are local in the object.
64
+ #
65
+ # :timeout:: This is used to limit the execution time of the code, it can be
66
+ # used to prevent runaway processes beeing executed. Very helpfull
67
+ # when the code executed isn't 100% trunstworty.
68
+ def rvm_execute code, options = {}
69
+ options = {
70
+ :language => :ecma,
71
+ :environment => RVM::Interpreter.env
72
+ }.merge(options)
73
+ compiler = RVM::Languages[options[:language]].new
74
+ code = compiler.compile(code)
75
+ code = RVM::Interpreter::ObjectContext.new(RVM::Interpreter::Constant.new(options[:object]), code) if options[:object]
76
+ if options[:environment][:render].is_a? RVM::Classes::Error or options[:environment][:render].nil?
77
+ options[:environment][:render] = ""
78
+ end
79
+ puts options[:environment][:render].inspect
80
+ if options[:timeout]
81
+ s = RVM::Safety.new :timeout => options[:timeout]
82
+ s.execute(code, options[:environment])
83
+ else
84
+ code.execute(options[:environment])
85
+ end
86
+ options[:environment][:render].val
61
87
  end
62
- options[:enviroment][:render].val
63
88
  end
64
89
  end
65
- require File.dirname(__FILE__) + '/functions/rails.rb'
90
+ require 'rvm/functions/rails.rb'
@@ -1,8 +1,8 @@
1
- require File.dirname(__FILE__) +'/../../../lib/rvm/classes'
2
- require File.dirname(__FILE__) +'/../../../lib/rvm/classes/association'
3
- require File.dirname(__FILE__) +'/../../../lib/rvm/functions/association/assoc_get'
4
- require File.dirname(__FILE__) +'/../../../lib/rvm/functions/association/assoc_set'
5
- require File.dirname(__FILE__) +'/../../../lib/rvm/functions/collection/size'
1
+ require 'rvm/classes'
2
+ require 'rvm/classes/association'
3
+ require 'rvm/functions/association/assoc_get'
4
+ require 'rvm/functions/association/assoc_set'
5
+ require 'rvm/functions/collection/size'
6
6
 
7
7
  describe RVM::Classes::Association do
8
8
 
@@ -26,14 +26,14 @@ describe RVM::Classes::Association do
26
26
  end
27
27
 
28
28
  it "should publish a get method" do
29
- @assoc.functions.should include('get')
29
+ @assoc.functions.keys.should include('get')
30
30
  end
31
31
 
32
32
  it "should publish a set method" do
33
- @assoc.functions.should include('set')
33
+ @assoc.functions.keys.should include('set')
34
34
  end
35
35
 
36
36
  it "should publich a size method" do
37
- @assoc.functions.should include('size')
37
+ @assoc.functions.keys.should include('size')
38
38
  end
39
39
  end
@@ -1,6 +1,11 @@
1
- require File.dirname(__FILE__) +'/../../../lib/rvm/classes'
1
+ require 'rvm/classes'
2
+ require 'rvm/interpreter'
2
3
  describe RVM::Classes::Block do
3
4
 
5
+ before(:each) do
6
+ @env = RVM::Interpreter.env
7
+ end
8
+
4
9
  it "should create with a value" do
5
10
  b = RVM::Classes::Block.new(nil)
6
11
  end
@@ -12,16 +17,14 @@ describe RVM::Classes::Block do
12
17
 
13
18
  it "should do nothign on execution" do
14
19
  code = mock('code mock')
15
- env = mock('env mock')
16
20
  b = RVM::Classes::Block.new(code)
17
- b.execute(env).should be_nil
21
+ b.execute(@env).should be_nil
18
22
  end
19
23
 
20
24
  it "should execute the given code" do
21
25
  code = mock('code mock')
22
- env = mock('env mock')
23
26
  b = RVM::Classes::Block.new(code)
24
27
  code.should_receive(:execute).once.with(any_args).and_return(42)
25
- b.call(env, []).should be(42)
28
+ b.call([], @env).should be(42)
26
29
  end
27
30
  end
@@ -1,4 +1,4 @@
1
- require "lib/rvm/classes/boolean"
1
+ require "rvm/classes/boolean"
2
2
  describe RVM::Classes::Boolean do
3
3
 
4
4
 
@@ -1,4 +1,4 @@
1
- require "lib/rvm/classes/error"
1
+ require "rvm/classes/error"
2
2
  describe RVM::Classes::Error do
3
3
 
4
4
  describe "(creation)" do
@@ -1,4 +1,4 @@
1
- require "lib/rvm/classes/list"
1
+ require "rvm/classes/list"
2
2
  describe RVM::Classes::List do
3
3
 
4
4
  describe "(creation)" do
@@ -1,5 +1,5 @@
1
- require "lib/rvm/classes"
2
- require "lib/rvm/classes/number"
1
+ require "rvm/classes"
2
+ require "rvm/classes/number"
3
3
 
4
4
  describe RVM::Classes::Number do
5
5
 
@@ -1,4 +1,4 @@
1
- require "lib/rvm/classes/string"
1
+ require "rvm/classes/string"
2
2
 
3
3
  describe RVM::Classes::String do
4
4
 
@@ -1,6 +1,6 @@
1
- require File.dirname(__FILE__) +'/../../../lib/rvm'
2
- require File.dirname(__FILE__) +'/../../../lib/rvm/languages'
3
- require File.dirname(__FILE__) +'/../../../lib/rvm/languages/ecma'
1
+ require 'rvm'
2
+ require 'rvm/languages'
3
+ require 'rvm/languages/ecma'
4
4
 
5
5
  describe RVM::Languages::ECMA do
6
6
  def exec code
@@ -27,28 +27,28 @@ describe RVM::Languages::ECMA do
27
27
  end
28
28
 
29
29
  it "should handle newline replacements" do
30
- res = exec <<-EOC
31
- "\\t"
30
+ res = exec <<-'EOC'
31
+ "\t"
32
32
  EOC
33
33
  res.should == "\t"
34
34
  end
35
35
  it "should handle newline replacements" do
36
- res = exec <<-EOC
37
- "\\n"
36
+ res = exec <<-'EOC'
37
+ "\n"
38
38
  EOC
39
39
  res.should == "\n"
40
40
  end
41
41
 
42
42
  it "should handle double escapes" do
43
- res = exec <<-EOC
44
- "\\\\t"
43
+ res = exec <<-'EOC'
44
+ "\\t"
45
45
  EOC
46
46
  res.should == "\\t"
47
47
  end
48
48
 
49
49
  it "should handle double escapes followed by single escapes" do
50
- res = exec <<-EOF
51
- "\\\\\\t"
50
+ res = exec <<-'EOF'
51
+ "\\\t"
52
52
  EOF
53
53
  res.should == "\\\t"
54
54
  end
@@ -89,36 +89,38 @@ describe RVM::Languages::ECMA do
89
89
  EOC
90
90
  res.should == [42, "Kekse!"]
91
91
  end
92
+
93
+ it "should allow to set array elements" do
94
+ res = exec <<-EOC
95
+ array = [];
96
+ array[0] = 42;
97
+ array;
98
+ EOC
99
+ res.should == [42]
100
+ end
92
101
  end
93
102
 
94
- describe "associative array" do
95
- it "should handle an empty associative array literals" do
103
+ describe "Objects array" do
104
+ it "should handle an empty object" do
96
105
  res = exec <<-EOC
97
106
  {}
98
107
  EOC
99
- res.should == {}
108
+ res.should be_instance_of(RVM::Classes::Object)
100
109
  end
101
110
 
102
- it "should handle an associative array literals with one element" do
111
+ it "should handle an object with variables" do
103
112
  res = exec <<-EOC
104
- {1:2}
113
+ {a: 1}
105
114
  EOC
106
- res.should == {1 => 2}
115
+ res.should be_instance_of(RVM::Classes::Object)
116
+ res.variables['a'].val.should == 1
107
117
  end
108
-
109
- it "should handle an associative array literals with multiple element" do
118
+ it "should handle an object with functions" do
110
119
  res = exec <<-EOC
111
- {1:2, 'test' : 'toast'}
120
+ {f: function(){1}}
112
121
  EOC
113
- res.should == {1 => 2, 'test' => 'toast'}
114
- end
115
-
116
- it "should handle hashes within hashes" do
117
- res = exec <<-EOC
118
- {1:{1:2}, 'test' : 'toast'}
119
- EOC
120
- res.should == {1 => {1 => 2}, 'test' => 'toast'}
121
-
122
+ res.should be_instance_of(RVM::Classes::Object)
123
+ res.functions.keys.should include('f')
122
124
  end
123
125
  end
124
126
 
@@ -143,16 +145,24 @@ describe RVM::Languages::ECMA do
143
145
  res = exec <<-EOC
144
146
  a[0]
145
147
  EOC
146
- res.should == 1
148
+ res.should == 1
149
+ end
150
+
151
+ it "should allow setting elements" do
152
+ @env['a'] = RVM::Classes::List.new([1,2,3])
153
+ res = exec <<-EOC
154
+ a[0] = 42;
155
+ EOC
156
+ res.should == 42
157
+ @env['a'].val[0].should == 42
147
158
  end
148
-
149
159
  it "should allow accessing the length" do
150
160
  @env['a'] = RVM::Classes::List.new([1,2,3])
151
161
  res = exec <<-EOC
152
162
  a.length()
153
163
  EOC
154
164
  res.should == 3
155
- end
165
+ end
156
166
  end
157
167
 
158
168
  describe "variables" do
@@ -172,6 +182,15 @@ describe RVM::Languages::ECMA do
172
182
  @env['variable'].val.should == 'value'
173
183
  end
174
184
 
185
+ it "should recognize multiple local assignments" do
186
+ res = exec <<-EOC
187
+ var i = 'a', j= 'b';
188
+ EOC
189
+ res.should == 'b'
190
+ @env['i'].val.should == 'a'
191
+ @env['j'].val.should == 'b'
192
+ end
193
+
175
194
  it "should scope local assignments correctly" do
176
195
  res = exec <<-EOC
177
196
  variable = 'outer scope';
@@ -275,14 +294,22 @@ describe RVM::Languages::ECMA do
275
294
  it "should handle for loops" do
276
295
  res = exec <<-EOC
277
296
  variable = "";
278
- for (i = 0; i < 3; i = i + 1) {
297
+ for (i = 0; i <= 3; i = i + 1) {
279
298
  variable = variable + i;
280
299
  }
281
300
  EOC
282
- res.should == 3
283
- @env['variable'].val.should == '012'
301
+ res.should == 4
302
+ @env['variable'].val.should == '0123'
284
303
  end
285
-
304
+
305
+ it "should handle for loops (bug prevention)" do
306
+ code =<<-EOC
307
+ function test() {for (var i = 1; i <= 2; i+=1) {};};
308
+ test();
309
+ EOC
310
+ proc { exec(code) }.should_not raise_error
311
+ end
312
+
286
313
  it "should handle while loops" do
287
314
  res = exec <<-EOC
288
315
  variable = "";
@@ -382,6 +409,35 @@ describe RVM::Languages::ECMA do
382
409
  end
383
410
  end
384
411
 
385
- describe "condition"
386
-
412
+
413
+ describe "opperators" do
414
+ it "should recognize ++" do
415
+ @env['i'] = RVM::Classes::Number.new(41)
416
+ res = exec <<-EOC
417
+ i++;
418
+ EOC
419
+ res.should == 42
420
+ end
421
+ it "should recognize --" do
422
+ @env['i'] = RVM::Classes::Number.new(43)
423
+ res = exec <<-EOC
424
+ i--;
425
+ EOC
426
+ res.should == 42
427
+ end
428
+ it "should recognize +=" do
429
+ @env['i'] = RVM::Classes::Number.new(40)
430
+ res = exec <<-EOC
431
+ i += 2;
432
+ EOC
433
+ res.should == 42
434
+ end
435
+ it "should recognize -=" do
436
+ @env['i'] = RVM::Classes::Number.new(44)
437
+ res = exec <<-EOC
438
+ i -= 2;
439
+ EOC
440
+ res.should == 42
441
+ end
442
+ end
387
443
  end