1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* Merge YARV

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11439 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2006-12-31 15:02:22 +00:00
parent 3e7566d8fb
commit a3e1b1ce7e
233 changed files with 46004 additions and 13653 deletions

10
yarvtest/runner.rb Normal file
View file

@ -0,0 +1,10 @@
require 'test/unit'
if $0 == __FILE__
# exit Test::Unit::AutoRunner.run(false, File.dirname($0))
Dir.glob(File.dirname($0) + '/test_*'){|file|
p file
require file
}
end

585
yarvtest/test_bin.rb Normal file
View file

@ -0,0 +1,585 @@
require 'yarvtest/yarvtest'
# test of basic instruction
class TestBIN < YarvTestBase
def test_literal
ae %q(true)
ae %q(false)
ae %q(nil)
ae %q(1234)
ae %q(:sym)
ae %q(123456789012345678901234567890)
ae %q(1.234)
ae %q(0x12)
ae %q(0b0101001)
ae %q(1_2_3) # 123
end
def test_self
ae %q(self)
end
def test_string
ae %q('str')
end
def test_dstring
ae %q(
"1+1 = #{1+1}"
)
ae %q{
i = 10
"#{i} ** #{i} = #{i ** i}"
}
ae %q{
s = "str"
s.__id__ == "#{s}".__id__
}
end
def test_dsym
ae %q{
:"a#{1+2}c"
}
end
def test_xstr
ae %q(`echo hoge`)
ae %q(hoge = 'huga'; `echo #{hoge}`)
end
def test_regexp
ae %q{
/test/ =~ 'test'
}
ae %q{
/test/ =~ 'tes'
}
ae %q{
r = /test/; l = 'test'
r =~ l
}
ae %q{
r = /testx/; l = 'test'
r =~ l
}
ae %q{
i = 10
/test#{i}/ =~ 'test10'
}
ae %q{
i = 10
/test#{i}/ =~ 'test20'
}
ae %q{
:sym =~ /sym/
}
ae %q{
sym = :sym
sym =~ /sym/
}
ae %q{
reg = /sym/
:sym =~ reg
}
end
def test_array
ae %q([])
ae %q([1,2,3])
ae %q([1+1,2+2,3+3])
ae %q([0][0]+=3)
ae %q([0][0]-=3)
end
def test_array_access
ae %q(ary = [1,2,3]; ary[1])
ae %q(ary = [1,2,3]; ary[1] = 10)
ae %q(ary = Array.new(10, 100); ary[3])
end
def test_hash
ae %q({})
ae %q({1 => 2})
ae %q({"str" => "val", "str2" => "valval"})
ae %q({1 => 2, 1=>3})
end
def test_range
ae %q((1..2))
ae %q((1...2))
ae %q(((1+1)..(2+2)))
ae %q(((1+1)...(2+2)))
end
def test_not
ae %q(!true)
ae %q(!nil)
ae %q(!false)
ae %q(!(1+1))
ae %q(!!nil)
ae %q(!!1)
end
# var
def test_local
ae %q(a = 1)
ae %q(a = 1; b = 2; a)
ae %q(a = b = 3)
ae %q(a = b = 3; a)
ae %q(a = b = c = 4)
ae %q(a = b = c = 4; c)
end
def test_constant
ae %q(C = 1; C)
ae %q(C = 1; $a = []; 2.times{$a << ::C}; $a)
ae %q(
class A
class B
class C
Const = 1
end
end
end
(1..2).map{
A::B::C::Const
}
) do
remove_const :A
end
ae %q(
class A
class B
Const = 1
class C
(1..2).map{
Const
}
end
end
end
) do
remove_const :A
end
ae %q(
class A
Const = 1
class B
class C
(1..2).map{
Const
}
end
end
end
) do
remove_const :A
end
ae %q(
Const = 1
class A
class B
class C
(1..2).map{
Const
}
end
end
end
) do
remove_const :A
remove_const :Const
end
ae %q{
C = 1
begin
C::D
rescue TypeError
:ok
else
:ng
end
}
end
def test_constant2
ae %q{
class A
class B
C = 10
end
end
i = 0
while i<3
i+=1
r = A::B::C
end
r
} do
remove_const :A
end
ae %q{
class A
class B
C = 10
end
end
i = 0
while i<3
i+=1
r = A::B::C
class A::B
remove_const :C
end
A::B::C = i**i
end
r
} do
remove_const :A
end
ae %q{
class C
Const = 1
(1..3).map{
self::Const
}
end
}
ae %q{
class C
Const = 1
(1..3).map{
eval('self')::Const
}
end
}
ae %q{
class C
Const = 0
def self.foo()
self::Const
end
end
class D < C
Const = 1
end
class E < C
Const = 2
end
[C.foo, D.foo, E.foo]
}
end
def test_gvar
ae %q(
$g1 = 1
)
ae %q(
$g2 = 2
$g2
)
end
def test_cvar
ae %q{
class C
@@c = 1
def m
@@c += 1
end
end
C.new.m
} do
remove_const :C
end
end
def test_cvar_from_singleton
ae %q{
class C
@@c=1
class << self
def m
@@c += 1
end
end
end
C.m
} do
remove_const :C
end
end
def test_cvar_from_singleton2
ae %q{
class C
@@c = 1
def self.m
@@c += 1
end
end
C.m
} do
remove_const :C
end
end
def test_op_asgin2
ae %q{
class C
attr_accessor :a
end
r = []
o = C.new
o.a &&= 1
r << o.a
o.a ||= 2
r << o.a
o.a &&= 3
r << o.a
r
} do
remove_const :C
end
ae %q{
@@x ||= 1
}
ae %q{
@@x = 0
@@x ||= 1
}
end
def test_op_assgin_and_or
ae %q{
r = []
a = 1 ; a ||= 2; r << a
a = nil; a ||= 2; r << a
a = 1 ; a &&= 2; r << a
a = nil; a &&= 2; r << a
r
}
ae %q{
a = {}
a[0] ||= 1
}
ae %q{
a = {}
a[0] &&= 1
}
ae %q{
a = {0 => 10}
a[0] ||= 1
}
ae %q{
a = {0 => 10}
a[0] &&= 1
}
end
def test_backref
ae %q{
/a(b)(c)d/ =~ 'xyzabcdefgabcdefg'
[$1, $2, $3, $~.class, $&, $`, $', $+]
}
ae %q{
def m
/a(b)(c)d/ =~ 'xyzabcdefgabcdefg'
[$1, $2, $3, $~.class, $&, $`, $', $+]
end
m
}
end
def test_fact
ae %q{
def fact(n)
if(n > 1)
n * fact(n-1)
else
1
end
end
fact(300)
}
end
def test_mul
ae %q{
2*0
}
ae %q{
0*2
}
ae %q{
2*2
}
end
def test_div
ae %q{
3/2
}
ae %q{
3.0/2.0
}
ae %q{
class C
def /(a)
a * 100
end
end
C.new/3
} do
remove_const :C
end
end
def test_length
ae %q{
[].length
}
ae %q{
[1, 2].length
}
ae %q{
{}.length
}
ae %q{
{:a => 1, :b => 2}.length
}
ae %q{
class C
def length
'hoge'
end
end
C.new.length
} do
remove_const :C
end
end
def test_mod
ae %q{
3%2
}
ae %q{
3.0%2.0
}
ae %q{
class C
def % (a)
a * 100
end
end
C.new%3
} do
remove_const :C
end
end
def test_attr_set
ae %q{
o = Object.new
def o.[]=(*args)
args
end
[o[]=:x, o[0]=:x, o[0, 1]=:x, o[0, 1, 2]=:x]
}
ae %q{
o = Object.new
def o.foo=(*args)
args
end
o.foo = :x
}
ae %q{
$r = []
class C
def [](*args)
$r << [:ref, args]
args.size
end
def []=(*args)
$r << [:set, args]
args.size
end
end
o = C.new
ary = [:x, :y]
o[1] = 2
o[1, 2] = 3
o[1, 2, *ary] = 3
o[1, 2, *ary, 3] = 4
$r
}
end
def test_aref_aset
ae %q{
a = []
a << 0
a[1] = 1
a[2] = 2
a[3] = a[1] + a[2]
}
ae %q{
a = {}
a[1] = 1
a[2] = 2
a[3] = a[1] + a[2]
a.sort
}
ae %q{
class C
attr_reader :a, :b
def [](a)
@a = a
end
def []=(a, b)
@b = [a, b]
end
end
c = C.new
c[3]
c[4] = 5
[c.a, c.b]
} do
remove_const :C
end
end
def test_array_concat
ae %q{
ary = []
[:x, *ary]
}
#ae %q{
# ary = 1
# [:x, *ary]
#}
ae %q{
ary = [1, 2]
[:x, *ary]
}
end
end

429
yarvtest/test_block.rb Normal file
View file

@ -0,0 +1,429 @@
require 'yarvtest/yarvtest'
class TestBlock < YarvTestBase
def test_simple
ae %q(
def m
yield
end
m{
1
}
)
end
def test_param
ae %q(
def m
yield 1
end
m{|ib|
ib*2
}
)
ae %q(
def m
yield 12345, 67890
end
m{|ib,jb|
ib*2+jb
}
)
end
def test_param2
ae %q{
def iter
yield 10
end
a = nil
[iter{|a|
a
}, a]
}
ae %q{
def iter
yield 10
end
iter{|a|
iter{|a|
a + 1
} + a
}
}
ae %q{
def iter
yield 10, 20, 30, 40
end
a = b = c = d = nil
iter{|a, b, c, d|
[a, b, c, d]
} + [a, b, c, d]
}
ae %q{
def iter
yield 10, 20, 30, 40
end
a = b = nil
iter{|a, b, c, d|
[a, b, c, d]
} + [a, b]
}
ae %q{
def iter
yield 10, 20, 30, 40
end
a = nil
iter{|a, $b, @c, d|
[a, $b]
} + [a, $b, @c]
} if false # 1.9 doesn't support expr block parameters
end
def test_param3
if false
# TODO: Ruby 1.9 doesn't support expr block parameter
ae %q{
h = {}
[1].each{|h[:foo]|}
h
}
ae %q{
obj = Object.new
def obj.x=(y)
$ans = y
end
[1].each{|obj.x|}
$ans
}
end
end
def test_blocklocal
ae %q{
1.times{
begin
a = 1
ensure
foo = nil
end
}
}
end
def test_simplenest
ae %q(
def m
yield 123
end
m{|ib|
m{|jb|
ib*jb
}
}
)
end
def test_simplenest2
ae %q(
def m a
yield a
end
m(1){|ib|
m(2){|jb|
ib*jb
}
}
)
end
def test_nest2
ae %q(
def m
yield
end
def n
yield
end
m{
n{
100
}
}
)
ae %q(
def m
yield 1
end
m{|ib|
m{|jb|
i = 20
}
}
)
ae %q(
def m
yield 1
end
m{|ib|
m{|jb|
ib = 20
kb = 2
}
}
)
ae %q(
def iter1
iter2{
yield
}
end
def iter2
yield
end
iter1{
jb = 2
iter1{
jb = 3
}
jb
}
)
ae %q(
def iter1
iter2{
yield
}
end
def iter2
yield
end
iter1{
jb = 2
iter1{
jb
}
jb
}
)
end
def test_ifunc
ae %q{
(1..3).to_a
}
ae %q{
(1..3).map{|e|
e * 4
}
}
ae %q{
class C
include Enumerable
def each
[1,2,3].each{|e|
yield e
}
end
end
C.new.to_a
}
ae %q{
class C
include Enumerable
def each
[1,2,3].each{|e|
yield e
}
end
end
C.new.map{|e|
e + 3
}
}
end
def test_times
ae %q{
sum = 0
3.times{|ib|
2.times{|jb|
sum += ib + jb
}}
sum
}
ae %q{
3.times{|bl|
break 10
}
}
end
def test_for
ae %q{
sum = 0
for x in [1, 2, 3]
sum += x
end
sum
}
ae %q{
sum = 0
for x in (1..5)
sum += x
end
sum
}
ae %q{
sum = 0
for x in []
sum += x
end
sum
}
ae %q{
ans = []
1.times{
for n in 1..3
a = n
ans << a
end
}
}
ae %q{
ans = []
for m in 1..3
for n in 1..3
a = [m, n]
ans << a
end
end
}
end
def test_unmatched_params
ae %q{
def iter
yield 1,2,3
end
iter{|i, j|
[i, j]
}
}
ae %q{
def iter
yield 1
end
iter{|i, j|
[i, j]
}
}
end
def test_rest
# TODO: known bug
#ae %q{
# def iter
# yield 1, 2
# end
#
# iter{|a, |
# [a]
# }
#}
ae %q{
def iter
yield 1, 2
end
iter{|a, *b|
[a, b]
}
}
ae %q{
def iter
yield 1, 2
end
iter{|*a|
[a]
}
}
ae %q{
def iter
yield 1, 2
end
iter{|a, b, *c|
[a, b, c]
}
}
ae %q{
def iter
yield 1, 2
end
iter{|a, b, c, *d|
[a, b, c, d]
}
}
end
def test_param_and_locals
ae %q{
$a = []
def iter
yield 1
end
def m
x = iter{|x|
$a << x
y = 0
}
end
m
$a
}
end
def test_c_break
ae %q{
[1,2,3].find{|x| x == 2}
}
ae %q{
class E
include Enumerable
def each(&block)
[1, 2, 3].each(&block)
end
end
E.new.find {|x| x == 2 }
}
end
end

753
yarvtest/test_class.rb Normal file
View file

@ -0,0 +1,753 @@
require 'yarvtest/yarvtest'
class TestClass < YarvTestBase
def test_simple
ae %q(
class C
def m(a,b)
a+b
end
end
C.new.m(1,2)
) do
remove_const(:C)
end
ae %q(
class A
end
class A::B
def m
A::B.name
end
end
A::B.new.m
) do
remove_const(:A)
end
#ae %q(
# class (class C;self; end)::D < C
# self.name
# end
#) do
# remove_const(:C)
#end
end
def test_sub
ae %q(
class A
def m
123
end
end
class B < A
end
B.new.m
) do
remove_const(:A)
remove_const(:B)
end
ae %q(
class A
class B
class C
def m
456
end
end
end
end
class A::BB < A::B::C
end
A::BB.new.m
) do
remove_const(:A)
end
end
def test_attr
ae %q(
class C
def set
@a = 1
end
def get
@a
end
end
c = C.new
c.set
c.get
) do
remove_const(:C)
end
end
def test_initialize
ae %q{
class C
def initialize
@a = :C
end
def a
@a
end
end
C.new.a
} do
remove_const(:C)
end
end
def test_to_s
ae %q{
class C
def to_s
"hoge"
end
end
"ab#{C.new}cd"
} do
remove_const(:C)
end
end
def test_attr_accessor
ae %q{
class C
attr_accessor :a
attr_reader :b
attr_writer :c
def b_write
@b = 'huga'
end
def m a
'test_attr_accessor' + @b + @c
end
end
c = C.new
c.a = true
c.c = 'hoge'
c.b_write
c.m(c.b)
} do
remove_const(:C)
end
end
def test_super
ae %q{
class C
def m1
100
end
def m2 a
a + 100
end
end
class CC < C
def m1
super() * 100
end
def m2
super(200) * 100
end
end
a = CC.new
a.m1 + a.m2
} do
remove_const(:C)
remove_const(:CC)
end
end
def test_super2
ae %q{
class C
def m(a, b)
a+b
end
end
class D < C
def m arg
super(*arg) + super(1, arg.shift)
end
end
D.new.m([1, 2])
}
ae %q{
class C
def m
yield
end
end
class D < C
def m
super(){
:D
}
end
end
D.new.m{
:top
}
}
ae %q{
class C0
def m a, &b
[a, b]
end
end
class C1 < C0
def m a, &b
super a, &b
end
end
C1.new.m(10)
}
end
def test_zsuper_from_define_method
ae %q{
class C
def a
"C#a"
end
def m
"C#m"
end
end
class D < C
define_method(:m){
super
}
define_method(:a){
r = nil
1.times{
r = super
}
r
}
end
D.new.m + D.new.a
}
ae %q{
class X
def a
"X#a"
end
def b
class << self
define_method(:a) {
super
}
end
end
end
x = X.new
x.b
x.a
}
ae %q{
class C
def m arg
"C#m(#{arg})"
end
def b
class << self
define_method(:m){|a|
super
}
end
self
end
end
C.new.b.m(:ok)
}
ae %q{
class C
def m *args
"C#m(#{args.join(', ')})"
end
def b
class << self
define_method(:m){|a, b|
r = nil
1.times{
r = super
}
r
}
end
self
end
end
C.new.b.m(:ok1, :ok2)
} if false # ruby 1.9 dumped core
ae %q{ # [yarv-dev:859]
$ans = []
class A
def m_a
$ans << "m_a"
end
def def_m_a
$ans << "def_m_a"
end
end
class B < A
def def_m_a
B.class_eval{
super
define_method(:m_a) do
super
end
}
super
end
end
b = B.new
b.def_m_a
b.m_a
$ans
}
ae %q{
class A
def hoge
:hoge
end
def foo
:foo
end
end
class B < A
def memoize(name)
B.instance_eval do
define_method(name) do
[name, super]
end
end
end
end
b = B.new
b.memoize(:hoge)
b.memoize(:foo)
[b.foo, b.hoge]
}
end
def test_zsuper
ae %q{
class C
def m1
100
end
def m2 a
a + 100
end
def m3 a
a + 200
end
end
class CC < C
def m1
super * 100
end
def m2 a
super * 100
end
def m3 a
a = 400
super * 100
end
end
a = CC.new
a.m1 + a.m2(200) + a.m3(300)
} do
remove_const(:C)
remove_const(:CC)
end
end
def test_zsuper2
ae %q{
class C1
def m
10
end
end
class C2 < C1
def m
20 + super
end
end
class C3 < C2
def m
30 + super
end
end
C3.new.m
} do
remove_const(:C1)
remove_const(:C2)
remove_const(:C3)
end
ae %q{
class C
def m
yield
end
end
class D < C
def m
super{
:D
}
end
end
D.new.m{
:top
}
}
ae %q{
class C
def m(a, b, c, d)
a+b+c+d
end
end
class D < C
def m(a, b=1, c=2, *d)
d[0] ||= 0.1
[super,
begin
a *= 2
b *= 3
c *= 4
d[0] *= 5
super
end
]
end
end
ary = []
ary << D.new.m(10, 20, 30, 40)
if false # On current ruby, these programs don't work
ary << D.new.m(10, 20, 30)
ary << D.new.m(10, 20)
ary << D.new.m(10)
end
ary
}
ae %q{
class C
def m(a, b, c, d)
a+b+c+d
end
end
class D < C
def m(a, b=1, c=2, d=3)
[super,
begin
a *= 2
b *= 3
c *= 4
d *= 5
super
end
]
end
end
ary = []
ary << D.new.m(10, 20, 30, 40)
ary << D.new.m(10, 20, 30)
ary << D.new.m(10, 20)
ary << D.new.m(10)
ary
}
ae %q{
class C
def m(a, b, c, d, &e)
a+b+c+d+e.call
end
def n(a, b, c, d, &e)
a+b+c+d+e.call
end
end
class D < C
def m(a, b=1, c=2, *d, &e)
super
end
def n(a, b=1, c=2, d=3, &e)
super
end
end
ary = []
ary << D.new.m(1, 2, 3, 4){
5
}
ary << D.new.m(1, 2, 3, 4, &lambda{
5
})
ary << D.new.n(1, 2, 3){
5
}
ary << D.new.n(1, 2){
5
}
ary << D.new.n(1){
5
}
ary
}
end
def test_super_with_private
ae %q{
class C
private
def m1
:OK
end
protected
def m2
end
end
class D < C
def m1
[super, super()]
end
def m2
[super, super()]
end
end
D.new.m1 + D.new.m2
}
end
def test_const_in_other_scope
ae %q{
class C
Const = :ok
def m
1.times{
Const
}
end
end
C.new.m
} do
remove_const(:C)
end
ae %q{
class C
Const = 1
def m
begin
raise
rescue
Const
end
end
end
C.new.m
} do
remove_const(:C)
end
end
def test_reopen_not_class
ae %q{ # [yarv-dev:782]
begin
B = 1
class B
p B
end
rescue TypeError => e
e.message
end
}
ae %q{ # [yarv-dev:800]
begin
B = 1
module B
p B
end
rescue TypeError => e
e.message
end
}
end
def test_set_const_not_class
ae %q{
begin
1::A = 1
rescue TypeError => e
e.message
end
}
end
def test_singletonclass
ae %q{
obj = ''
class << obj
def m
:OK
end
end
obj.m
}
ae %q{
obj = ''
Const = :NG
class << obj
Const = :OK
def m
Const
end
end
obj.m
}
ae %q{
obj = ''
class C
def m
:NG
end
end
class << obj
class C
def m
:OK
end
end
def m
C.new.m
end
end
obj.m
}
ae %q{ # [yarv-dev:818]
class A
end
class << A
C = "OK"
def m
class << Object
$a = C
end
end
end
A.m
$a
}
end
def test_include
ae %q{
module M
class A
def hoge
"hoge"
end
end
end
class A
include M
def m
[Module.nesting, A.new.hoge, instance_eval("A.new.hoge")]
end
end
A.new.m
}
end
def test_colon3
ae %q{
class A
::B = :OK
end
B
}
ae %q{
class A
class ::C
end
end
C
}
end
def test_undef
# [yarv-dev:999]
ae %q{
class Parent
def foo
end
end
class Child < Parent
def bar
end
undef foo, bar
end
c = Child.new
[c.methods.include?('foo'), c.methods.include?('bar')]
}
end
def test_dup
ae %q{
ObjectSpace.each_object{|obj|
if Module === obj && (obj.respond_to? :dup)
obj.dup
end
}
:ok
}
end
end

213
yarvtest/test_eval.rb Normal file
View file

@ -0,0 +1,213 @@
require 'yarvtest/yarvtest'
class TestEval < YarvTestBase
def test_eval
ae %q{
eval('1')
}
ae %q{
eval('a=1; a')
}
ae %q{
a = 1
eval('a')
}
end
def test_eval_with_send
ae %q{
__send! :eval, %{
:ok
}
}
ae %q{
1.__send! :instance_eval, %{
:ok
}
}
end
def test_module_eval
ae %q{
Const = :top
class C
Const = :C
end
C.module_eval{
Const
}
}
ae %q{
Const = :top
class C
Const = :C
end
C.module_eval %{
Const
}
} if false # TODO: Ruby 1.9 error
ae %q{
Const = :top
class C
Const = :C
end
C.class_eval %{
def m
Const
end
}
C.new.m
}
ae %q{
Const = :top
class C
Const = :C
end
C.class_eval{
def m
Const
end
}
C.new.m
}
end
def test_instance_eval
ae %q{
1.instance_eval{
self
}
}
ae %q{
'foo'.instance_eval{
self
}
}
ae %q{
class Fixnum
Const = 1
end
1.instance_eval %{
Const
}
}
end
def test_nest_eval
ae %q{
Const = :top
class C
Const = :C
end
$nest = false
$ans = []
def m
$ans << Const
C.module_eval %{
$ans << Const
Boo = false unless defined? Boo
unless $nest
$nest = true
m
end
}
end
m
$ans
}
ae %q{
$nested = false
$ans = []
$pr = proc{
$ans << self
unless $nested
$nested = true
$pr.call
end
}
class C
def initialize &b
10.instance_eval(&b)
end
end
C.new(&$pr)
$ans
}
end
def test_binding
ae %q{
def m
a = :ok
$b = binding
end
m
eval('a', $b)
}
ae %q{
def m
a = :ok
$b = binding
end
m
eval('b = :ok2', $b)
eval('[a, b]', $b)
}
ae %q{
$ans = []
def m
$b = binding
end
m
$ans << eval(%q{
$ans << eval(%q{
a
}, $b)
a = 1
}, $b)
$ans
}
ae %q{
Const = :top
class C
Const = :C
def m
binding
end
end
eval('Const', C.new.m)
}
ae %q{
Const = :top
a = 1
class C
Const = :C
def m
eval('Const', TOPLEVEL_BINDING)
end
end
C.new.m
}
ae %q{
class C
$b = binding
end
eval %q{
def m
:ok
end
}, $b
p C.new.m
}
ae %q{
b = proc{
a = :ok
binding
}.call
a = :ng
eval("a", b)
}
end
end

408
yarvtest/test_exception.rb Normal file
View file

@ -0,0 +1,408 @@
require 'yarvtest/yarvtest'
class TestException < YarvTestBase
def test_rescue
ae %q{
begin
1
rescue
2
end
}
ae %q{
begin
1
begin
2
rescue
3
end
4
rescue
5
end
}
ae %q{
begin
1
rescue
2
else
3
end
}
end
def test_ensure
ae %q{
begin
1+1
ensure
2+2
end
}
ae %q{
begin
1+1
begin
2+2
ensure
3+3
end
ensure
4+4
end
}
ae %q{
begin
1+1
begin
2+2
ensure
3+3
end
ensure
4+4
begin
5+5
ensure
6+6
end
end
}
end
def test_rescue_ensure
ae %q{
begin
1+1
rescue
2+2
ensure
3+3
end
}
ae %q{
begin
1+1
rescue
2+2
ensure
3+3
end
}
ae %q{
begin
1+1
rescue
2+2
else
3+3
ensure
4+4
end
}
ae %q{
begin
1+1
begin
2+2
rescue
3+3
else
4+4
end
rescue
5+5
else
6+6
ensure
7+7
end
}
end
def test_raise
ae %q{
begin
raise
rescue
:ok
end
}
ae %q{
begin
raise
rescue
:ok
ensure
:ng
end
}
ae %q{
begin
raise
rescue => e
e.class
end
}
ae %q{
begin
raise
rescue StandardError
:ng
rescue Exception
:ok
end
}
ae %q{
begin
begin
raise "a"
rescue
raise "b"
ensure
raise "c"
end
rescue => e
e.message
end
}
end
def test_error_variable
ae %q{
a = nil
1.times{|e|
begin
rescue => err
end
a = err.class
}
}
ae %q{
a = nil
1.times{|e|
begin
raise
rescue => err
end
a = err.class
}
a
}
end
def test_raise_in_other_scope
ae %q{
class E1 < Exception
end
def m
yield
end
begin
begin
begin
m{
raise
}
rescue E1
:ok2
ensure
end
rescue
:ok3
ensure
end
rescue E1
:ok
ensure
end
} do
remove_const :E1
end
ae %q{
$i = 0
def m
iter{
begin
$i += 1
begin
$i += 2
break
ensure
end
ensure
$i += 4
end
$i = 0
}
end
def iter
yield
end
m
$i
}
ae %q{
$i = 0
def m
begin
$i += 1
begin
$i += 2
return
ensure
$i += 3
end
ensure
$i += 4
end
p :end
end
m
$i
}
end
def test_raise_in_cont_sp
ae %q{
def m a, b
a + b
end
m(1, begin
raise
rescue
2
end) +
m(10, begin
raise
rescue
20
ensure
30
end)
}
ae %q{
def m a, b
a + b
end
m(begin
raise
rescue
1
end,
begin
raise
rescue
2
end)
}
end
def test_geterror
ae %q{
$!
}
ae %q{
begin
raise "FOO"
rescue
$!
end
}
ae %q{
def m
$!
end
begin
raise "FOO"
rescue
m()
end
}
ae %q{
$ans = []
def m
$!
end
begin
raise "FOO"
rescue
begin
raise "BAR"
rescue
$ans << m()
end
$ans << m()
end
$ans
}
ae %q{
$ans = []
def m
$!
end
begin
begin
raise "FOO"
ensure
$ans << m()
end
rescue
$ans << m()
end
}
ae %q{
$ans = []
def m
$!
end
def m2
1.times{
begin
return
ensure
$ans << m
end
}
end
m2
$ans
}
end
def test_stack_consistency
ae %q{ #
proc{
begin
raise
break
rescue
:ok
end
}.call
}
ae %q{
proc do
begin
raise StandardError
redo
rescue StandardError
end
end.call
}
end
end

591
yarvtest/test_flow.rb Normal file
View file

@ -0,0 +1,591 @@
#
# This test program is contributed by George Marrows
# Re: [Yarv-devel] Some tests for test_jump.rb
#
require 'yarvtest/yarvtest'
class TestFlow < YarvTestBase
def ae_flow(src, for_value=true)
# Tracks flow through the code
# A test like
# begin
# ensure
# end
# gets transformed into
# a = []
# begin
# begin; a << 1
# ensure; a << 2
# end; a << 3
# rescue Exception
# a << 99
# end
# a
# before being run. This tracks control flow through the code.
cnt = 0
src = src.gsub(/(\n|$)/) { "; $a << #{cnt+=1}\n" }
src = "$a = []; begin; #{src}; rescue Exception; $a << 99; end; $a"
if false#||true
STDERR.puts
STDERR.puts '#----'
STDERR.puts src
STDERR.puts '#----'
end
ae(src)
end
def test_while_with_ensure
ae %q{
a = []
i = 0
begin
while i < 1
i+=1
begin
begin
next
ensure
a << :ok
end
ensure
a << :ok2
end
end
ensure
a << :last
end
}
ae %q{
a = []
i = 0
begin
while i < 1
i+=1
begin
begin
break
ensure
a << :ok
end
ensure
a << :ok2
end
end
ensure
a << :last
end
}
ae %q{
a = []
i = 0
begin
while i < 1
if i>0
break
end
i+=1
begin
begin
redo
ensure
a << :ok
end
ensure
a << :ok2
end
end
ensure
a << :last
end
}
end
def test_ensure_normal_flow
ae_flow %{
begin
ensure
end }
end
def test_ensure_exception
ae_flow %{
begin
raise StandardError
ensure
end
}
end
def test_break_in_block_runs_ensure
ae_flow %{
[1,2].each do
begin
break
ensure
end
end
}
end
def test_next_in_block_runs_ensure
ae_flow %{
[1,2].each do
begin
next
ensure
end
end
}
end
def test_return_from_method_runs_ensure
ae_flow %{
o = "test"
def o.test(a)
return a
ensure
end
o.test(123)
}
end
def test_break_from_ifunc
ae %q{
["a"].inject("ng"){|x,y|
break :ok
}
}
ae %q{
unless ''.respond_to? :lines
class String
def lines
self
end
end
end
('a').lines.map{|e|
break :ok
}
}
ae_flow %q{
["a"].inject("ng"){|x,y|
break :ok
}
}
ae_flow %q{
('a'..'b').map{|e|
break :ok
}
}
end
def test_break_ensure_interaction1
# make sure that any 'break state' set up in the VM is c
# the time of the ensure
ae_flow %{
[1,2].each{
break
}
begin
ensure
end
}
end
def test_break_ensure_interaction2
# ditto, different arrangement
ae_flow %{
begin
[1,2].each do
break
end
ensure
end
}
end
def test_break_through_2_ensures
ae_flow %{
[1,2].each do
begin
begin
break
ensure
end
ensure
end
end
}
end
def test_ensure_break_ensure
# break through an ensure; run 2nd normally
ae_flow %{
begin
[1,2].each do
begin
break
ensure
end
end
ensure
end
}
end
def test_exception_overrides_break
ae_flow %{
[1,2].each do
begin
break
ensure
raise StandardError
end
end
}
end
def test_break_overrides_exception
ae_flow %{
[1,2].each do
begin
raise StandardError
ensure
break
end
end
}
ae_flow %{
[1,2].each do
begin
raise StandardError
rescue
break
end
end
}
end
def test_break_in_exception
ae_flow %q{
i=0
while i<3
i+=1
begin
ensure
break
end
end
}
ae_flow %q{
i=0
while i<3
i+=1
begin
raise
ensure
break
end
end
}
ae_flow %q{
i=0
while i<3
i+=1
begin
raise
rescue
break
end
end
}
end
def test_next_in_exception
return
ae_flow %q{
i=0
while i<3
i+=1
begin
ensure
next
end
end
}
ae_flow %q{
i=0
while i<3
i+=1
begin
raise
ensure
next
end
end
}
ae_flow %q{
i=0
while i<3
i+=1
begin
raise
rescue
next
end
end
}
end
def test_complex_break
ae_flow %q{
i = 0
while i<3
i+=1
j = 0
while j<3
j+=1
begin
raise
rescue
break
end
end
end
}
ae_flow %q{
i = 0
while i<3
i+=1
j = 0
while j<3
j+=1
1.times{
begin
raise
rescue
break
end
}
end
end
}
ae_flow %q{
i = 0
while i<3
i+=1
j = 0
while j<3
j+=1
begin
raise
ensure
break
end
end
end
}
ae_flow %q{
i = 0
while i<3
i+=1
j = 0
while j<3
j+=1
1.times{
begin
raise
ensure
break
end
}
end
end
}
ae_flow %q{
while true
begin
break
ensure
break
end
end
}
ae_flow %q{
while true
begin
break
ensure
raise
end
end
}
end
def test_jump_from_class
ae_flow %q{
3.times{
class C
break
end
}
}
ae_flow %q{
3.times{
class A
class B
break
end
end
}
}
ae_flow %q{
3.times{
class C
next
end
}
}
ae_flow %q{
3.times{
class C
class D
next
end
end
}
}
ae_flow %q{
while true
class C
break
end
end
}
ae_flow %q{
while true
class C
class D
break
end
end
end
}
ae_flow %q{
i=0
while i<3
i+=1
class C
next 10
end
end
}
ae %q{
1.times{
while true
class C
begin
break
ensure
break
end
end
end
}
}
end
def test_flow_with_cont_sp
ae %q{
def m a, b
a + b
end
m(1,
while true
break 2
end
)
}
ae %q{
def m a, b
a + b
end
m(1,
(i=0; while i<2
i+=1
class C
next 2
end
end; 3)
)
}
ae %q{
def m a, b
a+b
end
m(1, 1.times{break 3}) +
m(10, (1.times{next 3}; 20))
}
end
def test_return_in_deep_stack
ae_flow %q{
def m1 *args
end
def m2
m1(:a, :b, (return 1; :c))
end
m2
}
end
def test_return_in_ensure
ae_flow %q{
def m()
begin
2
ensure
return 3
end
end
m
}
ae_flow %q{
def m2
end
def m()
m2(begin
2
ensure
return 3
end)
4
end
m()
}
ae_flow %q{
def m
1
1.times{
2
begin
3
return
4
ensure
5
end
6
}
7
end
m()
}
end
end

296
yarvtest/test_jump.rb Normal file
View file

@ -0,0 +1,296 @@
require 'yarvtest/yarvtest'
class TestJump < YarvTestBase
def test_redo
ae %q{
def m
yield + 10
end
i=0
m{
if i>10
i*i
else
i+=1
redo
end
}
}
end
def test_next
ae %q{
def m
yield
:ok
end
i=0
m{
if i>10
i*i
else
i+=1
next
end
}
}
end
def test_next_with_val
ae %q{
def m
yield
end
m{
next :ok
}
}
end
def test_return
ae %q{
def m
return 3
end
m
}
ae %q{
def m
:ng1
mm{
return :ok
}
:ng2
end
def mm
:ng3
yield
:ng4
end
m
}
end
def test_return2
ae %q{
$i = 0
def m
begin
iter{
return
}
ensure
$i = 100
end
end
def iter
yield
end
m
$i
}
end
def test_return3
ae %q{
def m
begin
raise
rescue
return :ok
end
:ng
end
m
}
end
def test_break
ae %q{
def m
:ng1
mm{
yield
}
:ng2
end
def mm
:ng3
yield
:ng4
end
m{
break :ok
}
}
end
def test_exception_and_break
ae %q{
def m
yield
end
m{
begin
ensure
break :ok
end
}
}
end
def test_retry
# this test can't run on ruby 1.9(yarv can do)
%q{
def m a
mm{
yield
}
end
def mm
yield
end
i=0
m(i+=1){
retry if i<10
:ok
}
}
ae %q{
def m a
yield
end
i=0
m(i+=1){
retry if i<10
:ok
}
}
end
def test_complex_jump
ae %q{
module Enumerable
def all_?
self.each{|e|
unless yield(e)
return false
end
}
true
end
end
xxx = 0
[1,2].each{|bi|
[3,4].each{|bj|
[true, nil, true].all_?{|be| be}
break
}
xxx += 1
}
xxx
}
end
def test_return_from
ae %q{
def m
begin
raise
rescue
return 1
end
end
m
}
ae %q{
def m
begin
#
ensure
return 1
end
end
m
}
end
def test_break_from_times
ae %q{
3.times{
break :ok
}
}
end
def test_catch_and_throw
ae %q{
catch(:foo){
throw :foo
}
}
ae %q{
catch(:foo){
throw :foo, false
}
}
ae %q{
catch(:foo){
throw :foo, nil
}
}
ae %q{
catch(:foo){
throw :foo, :ok
}
}
ae %q{
catch(:foo){
1.times{
throw :foo
}
}
}
ae %q{
catch(:foo){
1.times{
throw :foo, :ok
}
}
}
ae %q{
catch(:foo){
catch(:bar){
throw :foo, :ok
}
:ng
}
}
ae %q{
catch(:foo){
catch(:bar){
1.times{
throw :foo, :ok
}
}
:ng
}
}
end
end

417
yarvtest/test_massign.rb Normal file
View file

@ -0,0 +1,417 @@
require 'yarvtest/yarvtest'
# test of syntax
class TestMassign < YarvTestBase
def test_simle
ae %q{
a = :a; b = :b; c = :c
x, y = a, b
[x, y]
}
ae %q{
a = :a; b = :b; c = :c
x, y, z = a, b, c
[x, y, z]
}
end
def test_diff_elems
ae %q{
a = :a ; b = :b ; c = :c
x, y, z = a, b
[x, y, z]
}
ae %q{
a = :a; b = :b; c = :c
x, y = a, b, c
[x, y]
}
end
def test_single_l
ae %q{
a = :a; b = :b
x = a, b
x
}
ae %q{
a = [1, 2]; b = [3, 4]
x = a, b
x
}
end
def test_single_r
ae %q{
a = :a
x, y = a
[x, y]
}
ae %q{
a = [1, 2]
x, y = a
[x, y]
}
ae %q{
a = [1, 2, 3]
x, y = a
[x, y]
}
end
def test_splat_l
ae %q{
a = :a; b = :b; c = :c
*x = a, b
[x]
}
ae %q{
a = :a; b = :b; c = :c
*x = a, b
[x]
}
ae %q{
a = :a; b = :b; c = :c
x, * = a, b
[x]
}
ae %q{
a = :a; b = :b; c = :c
x, *y = a, b
[x, y]
}
ae %q{
a = :a; b = :b; c = :c
x, y, *z = a, b
[x, y]
}
ae %q{ # only one item on rhs
*x = :x
x
}
ae %q{ # nil on rhs
*x = nil
x
}
end
def test_splat_r
if false
ae %q{
a = :a; b = :b; c = :c
x, y = *a
[x, y]
}
ae %q{
a = :a; b = :b; c = :c
x, y = a, *b
[x, y]
}
ae %q{
a = :a; b = :b; c = :c
x, y = a, b, *c
[x, y]
}
ae %q{
x=*nil
x
}
end
ae %q{
a = [:a, :a2]; b = [:b, :b2]; c = [:c, :c2]
x, y = *a
[x, y]
}
ae %q{
a = [:a, :a2]; b = [:b, :b2]; c = [:c, :c2]
x, y = a, *b
[x, y]
}
ae %q{
a = [:a, :a2]; b = [:b, :b2]; c = [:c, :c2]
x, y = a, b, *c
[x, y]
}
end
def test_splat_b1
if false
# error
ae %q{
a = :a; b = :b; c = :c
x, *y = *a
[x, y]
}
ae %q{
a = :a; b = :b; c = :c
x, *y = a, *b
[x, y]
}
ae %q{
a = :a; b = :b; c = :c
x, *y = a, b, *c
[x, y]
}
end
ae %q{
a = [:a, :a2]; b = [:b, :b2]; c = [:c, :c2]
x, *y = *a
[x, y]
}
ae %q{
a = [:a, :a2]; b = [:b, :b2]; c = [:c, :c2]
x, *y = a, *b
[x, y]
}
ae %q{
a = [:a, :a2]; b = [:b, :b2]; c = [:c, :c2]
x, *y = a, b, *c
[x, y]
}
end
def test_splat_b2
if false
# error
ae %q{
a = :a; b = :b; c = :c
*x = *a
x
}
ae %q{
a = :a; b = :b; c = :c
*x = a, *b
x
}
ae %q{
a = :a; b = :b; c = :c
*x = a, b, *c
x
}
end
ae %q{
a = [:a, :a2]; b = [:b, :b2]; c = [:c, :c2]
*x = *a
x
}
ae %q{
a = [:a, :a2]; b = [:b, :b2]; c = [:c, :c2]
*x = a, *b
x
}
ae %q{
a = [:a, :a2]; b = [:b, :b2]; c = [:c, :c2]
*x = a, b, *c
x
}
end
def test_toary
ae %q{
x, y = :a
[x, y]
}
ae %q{
x, y = [1, 2]
[x, y]
}
ae %q{
x, y = [1, 2, 3]
[x, y]
}
end
def test_swap
ae %q{
a = 1; b = 2
a, b = b, a
[a, b]
}
end
def test_mret
ae %q{
def m
return 1, 2
end
a, b = m
[a, b]
}
ae %q{
def m
return 1, 2
end
a = m
[a]
}
ae %q{
def m
return 1
end
a, b = m
[a, b]
}
end
def test_mret_splat
if false
ae %q{
def m
return *1
end
a, b = m
[a, b]
}
end
ae %q{
def m
return *[]
end
a, b = m
[a, b]
}
ae %q{
def m
return *[1]
end
a, b = m
[a, b]
}
ae %q{
def m
return *[1,2]
end
a, b = m
[a, b]
}
ae %q{
def m
return *[1,2,3]
end
a, b = m
[a, b]
}
ae %q{
def m
return *[1]
end
a = m
}
end
def test_mret_argscat
ae %q{
def m
return 1, *[]
end
a, b = m
[a, b]
}
ae %q{
def m
return 1, 2, *[1]
end
a, b = m
[a, b]
}
ae %q{
def m
return 1, 2, 3, *[1,2]
end
a, b = m
[a, b]
}
end
def test_nested_massign
ae %q{
(a, b), c = [[1, 2], 3]
[a, b, c]
}
ae %q{
a, (b, c) = [[1, 2], 3]
[a, b, c]
}
ae %q{
a, (b, c) = [1, [2, 3]]
[a, b, c]
}
ae %q{
(a, b), *c = [[1, 2], 3]
[a, b, c]
}
ae %q{
(a, b), c, (d, e) = [[1, 2], 3, [4, 5]]
[a, b, c, d, e]
}
ae %q{
(a, *b), c, (d, e, *) = [[1, 2], 3, [4, 5]]
[a, b, c, d, e]
}
ae %q{
(a, b), c, (d, *e) = [[1, 2, 3], 3, [4, 5, 6, 7]]
[a, b, c, d, e]
}
ae %q{
(a, (b1, b2)), c, (d, e) = [[1, 2], 3, [4, 5]]
[a, b1, b2, c, d, e]
}
ae %q{
(a, (b1, b2)), c, (d, e) = [[1, [21, 22]], 3, [4, 5]]
[a, b1, b2, c, d, e]
}
end
# ignore
def _test_massign_value
# Value of this massign statement should be [1, 2, 3]
ae %q{
a, b, c = [1, 2, 3]
}
end
def test_nested_splat
# Somewhat obscure nested splat
ae %q{
a = *[*[1]]
a
}
end
def test_calls_to_a
# Should be result of calling to_a on arg, ie [[1, 2], [3, 4]]
ae %q{
x=*{1=>2,3=>4}
x
}
end
def test_const_massign
ae %q{
class C
class D
end
end
X, Y = 1, 2
Z, C::Const, C::D::Const, ::C::Const2 = 3, 4, 5, 6
[X, Y, Z, C::Const, C::D::Const, ::C::Const2]
}
end
def test_massign_values
ae %q{
ary = [1, 2].partition {|n| n == 1 }
a, b = ary
[a, b]
}
end
end

539
yarvtest/test_method.rb Normal file
View file

@ -0,0 +1,539 @@
require 'yarvtest/yarvtest'
class TestMethod < YarvTestBase
def test_simple_method
ae %q{
def m_simple_method
1
end
m_simple_method()
}
end
def test_polymorphic
ae %q{
o1 = 'str'
o2 = 1
str = ''
i = 1
while i<10
i+=1
o = (i%2==0) ? o1 : o2
str += o.to_s
end
str
}
end
def test_arg
ae <<-'EOS'
def m_arg(a1, a2)
a1+a2
end
m_arg(1,2)
EOS
end
def test_rec
ae <<-'EOS'
def m_rec n
if n > 1
n + m_rec(n-1)
else
1
end
end
m_rec(10)
EOS
end
def test_splat
ae %q{
def m a
a
end
begin
m(*1)
rescue TypeError
:ok
end
}
ae %q{
def m a, b
[a, b]
end
m(*[1,2])
}
ae %q{
def m a, b, c
[a, b, c]
end
m(1, *[2, 3])
}
ae %q{
def m a, b, c
[a, b, c]
end
m(1, 2, *[3])
}
end
def test_rest
ae %q{
def m *a
a
end
m
}
ae %q{
def m *a
a
end
m 1
}
ae %q{
def m *a
a
end
m 1, 2, 3
}
ae %q{
def m x, *a
[x, a]
end
m 1
}
ae %q{
def m x, *a
[x, a]
end
m 1, 2
}
ae %q{
def m x, *a
[x, a]
end
m 1, 2, 3, 4
}
end
def test_opt
ae %q{
def m a=1
a
end
m
}
ae %q{
def m a=1
a
end
m 2
}
ae %q{
def m a=1, b=2
[a, b]
end
m
}
ae %q{
def m a=1, b=2
[a, b]
end
m 10
}
ae %q{
def m a=1, b=2
[a, b]
end
m 10, 20
}
ae %q{
def m x, a=1, b=2
[x, a, b]
end
m 10
}
ae %q{
def m x, a=1, b=2
[x, a, b]
end
m 10, 20
}
ae %q{
def m x, a=1, b=2
[x, a, b]
end
m 10, 20, 30
}
ae %q{
def m x, y, a
[x, y, a]
end
m 10, 20, 30
}
end
def test_opt_rest
ae %q{
def m0 b = 0, c = 1, *d
[:sep, b, c, d]
end
def m1 a, b = 0, c = 1, *d
[:sep, a, b, c, d]
end
def m2 x, a, b = 0, c = 1, *d
[:sep, x, a, b, c, d]
end
def m3 x, y, a, b = 0, c = 1, *d
[:sep, x, y, a, b, c, d]
end
def s3 x, y, a, b = 0, c = 1
[:sep, x, y, a, b, c]
end
m0() +
m0(:a) +
m0(:a, :b) +
m0(:a, :b, :c) +
m0(:a, :b, :c, :d) +
m0(:a, :b, :c, :d, :e) +
m1(:a) +
m1(:a, :b) +
m1(:a, :b, :c) +
m1(:a, :b, :c, :d) +
m1(:a, :b, :c, :d, :e) +
m2(:a, :b) +
m2(:a, :b, :c) +
m2(:a, :b, :c, :d) +
m2(:a, :b, :c, :d, :e) +
m2(:a, :b, :c, :d, :e, :f) +
m3(:a, :b, :c) +
m3(:a, :b, :c, :d) +
m3(:a, :b, :c, :d, :e) +
m3(:a, :b, :c, :d, :e, :f) +
m3(:a, :b, :c, :d, :e, :f, :g)
}
end
def test_opt_rest_block
ae %q{
def m a, b = 0, c = 1, *d, &pr
[a, b, c, d, pr]
end
m(:a) +
m(:a, :b) +
m(:a, :b, :c) +
m(:a, :b, :c, :d) +
m(:a, :b, :c, :d, :e)
}
ae %q{
def m a, b = 0, c = 1, *d, &pr
[a, b, c, d, pr.call]
end
m(:a){1} +
m(:a, :b){2} +
m(:a, :b, :c){3} +
m(:a, :b, :c, :d){4} +
m(:a, :b, :c, :d, :e){5}
}
end
def test_singletonmethod
ae %q{
lobj = Object.new
def lobj.m
:singleton
end
lobj.m
}
ae %q{
class C
def m
:C_m
end
end
lobj = C.new
def lobj.m
:Singleton_m
end
lobj.m
}
end
def test_singletonmethod_with_const
ae %q{
class C
Const = :C
def self.m
1.times{
Const
}
end
end
C.m
}
end
def test_alias
ae %q{
def m1
:ok
end
alias :m2 :m1
m1
}
ae %q{
def m1
:ok
end
alias m2 m1
m1
}
ae %q{
def m1
:ok
end
alias m2 :m1
m1
}
ae %q{
def m1
:ok
end
alias :m2 m1
m1
}
ae %q{
def m1
:ok
end
alias m2 m1
def m1
:ok2
end
[m1, m2]
}
end
def test_split
ae %q{
'abc'.split(/b/)
}
ae %q{
1.times{|bi|
'abc'.split(/b/)
}
}
end
def test_block_pass
ae %q{
def getproc &b
b
end
def m
yield
end
m(&getproc{
"test"
})
}
ae %q{
def getproc &b
b
end
def m a
yield a
end
m(123, &getproc{|block_a|
block_a
})
}
ae %q{
def getproc &b
b
end
def m *a
yield a
end
m(123, 456, &getproc{|block_a|
block_a
})
}
ae %q{
def getproc &b
b
end
[1,2,3].map(&getproc{|block_e| block_e*block_e})
}
ae %q{
def m a, b, &c
c.call(a, b)
end
m(10, 20){|x, y|
[x+y, x*y]
}
}
ae %q{
def m &b
b
end
m(&nil)
}
ae %q{
def m a, &b
[a, b]
end
m(1, &nil)
}
ae %q{
def m a
[a, block_given?]
end
m(1, &nil)
}
end
def test_method_missing
ae %q{
class C
def method_missing id
id
end
end
C.new.hoge
} do
remove_const :C
end
ae %q{
class C
def method_missing *args, &b
b.call(args)
end
end
C.new.foo(1){|args|
args
}
C.new.foo(1){|args|
args
} +
C.new.foo(1, 2){|args|
args
}
}
end
def test_svar
ae %q{
'abc'.match(/a(b)c/)
$1
}
end
def test_nested_method
ae %q{
class A
def m
def m2
p :m2
end
m2()
end
end
A.new.m
}
ae %q{
class A
def m
def m2
p :m2
end
m2()
end
end
instance_eval('A.new.m')
}
end
def test_private_class_method
ae %q{
class C
def self.m
:ok
end
def self.test
m
end
private_class_method :m
end
C.test
}
end
def test_alias_and_private
ae %q{ # [yarv-dev:899]
$ans = []
class C
def m
$ans << "OK"
end
end
C.new.m
class C
alias mm m
private :mm
end
C.new.m
begin
C.new.mm
rescue NoMethodError
$ans << "OK!"
end
$ans
}
end
def test_break_from_defined_method
ae %q{
class C
define_method(:foo){
break :ok
}
end
C.new.foo
}
end
def test_return_from_defined_method
ae %q{
class C
define_method(:m){
return :ok
}
end
C.new.m
}
end
end

118
yarvtest/test_opts.rb Normal file
View file

@ -0,0 +1,118 @@
require 'yarvtest/yarvtest'
class TestOpt < YarvTestBase
def test_plus
ae %q{
a, b = 1, 2
a+b
}
ae %q{
class Fixnum
def +(*o)
o
end
def -(*o)
o
end
end
[10+11, 100-101]
}
ae %q{
class Float
def +(o)
self * o
end
end
a, b = 1, 2
a+b
}
end
def test_opt_methdos
klasses = [[Fixnum, 2, 3], [Float, 1.1, 2.2],
[String, "abc", "def"], [Array, [1,2,3], [4, 5]],
[Hash, {:a=>1, :b=>2}, {:x=>"foo", :y=>"bar"}]]
bin_methods = [:+, :-, :*, :/, :%, ]
one_methods = [:length, :succ, ]
ary = []
bin_methods.each{|m|
klasses.each{|klass, obj, arg|
str = %{
ary = []
if (#{obj.inspect}).respond_to? #{m.inspect}
begin
ary << (#{obj.inspect}).#{m.to_s}(#{arg.inspect})
rescue Exception => e
ary << :error
end
end
class #{klass}
def #{m}(o)
[#{m.inspect}, :bin, #{klass}].inspect
end
end
ary << (#{obj.inspect}).#{m.to_s}(#{arg.inspect})
ary
}
ae str
}
}
one_methods.each{|m|
klasses.each{|klass, obj|
str = %{
ary = []
if (#{obj.inspect}).respond_to? #{m.inspect}
ary << (#{obj.inspect}).#{m.to_s}()
end
class #{klass}
def #{m}()
[#{m.inspect}, self, #{klass}].inspect
end
end
ary << (#{obj.inspect}).#{m.to_s}()
ary
}
ae str
}
}
end
def test_opt_plus
ae %q{
temp = 2**30 - 5
(1..5).map do
temp += 1
[temp, temp.class]
end
}
ae %q{
temp = -(2**30 - 5)
(1..10).map do
temp += 1
[temp, temp.class]
end
}
end
def test_eq
ae %q{
class Foo
def ==(other)
true
end
end
foo = Foo.new
[1.0 == foo,
1 == foo,
"abc" == foo,
]
}
end
end

293
yarvtest/test_proc.rb Normal file
View file

@ -0,0 +1,293 @@
require 'yarvtest/yarvtest'
class TestProc < YarvTestBase
def test_simpleproc
ae %q{
def m(&b)
b
end
m{1}.call
}
ae %q{
def m(&b)
b
end
m{
a = 1
a + 2
}.call
}
end
def test_procarg
ae %q{
def m(&b)
b
end
m{|e_proctest| e_proctest}.call(1)
}
ae %q{
def m(&b)
b
end
m{|e_proctest1, e_proctest2|
a = e_proctest1 * e_proctest2 * 2
a * 3
}.call(1, 2)
}
ae %q{
[
Proc.new{|*args| args}.call(),
Proc.new{|*args| args}.call(1),
Proc.new{|*args| args}.call(1, 2),
Proc.new{|*args| args}.call(1, 2, 3),
]
}
ae %q{
[
Proc.new{|a, *b| [a, b]}.call(),
Proc.new{|a, *b| [a, b]}.call(1),
Proc.new{|a, *b| [a, b]}.call(1, 2),
Proc.new{|a, *b| [a, b]}.call(1, 2, 3),
]
}
end
def test_closure
ae %q{
def make_proc(&b)
b
end
def make_closure
a = 0
make_proc{
a+=1
}
end
cl = make_closure
cl.call + cl.call * cl.call
}
end
def test_nestproc2
ae %q{
def iter
yield
end
def getproc &b
b
end
iter{
bvar = 3
getproc{
bvar2 = 4
bvar * bvar2
}
}.call
}
ae %q{
def iter
yield
end
def getproc &b
b
end
loc1 = 0
pr1 = iter{
bl1 = 1
getproc{
loc1 += 1
bl1 += 1
loc1 + bl1
}
}
pr2 = iter{
bl1 = 1
getproc{
loc1 += 1
bl1 += 1
loc1 + bl1
}
}
pr1.call; pr2.call
pr1.call; pr2.call
pr1.call; pr2.call
(pr1.call + pr2.call) * loc1
}
end
def test_proc_with_cref
ae %q{
Const = :top
class C
Const = :C
$pr = proc{
(1..2).map{
Const
}
}
end
$pr.call
}
ae %q{
Const = :top
class C
Const = :C
end
pr = proc{
Const
}
C.class_eval %q{
pr.call
}
}
end
def test_3nest
ae %q{
def getproc &b
b
end
def m
yield
end
m{
i = 1
m{
j = 2
m{
k = 3
getproc{
[i, j, k]
}
}
}
}.call
}
end
def test_nestproc1
ae %q{
def proc &b
b
end
pr = []
proc{|i_b|
p3 = proc{|j_b|
pr << proc{|k_b|
[i_b, j_b, k_b]
}
}
p3.call(1)
p3.call(2)
}.call(0)
pr[0].call(:last).concat pr[1].call(:last)
}
end
def test_proc_with_block
ae %q{
def proc(&pr)
pr
end
def m
a = 1
m2{
a
}
end
def m2
b = 2
proc{
[yield, b]
}
end
pr = m
x = ['a', 1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,
1,2,3,4,5,6,7,8,9,0,]
pr.call
}
ae %q{
def proc(&pr)
pr
end
def m
a = 1
m2{
a
}
end
def m2
b = 2
proc{
[yield, b]
}
100000.times{|x|
"#{x}"
}
yield
end
m
}
end
def test_method_to_proc
ae %q{
class C
def foo
:ok
end
end
def block
C.method(:new).to_proc
end
b = block()
b.call.foo
}
end
def test_safe
ae %q{
pr = proc{
$SAFE
}
$SAFE = 1
pr.call
}
ae %q{
pr = proc{
$SAFE += 1
}
[pr.call, $SAFE]
}
end
end

594
yarvtest/test_syntax.rb Normal file
View file

@ -0,0 +1,594 @@
require 'yarvtest/yarvtest'
# test of syntax
class TestSYNTAX < YarvTestBase
def test_if_unless
ae %q(if true then 1 ; end)
ae %q(if false then 1 ; end)
ae %q(if true then 1 ; else; 2; end)
ae %q(if false then 1 ; else; 2; end)
ae %q(if true then ; elsif true then ; 1 ; end)
ae %q(if false then ; elsif true then ; 1 ; end)
ae %q(unless true then 1 ; end)
ae %q(unless false then 1 ; end)
ae %q(unless true then 1 ; else; 2; end)
ae %q(unless false then 1 ; else; 2; end)
ae %q(1 if true)
ae %q(1 if false)
ae %q(1 if nil)
ae %q(1 unless true)
ae %q(1 unless false)
ae %q(1 unless nil)
end
def test_while_until
ae %q(
i = 0
while i < 10
i+=1
end)
ae %q(
i = 0
while i < 10
i+=1
end; i)
ae %q(
i = 0
until i > 10
i+=1
end)
ae %q(
i = 0
until i > 10
i+=1
end; i)
#
ae %q{
i = 0
begin
i+=1
end while false
i
}
ae %q{
i = 0
begin
i+=1
end until true
i
}
end
def test_and
ae %q(1 && 2 && 3 && 4)
ae %q(1 && nil && 3 && 4)
ae %q(1 && 2 && 3 && nil)
ae %q(1 && 2 && 3 && false)
ae %q(1 and 2 and 3 and 4)
ae %q(1 and nil and 3 and 4)
ae %q(1 and 2 and 3 and nil)
ae %q(1 and 2 and 3 and false)
ae %q(nil && true)
ae %q(false && true)
end
def test_or
ae %q(1 || 2 || 3 || 4)
ae %q(1 || false || 3 || 4)
ae %q(nil || 2 || 3 || 4)
ae %q(false || 2 || 3 || 4)
ae %q(nil || false || nil || false)
ae %q(1 or 2 or 3 or 4)
ae %q(1 or false or 3 or 4)
ae %q(nil or 2 or 3 or 4)
ae %q(false or 2 or 3 or 4)
ae %q(nil or false or nil or false)
end
def test_case
ae %q(
case 1
when 2
:ng
end)
ae %q(
case 1
when 10,20,30
:ng1
when 1,2,3
:ok
when 100,200,300
:ng2
else
:elseng
end)
ae %q(
case 123
when 10,20,30
:ng1
when 1,2,3
:ng2
when 100,200,300
:ng3
else
:elseok
end
)
ae %q(
case 'test'
when /testx/
:ng1
when /test/
:ok
when /tetxx/
:ng2
else
:ng_else
end
)
ae %q(
case Object.new
when Object
:ok
end
)
ae %q(
case Object
when Object.new
:ng
else
:ok
end
)
ae %q{
case 'test'
when 'tes'
:ng
when 'te'
:ng
else
:ok
end
}
ae %q{
case 'test'
when 'tes'
:ng
when 'te'
:ng
when 'test'
:ok
end
}
ae %q{
case 'test'
when 'tes'
:ng
when /te/
:ng
else
:ok
end
}
ae %q{
case 'test'
when 'tes'
:ng
when /test/
:ok
else
:ng
end
}
ae %q{
def test(arg)
case 1
when 2
3
end
return arg
end
test(100)
}
end
def test_case_splat
ae %q{
ary = [1, 2]
case 1
when *ary
:ok
else
:ng
end
}
ae %q{
ary = [1, 2]
case 3
when *ary
:ng
else
:ok
end
}
ae %q{
ary = [1, 2]
case 1
when :x, *ary
:ok
when :z
:ng1
else
:ng2
end
}
ae %q{
ary = [1, 2]
case 3
when :x, *ary
:ng1
when :z
:ng2
else
:ok
end
}
end
def test_when
ae %q(
case
when 1==2, 2==3
:ng1
when false, 4==5
:ok
when false
:ng2
else
:elseng
end
)
ae %q(
case
when nil, nil
:ng1
when 1,2,3
:ok
when false, false
:ng2
else
:elseng
end
)
ae %q(
case
when nil
:ng1
when false
:ng2
else
:elseok
end)
ae %q{
case
when 1
end
}
ae %q{
r = nil
ary = []
case
when false
r = :ng1
when false, false
r = :ng2
when *ary
r = :ng3
when false, *ary
r = :ng4
when true, *ary
r = :ok
end
r
}
end
def test_when_splat
ae %q{
ary = []
case
when false, *ary
:ng
else
:ok
end
}
ae %q{
ary = [false, nil]
case
when *ary
:ng
else
:ok
end
}
ae %q{
ary = [false, nil]
case
when *ary
:ng
when true
:ok
else
:ng2
end
}
ae %q{
ary = [false, nil]
case
when *ary
:ok
else
:ng
end
}
ae %q{
ary = [false, true]
case
when *ary
:ok
else
:ng
end
}
ae %q{
ary = [false, true]
case
when false, false
when false, *ary
:ok
else
:ng
end
}
end
def test_flipflop
ae %q{
sum = 0
30.times{|ib|
if ib % 10 == 0 .. true
sum += ib
end
}
sum
}
ae %q{
sum = 0
30.times{|ib|
if ib % 10 == 0 ... true
sum += ib
end
}
sum
}
ae %q{
t = nil
unless ''.respond_to? :lines
class String
def lines
self
end
end
end
"this must not print
Type: NUM
123
456
Type: ARP
aaa
bbb
\f
this must not print
hoge
Type: ARP
aaa
bbb
".lines.each{|l|
if (t = l[/^Type: (.*)/, 1])..(/^\f/ =~ l)
p [t, l]
end
}
}
end
def test_defined_vars
ae %q{
defined?(nil) + defined?(self) +
defined?(true) + defined?(false)
}
#ae %q{
# a = 1
# defined?(a) # yarv returns "in block" in eval context
#}
ae %q{
defined?(@a)
}
ae %q{
@a = 1
defined?(@a)
}
ae %q{
defined?(@@a)
}
ae %q{
@@a = 1
defined?(@@a)
}
ae %q{
defined?($a)
}
ae %q{
$a = 1
defined?($a)
}
ae %q{
defined?(C_definedtest)
}
ae %q{
C_definedtest = 1
defined?(C_definedtest)
} do
remove_const :C_definedtest
end
ae %q{
defined?(::C_definedtest)
}
ae %q{
C_definedtest = 1
defined?(::C_definedtest)
} do
remove_const :C_definedtest
end
ae %q{
defined?(C_definedtestA::C_definedtestB::C_definedtestC)
}
ae %q{
class C_definedtestA
class C_definedtestB
C_definedtestC = 1
end
end
defined?(C_definedtestA::C_definedtestB::C_definedtestC)
} do
remove_const :C_definedtestA
end
end
def test_defined_method
ae %q{
defined?(m)
}
ae %q{
def m
end
defined?(m)
}
ae %q{
defined?(a.class)
}
ae %q{
a = 1
defined?(a.class)
}
ae %q{
class C
def test
[defined?(m1()), defined?(self.m1), defined?(C.new.m1),
defined?(m2()), defined?(self.m2), defined?(C.new.m2),
defined?(m3()), defined?(self.m3), defined?(C.new.m3)]
end
def m1
end
private
def m2
end
protected
def m3
end
end
C.new.test + [defined?(C.new.m3)]
}
ae %q{
$ans = [defined?($1), defined?($2), defined?($3), defined?($4)]
/(a)(b)/ =~ 'ab'
$ans + [defined?($1), defined?($2), defined?($3), defined?($4)]
}
end
def test_condition
ae %q{
def make_perm ary, num
if num == 1
ary.map{|e| [e]}
else
base = make_perm(ary, num-1)
res = []
base.each{|b|
ary.each{|e|
res << [e] + b
}
}
res
end
end
def each_test
conds = make_perm(['fv', 'tv'], 3)
bangs = make_perm(['', '!'], 3)
exprs = make_perm(['and', 'or'], 3)
['if', 'unless'].each{|syn|
conds.each{|cs|
bangs.each{|bs|
exprs.each{|es|
yield(syn, cs, bs, es)
}
}
}
}
end
fv = false
tv = true
$ans = []
each_test{|syn, conds, bangs, exprs|
c1, c2, c3 = conds
bang1, bang2, bang3 = bangs
e1, e2 = exprs
eval %Q{
#{syn} #{bang1}#{c1} #{e1} #{bang2}#{c2} #{e2} #{bang3}#{c3}
$ans << :then
else
$ans << :false
end
}
}
each_test{|syn, conds, bangs, exprs|
c1, c2, c3 = conds
bang1, bang2, bang3 = bangs
e1, e2 = exprs
eval %Q{
#{syn} #{bang1}#{c1} #{e1} #{bang2}#{c2} #{e2} #{bang3}#{c3}
$ans << :then
end
$ans << :sep
}
}
$ans
}
end
end

8
yarvtest/test_test.rb Normal file
View file

@ -0,0 +1,8 @@
require 'yarvtest/yarvtest'
# test of syntax
class TestTest < YarvTestBase
def test_1
ae '100'
end
end

209
yarvtest/test_thread.rb Normal file
View file

@ -0,0 +1,209 @@
require 'yarvtest/yarvtest'
class TestThread < YarvTestBase
def test_create
ae %q{
Thread.new{
}.join
:ok
}
ae %q{
Thread.new{
:ok
}.value
}
end
def test_create_many_threads1
ae %q{
v = 0
(1..200).map{|i|
Thread.new{
i
}
}.each{|t|
v += t.value
}
v
}
end
def test_create_many_threads2
ae %q{
5000.times{|e|
(1..2).map{
Thread.new{
}
}.each{|e|
e.join
}
}
}
end
def test_create_many_threads3
ae %q{
5000.times{
t = Thread.new{}
while t.alive?
Thread.pass
end
}
}
end
def test_create_many_threads4
ae %q{
100.times{
Thread.new{loop{Thread.pass}}
}
}
end
def test_raise
ae %q{
t = Thread.new{
sleep
}
sleep 0.1
t.raise
begin
t.join
:ng
rescue
:ok
end
}
ae %q{
t = Thread.new{
loop{}
}
Thread.pass
t.raise
begin
t.join
:ng
rescue
:ok
end
}
ae %q{
t = Thread.new{
}
Thread.pass
t.join
t.raise # raise to exited thread
begin
t.join
:ok
rescue
:ng
end
}
end
def test_status
ae %q{
t = Thread.new{
loop{}
}
st = t.status
t.kill
st
}
ae %q{
t = Thread.new{
sleep
}
sleep 0.1
st = t.status
t.kill
st
}
ae %q{
t = Thread.new{
}
t.kill
sleep 0.1
t.status
}
end
def test_tlv
ae %q{
Thread.current[:a] = 1
Thread.new{
Thread.current[:a] = 10
Thread.pass
Thread.current[:a]
}.value + Thread.current[:a]
}
end
def test_thread_group
ae %q{
ptg = Thread.current.group
Thread.new{
ctg = Thread.current.group
[ctg.class, ctg == ptg]
}.value
}
ae %q{
thg = ThreadGroup.new
t = Thread.new{
thg.add Thread.current
sleep
}
sleep 0.1
[thg.list.size, ThreadGroup::Default.list.size]
}
end
def test_thread_local_svar
ae %q{
/a/ =~ 'a'
$a = $~
Thread.new{
$b = $~
/a/ =~ 'a'
$c = $~
}
$d = $~
[$a == $d, $b, $c != $d]
}
end
def test_join
ae %q{
Thread.new{
:ok
}.join.value
}
ae %q{
begin
Thread.new{
raise "ok"
}.join
rescue => e
e
end
}
ae %q{
ans = nil
t = Thread.new{
begin
sleep 0.5
ensure
ans = :ok
end
}
Thread.pass
t.kill
t.join
ans
}
end
end

207
yarvtest/test_yield.rb Normal file
View file

@ -0,0 +1,207 @@
require 'yarvtest/yarvtest'
class TestYield < YarvTestBase
def test_simple
ae %q{
def iter
yield
end
iter{
1
}
}
end
def test_hash_each
ae %q{
h = {:a => 1}
a = []
h.each{|k, v|
a << [k, v]
}
h.each{|kv|
a << kv
}
a
}
end
def test_ary_each
ae %q{
ans = []
ary = [1,2,3]
ary.each{|a, b, c, d|
ans << [a, b, c, d]
}
ary.each{|a, b, c|
ans << [a, b, c]
}
ary.each{|a, b|
ans << [a, b]
}
ary.each{|a|
ans << [a]
}
ans
}
end
def test_iter
ae %q{
def iter *args
yield *args
end
ans = []
ary = [1,2,3]
ary.each{|a, b, c, d|
ans << [a, b, c, d]
}
ary.each{|a, b, c|
ans << [a, b, c]
}
ary.each{|a, b|
ans << [a, b]
}
ary.each{|a|
ans << [a]
}
ans
}
end
def test_iter2
ae %q{
def iter args
yield *args
end
ans = []
iter([]){|a, b|
ans << [a, b]
}
iter([1]){|a, b|
ans << [a, b]
}
iter([1, 2]){|a, b|
ans << [a, b]
}
iter([1, 2, 3]){|a, b|
ans << [a, b]
}
ans
}
ae %q{
def iter args
yield *args
end
ans = []
iter([]){|a|
ans << a
}
iter([1]){|a|
ans << a
}
iter([1, 2]){|a|
ans << a
}
iter([1, 2, 3]){|a|
ans << a
}
ans
}
end
def test_1_ary_and_n_params
ae %q{
def iter args
yield args
end
ans = []
iter([]){|a, b|
ans << [a, b]
}
iter([1]){|a, b|
ans << [a, b]
}
iter([1, 2]){|a, b|
ans << [a, b]
}
iter([1, 2, 3]){|a, b|
ans << [a, b]
}
ans
}
end
def test_1_ary_and_1_params
ae %q{
def iter args
yield args
end
ans = []
iter([]){|a|
ans << a
}
iter([1]){|a|
ans << a
}
iter([1, 2]){|a|
ans << a
}
iter([1, 2, 3]){|a|
ans << a
}
ans
}
end
def test_argscat
ae %q{
def iter
yield 1, *[2, 3]
end
iter{|a, b, c|
[a, b, c]
}
}
ae %q{
def iter
yield 1, *[]
end
iter{|a, b, c|
[a, b, c]
}
}
if false
ae %q{
def iter
yield 1, *2
end
iter{|a, b, c|
[a, b, c]
}
}
end
end
def test_massgin
ae %q{
ans = []
[[1, [2, 3]], [4, [5, 6]]].each{|a, (b, c)|
ans << [a, b, c]
}
ans
}
ae %q{
ans = []
[[1, [2, 3]], [4, [5, 6]]].map{|a, (b, c)|
ans << [a, b, c]
} + ans
}
end
end

136
yarvtest/yarvtest.rb Normal file
View file

@ -0,0 +1,136 @@
require 'test/unit'
if defined? YARV_PATCHED
require 'yarvutil'
class YarvTestBase < Test::Unit::TestCase
def remove_const sym
Object.module_eval{
remove_const sym
}
end
def remove_method sym
Object.module_eval{
undef sym
}
end
def ae str
# puts str
# puts YARVUtil.parse(str, $0, 0).disasm
ruby = YARVUtil.eval_in_wrap(str)
yield if block_given?
yarv = YARVUtil.eval(str)
yield if block_given?
assert_equal(ruby, yarv)
end
def test_
end
end
else
require 'rbconfig'
class YarvTestBase < Test::Unit::TestCase
def initialize *args
super
if /mswin32/ !~ RUBY_PLATFORM
@yarv = './miniruby'
else
@yarv = 'miniruby'
end
@ruby = Config::CONFIG['ruby_install_name']
end
def remove_const sym
Object.module_eval{
remove_const sym
}
end
def remove_method sym
Object.module_eval{
undef sym
}
end
require 'tempfile'
def exec exec_file, program
dir = []
dir << ENV['RAMDISK'] if ENV['RAMDISK']
tmpf = Tempfile.new("yarvtest_#{Process.pid}_#{Time.now.to_i}", *dir)
tmpf.write program
tmpf.close
result = `#{exec_file} #{tmpf.path}`
tmpf.open
tmpf.close(true)
result
end
def dump_and_exec exec_file, str
asmstr = <<-EOASMSTR
iseq = YARVCore::InstructionSequence.compile(<<-'EOS__')
#{str}
EOS__
p YARVCore::InstructionSequence.load(iseq.to_a).eval
EOASMSTR
exec(exec_file, asmstr)
end
def exec_ exec_file, program
exec_file.tr!('\\', '/')
r = ''
IO.popen("#{exec_file}", 'r+'){|io|
#
io.write program
io.close_write
begin
while line = io.gets
r << line
# p line
end
rescue => e
# p e
end
}
r
end
def ae str
evalstr = %{
p eval(%q{
#{str}
})
}
ruby = exec(@ruby, evalstr)
yarv = exec(@yarv, evalstr)
if $DEBUG #|| true
puts "yarv (#@yarv): #{yarv}"
puts "ruby (#@ruby): #{ruby}"
end
assert_equal(ruby.gsub(/\r/, ''), yarv.gsub(/\r/, ''))
# store/load test
if false # || true
yarvasm = dump_and_exec(@yarv, str)
assert_equal(ruby.gsub(/\r/, ''), yarvasm.gsub(/\r/, ''))
end
end
def test_
end
end
end