diff --git a/ChangeLog b/ChangeLog index 85043b00dd..ba8db46ff8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Sat Aug 25 03:49:14 2007 Tanaka Akira + + * test/ruby/sentence.rb (Sentence): include Enumerable. + (Sentence#each): defined. + + * test/ruby/test_assignment.rb: use Sentence#expand. + Sat Aug 25 03:08:57 2007 Koichi Sasada * prelude.rb: fix Mutex#synchronize definition. diff --git a/test/ruby/sentence.rb b/test/ruby/sentence.rb index 048d453cc5..50f42d6885 100644 --- a/test/ruby/sentence.rb +++ b/test/ruby/sentence.rb @@ -170,6 +170,21 @@ class Sentence @sent.length end + # iterates over children. + # + # Sentence(%w[2 * 7], "+", %w[3 * 5]).each {|v| p v } + # #=> + # # + # "+" + # # + # + def each # :yield: element + @sent.each_index {|i| + yield self[i] + } + end + include Enumerable + def inspect "#<#{self.class}: #{inner_inspect(@sent, '')}>" end @@ -206,7 +221,7 @@ class Sentence # Sentence.new(%w[2 + 3]).subst(/\A\d+\z/) {|s| ((s.to_i)*2).to_s } # #=> # # - def subst(target, &b) + def subst(target, &b) # :yield: string Sentence.new(subst_rec(@sent, target, &b)) end @@ -231,7 +246,7 @@ class Sentence # Sentence(%w[2 * 7], "+", %w[3 * 5]).find_subtree {|s| s[1] == "*" } # #=> # # - def find_subtree(&b) + def find_subtree(&b) # :yield: sentence find_subtree_rec(@sent, &b) end @@ -268,25 +283,23 @@ class Sentence # s.expand {|s| s[0] == "3" } # #=> # # - def expand(&b) + def expand(&b) # :yield: sentence Sentence.new(expand_rec(@sent, &b)) end # :stopdoc: def expand_rec(obj, r=[], &b) if obj.respond_to? :to_ary - s = Sentence.new(obj) - if b.call s - obj.each {|o| + obj.each {|o| + s = Sentence.new(o) + if b.call s expand_rec(o, r, &b) - } - else - a = [] - obj.each {|o| + else + a = [] expand_rec(o, a, &b) - } - r << a - end + r << a + end + } else r << obj end @@ -482,16 +495,10 @@ class Sentence def self.expand_emptyable_syms(rhs, emptyable_syms) if rhs.empty? - elsif rhs.length == 1 - if emptyable_syms[rhs[0]] - yield rhs - yield [] - else - yield rhs - end + yield [] else - rest = rhs.dup - first = rest.shift + first = rhs[0] + rest = rhs[1..-1] if emptyable_syms[first] expand_emptyable_syms(rest, emptyable_syms) {|rhs2| yield [first] + rhs2 diff --git a/test/ruby/test_assignment.rb b/test/ruby/test_assignment.rb index c6b42d1b36..e6fad1d165 100644 --- a/test/ruby/test_assignment.rb +++ b/test/ruby/test_assignment.rb @@ -545,23 +545,12 @@ class TestAssignmentGen < Test::Unit::TestCase return r, vars end - def expand_except_paren(obj, r=[]) - if obj.respond_to? :to_ary - if (obj[0] == '(' && obj[-1] == ')') || (obj[0] == '[' && obj[-1] == ']') - a = [] - obj[1...-1].each {|o| - expand_except_paren(o, a) - } - r << a - else - obj.each {|o| - expand_except_paren(o, r) - } - end - else - r << obj - end - r + def expand_except_paren(obj) + return obj if obj.respond_to? :to_str + obj.expand {|s| + !(s[0] == '(' && s[-1] == ')') && + !(s[0] == '[' && s[-1] == ']') + } end def extract_single_element(ary) @@ -593,25 +582,34 @@ class TestAssignmentGen < Test::Unit::TestCase pre << e end } + pre.map! {|e| extract_single_element(e) } + if star + if star == ['*'] + star = nil + else + star = extract_single_element(star[1..-1]) + end + end + post.map! {|e| extract_single_element(e) } if post until pre.empty? - emu_assign_single(extract_single_element(pre.shift), rv.shift, h) + emu_assign_single(pre.shift, rv.shift, h) end if post if rv.length < post.length until post.empty? - emu_assign_single(extract_single_element(post.shift), rv.shift, h) + emu_assign_single(post.shift, rv.shift, h) end else until post.empty? - emu_assign_single(extract_single_element(post.pop), rv.pop, h) + emu_assign_single(post.pop, rv.pop, h) end end end - if star && 1 < star.length - emu_assign_single(extract_single_element(star[1..-1]), rv, h) + if star + emu_assign_single(star, rv, h) end end @@ -622,8 +620,14 @@ class TestAssignmentGen < Test::Unit::TestCase else raise "unexpected lhs string: #{lhs.inspect}" end - elsif lhs.respond_to? :to_ary - emu_assign_ary(lhs, rv, h) + elsif Sentence === lhs + if lhs[0] == '(' && lhs[-1] == ')' + emu_assign_ary(lhs[1...-1], rv, h) + elsif lhs.length == 1 && String === lhs[0] && /\A[a-z0-9]+\z/ =~ lhs[0] + h[lhs[0]] = rv + else + raise "unexpected lhs sentence: #{lhs.inspect}" + end else raise "unexpected lhs: #{lhs.inspect}" end @@ -633,9 +637,9 @@ class TestAssignmentGen < Test::Unit::TestCase def emu_assign(assign) lhs = expand_except_paren(assign[0]) rhs = expand_except_paren(assign[2]) - lopen = lhs.any? {|e| e == '*' || e == ',' } - ropen = rhs.any? {|e| e == '*' || e == ',' } - lhs = extract_single_element(lhs) if !lopen + lopen = Sentence === lhs && lhs[-1] != ')' && lhs.any? {|e| e == '*' || e == ',' } + ropen = Sentence === rhs && rhs[-1] != ']' && rhs.any? {|e| e == '*' || e == ',' } + lhs = Sentence.new(['(']+lhs.to_a+[')']) if lopen begin rv = eval((ropen ? ["[",assign[2],"]"] : assign[2]).join('')) rescue Exception @@ -657,14 +661,18 @@ class TestAssignmentGen < Test::Unit::TestCase h end + def check(assign) + assign, vars = rename_var(assign) + sent = assign.to_s + bruby = do_assign(assign, vars).to_a.sort + bemu = emu_assign(assign).to_a.sort + assert_equal(bemu, bruby, sent) + end + def test_assignment syntax = Sentence.expand_syntax(Syntax) - Sentence.each(syntax, :xassign, 3) {|assign| - assign, vars = rename_var(assign) - sent = assign.to_s - bruby = do_assign(assign, vars).to_a.sort - bemu = emu_assign(assign.to_a).to_a.sort - assert_equal(bemu, bruby, sent) + Sentence.each(syntax, :xassign, 4) {|assign| + check(assign) } end end