Module: Cel::Extensions::Math
- Defined in:
- lib/cel/extensions/math.rb
Class Method Summary collapse
- .__check(funcall, checker:) ⇒ Object
- .abs(num, program:) ⇒ Object
- .bitAnd(lhs, rhs, program:) ⇒ Object
- .bitNot(num, program:) ⇒ Object
- .bitOr(lhs, rhs, program:) ⇒ Object
- .bitShiftLeft(num, amount_of_bits, program:) ⇒ Object
- .bitShiftRight(num, amount_of_bits, program:) ⇒ Object
- .bitXor(lhs, rhs, program:) ⇒ Object
- .ceil(num, program:) ⇒ Object
- .floor(num, program:) ⇒ Object
- .greatest(*args, program:) ⇒ Object
- .isFinite(num, program:) ⇒ Object
- .isInf(num, program:) ⇒ Object
- .isNaN(num, program:) ⇒ Object
- .least(*args, program:) ⇒ Object
- .round(num, program:) ⇒ Object
- .sign(num, program:) ⇒ Object
- .trunc(num, program:) ⇒ Object
Class Method Details
.__check(funcall, checker:) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/cel/extensions/math.rb', line 8 def __check(funcall, checker:) func = funcall.func args = funcall.args case func when :round, :trunc, :floor, :ceil checker.check_arity(func, args, 1) arg = checker.call(args.first) return TYPES[:double] if checker.find_match_all_types(i[double], arg) when :isInf, :isNaN, :isFinite checker.check_arity(func, args, 1) arg = checker.call(args.first) return TYPES[:bool] if checker.find_match_all_types(i[double], arg) when :bitNot checker.check_arity(func, args, 1) arg = checker.call(args.first) return TYPES[:int] if checker.find_match_all_types(i[int uint], arg) when :bitOr, :bitAnd, :bitXor checker.check_arity(func, args, 2) args = args.map(&checker.method(:call)) type = checker.find_match_all_types(i[int uint], args) return type if type when :sign, :abs checker.check_arity(func, args, 1) arg = checker.call(args.first) type = checker.find_match_all_types(i[double int uint], arg) return if type when :least, :greatest checker.check_arity_any(func, args) args = args.map(&checker.method(:call)) return TYPES[:any] if args.all? do |arg| case arg when TYPES[:any], TYPES[:int], TYPES[:uint], TYPES[:double], TYPES[:list, :int], TYPES[:list, :uint], TYPES[:list, :double], TYPES[:list, :any] true else false end end when :bitShiftRight, :bitShiftLeft checker.check_arity(func, args, 2) num, amount_of_bits = args.map(&checker.method(:call)) return num if checker.find_match_all_types(i[int uint], num) && checker.find_match_all_types(i[int], amount_of_bits) else checker.unsupported_operation(funcall) end checker.unsupported_operation(funcall) end |
.abs(num, program:) ⇒ Object
62 63 64 65 66 67 68 |
# File 'lib/cel/extensions/math.rb', line 62 def abs(num, program:) num = program.call(num) raise EvaluateError, "out of range" unless num.value.between?(-MAX_INT + 1, MAX_INT - 1) Number.new(num.type, num.value.abs) end |
.bitAnd(lhs, rhs, program:) ⇒ Object
111 112 113 114 115 |
# File 'lib/cel/extensions/math.rb', line 111 def bitAnd(lhs, rhs, program:) lhs = program.call(lhs) rhs = program.call(rhs) Number.new(lhs.type, lhs & rhs) end |
.bitNot(num, program:) ⇒ Object
94 95 96 97 98 99 100 101 102 103 |
# File 'lib/cel/extensions/math.rb', line 94 def bitNot(num, program:) val = program.call(num).value case num.type when TYPES[:int] Number.new(:int, ~val) when TYPES[:uint] Number.new(:uint, ((2**64) - 1) - val) end end |
.bitOr(lhs, rhs, program:) ⇒ Object
105 106 107 108 109 |
# File 'lib/cel/extensions/math.rb', line 105 def bitOr(lhs, rhs, program:) lhs = program.call(lhs) rhs = program.call(rhs) Number.new(lhs.type, lhs | rhs) end |
.bitShiftLeft(num, amount_of_bits, program:) ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/cel/extensions/math.rb', line 178 def bitShiftLeft(num, amount_of_bits, program:) num = program.call(num) amount_of_bits = program.call(amount_of_bits).value raise EvaluateError, "math.#{__method__}() negative offset: #{amount_of_bits}" if amount_of_bits.negative? # When the second parameter is 64 or greater, 0 will always be returned return Number.new(num.type, 0) if amount_of_bits >= 64 Number.new(num.type, num.value << amount_of_bits) end |
.bitShiftRight(num, amount_of_bits, program:) ⇒ Object
164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/cel/extensions/math.rb', line 164 def bitShiftRight(num, amount_of_bits, program:) num = program.call(num) amount_of_bits = program.call(amount_of_bits).value raise EvaluateError, "math.#{__method__}() negative offset: #{amount_of_bits}" if amount_of_bits.negative? # When the second parameter is 64 or greater, 0 will always be returned return Number.new(num.type, 0) if amount_of_bits >= 64 value = num.value.negative? ? ((2**64) - 1) & num.value : num.value Number.new(num.type, value >> amount_of_bits) end |
.bitXor(lhs, rhs, program:) ⇒ Object
117 118 119 120 121 |
# File 'lib/cel/extensions/math.rb', line 117 def bitXor(lhs, rhs, program:) lhs = program.call(lhs) rhs = program.call(rhs) Number.new(lhs.type, lhs ^ rhs) end |
.ceil(num, program:) ⇒ Object
88 89 90 91 92 |
# File 'lib/cel/extensions/math.rb', line 88 def ceil(num, program:) num = program.call(num) Number.new(:double, num.value.ceil) end |
.floor(num, program:) ⇒ Object
82 83 84 85 86 |
# File 'lib/cel/extensions/math.rb', line 82 def floor(num, program:) num = program.call(num) Number.new(:double, num.value.floor) end |
.greatest(*args, program:) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/cel/extensions/math.rb', line 149 def greatest(*args, program:) args = args.map(&program.method(:call)) return args.max if args.size > 1 arg = args.first case arg when List greatest(*arg.value, program: program) else arg end end |
.isFinite(num, program:) ⇒ Object
204 205 206 207 208 |
# File 'lib/cel/extensions/math.rb', line 204 def isFinite(num, program:) val = program.call(num).value Bool.cast(!val.infinite? && !val.nan?) end |
.isInf(num, program:) ⇒ Object
190 191 192 193 194 |
# File 'lib/cel/extensions/math.rb', line 190 def isInf(num, program:) val = program.call(num).value Bool.cast(val.infinite?) end |
.isNaN(num, program:) ⇒ Object
196 197 198 199 200 201 202 |
# File 'lib/cel/extensions/math.rb', line 196 def isNaN(num, program:) val = program.call(num).value Bool.cast(val.nan?) rescue FloatDomainError Bool.cast(true) end |
.least(*args, program:) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/cel/extensions/math.rb', line 134 def least(*args, program:) args = args.map(&program.method(:call)) return args.min if args.size > 1 arg = args.first case arg when List least(*arg.value, program: program) else arg end end |
.round(num, program:) ⇒ Object
70 71 72 73 74 |
# File 'lib/cel/extensions/math.rb', line 70 def round(num, program:) num = program.call(num) Number.new(:double, num.value.round) end |
.sign(num, program:) ⇒ Object
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/cel/extensions/math.rb', line 123 def sign(num, program:) num = program.call(num) value = num.value Number.new(num.type, if value.negative? -1 else value.positive? ? 1 : 0 end) end |
.trunc(num, program:) ⇒ Object
76 77 78 79 80 |
# File 'lib/cel/extensions/math.rb', line 76 def trunc(num, program:) num = program.call(num) Number.new(:double, num.value.truncate) end |