Module: RubyRunJs::Operation
Instance Method Summary collapse
- #abstract_equality_op(p1, p2) ⇒ Object
- #abstract_inequality_op(p1, p2) ⇒ Object
-
#abstract_relational_comparison(p1, p2, p1_first = true) ⇒ Object
Comparisons <, <=, !=, ==, >=, > are implemented here.
-
#add_op(p1, p2) ⇒ Object
+.
- #binary_operation(operator, p1, p2) ⇒ Object
-
#bit_and_op(p1, p2) ⇒ Object
&.
-
#bit_bshift_op(p1, p2) ⇒ Object
>>>.
-
#bit_invert_uop(target) ⇒ Object
~u.
- #bit_lshift_op(p1, p2) ⇒ Object
-
#bit_or_op(p1, p2) ⇒ Object
|.
-
#bit_rshift_op(p1, p2) ⇒ Object
>>.
-
#bit_xor_op(p1, p2) ⇒ Object
^.
-
#div_op(p1, p2) ⇒ Object
/.
-
#float(x) ⇒ Object
<<.
-
#greater_eq_op(p1, p2) ⇒ Object
>=.
-
#greater_op(p1, p2) ⇒ Object
>.
- #in_op(p1, p2) ⇒ Object
- #instanceof_op(p1, p2) ⇒ Object
-
#less_eq_op(p1, p2) ⇒ Object
<=.
-
#less_op(p1, p2) ⇒ Object
<.
-
#logical_negation_uop(target) ⇒ Object
!x.
-
#minus_uop(target) ⇒ Object
-x.
-
#mod_op(p1, p2) ⇒ Object
%.
-
#mul_op(p1, p2) ⇒ Object
*.
-
#plus_uop(target) ⇒ Object
+x.
- #strict_equality_op(p1, p2) ⇒ Object
- #strict_inequality_op(p1, p2) ⇒ Object
-
#sub_op(p1, p2) ⇒ Object
-.
-
#typeof_uop(target) ⇒ Object
typeof x.
- #unary_operation(operator, target) ⇒ Object
-
#void_op(target) ⇒ Object
void.
Methods included from Helper
#check_object, #get_member, #get_member_dot, #is_accessor_descriptor, #is_callable, #is_data_descriptor, #is_generic_descriptor, #is_primitive, #make_error, #strict_equality
Methods included from ConversionHelper
#convert_to_js_type, #to_boolean, #to_int32, #to_integer, #to_number, #to_object, #to_primitive, #to_string, #to_uint16, #to_uint32
Instance Method Details
#abstract_equality_op(p1, p2) ⇒ Object
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/ruby_run_js/operations.rb', line 305 def abstract_equality_op(p1, p2) ''' returns the result of JS == compare. result is PyJs type: bool''' tx, ty = p1.js_type, p2.js_type if tx == ty if tx == :Undefined || tx == :Null return true end if tx == :Number || tx == :String || tx == :Boolean return p1 == p2 end return p1.equal?(p2) elsif (tx == :Undefined && ty == :Null) || (ty == :Undefined && tx == :Null) return true elsif tx == :Number && ty == :String return abstract_equality_op(p1, to_number(p2)) elsif tx == :String && ty == :Number return abstract_equality_op(to_number(p1), p2) elsif tx == :Boolean return abstract_equality_op(to_number(p1), p2) elsif ty == :Boolean return abstract_equality_op(p1, to_number(p2)) elsif (tx == :String || tx == :Number) && p2.js_type == :Object return abstract_equality_op(p1, to_primitive(p2)) elsif (ty == :String || ty == :Number) && p1.js_type == :Object return abstract_equality_op(to_primitive(p1), p2) else return false end end |
#abstract_inequality_op(p1, p2) ⇒ Object
336 337 338 |
# File 'lib/ruby_run_js/operations.rb', line 336 def abstract_inequality_op(p1, p2) !abstract_equality_op(p1, p2) end |
#abstract_relational_comparison(p1, p2, p1_first = true) ⇒ Object
Comparisons <, <=, !=, ==, >=, > are implemented here.
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/ruby_run_js/operations.rb', line 238 def abstract_relational_comparison(p1, p2, p1_first = true) # todo speed up! ''' p1<p2 if p1_first else p2<p1. Returns the result of the question: is p1 smaller than p2? in case p1_first is false it returns the answer of: is p2 smaller than p1. result is PyJs type: bool || undefined''' px = to_primitive(p1, :Number) py = to_primitive(p2, :Number) if !p1_first # reverse ||der px, py = py, px end unless (px.js_type == :String && py.js_type == :String) px = to_number(px) py = to_number(py) if px.nan? || py.nan? return nil # watch out here! end return px < py # same cmp alg||ithm else return px < py end end |
#add_op(p1, p2) ⇒ Object
+
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/ruby_run_js/operations.rb', line 176 def add_op(p1, p2) if p1.js_type == :Float && p2.js_type == :Float return p1 + p2 end if p1.js_type == :String && p2.js_type == :String return p1 + p2 end # st&&ard way... a = to_primitive(p1) b = to_primitive(p2) if a.js_type == :String || b.js_type == :String # string wins hehe return to_string(a) + to_string(b) end to_number(a) + to_number(b) end |
#binary_operation(operator, p1, p2) ⇒ Object
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 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/ruby_run_js/operations.rb', line 25 def binary_operation(operator, p1, p2) case operator when '+' add_op(p1, p2) when '-' sub_op(p1, p2) when '*' mul_op(p1, p2) when '/' div_op(p1, p2) when '%' mod_op(p1, p2) when '<<' bit_lshift_op(p1, p2) when '>>' bit_rshift_op(p1, p2) when '>>>' bit_bshift_op(p1, p2) when '|' bit_or_op(p1, p2) when '&' bit_and_op(p1, p2) when '^' bit_xor_op(p1, p2) when '==' abstract_equality_op(p1, p2) when '!=' abstract_inequality_op(p1, p2) when '===' strict_equality_op(p1, p2) when '!==' strict_inequality_op(p1, p2) when '<' less_op(p1, p2) when '<=' less_eq_op(p1, p2) when '>' greater_op(p1, p2) when '>=' greater_eq_op(p1, p2) when 'in' in_op(p1, p2) when 'instanceof' instanceof_op(p1, p2) end end |
#bit_and_op(p1, p2) ⇒ Object
&
148 149 150 151 152 |
# File 'lib/ruby_run_js/operations.rb', line 148 def bit_and_op(p1, p2) lnum = to_int32(p1) rnum = to_int32(p2) float(to_int32(float(lnum & rnum))) end |
#bit_bshift_op(p1, p2) ⇒ Object
139 140 141 142 143 144 |
# File 'lib/ruby_run_js/operations.rb', line 139 def bit_bshift_op(p1, p2) lnum = to_uint32(p1) rnum = to_uint32(p2) shiftCount = rnum & 0x1F float(to_uint32(float(lnum >> shiftCount))) end |
#bit_invert_uop(target) ⇒ Object
~u
99 100 101 102 103 |
# File 'lib/ruby_run_js/operations.rb', line 99 def bit_invert_uop(target) target = ~to_int32(target) target = to_int32(target.to_f) target.to_f end |
#bit_lshift_op(p1, p2) ⇒ Object
122 123 124 125 126 127 |
# File 'lib/ruby_run_js/operations.rb', line 122 def bit_lshift_op(p1, p2) lnum = to_int32(p1) rnum = to_uint32(p2) shiftCount = rnum & 0x1F float(to_int32(float(lnum << shiftCount))) end |
#bit_or_op(p1, p2) ⇒ Object
|
164 165 166 167 168 |
# File 'lib/ruby_run_js/operations.rb', line 164 def bit_or_op(p1, p2) lnum = to_int32(p1) rnum = to_int32(p2) float(to_int32(float(lnum | rnum))) end |
#bit_rshift_op(p1, p2) ⇒ Object
>>
130 131 132 133 134 135 |
# File 'lib/ruby_run_js/operations.rb', line 130 def bit_rshift_op(p1, p2) lnum = to_int32(p1) rnum = to_uint32(p2) shiftCount = rnum & 0x1F float(to_int32(float(lnum >> shiftCount))) end |
#bit_xor_op(p1, p2) ⇒ Object
^
156 157 158 159 160 |
# File 'lib/ruby_run_js/operations.rb', line 156 def bit_xor_op(p1, p2) lnum = to_int32(p1) rnum = to_int32(p2) float(to_int32(float(lnum ^ rnum))) end |
#div_op(p1, p2) ⇒ Object
/
207 208 209 210 211 |
# File 'lib/ruby_run_js/operations.rb', line 207 def div_op(p1, p2) a = to_number(p1) b = to_number(p2) a / b end |
#float(x) ⇒ Object
<<
118 119 120 |
# File 'lib/ruby_run_js/operations.rb', line 118 def float(x) x.to_f end |
#greater_eq_op(p1, p2) ⇒ Object
>=
284 285 286 287 288 289 290 |
# File 'lib/ruby_run_js/operations.rb', line 284 def greater_eq_op(p1, p2) res = abstract_relational_comparison(p1, p2, true) if res.nil? return false end return !res end |
#greater_op(p1, p2) ⇒ Object
>
294 295 296 297 298 299 300 |
# File 'lib/ruby_run_js/operations.rb', line 294 def greater_op(p1, p2) res = abstract_relational_comparison(p1, p2, false) if res.nil? return false end return res end |
#in_op(p1, p2) ⇒ Object
370 371 372 373 374 375 376 |
# File 'lib/ruby_run_js/operations.rb', line 370 def in_op(p1, p2) '''checks if p1 is in p2''' if p2.js_type != :Object raise make_error('TypeError', "You can\'t use 'in' operator to search in non-objects") end p2.has_property(to_string(p1)) end |
#instanceof_op(p1, p2) ⇒ Object
359 360 361 362 363 364 365 366 367 368 |
# File 'lib/ruby_run_js/operations.rb', line 359 def instanceof_op(p1, p2) '''checks if p1 is instance of p2''' if p2.js_type != :Object raise make_error('TypeError', 'instanceof called on a non-object') end unless p2.methods.include?(:has_instance) raise make_error('TypeError', 'instanceof called on a non-object') end return p2.has_instance(p1) end |
#less_eq_op(p1, p2) ⇒ Object
<=
274 275 276 277 278 279 280 |
# File 'lib/ruby_run_js/operations.rb', line 274 def less_eq_op(p1, p2) res = abstract_relational_comparison(p1, p2, false) if res.nil? return false end return !res end |
#less_op(p1, p2) ⇒ Object
<
264 265 266 267 268 269 270 |
# File 'lib/ruby_run_js/operations.rb', line 264 def less_op(p1, p2) res = abstract_relational_comparison(p1, p2, true) if res.nil? return false end return res end |
#logical_negation_uop(target) ⇒ Object
!x
82 83 84 |
# File 'lib/ruby_run_js/operations.rb', line 82 def logical_negation_uop(target) # !u cant do 'not u' :( !to_boolean(target) end |
#minus_uop(target) ⇒ Object
-x
73 74 75 |
# File 'lib/ruby_run_js/operations.rb', line 73 def minus_uop(target) -to_number(target) end |
#mod_op(p1, p2) ⇒ Object
%
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/ruby_run_js/operations.rb', line 214 def mod_op(p1, p2) a = to_number(p1) b = to_number(p2) if a.abs == Float::INFINITY || b == 0.0 return Float::NAN end if b.abs == Float::INFINITY return a end res = a % b # different signs in python && javascript # python has the same sign as b && js has the same # sign as a. if a < 0 && res > 0 res -= b.abs elsif a > 0 && res < 0 res += b.abs end return float(res) end |
#mul_op(p1, p2) ⇒ Object
*
202 203 204 |
# File 'lib/ruby_run_js/operations.rb', line 202 def mul_op(p1, p2) return to_number(p1) * to_number(p2) end |
#plus_uop(target) ⇒ Object
+x
77 78 79 |
# File 'lib/ruby_run_js/operations.rb', line 77 def plus_uop(target) # +u to_number(target) end |
#strict_equality_op(p1, p2) ⇒ Object
340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/ruby_run_js/operations.rb', line 340 def strict_equality_op(p1, p2) typ = p1.js_type if typ != p2.js_type return false end if typ == :Undefined || typ == :Null return true end if typ == :Boolean || typ == :String || typ == :Number return p1 == p2 else # object return p1.equal?(p2) # Id compare. end end |
#strict_inequality_op(p1, p2) ⇒ Object
355 356 357 |
# File 'lib/ruby_run_js/operations.rb', line 355 def strict_inequality_op(p1, p2) !strict_equality_op(p1, p2) end |
#sub_op(p1, p2) ⇒ Object
-
193 194 195 |
# File 'lib/ruby_run_js/operations.rb', line 193 def sub_op(p1, p2) return to_number(p1) - to_number(p2) end |
#typeof_uop(target) ⇒ Object
typeof x
87 88 89 90 91 92 93 94 95 96 |
# File 'lib/ruby_run_js/operations.rb', line 87 def typeof_uop(target) if is_callable(target) return 'function' end typ = target.js_type.to_s.downcase if typ == 'null' typ = 'object' # absolutely idiotic... end typ end |
#unary_operation(operator, target) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/ruby_run_js/operations.rb', line 6 def unary_operation(operator, target) case operator when '+' plus_uop(target) when '-' minus_uop(target) when '!' logical_negation_uop(target) when '~' bit_invert_uop(target) when 'void' void_op(target) when 'typeof' typeof_uop(target) else raise 'Unkown operator: ' + operator end end |
#void_op(target) ⇒ Object
void
106 107 108 |
# File 'lib/ruby_run_js/operations.rb', line 106 def void_op(target) undefined end |