lib/code/object/decimal.rb in code-ruby-0.5.6 vs lib/code/object/decimal.rb in code-ruby-0.6.0

- old
+ new

@@ -1,162 +1,314 @@ +# frozen_string_literal: true + class Code class Object class Decimal < ::Code::Object::Number attr_reader :raw def initialize(decimal, exponent: nil) @raw = BigDecimal(decimal) - if exponent - if exponent.is_a?(::Code::Object::Number) - @raw = @raw * 10**exponent.raw - else - raise ::Code::Error::TypeError.new("exponent is not a number") - end + return unless exponent + unless exponent.is_a?(Number) + raise ::Code::Error::TypeError, "exponent is not a number" end + + @raw *= 10**exponent.raw end + def self.name + "Decimal" + end + def call(**args) operator = args.fetch(:operator, nil) arguments = args.fetch(:arguments, []) value = arguments.first&.value - if operator == "%" - sig(arguments) { ::Code::Object::Number } - modulo(value) - elsif operator == "+" - if value - sig(arguments) { ::Code::Object } - plus(value) - else - sig(arguments) - self - end - elsif operator == "-" - if value - sig(arguments) { ::Code::Object::Number } - minus(value) - else - sig(arguments) - unary_minus - end - elsif operator == "/" - sig(arguments) { ::Code::Object::Number } - division(value) - elsif operator == "*" - sig(arguments) { ::Code::Object::Number } - multiplication(value) - elsif operator == "**" - sig(arguments) { ::Code::Object::Number } - power(value) - elsif operator == "<" - sig(arguments) { ::Code::Object::Number } - inferior(value) - elsif operator == "<=" - sig(arguments) { ::Code::Object::Number } - inferior_or_equal(value) - elsif operator == ">" - sig(arguments) { ::Code::Object::Number } - superior(value) - elsif operator == ">=" - sig(arguments) { ::Code::Object::Number } - superior_or_equal(value) - elsif operator == "<<" - sig(arguments) { ::Code::Object::Number } - left_shift(value) - elsif operator == ">>" - sig(arguments) { ::Code::Object::Number } - right_shift(value) - elsif operator == "&" - sig(arguments) { ::Code::Object::Number } - bitwise_and(value) - elsif operator == "|" - sig(arguments) { ::Code::Object::Number } - bitwise_or(value) - elsif operator == "^" - sig(arguments) { ::Code::Object::Number } - bitwise_xor(value) + case operator.to_s + when "%", "modulo" + sig(args) { Number } + code_modulo(value) + when "&", "bitwise_and" + sig(args) { Number } + code_bitwise_and(value) + when "*", "multiplication" + sig(args) { Number } + code_multiplication(value) + when "**", "power" + sig(args) { Number } + code_power(value) + when "+", "plus" + sig(args) { Object.maybe } + value ? code_plus(value) : self + when "-", "minus" + sig(args) { Number.maybe } + value ? code_minus(value) : code_unary_minus + when "/", "division" + sig(args) { Number } + code_division(value) + when "<", "inferior" + sig(args) { Number } + code_inferior(value) + when "<<", "left_shift" + sig(args) { Number } + code_left_shift(value) + when "<=", "inferior_or_equal" + sig(args) { Number } + code_inferior_or_equal(value) + when "<=>", "compare" + sig(args) { Number } + code_compare(value) + when ">", "superior" + sig(args) { Number } + code_superior(value) + when ">=", "superior_or_equal" + sig(args) { Number } + code_superior_or_equal(value) + when ">>", "right_shift" + sig(args) { Number } + code_right_shift(value) + when "^", "bitwise_xor" + sig(args) { Number } + code_bitwise_xor(value) + when "abs" + sig(args) + code_abs + when "ceil" + sig(args) { Integer.maybe } + code_ceil(value) + when "clone" + sig(args) + code_clone + when "eight?" + sig(args) + code_eight? + when "five?" + sig(args) + code_five? + when "floor" + sig(args) { Integer.maybe } + code_floor(value) + when "four?" + sig(args) + code_four? + when "nine?" + sig(args) + code_nine? + when "one?" + sig(args) + code_one? + when "round" + sig(args) { Integer.maybe } + code_round(value) + when "seven?" + sig(args) + code_seven? + when "six?" + sig(args) + code_six? + when "sqrt" + sig(args) + code_sqrt + when "ten?" + sig(args) + code_ten? + when "three?" + sig(args) + code_three? + when "to_decimal" + sig(args) + code_to_decimal + when "to_integer" + sig(args) + code_to_integer + when "to_string" + sig(args) + code_to_string + when "truncate" + sig(args) { Integer.maybe } + code_truncate(value) + when "two?" + sig(args) + code_two? + when "zero?" + sig(args) + code_zero? + when "|", "bitwise_or" + sig(args) { Number } + code_bitwise_or(value) else super end end - def to_s - raw.to_s("F") + def code_abs + Decimal.new(raw.abs) end - def inspect - to_s + def code_bitwise_and(other) + Integer.new(raw.to_i & other.raw.to_i) end - private + def code_bitwise_or(other) + Integer.new(raw.to_i | other.raw.to_i) + end - def modulo(other) - ::Code::Object::Decimal.new(raw % other.raw) + def code_bitwise_xor(other) + Integer.new(raw.to_i ^ other.raw.to_i) end - def plus(other) - if other.is_a?(::Code::Object::Number) - ::Code::Object::Decimal.new(raw + other.raw) + def code_ceil(n = nil) + n ||= Integer.new(0) + Decimal.new(raw.ceil(n.raw)) + end + + def code_clone + Decimal.new(raw) + end + + def code_compare(other) + Integer.new(raw <=> other.raw) + end + + def code_division(other) + Decimal.new(raw / other.raw) + end + + def code_eight? + Boolean.new(raw == 8) + end + + def code_five? + Boolean.new(raw == 5) + end + + def code_floor(n = nil) + n ||= Integer.new(0) + Decimal.new(raw.floor(n.raw)) + end + + def code_four? + Boolean.new(raw == 4) + end + + def code_inferior(other) + Boolean.new(raw < other.raw) + end + + def code_inferior_or_equal(other) + Boolean.new(raw <= other.raw) + end + + def code_left_shift(other) + Integer.new(raw.to_i << other.raw.to_i) + end + + def code_minus(other) + Decimal.new(raw - other.raw) + end + + def code_modulo(other) + Decimal.new(raw % other.raw) + end + + def code_multiplication(other) + Decimal.new(raw * other.raw) + end + + def code_nine? + Boolean.new(raw == 9) + end + + def code_one? + Boolean.new(raw == 1) + end + + def code_plus(other) + if other.is_a?(Number) + Decimal.new(raw + other.raw) else - ::Code::Object::String.new(to_s + other.to_s) + String.new(to_s + other.to_s) end end - def minus(other) - ::Code::Object::Decimal.new(raw - other.raw) + def code_power(other) + Decimal.new(raw**other.raw) end - def division(other) - ::Code::Object::Decimal.new(raw / other.raw) + def code_right_shift(other) + Integer.new(raw.to_i >> other.raw.to_i) end - def multiplication(other) - ::Code::Object::Decimal.new(raw * other.raw) + def code_round(n = nil) + n ||= Integer.new(0) + Decimal.new(raw.round(n.raw)) end - def power(other) - ::Code::Object::Decimal.new(raw**other.raw) + def code_seven? + Boolean.new(raw == 7) end - def inferior(other) - ::Code::Object::Boolean.new(raw < other.raw) + def code_six? + Boolean.new(raw == 6) end - def inferior_or_equal(other) - ::Code::Object::Boolean.new(raw <= other.raw) + def code_sqrt + Decimal.new(Math.sqrt(raw).to_s) end - def superior(other) - ::Code::Object::Boolean.new(raw > other.raw) + def code_superior(other) + Boolean.new(raw > other.raw) end - def superior_or_equal(other) - ::Code::Object::Boolean.new(raw >= other.raw) + def code_superior_or_equal(other) + Boolean.new(raw >= other.raw) end - def left_shift(other) - ::Code::Object::Integer.new(raw.to_i << other.raw.to_i) + def code_ten? + Boolean.new(raw == 10) end - def right_shift(other) - ::Code::Object::Integer.new(raw.to_i >> other.raw.to_i) + def code_three? + Boolean.new(raw == 3) end - def bitwise_and(other) - ::Code::Object::Integer.new(raw.to_i & other.raw.to_i) + def code_to_decimal + Decimal.new(raw) end - def bitwise_or(other) - ::Code::Object::Integer.new(raw.to_i | other.raw.to_i) + def code_to_integer + Integer.new(raw.to_i) end - def bitwise_xor(other) - ::Code::Object::Integer.new(raw.to_i ^ other.raw.to_i) + def code_to_string + String.new(raw.to_s("F")) end - def unary_minus - ::Code::Object::Decimal.new(-raw) + def code_truncate(n = nil) + n ||= Integer.new(0) + Decimal.new(raw.truncate(n.raw)) + end + + def code_two? + Boolean.new(raw == 2) + end + + def code_unary_minus + Decimal.new(-raw) + end + + def code_zero? + Boolean.new(raw.zero?) + end + + def inspect + to_s + end + + def to_s + raw.to_s("F") end end end end