mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* test/ruby/sentgen.rb: new file.
* test/ruby/test_assignment.rb: tests implemeneted using assignment generator and emulator. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12709 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
976bfae03b
commit
56fe47de3a
3 changed files with 246 additions and 0 deletions
|
@ -1,3 +1,10 @@
|
|||
Fri Jul 6 12:15:01 2007 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* test/ruby/sentgen.rb: new file.
|
||||
|
||||
* test/ruby/test_assignment.rb: tests implemeneted using assignment
|
||||
generator and emulator.
|
||||
|
||||
Fri Jul 6 03:06:58 2007 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* insns.def: remove unused code.
|
||||
|
|
54
test/ruby/sentgen.rb
Normal file
54
test/ruby/sentgen.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
# sentence generator
|
||||
|
||||
class SentGen
|
||||
def initialize(syntax)
|
||||
@syntax = syntax
|
||||
end
|
||||
|
||||
def each_tree(sym, limit)
|
||||
generate_from_sym(sym, limit) {|_, tree|
|
||||
yield tree
|
||||
}
|
||||
nil
|
||||
end
|
||||
|
||||
def each_string(sym, limit)
|
||||
generate_from_sym(sym, limit) {|_, tree|
|
||||
yield [tree].join('')
|
||||
}
|
||||
nil
|
||||
end
|
||||
|
||||
def generate_from_sym(sym, limit, &b)
|
||||
return if limit < 0
|
||||
if String === sym
|
||||
yield limit, sym
|
||||
else
|
||||
rules = @syntax[sym]
|
||||
rules.each {|rhs|
|
||||
if rhs.length == 1 || rules.length == 1
|
||||
limit1 = limit
|
||||
else
|
||||
limit1 = limit-1
|
||||
end
|
||||
generate_from_rhs(rhs, limit1, &b)
|
||||
}
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def generate_from_rhs(rhs, limit)
|
||||
return if limit < 0
|
||||
if rhs.empty?
|
||||
yield limit, []
|
||||
else
|
||||
generate_from_sym(rhs[0], limit) {|limit1, child|
|
||||
generate_from_rhs(rhs[1..-1], limit1) {|limit2, arr|
|
||||
yield limit2, [child, *arr]
|
||||
}
|
||||
}
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
@ -489,3 +489,188 @@ class TestAssignment < Test::Unit::TestCase
|
|||
assert_equal [3,4], [a,b]
|
||||
end
|
||||
end
|
||||
|
||||
require 'sentgen'
|
||||
class TestAssignmentGen < Test::Unit::TestCase
|
||||
Syntax = {
|
||||
:exp => [["0"],
|
||||
["nil"],
|
||||
["false"],
|
||||
["[]"],
|
||||
["[",:exps,"]"]],
|
||||
:exps => [[:exp],
|
||||
[:exp,",",:exps]],
|
||||
:arg => [[:exp]],
|
||||
:mrhs => [[:args,",",:arg],
|
||||
[:args,",","*",:arg],
|
||||
["*",:arg]],
|
||||
:args => [[:arg],
|
||||
["*",:arg],
|
||||
[:args,",",:arg],
|
||||
[:args,",","*",:arg]],
|
||||
:mlhs => [[:mlhs_basic],
|
||||
["(",:mlhs_inner,")"]],
|
||||
:mlhs_inner => [[:mlhs_basic],
|
||||
["(",:mlhs_inner,")"]],
|
||||
:mlhs_basic => [[:mlhs_head],
|
||||
[:mlhs_head,:mlhs_item],
|
||||
[:mlhs_head,"*",:mlhs_node],
|
||||
[:mlhs_head,"*",:mlhs_node,",",:mlhs_post],
|
||||
[:mlhs_head,"*"],
|
||||
[:mlhs_head,"*",",", :mlhs_post],
|
||||
[ "*",:mlhs_node],
|
||||
[ "*",:mlhs_node,",",:mlhs_post],
|
||||
[ "*"],
|
||||
[ "*",",", :mlhs_post]],
|
||||
:mlhs_head => [[:mlhs_item,","],
|
||||
[:mlhs_head,:mlhs_item,","]],
|
||||
:mlhs_post => [[:mlhs_item],
|
||||
[:mlhs_post,",",:mlhs_item]],
|
||||
:mlhs_item => [[:mlhs_node],
|
||||
["(",:mlhs_inner,")"]],
|
||||
:mlhs_node => [["var"]],
|
||||
:xassign => [["var"," = ",:exp],
|
||||
["var"," = ",:mrhs],
|
||||
[:mlhs," = ",:exp],
|
||||
[:mlhs," = ",:mrhs]],
|
||||
}
|
||||
|
||||
def rename_var(obj, nbox=[0])
|
||||
if obj.respond_to? :to_ary
|
||||
a = []
|
||||
obj.each {|e| a << rename_var(e, nbox) }
|
||||
a
|
||||
elsif obj == 'var'
|
||||
n = nbox[0]
|
||||
nbox[0] += 1
|
||||
"v#{n}"
|
||||
else
|
||||
obj
|
||||
end
|
||||
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
|
||||
end
|
||||
|
||||
def extract_single_element(ary)
|
||||
raise "not a single element array: #{ary.inspect}" if ary.length != 1
|
||||
ary[0]
|
||||
end
|
||||
|
||||
def emu_assign_ary(lhs, rv, h)
|
||||
rv = rv.respond_to?(:to_ary) ? rv : [rv]
|
||||
rv = rv.dup
|
||||
a = [[]]
|
||||
lhs.each {|e|
|
||||
if e == ','
|
||||
a << []
|
||||
else
|
||||
a.last << e
|
||||
end
|
||||
}
|
||||
a.pop if a.last == []
|
||||
pre = []
|
||||
star = post = nil
|
||||
a.each {|e|
|
||||
if post
|
||||
post << e
|
||||
elsif e[0] == '*'
|
||||
star = e
|
||||
post = []
|
||||
else
|
||||
pre << e
|
||||
end
|
||||
}
|
||||
|
||||
until pre.empty?
|
||||
emu_assign_single(extract_single_element(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)
|
||||
end
|
||||
else
|
||||
until post.empty?
|
||||
emu_assign_single(extract_single_element(post.pop), rv.pop, h)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if star && 1 < star.length
|
||||
emu_assign_single(extract_single_element(star[1..-1]), rv, h)
|
||||
end
|
||||
end
|
||||
|
||||
def emu_assign_single(lhs, rv, h={})
|
||||
if lhs.respond_to? :to_str
|
||||
if /\A[a-z0-9]+\z/ =~ lhs
|
||||
h[lhs] = rv
|
||||
else
|
||||
raise "unexpected lhs string: #{lhs.inspect}"
|
||||
end
|
||||
elsif lhs.respond_to? :to_ary
|
||||
emu_assign_ary(lhs, rv, h)
|
||||
else
|
||||
raise "unexpected lhs: #{lhs.inspect}"
|
||||
end
|
||||
h
|
||||
end
|
||||
|
||||
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
|
||||
rhs = ["(",rhs,")"] if ropen
|
||||
begin
|
||||
rv = eval((ropen ? ["[",assign[2],"]"] : assign[2]).join(''))
|
||||
rescue Exception
|
||||
rv = $!.message
|
||||
end
|
||||
emu_assign_single(lhs, rv)
|
||||
end
|
||||
|
||||
def do_assign(assign)
|
||||
assign = assign.join('')
|
||||
vars = []
|
||||
vars = assign.scan(/v[0-9]+/)
|
||||
code = "#{assign}; [#{vars.join(",")}]"
|
||||
begin
|
||||
vals = eval(code)
|
||||
rescue Exception
|
||||
return {:ex=>$!.message}
|
||||
end
|
||||
h = {}
|
||||
[vars, vals].transpose.each {|k,v| h[k] = v }
|
||||
h
|
||||
end
|
||||
|
||||
def test_assignment
|
||||
SentGen.new(Syntax).each_tree(:xassign, 3) {|assign|
|
||||
assign[0] = rename_var(assign[0])
|
||||
sent = [assign].join('')
|
||||
bruby = do_assign(assign).to_a.sort
|
||||
bemu = emu_assign(assign).to_a.sort
|
||||
assert_equal(bemu, bruby, sent)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue