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.
- data/README +38 -0
- data/bin/ambervm +278 -0
- data/lib/amber/acts_as_rvm_type.rb +157 -0
- data/lib/amber/classes/association.rb +36 -0
- data/lib/amber/classes/block.rb +52 -0
- data/lib/amber/classes/boolean.rb +40 -0
- data/lib/amber/classes/class.rb +50 -0
- data/lib/amber/classes/error.rb +22 -0
- data/lib/amber/classes/list.rb +96 -0
- data/lib/amber/classes/null.rb +35 -0
- data/lib/amber/classes/number.rb +95 -0
- data/lib/amber/classes/object.rb +56 -0
- data/lib/amber/classes/string.rb +79 -0
- data/lib/amber/classes.rb +113 -0
- data/lib/amber/environment.rb +251 -0
- data/lib/amber/fukubukuro/ecma_core.rb +409 -0
- data/lib/amber/fukubukuro.rb +866 -0
- data/lib/amber/functions/all.rb +3 -0
- data/lib/amber/functions/array/append.rb +50 -0
- data/lib/amber/functions/array/at.rb +50 -0
- data/lib/amber/functions/array/set_at.rb +50 -0
- data/lib/amber/functions/array.rb +30 -0
- data/lib/amber/functions/association/assoc_get.rb +55 -0
- data/lib/amber/functions/association/assoc_set.rb +56 -0
- data/lib/amber/functions/bitwise/bitwise_and.rb +41 -0
- data/lib/amber/functions/bitwise/bitwise_not.rb +41 -0
- data/lib/amber/functions/bitwise/bitwise_or.rb +41 -0
- data/lib/amber/functions/bitwise/bitwise_xor.rb +41 -0
- data/lib/amber/functions/bitwise.rb +3 -0
- data/lib/amber/functions/collection/get.rb +66 -0
- data/lib/amber/functions/collection/set.rb +67 -0
- data/lib/amber/functions/collection/size.rb +54 -0
- data/lib/amber/functions/general/cmp.rb +43 -0
- data/lib/amber/functions/general/eq.rb +45 -0
- data/lib/amber/functions/general/gt.rb +45 -0
- data/lib/amber/functions/general/gte.rb +45 -0
- data/lib/amber/functions/general/lt.rb +45 -0
- data/lib/amber/functions/general/lte.rb +45 -0
- data/lib/amber/functions/general/neq.rb +45 -0
- data/lib/amber/functions/general/type.rb +43 -0
- data/lib/amber/functions/general.rb +3 -0
- data/lib/amber/functions/io/print.rb +45 -0
- data/lib/amber/functions/io.rb +3 -0
- data/lib/amber/functions/list/align.rb +73 -0
- data/lib/amber/functions/list/join.rb +45 -0
- data/lib/amber/functions/list/map.rb +58 -0
- data/lib/amber/functions/list/split.rb +55 -0
- data/lib/amber/functions/list.rb +3 -0
- data/lib/amber/functions/logic/and.rb +55 -0
- data/lib/amber/functions/logic/not.rb +40 -0
- data/lib/amber/functions/logic/or.rb +50 -0
- data/lib/amber/functions/logic.rb +3 -0
- data/lib/amber/functions/math/abs.rb +39 -0
- data/lib/amber/functions/math/acos.rb +39 -0
- data/lib/amber/functions/math/add.rb +40 -0
- data/lib/amber/functions/math/asin.rb +39 -0
- data/lib/amber/functions/math/atan.rb +39 -0
- data/lib/amber/functions/math/ceil.rb +39 -0
- data/lib/amber/functions/math/cos.rb +39 -0
- data/lib/amber/functions/math/dec.rb +39 -0
- data/lib/amber/functions/math/div.rb +44 -0
- data/lib/amber/functions/math/exp.rb +39 -0
- data/lib/amber/functions/math/floor.rb +39 -0
- data/lib/amber/functions/math/inc.rb +39 -0
- data/lib/amber/functions/math/log.rb +39 -0
- data/lib/amber/functions/math/mod.rb +41 -0
- data/lib/amber/functions/math/mul.rb +43 -0
- data/lib/amber/functions/math/neg.rb +43 -0
- data/lib/amber/functions/math/power.rb +43 -0
- data/lib/amber/functions/math/rand.rb +36 -0
- data/lib/amber/functions/math/round.rb +39 -0
- data/lib/amber/functions/math/shl.rb +41 -0
- data/lib/amber/functions/math/shr.rb +41 -0
- data/lib/amber/functions/math/sin.rb +39 -0
- data/lib/amber/functions/math/sub.rb +43 -0
- data/lib/amber/functions/math/tan.rb +39 -0
- data/lib/amber/functions/math.rb +3 -0
- data/lib/amber/functions/objects/send.rb +22 -0
- data/lib/amber/functions/rails/print.rb +44 -0
- data/lib/amber/functions/rails.rb +3 -0
- data/lib/amber/functions/string/ansi.rb +24 -0
- data/lib/amber/functions/string/capstr.rb +23 -0
- data/lib/amber/functions/string/center.rb +25 -0
- data/lib/amber/functions/string/chr.rb +16 -0
- data/lib/amber/functions/string/ljust.rb +26 -0
- data/lib/amber/functions/string/regmatch.rb +34 -0
- data/lib/amber/functions/string/rjust.rb +26 -0
- data/lib/amber/functions/string.rb +3 -0
- data/lib/amber/functions.rb +103 -0
- data/lib/amber/interpreter.rb +1380 -0
- data/lib/amber/languages/brainfuck.rb +153 -0
- data/lib/amber/languages/ecma/compiler.rb +1661 -0
- data/lib/amber/languages/ecma/core-math.js +67 -0
- data/lib/amber/languages/ecma/core-objects.js +57 -0
- data/lib/amber/languages/ecma.rb +9 -0
- data/lib/amber/languages/ecma_fuku/compiler.rb +1622 -0
- data/lib/amber/languages/ecma_fuku/core-math.js +67 -0
- data/lib/amber/languages/ecma_fuku/core-objects.js +56 -0
- data/lib/amber/languages/ecma_fuku.rb +13 -0
- data/lib/amber/languages/math/compiler.rb +70 -0
- data/lib/amber/languages/math/tokenizer.rb +69 -0
- data/lib/amber/languages/math/tree.rb +110 -0
- data/lib/amber/languages/math.rb +26 -0
- data/lib/amber/languages.rb +99 -0
- data/lib/amber/library.rb +79 -0
- data/lib/amber/optimisation.rb +299 -0
- data/lib/amber/plugin.rb +337 -0
- data/lib/amber/rails.rb +90 -0
- data/lib/amber.rb +106 -0
- data/spec/amber/class_spec.rb +27 -0
- data/spec/amber/enviroment_spec.rb +61 -0
- data/spec/amber/function_spec.rb +25 -0
- data/spec/amber/functions/association/assoc_get_spec.rb +41 -0
- data/spec/amber/functions/association/assoc_set_spec.rb +43 -0
- data/spec/amber/functions/collection/get_spec.rb +12 -0
- data/spec/amber/functions/collection/set_spec.rb +10 -0
- data/spec/amber/functions/collection/size_spec.rb +10 -0
- data/spec/amber/functions/list/split_spec.rb +47 -0
- data/spec/amber/functions/string/ansi_spec.rb +44 -0
- data/spec/amber/functions/string/capstr_spec.rb +42 -0
- data/spec/amber/functions/string/center_spec.rb +49 -0
- data/spec/amber/functions/string/ljust_spec.rb +49 -0
- data/spec/amber/functions/string/regmatch_spec.rb +52 -0
- data/spec/amber/functions/string/rjust_spec.rb +49 -0
- data/spec/amber/interpreter/assignment_spec.rb +22 -0
- data/spec/amber/interpreter/condition_spec.rb +103 -0
- data/spec/amber/interpreter/constant_spec.rb +31 -0
- data/spec/amber/interpreter/core_call_spec.rb +72 -0
- data/spec/amber/interpreter/interpreter_spec.rb +11 -0
- data/spec/amber/interpreter/parameter_spec.rb +24 -0
- data/spec/amber/interpreter/sequence_spec.rb +47 -0
- data/spec/amber/interpreter/variable_spec.rb +24 -0
- data/spec/amber/plugin_spec.rb +10 -0
- data/spec/classes/atom/association_spec.rb +39 -0
- data/spec/classes/atom/block_spec.rb +25 -0
- data/spec/classes/atom/boolean_spec.rb +67 -0
- data/spec/classes/atom/error_spec.rb +43 -0
- data/spec/classes/atom/list_spec.rb +68 -0
- data/spec/classes/atom/number_spec.rb +132 -0
- data/spec/classes/atom/string_spec.rb +175 -0
- data/spec/languages/ecma/ecma_array_spec.rb +79 -0
- data/spec/languages/ecma/ecma_closure_spec.rb +38 -0
- data/spec/languages/ecma/ecma_literals_spec.rb +71 -0
- data/spec/languages/ecma/ecma_objects_spec.rb +165 -0
- data/spec/languages/ecma/ecma_old_spec.rb +540 -0
- data/spec/languages/ecma/ecma_spec.rb +64 -0
- data/spec/languages/ecma_fuku/ecma_array_spec.rb +61 -0
- data/spec/languages/ecma_fuku/ecma_closure_spec.rb +33 -0
- data/spec/languages/ecma_fuku/ecma_function_spec.rb +84 -0
- data/spec/languages/ecma_fuku/ecma_literals_spec.rb +55 -0
- data/spec/languages/ecma_fuku/ecma_objects_spec.rb +133 -0
- data/spec/languages/ecma_fuku/ecma_old_spec.rb +415 -0
- data/spec/languages/ecma_fuku/ecma_operator_spec.rb +33 -0
- data/spec/languages/ecma_fuku/ecma_spec.rb +52 -0
- data/spec/languages/math/compiler_spec.rb +49 -0
- data/spec/languages/math/tokenizer_spec.rb +73 -0
- data/spec/languages/math/tree_spec.rb +153 -0
- 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
|