opal 0.8.1 → 0.9.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (331) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -2
  3. data/.gitmodules +3 -3
  4. data/.jshintrc +17 -20
  5. data/.travis.yml +22 -11
  6. data/CHANGELOG.md +51 -1
  7. data/CODE_OF_CONDUCT.md +15 -0
  8. data/CONTRIBUTING.md +125 -9
  9. data/Gemfile +1 -1
  10. data/Guardfile +2 -2
  11. data/README.md +95 -29
  12. data/Rakefile +1 -1
  13. data/benchmark/benchmarks +103 -0
  14. data/benchmark/bm_array_flatten.rb +9 -0
  15. data/benchmark/bm_array_intersection_numbers.rb +7 -0
  16. data/benchmark/bm_array_intersection_objects.rb +7 -0
  17. data/benchmark/bm_array_intersection_strings.rb +7 -0
  18. data/benchmark/bm_array_join_ary.rb +9 -0
  19. data/benchmark/bm_array_minus_numbers.rb +7 -0
  20. data/benchmark/bm_array_minus_objects.rb +7 -0
  21. data/benchmark/bm_array_minus_strings.rb +7 -0
  22. data/benchmark/bm_array_union_numbers.rb +7 -0
  23. data/benchmark/bm_array_union_objects.rb +7 -0
  24. data/benchmark/bm_array_union_strings.rb +7 -0
  25. data/benchmark/bm_array_uniq_bang_numbers.rb +5 -0
  26. data/benchmark/bm_array_uniq_bang_objects.rb +5 -0
  27. data/benchmark/bm_array_uniq_bang_strings.rb +5 -0
  28. data/benchmark/bm_array_uniq_numbers.rb +5 -0
  29. data/benchmark/bm_array_uniq_objects.rb +5 -0
  30. data/benchmark/bm_array_uniq_strings.rb +5 -0
  31. data/benchmark/bm_dispatch_bind_table.rb +57 -0
  32. data/benchmark/bm_dispatch_code_gen.rb +65 -0
  33. data/benchmark/bm_dispatch_code_gen_if.rb +64 -0
  34. data/benchmark/bm_dispatch_hardcoded.rb +44 -0
  35. data/benchmark/bm_dispatch_send.rb +38 -0
  36. data/benchmark/bm_dispatch_send_table.rb +57 -0
  37. data/benchmark/bm_hash_assoc_object.rb +11 -0
  38. data/benchmark/bm_hash_assoc_string.rb +9 -0
  39. data/benchmark/bm_hash_clone_object.rb +9 -0
  40. data/benchmark/bm_hash_clone_string.rb +9 -0
  41. data/benchmark/bm_hash_delete_object.rb +11 -0
  42. data/benchmark/bm_hash_delete_string.rb +9 -0
  43. data/benchmark/bm_hash_each_key_object.rb +9 -0
  44. data/benchmark/bm_hash_each_key_string.rb +9 -0
  45. data/benchmark/bm_hash_each_object.rb +9 -0
  46. data/benchmark/bm_hash_each_string.rb +9 -0
  47. data/benchmark/bm_hash_each_value_object.rb +9 -0
  48. data/benchmark/bm_hash_each_value_string.rb +9 -0
  49. data/benchmark/bm_hash_element_reference_object.rb +11 -0
  50. data/benchmark/bm_hash_element_reference_string.rb +9 -0
  51. data/benchmark/bm_hash_element_set_object.rb +5 -0
  52. data/benchmark/bm_hash_element_set_string.rb +5 -0
  53. data/benchmark/bm_hash_equal_value_object.rb +14 -0
  54. data/benchmark/bm_hash_equal_value_string.rb +11 -0
  55. data/benchmark/bm_hash_fetch_object.rb +11 -0
  56. data/benchmark/bm_hash_fetch_string.rb +9 -0
  57. data/benchmark/bm_hash_flatten_object.rb +9 -0
  58. data/benchmark/bm_hash_flatten_string.rb +9 -0
  59. data/benchmark/bm_hash_has_key_object.rb +11 -0
  60. data/benchmark/bm_hash_has_key_string.rb +9 -0
  61. data/benchmark/bm_hash_has_value_object.rb +9 -0
  62. data/benchmark/bm_hash_has_value_string.rb +9 -0
  63. data/benchmark/bm_hash_hash_object.rb +9 -0
  64. data/benchmark/bm_hash_hash_string.rb +9 -0
  65. data/benchmark/bm_hash_inspect_object.rb +9 -0
  66. data/benchmark/bm_hash_inspect_string.rb +9 -0
  67. data/benchmark/bm_hash_invert_object.rb +9 -0
  68. data/benchmark/bm_hash_invert_string.rb +9 -0
  69. data/benchmark/bm_hash_keep_if_object.rb +9 -0
  70. data/benchmark/bm_hash_keep_if_string.rb +9 -0
  71. data/benchmark/bm_hash_key_object.rb +9 -0
  72. data/benchmark/bm_hash_key_string.rb +9 -0
  73. data/benchmark/bm_hash_keys_object.rb +9 -0
  74. data/benchmark/bm_hash_keys_string.rb +9 -0
  75. data/benchmark/bm_hash_literal_mixed_large.rb +3 -0
  76. data/benchmark/bm_hash_literal_mixed_small.rb +3 -0
  77. data/benchmark/bm_hash_literal_object_large.rb +4 -0
  78. data/benchmark/bm_hash_literal_object_small.rb +3 -0
  79. data/benchmark/bm_hash_literal_string_large.rb +4 -0
  80. data/benchmark/bm_hash_literal_string_small.rb +3 -0
  81. data/benchmark/bm_hash_merge_object.rb +22 -0
  82. data/benchmark/bm_hash_merge_string.rb +18 -0
  83. data/benchmark/bm_hash_rassoc_object.rb +9 -0
  84. data/benchmark/bm_hash_rassoc_string.rb +9 -0
  85. data/benchmark/bm_hash_rehash_object.rb +9 -0
  86. data/benchmark/bm_hash_rehash_string.rb +9 -0
  87. data/benchmark/bm_hash_reject_bang_object.rb +9 -0
  88. data/benchmark/bm_hash_reject_bang_string.rb +9 -0
  89. data/benchmark/bm_hash_reject_object.rb +9 -0
  90. data/benchmark/bm_hash_reject_string.rb +9 -0
  91. data/benchmark/bm_hash_replace_object.rb +18 -0
  92. data/benchmark/bm_hash_replace_string.rb +14 -0
  93. data/benchmark/bm_hash_select_bang_object.rb +9 -0
  94. data/benchmark/bm_hash_select_bang_string.rb +9 -0
  95. data/benchmark/bm_hash_select_object.rb +9 -0
  96. data/benchmark/bm_hash_select_string.rb +9 -0
  97. data/benchmark/bm_hash_shift_object.rb +10 -0
  98. data/benchmark/bm_hash_shift_string.rb +10 -0
  99. data/benchmark/bm_hash_to_a_object.rb +9 -0
  100. data/benchmark/bm_hash_to_a_string.rb +9 -0
  101. data/benchmark/bm_hash_to_h_object.rb +10 -0
  102. data/benchmark/bm_hash_to_h_string.rb +10 -0
  103. data/benchmark/bm_hash_values_object.rb +9 -0
  104. data/benchmark/bm_hash_values_string.rb +9 -0
  105. data/benchmark/run.rb +48 -0
  106. data/bin/opal-mspec +1 -1
  107. data/bin/opal-repl +4 -4
  108. data/docs/compiled_ruby.md +214 -56
  109. data/docs/configuring_gems.md +2 -2
  110. data/docs/faq.md +2 -2
  111. data/docs/getting_started.md +19 -2
  112. data/docs/jquery.md +5 -5
  113. data/docs/opal_parser.md +53 -0
  114. data/docs/unsupported_features.md +2 -2
  115. data/docs/upgrading.md +22 -0
  116. data/docs/using_sprockets.md +15 -0
  117. data/examples/rack/config.ru +13 -0
  118. data/examples/sinatra/config.ru +4 -5
  119. data/lib/mspec/opal/runner.rb +54 -11
  120. data/lib/opal.rb +1 -1
  121. data/lib/opal/builder.rb +1 -1
  122. data/lib/opal/builder_processors.rb +1 -1
  123. data/lib/opal/cli.rb +17 -13
  124. data/lib/opal/cli_options.rb +1 -1
  125. data/lib/opal/compiler.rb +12 -0
  126. data/lib/opal/config.rb +4 -0
  127. data/lib/opal/nodes/arglist.rb +5 -7
  128. data/lib/opal/nodes/call.rb +6 -1
  129. data/lib/opal/nodes/call_special.rb +74 -0
  130. data/lib/opal/nodes/def.rb +35 -28
  131. data/lib/opal/nodes/definitions.rb +3 -5
  132. data/lib/opal/nodes/for.rb +13 -0
  133. data/lib/opal/nodes/helpers.rb +15 -1
  134. data/lib/opal/nodes/if.rb +5 -5
  135. data/lib/opal/nodes/iter.rb +6 -1
  136. data/lib/opal/nodes/literal.rb +1 -1
  137. data/lib/opal/nodes/logic.rb +2 -2
  138. data/lib/opal/nodes/masgn.rb +1 -2
  139. data/lib/opal/nodes/module.rb +2 -1
  140. data/lib/opal/nodes/rescue.rb +10 -1
  141. data/lib/opal/nodes/scope.rb +8 -2
  142. data/lib/opal/nodes/singleton_class.rb +1 -1
  143. data/lib/opal/nodes/top.rb +11 -0
  144. data/lib/opal/nodes/variables.rb +4 -4
  145. data/lib/opal/parser.rb +21 -3
  146. data/lib/opal/parser/grammar.rb +3115 -2961
  147. data/lib/opal/parser/grammar.y +29 -6
  148. data/lib/opal/parser/lexer.rb +18 -8
  149. data/lib/opal/sprockets.rb +85 -0
  150. data/lib/opal/sprockets/processor.rb +11 -35
  151. data/lib/opal/sprockets/server.rb +3 -15
  152. data/lib/opal/version.rb +2 -2
  153. data/opal.gemspec +4 -4
  154. data/opal/README.md +9 -0
  155. data/opal/corelib/array.rb +433 -181
  156. data/opal/corelib/basic_object.rb +48 -4
  157. data/opal/corelib/boolean.rb +15 -6
  158. data/opal/corelib/class.rb +6 -5
  159. data/opal/corelib/comparable.rb +12 -0
  160. data/opal/corelib/complex.rb +282 -0
  161. data/opal/corelib/constants.rb +9 -0
  162. data/opal/corelib/enumerable.rb +83 -34
  163. data/opal/corelib/enumerator.rb +3 -1
  164. data/opal/corelib/error.rb +49 -10
  165. data/opal/corelib/file.rb +1 -0
  166. data/opal/corelib/hash.rb +353 -577
  167. data/opal/corelib/helpers.rb +20 -0
  168. data/opal/corelib/kernel.rb +114 -59
  169. data/opal/corelib/math.rb +470 -0
  170. data/opal/corelib/method.rb +11 -2
  171. data/opal/corelib/module.rb +96 -96
  172. data/opal/corelib/{nil_class.rb → nil.rb} +20 -1
  173. data/opal/corelib/number.rb +751 -0
  174. data/opal/corelib/numeric.rb +77 -437
  175. data/opal/corelib/proc.rb +81 -1
  176. data/opal/corelib/process.rb +27 -0
  177. data/opal/corelib/rational.rb +358 -0
  178. data/opal/corelib/regexp.rb +156 -27
  179. data/opal/corelib/runtime.js +724 -335
  180. data/opal/corelib/string.rb +93 -104
  181. data/opal/corelib/string/encoding.rb +177 -0
  182. data/opal/corelib/string/inheritance.rb +2 -0
  183. data/opal/corelib/struct.rb +105 -18
  184. data/opal/corelib/time.rb +267 -146
  185. data/opal/corelib/unsupported.rb +216 -0
  186. data/opal/corelib/variables.rb +0 -6
  187. data/opal/opal.rb +8 -22
  188. data/opal/opal/base.rb +9 -0
  189. data/opal/opal/mini.rb +17 -0
  190. data/spec/README.md +1 -1
  191. data/spec/filters/bugs/array.rb +38 -136
  192. data/spec/filters/bugs/{basic_object.rb → basicobject.rb} +14 -15
  193. data/spec/filters/bugs/class.rb +6 -12
  194. data/spec/filters/bugs/complex.rb +3 -0
  195. data/spec/filters/bugs/date.rb +162 -10
  196. data/spec/filters/bugs/enumerable.rb +31 -58
  197. data/spec/filters/bugs/enumerator.rb +42 -0
  198. data/spec/filters/bugs/exception.rb +66 -10
  199. data/spec/filters/bugs/float.rb +17 -0
  200. data/spec/filters/bugs/hash.rb +11 -97
  201. data/spec/filters/bugs/inheritance.rb +5 -0
  202. data/spec/filters/bugs/integer.rb +28 -0
  203. data/spec/filters/bugs/kernel.rb +304 -12
  204. data/spec/filters/bugs/language.rb +133 -399
  205. data/spec/filters/bugs/language_opal.rb +88 -0
  206. data/spec/filters/bugs/module.rb +203 -62
  207. data/spec/filters/bugs/numeric.rb +32 -0
  208. data/spec/filters/bugs/proc.rb +39 -0
  209. data/spec/filters/bugs/range.rb +148 -0
  210. data/spec/filters/bugs/regexp.rb +168 -0
  211. data/spec/filters/bugs/set.rb +46 -3
  212. data/spec/filters/bugs/singleton.rb +1 -2
  213. data/spec/filters/bugs/string.rb +59 -90
  214. data/spec/filters/bugs/strscan.rb +80 -0
  215. data/spec/filters/bugs/struct.rb +10 -20
  216. data/spec/filters/bugs/time.rb +17 -184
  217. data/spec/filters/bugs/unboundmethod.rb +22 -0
  218. data/spec/filters/unsupported/array.rb +163 -0
  219. data/spec/filters/unsupported/basicobject.rb +14 -0
  220. data/spec/filters/unsupported/bignum.rb +46 -0
  221. data/spec/filters/unsupported/class.rb +4 -0
  222. data/spec/filters/unsupported/delegator.rb +5 -0
  223. data/spec/filters/unsupported/enumerable.rb +11 -0
  224. data/spec/filters/unsupported/enumerator.rb +8 -9
  225. data/spec/filters/unsupported/fixnum.rb +14 -0
  226. data/spec/filters/unsupported/float.rb +41 -7
  227. data/spec/filters/unsupported/freeze.rb +45 -0
  228. data/spec/filters/unsupported/hash.rb +50 -0
  229. data/spec/filters/unsupported/integer.rb +3 -0
  230. data/spec/filters/unsupported/kernel.rb +31 -0
  231. data/spec/filters/unsupported/language.rb +17 -0
  232. data/spec/filters/unsupported/matchdata.rb +30 -0
  233. data/spec/filters/unsupported/math.rb +3 -0
  234. data/spec/filters/unsupported/module.rb +5 -3
  235. data/spec/filters/unsupported/pathname.rb +3 -0
  236. data/spec/filters/unsupported/privacy.rb +136 -0
  237. data/spec/filters/unsupported/proc.rb +3 -0
  238. data/spec/filters/unsupported/regexp.rb +59 -0
  239. data/spec/filters/unsupported/set.rb +4 -0
  240. data/spec/filters/unsupported/{marshal.rb → singleton.rb} +4 -2
  241. data/spec/filters/unsupported/{mutable_strings.rb → string.rb} +456 -336
  242. data/spec/filters/unsupported/struct.rb +3 -0
  243. data/spec/filters/unsupported/symbol.rb +5 -0
  244. data/spec/filters/unsupported/taint.rb +16 -0
  245. data/spec/filters/unsupported/thread.rb +5 -0
  246. data/spec/filters/unsupported/time.rb +197 -16
  247. data/spec/lib/cli_spec.rb +14 -4
  248. data/spec/lib/compiler_spec.rb +9 -1
  249. data/spec/lib/parser/call_spec.rb +18 -0
  250. data/spec/lib/parser/not_spec.rb +2 -8
  251. data/spec/lib/sprockets_spec.rb +24 -0
  252. data/spec/opal/core/array/intersection_spec.rb +38 -0
  253. data/spec/opal/core/array/minus_spec.rb +38 -0
  254. data/spec/opal/core/array/union_spec.rb +38 -0
  255. data/spec/opal/core/array/uniq_spec.rb +49 -0
  256. data/spec/opal/core/exception_spec.rb +7 -0
  257. data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +1 -0
  258. data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +1 -0
  259. data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +1 -0
  260. data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +3 -0
  261. data/spec/opal/core/hash/internals_spec.rb +332 -0
  262. data/spec/opal/core/helpers_spec.rb +14 -0
  263. data/spec/opal/core/kernel/freeze_spec.rb +1 -1
  264. data/spec/opal/core/kernel/raise_spec.rb +13 -0
  265. data/spec/opal/core/kernel/require_tree_spec.rb +9 -0
  266. data/spec/opal/core/language/class_spec.rb +55 -0
  267. data/spec/opal/core/language/fixtures/send.rb +1 -0
  268. data/spec/opal/core/language/keyword_arguments_spec.rb +11 -0
  269. data/spec/opal/core/language/send_spec.rb +5 -0
  270. data/spec/opal/core/method/to_proc_spec.rb +28 -0
  271. data/spec/opal/core/module/name_spec.rb +0 -17
  272. data/spec/opal/core/runtime/bridged_classes_spec.rb +2 -2
  273. data/spec/opal/core/runtime/eval_spec.rb +1 -1
  274. data/spec/opal/core/runtime/method_missing_spec.rb +6 -0
  275. data/spec/opal/core/runtime_spec.rb +51 -0
  276. data/spec/opal/stdlib/js_spec.rb +66 -0
  277. data/spec/opal/stdlib/native/hash_spec.rb +36 -0
  278. data/spec/rubyspecs +152 -273
  279. data/spec/spec_helper.rb +10 -11
  280. data/stdlib/base64.rb +9 -9
  281. data/stdlib/benchmark.rb +551 -4
  282. data/stdlib/console.rb +94 -0
  283. data/stdlib/date.rb +1 -1
  284. data/stdlib/encoding.rb +1 -170
  285. data/stdlib/js.rb +56 -0
  286. data/stdlib/json.rb +9 -14
  287. data/stdlib/math.rb +1 -370
  288. data/stdlib/native.rb +133 -63
  289. data/stdlib/nodejs/file.rb +5 -0
  290. data/stdlib/nodejs/fileutils.rb +13 -6
  291. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/README.md +1 -1
  292. data/stdlib/opal-parser.rb +1 -2
  293. data/stdlib/ostruct.rb +65 -6
  294. data/stdlib/pp.rb +2 -4
  295. data/stdlib/rbconfig.rb +1 -3
  296. data/stdlib/strscan.rb +164 -28
  297. data/tasks/benchmarking.rake +88 -0
  298. data/tasks/testing.rake +181 -55
  299. data/{lib/mspec/opal/special_calls.rb → tasks/testing/mspec_special_calls.rb} +1 -1
  300. data/{lib/mspec/opal/sprockets.js → tasks/testing/phantomjs1-sprockets.js} +17 -6
  301. data/test/opal/test_keyword.rb +590 -0
  302. data/vendored-minitest/minitest.rb +2 -2
  303. data/vendored-minitest/test/unit.rb +5 -0
  304. metadata +229 -62
  305. data/benchmarks/operators.rb +0 -11
  306. data/benchmarks/prova.js.rb +0 -13
  307. data/docs/libraries.md +0 -36
  308. data/lib/mspec/opal/new.html.erb +0 -1
  309. data/lib/mspec/opal/rake_task.rb +0 -248
  310. data/opal/corelib/match_data.rb +0 -128
  311. data/spec/filters/bugs/math.rb +0 -95
  312. data/spec/filters/bugs/nil.rb +0 -7
  313. data/spec/filters/bugs/opal.rb +0 -9
  314. data/spec/filters/bugs/regular_expressions.rb +0 -41
  315. data/spec/filters/bugs/stringscanner.rb +0 -33
  316. data/spec/filters/unsupported/encoding.rb +0 -102
  317. data/spec/filters/unsupported/frozen.rb +0 -92
  318. data/spec/filters/unsupported/hash_compare_by_identity.rb +0 -16
  319. data/spec/filters/unsupported/integer_size.rb +0 -59
  320. data/spec/filters/unsupported/method_added.rb +0 -10
  321. data/spec/filters/unsupported/private_constants.rb +0 -30
  322. data/spec/filters/unsupported/private_methods.rb +0 -55
  323. data/spec/filters/unsupported/random.rb +0 -4
  324. data/spec/filters/unsupported/rational_numbers.rb +0 -4
  325. data/spec/filters/unsupported/regular_expressions.rb +0 -137
  326. data/spec/filters/unsupported/ruby_exe.rb +0 -5
  327. data/spec/filters/unsupported/symbols.rb +0 -17
  328. data/spec/filters/unsupported/tainted.rb +0 -180
  329. data/spec/filters/unsupported/trusted.rb +0 -88
  330. data/stdlib/process.rb +0 -10
  331. data/tasks/documenting.rake +0 -37
@@ -27,11 +27,16 @@ class Method
27
27
  end
28
28
 
29
29
  def to_proc
30
- @method
30
+ %x{
31
+ var proc = function () { return self.$call.apply(self, $slice.call(arguments)); };
32
+ proc.$$unbound = #@method;
33
+ proc.$$is_lambda = true;
34
+ return proc;
35
+ }
31
36
  end
32
37
 
33
38
  def inspect
34
- "#<Method: #{@obj.class}##@name}>"
39
+ "#<Method: #{@receiver.class}##@name>"
35
40
  end
36
41
  end
37
42
 
@@ -49,6 +54,10 @@ class UnboundMethod
49
54
  end
50
55
 
51
56
  def bind(object)
57
+ # TODO: re-enable when Module#< is fixed
58
+ # unless object.class <= @owner
59
+ # raise TypeError, "can't bind singleton method to a different class"
60
+ # end
52
61
  Method.new(object, @method, @name)
53
62
  end
54
63
 
@@ -2,12 +2,12 @@ class Module
2
2
  def self.new(&block)
3
3
  %x{
4
4
  function AnonModule(){}
5
- var klass = Opal.boot(Opal.Module, AnonModule);
6
- klass.$$name = nil;
7
- klass.$$class = Opal.Module;
8
- klass.$$dep = []
9
- klass.$$is_mod = true;
10
- klass.$$proto = {};
5
+ var klass = Opal.boot(Opal.Module, AnonModule);
6
+ klass.$$name = nil;
7
+ klass.$$class = Opal.Module;
8
+ klass.$$dep = []
9
+ klass.$$is_module = true;
10
+ klass.$$proto = {};
11
11
 
12
12
  // inherit scope from parent
13
13
  Opal.create_scope(Opal.Module.$$scope, klass);
@@ -30,9 +30,14 @@ class Module
30
30
  end
31
31
 
32
32
  def <(other)
33
+ # class cannot be a descendant of itself
33
34
  %x{
34
35
  var working = self;
35
36
 
37
+ if (working === other) {
38
+ return false;
39
+ }
40
+
36
41
  while (working) {
37
42
  if (working === other) {
38
43
  return true;
@@ -45,25 +50,20 @@ class Module
45
50
  }
46
51
  end
47
52
 
48
- def alias_method(newname, oldname)
49
- %x{
50
- var newjsid = '$' + newname,
51
- body = self.$$proto['$' + oldname];
53
+ def <=(other)
54
+ equal?(other) or self < other
55
+ end
52
56
 
53
- if (self.$$is_singleton) {
54
- self.$$proto[newjsid] = body;
55
- }
56
- else {
57
- Opal.defn(self, newjsid, body);
58
- }
57
+ def alias_method(newname, oldname)
58
+ `Opal.alias(self, newname, oldname)`
59
59
 
60
- return self;
61
- }
62
60
  self
63
61
  end
64
62
 
65
63
  def alias_native(mid, jsid = mid)
66
- `self.$$proto['$' + mid] = self.$$proto[jsid]`
64
+ `Opal.alias_native(self, mid, jsid)`
65
+
66
+ self
67
67
  end
68
68
 
69
69
  def ancestors
@@ -73,9 +73,11 @@ class Module
73
73
 
74
74
  while (parent) {
75
75
  result.push(parent);
76
- result = result.concat(parent.$$inc);
76
+ for (var i=0; i < parent.$$inc.length; i++) {
77
+ result = result.concat(parent.$$inc[i].$ancestors());
78
+ }
77
79
 
78
- parent = parent.$$super;
80
+ parent = parent.$$is_class ? parent.$$super : null;
79
81
  }
80
82
 
81
83
  return result;
@@ -100,18 +102,24 @@ class Module
100
102
 
101
103
  for (var i = names.length - 1; i >= 0; i--) {
102
104
  var name = names[i],
103
- id = '$' + name;
105
+ id = '$' + name,
106
+ ivar = Opal.ivar(name);
104
107
 
105
108
  // the closure here is needed because name will change at the next
106
109
  // cycle, I wish we could use let.
107
- var body = (function(name) {
110
+ var body = (function(ivar) {
108
111
  return function() {
109
- return this[name];
112
+ if (this[ivar] == null) {
113
+ return nil;
114
+ }
115
+ else {
116
+ return this[ivar];
117
+ }
110
118
  };
111
- })(name);
119
+ })(ivar);
112
120
 
113
121
  // initialize the instance variable as nil
114
- proto[name] = nil;
122
+ proto[ivar] = nil;
115
123
 
116
124
  if (self.$$is_singleton) {
117
125
  proto.constructor.prototype[id] = body;
@@ -131,18 +139,19 @@ class Module
131
139
 
132
140
  for (var i = names.length - 1; i >= 0; i--) {
133
141
  var name = names[i],
134
- id = '$' + name + '=';
142
+ id = '$' + name + '=',
143
+ ivar = Opal.ivar(name);
135
144
 
136
145
  // the closure here is needed because name will change at the next
137
146
  // cycle, I wish we could use let.
138
- var body = (function(name){
147
+ var body = (function(ivar){
139
148
  return function(value) {
140
- return this[name] = value;
149
+ return this[ivar] = value;
141
150
  }
142
- })(name);
151
+ })(ivar);
143
152
 
144
153
  // initialize the instance variable as nil
145
- proto[name] = nil;
154
+ proto[ivar] = nil;
146
155
 
147
156
  if (self.$$is_singleton) {
148
157
  proto.constructor.prototype[id] = body;
@@ -189,7 +198,7 @@ class Module
189
198
  end
190
199
 
191
200
  def constants
192
- `self.$$scope.constants`
201
+ `self.$$scope.constants.slice(0)`
193
202
  end
194
203
 
195
204
  # check for constant within current scope
@@ -221,10 +230,12 @@ class Module
221
230
  end
222
231
 
223
232
  def const_get(name, inherit = true)
224
- if name['::'] && name != '::'
225
- return name.split('::').inject(self){|o, c| o.const_get(c)}
233
+ if `name.indexOf('::') != -1 && name != '::'`
234
+ return name.split('::').inject(self) { |o, c| o.const_get(c) }
226
235
  end
227
- raise NameError, "wrong constant name #{name}" unless name =~ /^[A-Z]\w*$/
236
+
237
+ raise NameError, "wrong constant name #{name}" unless `/^[A-Z]\w*$/.test(name)`
238
+
228
239
  %x{
229
240
  var scopes = [self.$$scope];
230
241
 
@@ -279,23 +290,26 @@ class Module
279
290
  end
280
291
 
281
292
  def define_method(name, method = undefined, &block)
282
- if `method === undefined && !#{block_given?}`
293
+ if `method === undefined && block === nil`
283
294
  raise ArgumentError, "tried to create a Proc object without a block"
284
295
  end
285
296
 
286
297
  block ||= case method
287
- when Proc
288
- method
289
- when Method
290
- method.to_proc
291
- when UnboundMethod
292
- lambda do |*args|
293
- bound = method.bind(self)
294
- bound.call *args
295
- end
296
- else
297
- raise TypeError, "wrong argument type #{block.class} (expected Proc/Method)"
298
- end
298
+ when Proc
299
+ method
300
+
301
+ when Method
302
+ `#{method.to_proc}.$$unbound`
303
+
304
+ when UnboundMethod
305
+ lambda {|*args|
306
+ bound = method.bind(self)
307
+ bound.call(*args)
308
+ }
309
+
310
+ else
311
+ raise TypeError, "wrong argument type #{block.class} (expected Proc/Method)"
312
+ end
299
313
 
300
314
  %x{
301
315
  var id = '$' + name;
@@ -304,23 +318,26 @@ class Module
304
318
  block.$$s = null;
305
319
  block.$$def = block;
306
320
 
307
- if (self.$$is_singleton) {
308
- self.$$proto[id] = block;
309
- }
310
- else {
311
- Opal.defn(self, id, block);
312
- }
321
+ Opal.defn(self, id, block);
313
322
 
314
323
  return name;
315
324
  }
316
325
  end
317
326
 
318
- def remove_method(name)
319
- `Opal.undef(self, '$' + name)`
327
+ def remove_method(*names)
328
+ %x{
329
+ for (var i = 0, length = names.length; i < length; i++) {
330
+ Opal.rdef(self, "$" + names[i]);
331
+ }
332
+ }
320
333
 
321
334
  self
322
335
  end
323
336
 
337
+ def singleton_class?
338
+ `!!self.$$is_singleton`
339
+ end
340
+
324
341
  def include(*mods)
325
342
  %x{
326
343
  for (var i = mods.length - 1; i >= 0; i--) {
@@ -370,11 +387,11 @@ class Module
370
387
  proto = self.$$proto;
371
388
 
372
389
  for (var prop in proto) {
373
- if (!(prop.charAt(0) === '$')) {
390
+ if (prop.charAt(0) !== '$') {
374
391
  continue;
375
392
  }
376
393
 
377
- if (!(typeof(proto[prop]) === "function")) {
394
+ if (typeof(proto[prop]) !== "function") {
378
395
  continue;
379
396
  }
380
397
 
@@ -382,7 +399,7 @@ class Module
382
399
  continue;
383
400
  }
384
401
 
385
- if (!self.$$is_mod) {
402
+ if (!self.$$is_module) {
386
403
  if (self !== Opal.BasicObject && proto[prop] === Opal.BasicObject.$$proto[prop]) {
387
404
  continue;
388
405
  }
@@ -409,6 +426,15 @@ class Module
409
426
  def extended(mod)
410
427
  end
411
428
 
429
+ def method_added(*)
430
+ end
431
+
432
+ def method_removed(*)
433
+ end
434
+
435
+ def method_undefined(*)
436
+ end
437
+
412
438
  def module_eval(&block)
413
439
  raise ArgumentError, 'no block given' unless block
414
440
 
@@ -458,9 +484,11 @@ class Module
458
484
  }
459
485
  else {
460
486
  for (var i = 0, length = methods.length; i < length; i++) {
461
- var meth = methods[i], func = self.$$proto['$' + meth];
487
+ var meth = methods[i],
488
+ id = '$' + meth,
489
+ func = self.$$proto[id];
462
490
 
463
- self.constructor.prototype['$' + meth] = func;
491
+ Opal.defs(self, id, func);
464
492
  }
465
493
  }
466
494
 
@@ -498,38 +526,6 @@ class Module
498
526
  }
499
527
  end
500
528
 
501
- def public(*methods)
502
- %x{
503
- if (methods.length === 0) {
504
- self.$$module_function = false;
505
- }
506
-
507
- return nil;
508
- }
509
- end
510
-
511
- alias private public
512
- alias protected public
513
- alias nesting public
514
-
515
- def private_class_method(name)
516
- `self['$' + name] || nil`
517
- end
518
- alias public_class_method private_class_method
519
-
520
- def private_method_defined?(obj)
521
- false
522
- end
523
-
524
- def private_constant(*)
525
- end
526
-
527
- alias protected_method_defined? private_method_defined?
528
-
529
- alias public_instance_methods instance_methods
530
-
531
- alias public_method_defined? method_defined?
532
-
533
529
  def remove_class_variable(*)
534
530
  end
535
531
 
@@ -542,11 +538,15 @@ class Module
542
538
  end
543
539
 
544
540
  def to_s
545
- `self.$$name` || "#<#{`self.$$is_mod ? 'Module' : 'Class'`}:0x#{__id__.to_s(16)}>"
541
+ `Opal.Module.$name.call(self)` || "#<#{`self.$$is_module ? 'Module' : 'Class'`}:0x#{__id__.to_s(16)}>"
546
542
  end
547
543
 
548
- def undef_method(symbol)
549
- `Opal.add_stub_for(self.$$proto, "$" + symbol)`
544
+ def undef_method(*names)
545
+ %x{
546
+ for (var i = 0, length = names.length; i < length; i++) {
547
+ Opal.udef(self, "$" + names[i]);
548
+ }
549
+ }
550
550
 
551
551
  self
552
552
  end
@@ -1,4 +1,6 @@
1
1
  class NilClass
2
+ `def.$$meta = #{self}`
3
+
2
4
  def !
3
5
  true
4
6
  end
@@ -20,7 +22,11 @@ class NilClass
20
22
  end
21
23
 
22
24
  def dup
23
- raise TypeError
25
+ raise TypeError, "can't dup #{self.class}"
26
+ end
27
+
28
+ def clone
29
+ raise TypeError, "can't clone #{self.class}"
24
30
  end
25
31
 
26
32
  def inspect
@@ -52,6 +58,19 @@ class NilClass
52
58
  def to_s
53
59
  ''
54
60
  end
61
+
62
+ def to_c
63
+ Complex.new(0, 0)
64
+ end
65
+
66
+ def rationalize(*args)
67
+ raise ArgumentError if args.length > 1
68
+ Rational(0, 1)
69
+ end
70
+
71
+ def to_r
72
+ Rational(0, 1)
73
+ end
55
74
  end
56
75
 
57
76
  NIL = nil
@@ -0,0 +1,751 @@
1
+ require 'corelib/numeric'
2
+
3
+ class Number < Numeric
4
+ Opal.bridge(self, `Number`)
5
+
6
+ `Number.prototype.$$is_number = true`
7
+
8
+ def coerce(other)
9
+ %x{
10
+ if (other === nil) {
11
+ #{raise TypeError, "can't convert #{other.class} into Float"};
12
+ }
13
+ else if (other.$$is_string) {
14
+ return [#{Float(other)}, self];
15
+ }
16
+ else if (#{other.respond_to?(:to_f)}) {
17
+ return [#{Opal.coerce_to!(other, Float, :to_f)}, self];
18
+ }
19
+ else if (other.$$is_number) {
20
+ return [other, self];
21
+ }
22
+ else {
23
+ #{raise TypeError, "can't convert #{other.class} into Float"};
24
+ }
25
+ }
26
+ end
27
+
28
+ def __id__
29
+ `(self * 2) + 1`
30
+ end
31
+
32
+ alias object_id __id__
33
+
34
+ def +(other)
35
+ %x{
36
+ if (other.$$is_number) {
37
+ return self + other;
38
+ }
39
+ else {
40
+ return #{__coerced__ :+, other};
41
+ }
42
+ }
43
+ end
44
+
45
+ def -(other)
46
+ %x{
47
+ if (other.$$is_number) {
48
+ return self - other;
49
+ }
50
+ else {
51
+ return #{__coerced__ :-, other};
52
+ }
53
+ }
54
+ end
55
+
56
+ def *(other)
57
+ %x{
58
+ if (other.$$is_number) {
59
+ return self * other;
60
+ }
61
+ else {
62
+ return #{__coerced__ :*, other};
63
+ }
64
+ }
65
+ end
66
+
67
+ def /(other)
68
+ %x{
69
+ if (other.$$is_number) {
70
+ return self / other;
71
+ }
72
+ else {
73
+ return #{__coerced__ :/, other};
74
+ }
75
+ }
76
+ end
77
+
78
+ alias fdiv /
79
+
80
+ def %(other)
81
+ %x{
82
+ if (other.$$is_number) {
83
+ if (other == -Infinity) {
84
+ return other;
85
+ }
86
+ else if (other == 0) {
87
+ #{raise ZeroDivisionError, "divided by 0"};
88
+ }
89
+ else if (other < 0 || self < 0) {
90
+ return (self % other + other) % other;
91
+ }
92
+ else {
93
+ return self % other;
94
+ }
95
+ }
96
+ else {
97
+ return #{__coerced__ :%, other};
98
+ }
99
+ }
100
+ end
101
+
102
+ def &(other)
103
+ %x{
104
+ if (other.$$is_number) {
105
+ return self & other;
106
+ }
107
+ else {
108
+ return #{__coerced__ :&, other};
109
+ }
110
+ }
111
+ end
112
+
113
+ def |(other)
114
+ %x{
115
+ if (other.$$is_number) {
116
+ return self | other;
117
+ }
118
+ else {
119
+ return #{__coerced__ :|, other};
120
+ }
121
+ }
122
+ end
123
+
124
+ def ^(other)
125
+ %x{
126
+ if (other.$$is_number) {
127
+ return self ^ other;
128
+ }
129
+ else {
130
+ return #{__coerced__ :^, other};
131
+ }
132
+ }
133
+ end
134
+
135
+ def <(other)
136
+ %x{
137
+ if (other.$$is_number) {
138
+ return self < other;
139
+ }
140
+ else {
141
+ return #{__coerced__ :<, other};
142
+ }
143
+ }
144
+ end
145
+
146
+ def <=(other)
147
+ %x{
148
+ if (other.$$is_number) {
149
+ return self <= other;
150
+ }
151
+ else {
152
+ return #{__coerced__ :<=, other};
153
+ }
154
+ }
155
+ end
156
+
157
+ def >(other)
158
+ %x{
159
+ if (other.$$is_number) {
160
+ return self > other;
161
+ }
162
+ else {
163
+ return #{__coerced__ :>, other};
164
+ }
165
+ }
166
+ end
167
+
168
+ def >=(other)
169
+ %x{
170
+ if (other.$$is_number) {
171
+ return self >= other;
172
+ }
173
+ else {
174
+ return #{__coerced__ :>=, other};
175
+ }
176
+ }
177
+ end
178
+
179
+ def <=>(other)
180
+ %x{
181
+ if (other.$$is_number) {
182
+ if (isNaN(self) || isNaN(other)) {
183
+ return nil;
184
+ }
185
+
186
+ return self > other ? 1 : (self < other ? -1 : 0);
187
+ }
188
+ else {
189
+ return #{__coerced__ :<=>, other};
190
+ }
191
+ }
192
+ rescue ArgumentError
193
+ nil
194
+ end
195
+
196
+ def <<(count)
197
+ count = Opal.coerce_to! count, Integer, :to_int
198
+
199
+ `#{count} > 0 ? self << #{count} : self >> -#{count}`
200
+ end
201
+
202
+ def >>(count)
203
+ count = Opal.coerce_to! count, Integer, :to_int
204
+
205
+ `#{count} > 0 ? self >> #{count} : self << -#{count}`
206
+ end
207
+
208
+ def [](bit)
209
+ bit = Opal.coerce_to! bit, Integer, :to_int
210
+
211
+ %x{
212
+ if (#{bit} < #{Integer::MIN} || #{bit} > #{Integer::MAX}) {
213
+ return 0;
214
+ }
215
+
216
+ if (self < 0) {
217
+ return (((~self) + 1) >> #{bit}) % 2;
218
+ }
219
+ else {
220
+ return (self >> #{bit}) % 2;
221
+ }
222
+ }
223
+ end
224
+
225
+ def +@
226
+ `+self`
227
+ end
228
+
229
+ def -@
230
+ `-self`
231
+ end
232
+
233
+ def ~
234
+ `~self`
235
+ end
236
+
237
+ def **(other)
238
+ if Integer === other
239
+ if !(Integer === self) || other > 0
240
+ `Math.pow(self, other)`
241
+ else
242
+ Rational.new(self, 1) ** other
243
+ end
244
+ elsif self < 0 && (Float === other || Rational === other)
245
+ Complex.new(self, 0) ** other.to_f
246
+ elsif `other.$$is_number != null`
247
+ `Math.pow(self, other)`
248
+ else
249
+ __coerced__ :**, other
250
+ end
251
+ end
252
+
253
+ def ==(other)
254
+ %x{
255
+ if (other.$$is_number) {
256
+ return self == Number(other);
257
+ }
258
+ else if (#{other.respond_to? :==}) {
259
+ return #{other == self};
260
+ }
261
+ else {
262
+ return false;
263
+ }
264
+ }
265
+ end
266
+
267
+ def abs
268
+ `Math.abs(self)`
269
+ end
270
+
271
+ def abs2
272
+ `Math.abs(self * self)`
273
+ end
274
+
275
+ def angle
276
+ return self if nan?
277
+
278
+ %x{
279
+ if (self == 0) {
280
+ if (1 / self > 0) {
281
+ return 0;
282
+ }
283
+ else {
284
+ return Math.PI;
285
+ }
286
+ }
287
+ else if (self < 0) {
288
+ return Math.PI;
289
+ }
290
+ else {
291
+ return 0;
292
+ }
293
+ }
294
+ end
295
+
296
+ alias arg angle
297
+ alias phase angle
298
+
299
+ def bit_length
300
+ unless Integer === self
301
+ raise NoMethodError, "undefined method `bit_length` for #{self}:Float"
302
+ end
303
+
304
+ %x{
305
+ if (self === 0 || self === -1) {
306
+ return 0;
307
+ }
308
+
309
+ var result = 0,
310
+ value = self < 0 ? ~self : self;
311
+
312
+ while (value != 0) {
313
+ result += 1;
314
+ value >>>= 1;
315
+ }
316
+
317
+ return result;
318
+ }
319
+ end
320
+
321
+ def ceil
322
+ `Math.ceil(self)`
323
+ end
324
+
325
+ def chr(encoding = undefined)
326
+ `String.fromCharCode(self)`
327
+ end
328
+
329
+ def denominator
330
+ if nan? || infinite?
331
+ 1
332
+ else
333
+ super
334
+ end
335
+ end
336
+
337
+ def downto(stop, &block)
338
+ return enum_for(:downto, stop){
339
+ raise ArgumentError, "comparison of #{self.class} with #{stop.class} failed" unless Numeric === stop
340
+ stop > self ? 0 : self - stop + 1
341
+ } unless block_given?
342
+
343
+ %x{
344
+ if (!stop.$$is_number) {
345
+ #{raise ArgumentError, "comparison of #{self.class} with #{stop.class} failed"}
346
+ }
347
+ for (var i = self; i >= stop; i--) {
348
+ if (block(i) === $breaker) {
349
+ return $breaker.$v;
350
+ }
351
+ }
352
+ }
353
+
354
+ self
355
+ end
356
+
357
+ alias eql? ==
358
+
359
+ def equal?(other)
360
+ self == other || `isNaN(self) && isNaN(other)`
361
+ end
362
+
363
+ def even?
364
+ `self % 2 === 0`
365
+ end
366
+
367
+ def floor
368
+ `Math.floor(self)`
369
+ end
370
+
371
+ def gcd(other)
372
+ unless Integer === other
373
+ raise TypeError, 'not an integer'
374
+ end
375
+
376
+ %x{
377
+ var min = Math.abs(self),
378
+ max = Math.abs(other);
379
+
380
+ while (min > 0) {
381
+ var tmp = min;
382
+
383
+ min = max % min;
384
+ max = tmp;
385
+ }
386
+
387
+ return max;
388
+ }
389
+ end
390
+
391
+ def gcdlcm(other)
392
+ [gcd, lcm]
393
+ end
394
+
395
+ def hash
396
+ `'Numeric:'+self.toString()`
397
+ end
398
+
399
+ def integer?
400
+ `self % 1 === 0`
401
+ end
402
+
403
+ def is_a?(klass)
404
+ return true if klass == Fixnum && Integer === self
405
+ return true if klass == Integer && Integer === self
406
+ return true if klass == Float && Float === self
407
+
408
+ super
409
+ end
410
+
411
+ alias kind_of? is_a?
412
+
413
+ def instance_of?(klass)
414
+ return true if klass == Fixnum && Integer === self
415
+ return true if klass == Integer && Integer === self
416
+ return true if klass == Float && Float === self
417
+
418
+ super
419
+ end
420
+
421
+ def lcm(other)
422
+ unless Integer === other
423
+ raise TypeError, 'not an integer'
424
+ end
425
+
426
+ %x{
427
+ if (self == 0 || other == 0) {
428
+ return 0;
429
+ }
430
+ else {
431
+ return Math.abs(self * other / #{gcd(other)});
432
+ }
433
+ }
434
+ end
435
+
436
+ alias magnitude abs
437
+
438
+ alias modulo %
439
+
440
+ def next
441
+ `self + 1`
442
+ end
443
+
444
+ def nonzero?
445
+ `self == 0 ? nil : self`
446
+ end
447
+
448
+ def numerator
449
+ if nan? || infinite?
450
+ self
451
+ else
452
+ super
453
+ end
454
+ end
455
+
456
+ def odd?
457
+ `self % 2 !== 0`
458
+ end
459
+
460
+ def ord
461
+ self
462
+ end
463
+
464
+ def pred
465
+ `self - 1`
466
+ end
467
+
468
+ def quo(other)
469
+ if Integer === self
470
+ super
471
+ else
472
+ self / other
473
+ end
474
+ end
475
+
476
+ def rationalize(eps = undefined)
477
+ %x{
478
+ if (arguments.length > 1) {
479
+ #{raise ArgumentError, "wrong number of arguments (#{`arguments.length`} for 0..1)"};
480
+ }
481
+ }
482
+
483
+ if Integer === self
484
+ Rational.new(self, 1)
485
+ elsif infinite?
486
+ raise FloatDomainError, "Infinity"
487
+ elsif nan?
488
+ raise FloatDomainError, "NaN"
489
+ elsif `eps == null`
490
+ f, n = Math.frexp self
491
+ f = Math.ldexp(f, Float::MANT_DIG).to_i
492
+ n -= Float::MANT_DIG
493
+
494
+ Rational.new(2 * f, 1 << (1 - n)).rationalize(Rational.new(1, 1 << (1 - n)))
495
+ else
496
+ to_r.rationalize(eps)
497
+ end
498
+ end
499
+
500
+ def round(ndigits = undefined)
501
+ if Integer === self
502
+ if `ndigits == null`
503
+ return self
504
+ end
505
+
506
+ if Float === ndigits && ndigits.infinite?
507
+ raise RangeError, "Infinity"
508
+ end
509
+
510
+ ndigits = Opal.coerce_to!(ndigits, Integer, :to_int)
511
+
512
+ if ndigits < Integer::MIN
513
+ raise RangeError, "out of bounds"
514
+ end
515
+
516
+ if `ndigits >= 0`
517
+ return self
518
+ end
519
+
520
+ ndigits = -ndigits;
521
+
522
+ %x{
523
+ if (0.415241 * ndigits - 0.125 > #{size}) {
524
+ return 0;
525
+ }
526
+
527
+ var f = Math.pow(10, ndigits),
528
+ x = Math.floor((Math.abs(x) + f / 2) / f) * f;
529
+
530
+ return self < 0 ? -x : x;
531
+ }
532
+ else
533
+ if nan? && `ndigits == null`
534
+ raise FloatDomainError, "NaN"
535
+ end
536
+
537
+ ndigits = Opal.coerce_to!(`ndigits || 0`, Integer, :to_int)
538
+
539
+ if ndigits <= 0
540
+ if nan?
541
+ raise RangeError, "NaN"
542
+ elsif infinite?
543
+ raise FloatDomainError, "Infinity"
544
+ end
545
+ elsif ndigits == 0
546
+ return `Math.round(self)`
547
+ elsif nan? || infinite?
548
+ return self
549
+ end
550
+
551
+ _, exp = Math.frexp(self)
552
+
553
+ if ndigits >= (Float::DIG + 2) - (exp > 0 ? exp / 4 : exp / 3 - 1)
554
+ return self
555
+ end
556
+
557
+ if ndigits < -(exp > 0 ? exp / 3 + 1 : exp / 4)
558
+ return 0
559
+ end
560
+
561
+ `Math.round(self * Math.pow(10, ndigits)) / Math.pow(10, ndigits)`
562
+ end
563
+ end
564
+
565
+ def step(limit, step = 1, &block)
566
+ return enum_for :step, limit, step unless block
567
+
568
+ raise ArgumentError, 'step cannot be 0' if `step == 0`
569
+
570
+ %x{
571
+ var value = self;
572
+
573
+ if (limit === Infinity || limit === -Infinity) {
574
+ block(value);
575
+ return self;
576
+ }
577
+
578
+ if (step > 0) {
579
+ while (value <= limit) {
580
+ block(value);
581
+ value += step;
582
+ }
583
+ }
584
+ else {
585
+ while (value >= limit) {
586
+ block(value);
587
+ value += step;
588
+ }
589
+ }
590
+ }
591
+
592
+ self
593
+ end
594
+
595
+ alias succ next
596
+
597
+ def times(&block)
598
+ return enum_for :times unless block
599
+
600
+ %x{
601
+ for (var i = 0; i < self; i++) {
602
+ if (block(i) === $breaker) {
603
+ return $breaker.$v;
604
+ }
605
+ }
606
+ }
607
+
608
+ self
609
+ end
610
+
611
+ def to_f
612
+ self
613
+ end
614
+
615
+ def to_i
616
+ `parseInt(self, 10)`
617
+ end
618
+
619
+ alias to_int to_i
620
+
621
+ def to_r
622
+ if Integer === self
623
+ Rational.new(self, 1)
624
+ else
625
+ f, e = Math.frexp(self)
626
+ f = Math.ldexp(f, Float::MANT_DIG).to_i
627
+ e -= Float::MANT_DIG
628
+
629
+ (f * (Float::RADIX ** e)).to_r
630
+ end
631
+ end
632
+
633
+ def to_s(base = 10)
634
+ if base < 2 || base > 36
635
+ raise ArgumentError, 'base must be between 2 and 36'
636
+ end
637
+
638
+ `self.toString(base)`
639
+ end
640
+
641
+ alias truncate to_i
642
+
643
+ alias inspect to_s
644
+
645
+ def divmod(other)
646
+ if nan? || other.nan?
647
+ raise FloatDomainError, "NaN"
648
+ elsif infinite?
649
+ raise FloatDomainError, "Infinity"
650
+ else
651
+ super
652
+ end
653
+ end
654
+
655
+ def upto(stop, &block)
656
+ return enum_for(:upto, stop){
657
+ raise ArgumentError, "comparison of #{self.class} with #{stop.class} failed" unless Numeric === stop
658
+ stop < self ? 0 : stop - self + 1
659
+ } unless block_given?
660
+
661
+ %x{
662
+ if (!stop.$$is_number) {
663
+ #{raise ArgumentError, "comparison of #{self.class} with #{stop.class} failed"}
664
+ }
665
+ for (var i = self; i <= stop; i++) {
666
+ if (block(i) === $breaker) {
667
+ return $breaker.$v;
668
+ }
669
+ }
670
+ }
671
+
672
+ self
673
+ end
674
+
675
+ def zero?
676
+ `self == 0`
677
+ end
678
+
679
+ # Since bitwise operations are 32 bit, declare it to be so.
680
+ def size
681
+ 4
682
+ end
683
+
684
+ def nan?
685
+ `isNaN(self)`
686
+ end
687
+
688
+ def finite?
689
+ `self != Infinity && self != -Infinity && !isNaN(self)`
690
+ end
691
+
692
+ def infinite?
693
+ %x{
694
+ if (self == Infinity) {
695
+ return +1;
696
+ }
697
+ else if (self == -Infinity) {
698
+ return -1;
699
+ }
700
+ else {
701
+ return nil;
702
+ }
703
+ }
704
+ end
705
+
706
+ def positive?
707
+ `self == Infinity || 1 / self > 0`
708
+ end
709
+
710
+ def negative?
711
+ `self == -Infinity || 1 / self < 0`
712
+ end
713
+ end
714
+
715
+ Fixnum = Number
716
+
717
+ class Integer < Numeric
718
+ def self.===(other)
719
+ %x{
720
+ if (!other.$$is_number) {
721
+ return false;
722
+ }
723
+
724
+ return (other % 1) === 0;
725
+ }
726
+ end
727
+
728
+ MAX = `Math.pow(2, 30) - 1`
729
+ MIN = `-Math.pow(2, 30)`
730
+ end
731
+
732
+ class Float < Numeric
733
+ def self.===(other)
734
+ `!!other.$$is_number`
735
+ end
736
+
737
+ INFINITY = `Infinity`
738
+ MAX = `Number.MAX_VALUE`
739
+ MIN = `Number.MIN_VALUE`
740
+ NAN = `NaN`
741
+
742
+ DIG = 15
743
+ MANT_DIG = 53
744
+ RADIX = 2
745
+
746
+ if defined?(`Number.EPSILON`)
747
+ EPSILON = `Number.EPSILON`
748
+ else
749
+ EPSILON = `2.2204460492503130808472633361816E-16`
750
+ end
751
+ end