add binary operators

This commit is contained in:
simon lehericey 2022-06-09 12:14:08 +02:00
parent 6ebfc505c4
commit a98a6d6d1e
9 changed files with 131 additions and 1 deletions

View file

@ -8,12 +8,23 @@ module Logic
end
def self.class_from_name(name)
[Constant, Empty]
[Constant, Empty, LessThan, LessThanEq, Eq, GreaterThanEq, GreaterThan, EmptyOperator]
.find { |c| c.name == name }
end
def ds_eq(left, right) = Logic::Eq.new(left, right)
def greater_than(left, right) = Logic::GreaterThan.new(left, right)
def greater_than_eq(left, right) = Logic::GreaterThanEq.new(left, right)
def less_than(left, right) = Logic::LessThan.new(left, right)
def less_than_eq(left, right) = Logic::LessThanEq.new(left, right)
def constant(value) = Logic::Constant.new(value)
def empty = Logic::Empty.new
def empty_operator(left, right) = Logic::EmptyOperator.new(left, right)
end

View file

@ -0,0 +1,46 @@
class Logic::BinaryOperator < Logic::Term
attr_reader :left, :right
def initialize(left, right)
@left, @right = left, right
end
def to_h
{
"op" => self.class.name,
"left" => @left.to_h,
"right" => @right.to_h
}
end
def self.from_h(h)
self.new(Logic.from_h(h['left']), Logic.from_h(h['right']))
end
def errors(stable_ids = [])
errors = []
if @left.type != :number || @right.type != :number
errors += ["les types sont incompatibles : #{self}"]
end
errors + @left.errors(stable_ids) + @right.errors(stable_ids)
end
def type = :boolean
def compute(champs = [])
l = @left.compute(champs)
r = @right.compute(champs)
l.send(operation, r)
end
def to_s = "(#{@left} #{operation} #{@right})"
def ==(other)
self.class == other.class &&
@left == other.left &&
@right == other.right
end
end

View file

@ -0,0 +1,7 @@
class Logic::EmptyOperator < Logic::BinaryOperator
def to_s = "empty operator"
def type = :empty
def errors(_stable_ids = nil) = ['empty']
end

View file

@ -0,0 +1,3 @@
class Logic::GreaterThan < Logic::BinaryOperator
def operation = :>
end

View file

@ -0,0 +1,3 @@
class Logic::GreaterThanEq < Logic::BinaryOperator
def operation = :>=
end

View file

@ -0,0 +1,3 @@
class Logic::LessThan < Logic::BinaryOperator
def operation = :<
end

View file

@ -0,0 +1,3 @@
class Logic::LessThanEq < Logic::BinaryOperator
def operation = :<=
end

View file

@ -0,0 +1,52 @@
include Logic
describe Logic::BinaryOperator do
let(:two_greater_than_one) { greater_than(constant(2), constant(1))}
describe '#type' do
it { expect(two_greater_than_one.type).to eq(:boolean) }
end
describe '#to_s' do
it { expect(two_greater_than_one.to_s).to eq('(2 > 1)') }
end
describe '#==' do
it { expect(two_greater_than_one).to eq(greater_than(constant(2), constant(1))) }
it { expect(two_greater_than_one).not_to eq(greater_than(constant(1), constant(2))) }
end
describe '#errors' do
it { expect(greater_than(constant(1), constant(true)).errors).to eq(['les types sont incompatibles : (1 > true)']) }
end
end
describe Logic::GreaterThan do
it 'computes' do
expect(greater_than(constant(1), constant(1)).compute).to be(false)
expect(greater_than(constant(2), constant(1)).compute).to be(true)
end
end
describe Logic::GreaterThanEq do
it 'computes' do
expect(greater_than_eq(constant(0), constant(1)).compute).to be(false)
expect(greater_than_eq(constant(1), constant(1)).compute).to be(true)
expect(greater_than_eq(constant(2), constant(1)).compute).to be(true)
end
end
describe Logic::LessThan do
it 'computes' do
expect(less_than(constant(1), constant(1)).compute).to be(false)
expect(less_than(constant(1), constant(2)).compute).to be(true)
end
end
describe Logic::LessThanEq do
it 'computes' do
expect(less_than_eq(constant(0), constant(1)).compute).to be(true)
expect(less_than_eq(constant(1), constant(1)).compute).to be(true)
expect(less_than_eq(constant(2), constant(1)).compute).to be(false)
end
end

View file

@ -6,5 +6,7 @@ describe Logic do
expect(Logic.from_json(constant(1).to_json)).to eq(constant(1))
expect(Logic.from_h(empty.to_h)).to eq(empty)
expect(Logic.from_h(greater_than(constant(1), constant(2)).to_h)).to eq(greater_than(constant(1), constant(2)))
end
end