skip to main |
skip to sidebar
Interpreter
tc_ast.rb
require "test/unit"
require_relative "ast"
class TestAst < Test::Unit::TestCase
def test_bigger
assert_equal((91..100).to_a, bigger(90).evaluate(1..100))
end
def test_smaller
assert_equal([1,4,9,12], smaller(15).evaluate([1,20,4,66,23,9,40,12]))
end
def test_even
assert_equal([2,4,6,8,10,12,14,16], even.evaluate(1..16))
end
def test_odd
assert_equal([1,3,5,7,9,11,13,15], odd.evaluate(1..16))
end
def test_bigger_and_even
assert_equal([32,44,56],
( bigger(30) & even ).evaluate([4,32,11,23,56,7,43,44,2,14]))
end
def test_smaller_and_odd
assert_equal([7,11,23],
( smaller(30) & odd ).evaluate([4,32,11,23,56,7,43,44,2,14]))
end
def test_bigger_or_even
assert_equal([2,4,14,32,43,44,56],
( bigger(30) | even ).evaluate([4,32,11,23,56,7,43,44,2,14]))
end
def test_smaller_or_odd
assert_equal([2,4,7,11,14,23,43],
( smaller(30) | odd ).evaluate([4,32,11,23,56,7,43,44,2,14]))
end
def test_bigger_and_even_or_smaller_and_odd
assert_equal([7,11,23,44,56],
( ( bigger(40) & even ) | ( smaller(30) & odd ))
.evaluate([4,32,11,23,56,7,43,44,2,14]))
end
end
ast.rb
#!/usr/local/bin/ruby
# -*- encoding:utf-8 -*-
class Expression
def evaluate(context)
context.select { |x| yield(x) }
end
def &(other)
And.new(self, other)
end
def |(other)
Or.new(self, other)
end
end
class Bigger < Expression
def initialize(num)
@num = num
end
def evaluate(context)
super { |n| n > @num }
end
end
class Smaller < Expression
def initialize(num)
@num = num
end
def evaluate(context)
super { |n| n < @num }
end
end
class Even < Expression
def evaluate(context)
super { |n| n.even? }
end
end
class Odd < Expression
def evaluate(context)
super { |n| n.odd? }
end
end
class And < Expression
def initialize(exp1, exp2)
@exp1, @exp2 = exp1, exp2
end
def evaluate(context)
(@exp1.evaluate(context) & @exp2.evaluate(context)).sort
end
end
class Or < Expression
def initialize(exp1, exp2)
@exp1, @exp2 = exp1, exp2
end
def evaluate(context)
(@exp1.evaluate(context) | @exp2.evaluate(context)).sort
end
end
def bigger(num)
Bigger.new(num)
end
def smaller(num)
Smaller.new(num)
end
def even
Even.new
end
def odd
Odd.new
end
interpreter = bigger(70) & even | smaller(20) & odd
p interpreter.evaluate(1..100)
def extract(context)
(context.select { |n| n > 70 }.select { |n| n.even? } |
context.select { |n| n < 20 }.select { |n| n.odd? }).sort
end
p extract(1..100)
No comments:
Post a Comment