Sha256: f7105150a53009a7d81557685a7ba35baa6df88cf26928827cdc19ba16a4b47a

Contents?: true

Size: 1.62 KB

Versions: 1

Compression:

Stored size: 1.62 KB

Contents

require_relative './operation'
require 'bigdecimal'

module Dentaku
  module AST
    class Arithmetic < Operation
      def initialize(*)
        super
        fail "#{ self.class } requires numeric operands" unless valid_node?(left) && valid_node?(right)
      end

      def type
        :numeric
      end

      private

      def valid_node?(node)
        node.is_a?(Identifier) || node.type == :numeric
      end
    end

    class Addition < Arithmetic
      def value(context={})
        left.value(context) + right.value(context)
      end

      def self.precedence
        10
      end
    end

    class Subtraction < Arithmetic
      def value(context={})
        left.value(context) - right.value(context)
      end

      def self.precedence
        10
      end
    end

    class Multiplication < Arithmetic
      def value(context={})
        left.value(context) * right.value(context)
      end

      def self.precedence
        20
      end
    end

    class Division < Arithmetic
      def value(context={})
        r = BigDecimal.new(right.value(context))
        raise ZeroDivisionError if r.zero?

        v = BigDecimal.new(left.value(context)) / r
        v = v.to_i if v.frac.zero?
        v
      end

      def self.precedence
        20
      end
    end

    class Modulo < Arithmetic
      def value(context={})
        left.value(context) % right.value(context)
      end

      def self.precedence
        20
      end
    end

    class Exponentiation < Arithmetic
      def value(context={})
        left.value(context) ** right.value(context)
      end

      def self.precedence
        30
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
dentaku-2.0.3 lib/dentaku/ast/arithmetic.rb