Sha256: 5f6b01cf3d3689a927988f2c05eef62a3382ebdb141d85041cb99d52739ef39b

Contents?: true

Size: 1.67 KB

Versions: 2

Compression:

Stored size: 1.67 KB

Contents

require_relative './operation'

module Dentaku
  module AST
    class Comparator < Operation
      def self.precedence
        5
      end

      def type
        :logical
      end

      def operator
        raise NotImplementedError
      end

      def value(context = {})
        l = validate_value(cast(left.value(context)))
        r = validate_value(cast(right.value(context)))

        l.public_send(operator, r)
      rescue ::ArgumentError => e
        raise Dentaku::ArgumentError.for(:incompatible_type, value: r, for: l.class), e.message
      end

      private

      def cast(val)
        return val unless val.is_a?(::String)
        return val if val.empty?
        return val unless val.match?(/\A-?\d*(\.\d+)?\z/)

        v = BigDecimal(val, Float::DIG + 1)
        v = v.to_i if v.frac.zero?
        v
      end

      def validate_value(value)
        unless value.respond_to?(operator)
          raise Dentaku::ArgumentError.for(:invalid_operator, operation: self.class, operator: operator),
                "#{ self.class } requires operands that respond to #{operator}"
        end

        value
      end
    end

    class LessThan < Comparator
      def operator
        :<
      end
    end

    class LessThanOrEqual < Comparator
      def operator
        :<=
      end
    end

    class GreaterThan < Comparator
      def operator
        :>
      end
    end

    class GreaterThanOrEqual < Comparator
      def operator
        :>=
      end
    end

    class NotEqual < Comparator
      def operator
        :!=
      end
    end

    class Equal < Comparator
      def operator
        :==
      end

      def display_operator
        "="
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 2 rubygems

Version Path
dentaku_zevo-3.5.2 lib/dentaku/ast/comparators.rb
dentaku-3.5.1 lib/dentaku/ast/comparators.rb