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
@@ -1,4 +1,8 @@
1
1
  module Opal
2
+ def self.bridge(klass, constructor)
3
+ `Opal.bridge(klass, constructor)`
4
+ end
5
+
2
6
  def self.type_error(object, type, method = nil, coerced = nil)
3
7
  if method && coerced
4
8
  TypeError.new "can't convert #{object.class} into #{type} (#{object.class}##{method} gives #{coerced.class}"
@@ -99,4 +103,20 @@ module Opal
99
103
  }
100
104
  }
101
105
  end
106
+
107
+ def self.instance_variable_name!(name)
108
+ name = Opal.coerce_to!(name, String, :to_str)
109
+
110
+ unless `/^@[a-zA-Z_][a-zA-Z0-9_]*?$/.test(name)`
111
+ raise NameError, "'#{name}' is not allowed as an instance variable name"
112
+ end
113
+
114
+ name
115
+ end
116
+
117
+ def self.valid_method_name?(method_name)
118
+ method_name = Opal.coerce_to!(method_name, String, :to_str)
119
+
120
+ `/^[a-zA-Z_][a-zA-Z0-9_]*?$/.test(method_name)`
121
+ end
102
122
  end
@@ -7,12 +7,19 @@ module Kernel
7
7
  false
8
8
  end
9
9
 
10
+ def !~(obj)
11
+ not(self =~ obj)
12
+ end
13
+
10
14
  def ===(other)
11
15
  self.object_id == other.object_id || self == other
12
16
  end
13
17
 
14
18
  def <=>(other)
15
19
  %x{
20
+ // set guard for infinite recursion
21
+ self.$$comparable = true;
22
+
16
23
  var x = #{self == other};
17
24
 
18
25
  if (x && x !== nil) {
@@ -56,6 +63,8 @@ module Kernel
56
63
  }
57
64
  end
58
65
 
66
+ alias public_methods methods
67
+
59
68
  def Array(object)
60
69
  %x{
61
70
  var coerced;
@@ -103,10 +112,34 @@ module Kernel
103
112
  }
104
113
  end
105
114
 
115
+ def copy_singleton_methods(other)
116
+ %x{
117
+ var name;
118
+
119
+ if (other.hasOwnProperty('$$meta')) {
120
+ var other_singleton_class_proto = Opal.get_singleton_class(other).$$proto;
121
+ var self_singleton_class_proto = Opal.get_singleton_class(self).$$proto;
122
+
123
+ for (name in other_singleton_class_proto) {
124
+ if (name.charAt(0) === '$' && other_singleton_class_proto.hasOwnProperty(name)) {
125
+ self_singleton_class_proto[name] = other_singleton_class_proto[name];
126
+ }
127
+ }
128
+ }
129
+
130
+ for (name in other) {
131
+ if (name.charAt(0) === '$' && name.charAt(1) !== '$' && other.hasOwnProperty(name)) {
132
+ self[name] = other[name];
133
+ }
134
+ }
135
+ }
136
+ end
137
+
106
138
  def clone
107
139
  copy = self.class.allocate
108
140
 
109
141
  copy.copy_instance_variables(self)
142
+ copy.copy_singleton_methods(self)
110
143
  copy.initialize_clone(self)
111
144
 
112
145
  copy
@@ -116,23 +149,8 @@ module Kernel
116
149
  initialize_copy(other)
117
150
  end
118
151
 
119
- def define_singleton_method(name, body = nil, &block)
120
- body ||= block
121
-
122
- unless body
123
- raise ArgumentError, "tried to create Proc object without a block"
124
- end
125
-
126
- %x{
127
- var jsid = '$' + name;
128
- body.$$jsid = name;
129
- body.$$s = null;
130
- body.$$def = body;
131
-
132
- #{singleton_class}.$$proto[jsid] = body;
133
-
134
- return self;
135
- }
152
+ def define_singleton_method(name, method = undefined, &block)
153
+ singleton_class.define_method(name, method, &block)
136
154
  end
137
155
 
138
156
  def dup
@@ -278,7 +296,7 @@ module Kernel
278
296
  }
279
297
  if (format_string.charCodeAt(i) < 48 || format_string.charCodeAt(i) > 57) {
280
298
  i--;
281
- num = parseInt(str) || 0;
299
+ num = parseInt(str, 10) || 0;
282
300
  if (num > 2147483647) {
283
301
  #{raise ArgumentError, "#{`label`} too big"}
284
302
  }
@@ -597,7 +615,7 @@ module Kernel
597
615
  case 'g':
598
616
  case 'G':
599
617
  str = arg.toExponential();
600
- exponent = parseInt(str.split('e')[1]);
618
+ exponent = parseInt(str.split('e')[1], 10);
601
619
  if (!(exponent < -4 || exponent >= (precision === -1 ? 6 : precision))) {
602
620
  str = arg.toPrecision(precision === -1 ? (flags&FSHARP ? 6 : undefined) : precision);
603
621
  }
@@ -631,7 +649,7 @@ module Kernel
631
649
  case 'g':
632
650
  case 'G':
633
651
  str = (-arg).toExponential();
634
- exponent = parseInt(str.split('e')[1]);
652
+ exponent = parseInt(str.split('e')[1], 10);
635
653
  if (!(exponent < -4 || exponent >= (precision === -1 ? 6 : precision))) {
636
654
  str = (-arg).toPrecision(precision === -1 ? (flags&FSHARP ? 6 : undefined) : precision);
637
655
  }
@@ -721,15 +739,6 @@ module Kernel
721
739
  }
722
740
  end
723
741
 
724
- def freeze
725
- @___frozen___ = true
726
- self
727
- end
728
-
729
- def frozen?
730
- @___frozen___ || false
731
- end
732
-
733
742
  def hash
734
743
  "#{self.class}:#{self.class.__id__}:#{__id__}"
735
744
  end
@@ -742,14 +751,24 @@ module Kernel
742
751
  end
743
752
 
744
753
  def instance_of?(klass)
745
- `self.$$class === klass`
754
+ %x{
755
+ if (!klass.$$is_class && !klass.$$is_module) {
756
+ #{raise TypeError, 'class or module required'};
757
+ }
758
+
759
+ return self.$$class === klass;
760
+ }
746
761
  end
747
762
 
748
763
  def instance_variable_defined?(name)
764
+ name = Opal.instance_variable_name!(name)
765
+
749
766
  `Opal.hasOwnProperty.call(self, name.substr(1))`
750
767
  end
751
768
 
752
769
  def instance_variable_get(name)
770
+ name = Opal.instance_variable_name!(name)
771
+
753
772
  %x{
754
773
  var ivar = self[name.substr(1)];
755
774
 
@@ -758,6 +777,8 @@ module Kernel
758
777
  end
759
778
 
760
779
  def instance_variable_set(name, value)
780
+ name = Opal.instance_variable_name!(name)
781
+
761
782
  `self[name.substr(1)] = value`
762
783
  end
763
784
 
@@ -897,7 +918,13 @@ module Kernel
897
918
  end
898
919
 
899
920
  def is_a?(klass)
900
- `Opal.is_a(self, klass)`
921
+ %x{
922
+ if (!klass.$$is_class && !klass.$$is_module) {
923
+ #{raise TypeError, 'class or module required'};
924
+ }
925
+
926
+ return Opal.is_a(self, klass);
927
+ }
901
928
  end
902
929
 
903
930
  alias kind_of? is_a?
@@ -910,7 +937,7 @@ module Kernel
910
937
 
911
938
  def load(file)
912
939
  file = Opal.coerce_to!(file, String, :to_str)
913
- `Opal.load(Opal.normalize_loadable_path(#{file}))`
940
+ `Opal.load(#{file})`
914
941
  end
915
942
 
916
943
  def loop(&block)
@@ -939,11 +966,6 @@ module Kernel
939
966
  nil
940
967
  end
941
968
 
942
- def private_methods(*)
943
- []
944
- end
945
- alias private_instance_methods private_methods
946
-
947
969
  def proc(&block)
948
970
  unless block
949
971
  raise ArgumentError, "tried to create Proc object without a block"
@@ -971,23 +993,33 @@ module Kernel
971
993
  $stderr.puts(*strs) unless $VERBOSE.nil? || strs.empty?
972
994
  end
973
995
 
974
- def raise(exception = undefined, string = undefined)
996
+ def raise(exception = undefined, string = nil)
975
997
  %x{
976
- if (exception == null && #$!) {
998
+ if (exception == null && #$! !== nil) {
977
999
  throw #$!;
978
1000
  }
979
-
980
1001
  if (exception == null) {
981
1002
  exception = #{RuntimeError.new};
982
1003
  }
983
1004
  else if (exception.$$is_string) {
984
1005
  exception = #{RuntimeError.new exception};
985
1006
  }
986
- else if (exception.$$is_class) {
987
- exception = #{exception.new string};
1007
+ // using respond_to? and not an undefined check to avoid method_missing matching as true
1008
+ else if (exception.$$is_class && #{exception.respond_to?(:exception)}) {
1009
+ exception = #{exception.exception string};
988
1010
  }
989
-
990
- #$! = exception;
1011
+ else if (#{exception.kind_of?(Exception)}) {
1012
+ // exception is fine
1013
+ }
1014
+ else {
1015
+ exception = #{TypeError.new 'exception class/object expected'};
1016
+ }
1017
+
1018
+ if (#$! !== nil) {
1019
+ Opal.exceptions.push(#$!);
1020
+ }
1021
+
1022
+ #$! = exception;
991
1023
 
992
1024
  throw exception;
993
1025
  }
@@ -1001,9 +1033,10 @@ module Kernel
1001
1033
  return Math.random();
1002
1034
  }
1003
1035
  else if (max.$$is_range) {
1004
- var arr = #{max.to_a};
1036
+ var min = max.begin, range = max.end - min;
1037
+ if(!max.exclude) range++;
1005
1038
 
1006
- return arr[#{rand(`arr.length`)}];
1039
+ return self.$rand(range) + min;
1007
1040
  }
1008
1041
  else {
1009
1042
  return Math.floor(Math.random() *
@@ -1013,7 +1046,7 @@ module Kernel
1013
1046
  end
1014
1047
 
1015
1048
  def respond_to?(name, include_all = false)
1016
- return true if respond_to_missing?(name)
1049
+ return true if respond_to_missing?(name, include_all)
1017
1050
 
1018
1051
  %x{
1019
1052
  var body = self['$' + name];
@@ -1026,20 +1059,20 @@ module Kernel
1026
1059
  false
1027
1060
  end
1028
1061
 
1029
- def respond_to_missing?(method_name)
1062
+ def respond_to_missing?(method_name, include_all = false)
1030
1063
  false
1031
1064
  end
1032
1065
 
1033
1066
  def require(file)
1034
1067
  file = Opal.coerce_to!(file, String, :to_str)
1035
- `Opal.require(Opal.normalize_loadable_path(#{file}))`
1068
+ `Opal.require(#{file})`
1036
1069
  end
1037
1070
 
1038
1071
  def require_relative(file)
1039
1072
  Opal.try_convert!(file, String, :to_str)
1040
1073
  file = File.expand_path File.join(`Opal.current_file`, '..', file)
1041
1074
 
1042
- `Opal.require(Opal.normalize_loadable_path(#{file}))`
1075
+ `Opal.require(#{file})`
1043
1076
  end
1044
1077
 
1045
1078
  # `path` should be the full path to be found in registered modules (`Opal.modules`)
@@ -1065,6 +1098,23 @@ module Kernel
1065
1098
  `Opal.get_singleton_class(self)`
1066
1099
  end
1067
1100
 
1101
+ def sleep(seconds = nil)
1102
+ %x{
1103
+ if (seconds === nil) {
1104
+ #{raise TypeError, "can't convert NilClass into time interval"}
1105
+ }
1106
+ if (!seconds.$$is_number) {
1107
+ #{raise TypeError, "can't convert #{seconds.class} into time interval"}
1108
+ }
1109
+ if (seconds < 0) {
1110
+ #{raise ArgumentError, "time interval must be positive"}
1111
+ }
1112
+ var t = new Date();
1113
+ while (new Date() - t <= seconds * 1000);
1114
+ return seconds;
1115
+ }
1116
+ end
1117
+
1068
1118
  alias sprintf format
1069
1119
 
1070
1120
  alias srand rand
@@ -1074,14 +1124,6 @@ module Kernel
1074
1124
  Opal.coerce_to!(str, String, :to_s)
1075
1125
  end
1076
1126
 
1077
- def taint
1078
- self
1079
- end
1080
-
1081
- def tainted?
1082
- false
1083
- end
1084
-
1085
1127
  def tap(&block)
1086
1128
  yield self
1087
1129
  self
@@ -1095,5 +1137,18 @@ module Kernel
1095
1137
  "#<#{self.class}:0x#{__id__.to_s(16)}>"
1096
1138
  end
1097
1139
 
1098
- alias untaint taint
1140
+ def catch(sym)
1141
+ yield
1142
+ rescue UncaughtThrowError => e
1143
+ return e.arg if e.sym == sym
1144
+ raise
1145
+ end
1146
+
1147
+ def throw(*args)
1148
+ raise UncaughtThrowError.new(args)
1149
+ end
1150
+ end
1151
+
1152
+ class Object
1153
+ include Kernel
1099
1154
  end
@@ -0,0 +1,470 @@
1
+ module Math
2
+ E = `Math.E`
3
+ PI = `Math.PI`
4
+
5
+ DomainError = Class.new(StandardError)
6
+
7
+ def self.checked(method, *args)
8
+ %x{
9
+ if (isNaN(args[0]) || (args.length == 2 && isNaN(args[1]))) {
10
+ return NaN;
11
+ }
12
+
13
+ var result = Math[method].apply(null, args);
14
+
15
+ if (isNaN(result)) {
16
+ #{raise DomainError, "Numerical argument is out of domain - \"#{method}\""};
17
+ }
18
+
19
+ return result;
20
+ }
21
+ end
22
+
23
+ def self.float!(value)
24
+ begin
25
+ Float(value)
26
+ rescue ArgumentError
27
+ raise Opal.type_error(value, Float)
28
+ end
29
+ end
30
+
31
+ def self.integer!(value)
32
+ begin
33
+ Integer(value)
34
+ rescue ArgumentError
35
+ raise Opal.type_error(value, Integer)
36
+ end
37
+ end
38
+
39
+ module_function
40
+
41
+ def acos(x)
42
+ Math.checked :acos, Math.float!(x)
43
+ end
44
+
45
+ unless defined?(`Math.acosh`)
46
+ %x{
47
+ Math.acosh = function(x) {
48
+ return Math.log(x + Math.sqrt(x * x - 1));
49
+ }
50
+ }
51
+ end
52
+
53
+ def acosh(x)
54
+ Math.checked :acosh, Math.float!(x)
55
+ end
56
+
57
+ def asin(x)
58
+ Math.checked :asin, Math.float!(x)
59
+ end
60
+
61
+ unless defined?(`Math.asinh`)
62
+ %x{
63
+ Math.asinh = function(x) {
64
+ return Math.log(x + Math.sqrt(x * x + 1))
65
+ }
66
+ }
67
+ end
68
+
69
+ def asinh(x)
70
+ Math.checked :asinh, Math.float!(x)
71
+ end
72
+
73
+ def atan(x)
74
+ Math.checked :atan, Math.float!(x)
75
+ end
76
+
77
+ def atan2(y, x)
78
+ Math.checked :atan2, Math.float!(y), Math.float!(x)
79
+ end
80
+
81
+ unless defined?(`Math.atanh`)
82
+ %x{
83
+ Math.atanh = function(x) {
84
+ return 0.5 * Math.log((1 + x) / (1 - x));
85
+ }
86
+ }
87
+ end
88
+
89
+ def atanh(x)
90
+ Math.checked :atanh, Math.float!(x)
91
+ end
92
+
93
+ unless defined?(`Math.cbrt`)
94
+ %x{
95
+ Math.cbrt = function(x) {
96
+ if (x == 0) {
97
+ return 0;
98
+ }
99
+
100
+ if (x < 0) {
101
+ return -Math.cbrt(-x);
102
+ }
103
+
104
+ var r = x,
105
+ ex = 0;
106
+
107
+ while (r < 0.125) {
108
+ r *= 8;
109
+ ex--;
110
+ }
111
+
112
+ while (r > 1.0) {
113
+ r *= 0.125;
114
+ ex++;
115
+ }
116
+
117
+ r = (-0.46946116 * r + 1.072302) * r + 0.3812513;
118
+
119
+ while (ex < 0) {
120
+ r *= 0.5;
121
+ ex++;
122
+ }
123
+
124
+ while (ex > 0) {
125
+ r *= 2;
126
+ ex--;
127
+ }
128
+
129
+ r = (2.0 / 3.0) * r + (1.0 / 3.0) * x / (r * r);
130
+ r = (2.0 / 3.0) * r + (1.0 / 3.0) * x / (r * r);
131
+ r = (2.0 / 3.0) * r + (1.0 / 3.0) * x / (r * r);
132
+ r = (2.0 / 3.0) * r + (1.0 / 3.0) * x / (r * r);
133
+
134
+ return r;
135
+ }
136
+ }
137
+ end
138
+
139
+ def cbrt(x)
140
+ Math.checked :cbrt, Math.float!(x)
141
+ end
142
+
143
+ def cos(x)
144
+ Math.checked :cos, Math.float!(x)
145
+ end
146
+
147
+ unless defined?(`Math.cosh`)
148
+ %x{
149
+ Math.cosh = function(x) {
150
+ return (Math.exp(x) + Math.exp(-x)) / 2;
151
+ }
152
+ }
153
+ end
154
+
155
+ def cosh(x)
156
+ Math.checked :cosh, Math.float!(x)
157
+ end
158
+
159
+ unless defined?(`Math.erf`)
160
+ %x{
161
+ Math.erf = function(x) {
162
+ var A1 = 0.254829592,
163
+ A2 = -0.284496736,
164
+ A3 = 1.421413741,
165
+ A4 = -1.453152027,
166
+ A5 = 1.061405429,
167
+ P = 0.3275911;
168
+
169
+ var sign = 1;
170
+
171
+ if (x < 0) {
172
+ sign = -1;
173
+ }
174
+
175
+ x = Math.abs(x);
176
+
177
+ var t = 1.0 / (1.0 + P * x);
178
+ var y = 1.0 - (((((A5 * t + A4) * t) + A3) * t + A2) * t + A1) * t * Math.exp(-x * x);
179
+
180
+ return sign * y;
181
+ }
182
+ }
183
+ end
184
+
185
+ def erf(x)
186
+ Math.checked :erf, Math.float!(x)
187
+ end
188
+
189
+ unless defined?(`Math.erfc`)
190
+ %x{
191
+ Math.erfc = function(x) {
192
+ var z = Math.abs(x),
193
+ t = 1.0 / (0.5 * z + 1.0);
194
+
195
+ var A1 = t * 0.17087277 + -0.82215223,
196
+ A2 = t * A1 + 1.48851587,
197
+ A3 = t * A2 + -1.13520398,
198
+ A4 = t * A3 + 0.27886807,
199
+ A5 = t * A4 + -0.18628806,
200
+ A6 = t * A5 + 0.09678418,
201
+ A7 = t * A6 + 0.37409196,
202
+ A8 = t * A7 + 1.00002368,
203
+ A9 = t * A8,
204
+ A10 = -z * z - 1.26551223 + A9;
205
+
206
+ var a = t * Math.exp(A10);
207
+
208
+ if (x < 0.0) {
209
+ return 2.0 - a;
210
+ }
211
+ else {
212
+ return a;
213
+ }
214
+ }
215
+ }
216
+ end
217
+
218
+ def erfc(x)
219
+ Math.checked :erfc, Math.float!(x)
220
+ end
221
+
222
+ def exp(x)
223
+ Math.checked :exp, Math.float!(x)
224
+ end
225
+
226
+ def frexp(x)
227
+ x = Math.float!(x)
228
+
229
+ %x{
230
+ if (isNaN(x)) {
231
+ return [NaN, 0];
232
+ }
233
+
234
+ var ex = Math.floor(Math.log(Math.abs(x)) / Math.log(2)) + 1,
235
+ frac = x / Math.pow(2, ex);
236
+
237
+ return [frac, ex];
238
+ }
239
+ end
240
+
241
+ def gamma(n)
242
+ n = Math.float!(n)
243
+
244
+ %x{
245
+ var i, t, x, value, result, twoN, threeN, fourN, fiveN;
246
+
247
+ var G = 4.7421875;
248
+
249
+ var P = [
250
+ 0.99999999999999709182,
251
+ 57.156235665862923517,
252
+ -59.597960355475491248,
253
+ 14.136097974741747174,
254
+ -0.49191381609762019978,
255
+ 0.33994649984811888699e-4,
256
+ 0.46523628927048575665e-4,
257
+ -0.98374475304879564677e-4,
258
+ 0.15808870322491248884e-3,
259
+ -0.21026444172410488319e-3,
260
+ 0.21743961811521264320e-3,
261
+ -0.16431810653676389022e-3,
262
+ 0.84418223983852743293e-4,
263
+ -0.26190838401581408670e-4,
264
+ 0.36899182659531622704e-5
265
+ ];
266
+
267
+
268
+ if (isNaN(n)) {
269
+ return NaN;
270
+ }
271
+
272
+ if (n === 0 && 1 / n < 0) {
273
+ return -Infinity;
274
+ }
275
+
276
+ if (n === -1 || n === -Infinity) {
277
+ #{raise DomainError, "Numerical argument is out of domain - \"gamma\""};
278
+ }
279
+
280
+ if (#{Integer === n}) {
281
+ if (n <= 0) {
282
+ return isFinite(n) ? Infinity : NaN;
283
+ }
284
+
285
+ if (n > 171) {
286
+ return Infinity;
287
+ }
288
+
289
+ value = n - 2;
290
+ result = n - 1;
291
+
292
+ while (value > 1) {
293
+ result *= value;
294
+ value--;
295
+ }
296
+
297
+ if (result == 0) {
298
+ result = 1;
299
+ }
300
+
301
+ return result;
302
+ }
303
+
304
+ if (n < 0.5) {
305
+ return Math.PI / (Math.sin(Math.PI * n) * #{Math.gamma(1 - n)});
306
+ }
307
+
308
+ if (n >= 171.35) {
309
+ return Infinity;
310
+ }
311
+
312
+ if (n > 85.0) {
313
+ twoN = n * n;
314
+ threeN = twoN * n;
315
+ fourN = threeN * n;
316
+ fiveN = fourN * n;
317
+
318
+ return Math.sqrt(2 * Math.PI / n) * Math.pow((n / Math.E), n) *
319
+ (1 + 1 / (12 * n) + 1 / (288 * twoN) - 139 / (51840 * threeN) -
320
+ 571 / (2488320 * fourN) + 163879 / (209018880 * fiveN) +
321
+ 5246819 / (75246796800 * fiveN * n));
322
+ }
323
+
324
+ n -= 1;
325
+ x = P[0];
326
+
327
+ for (i = 1; i < P.length; ++i) {
328
+ x += P[i] / (n + i);
329
+ }
330
+
331
+ t = n + G + 0.5;
332
+
333
+ return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x;
334
+ }
335
+ end
336
+
337
+ unless defined?(`Math.hypot`)
338
+ %x{
339
+ Math.hypot = function(x, y) {
340
+ return Math.sqrt(x * x + y * y)
341
+ }
342
+ }
343
+ end
344
+
345
+ def hypot(x, y)
346
+ Math.checked :hypot, Math.float!(x), Math.float!(y)
347
+ end
348
+
349
+ def ldexp(mantissa, exponent)
350
+ mantissa = Math.float!(mantissa)
351
+ exponent = Math.integer!(exponent)
352
+
353
+ %x{
354
+ if (isNaN(exponent)) {
355
+ #{raise RangeError, "float NaN out of range of integer"};
356
+ }
357
+
358
+ return mantissa * Math.pow(2, exponent);
359
+ }
360
+ end
361
+
362
+ def lgamma(n)
363
+ %x{
364
+ if (n == -1) {
365
+ return [Infinity, 1];
366
+ }
367
+ else {
368
+ return [Math.log(Math.abs(#{Math.gamma(n)})), #{Math.gamma(n)} < 0 ? -1 : 1];
369
+ }
370
+ }
371
+ end
372
+
373
+ def log(x, base = undefined)
374
+ if String === x
375
+ raise Opal.type_error(x, Float)
376
+ end
377
+
378
+ if `base == null`
379
+ Math.checked :log, Math.float!(x)
380
+ else
381
+ if String === base
382
+ raise Opal.type_error(base, Float)
383
+ end
384
+
385
+ Math.checked(:log, Math.float!(x)) / Math.checked(:log, Math.float!(base))
386
+ end
387
+ end
388
+
389
+ unless defined?(`Math.log10`)
390
+ %x{
391
+ Math.log10 = function(x) {
392
+ return Math.log(x) / Math.LN10;
393
+ }
394
+ }
395
+ end
396
+
397
+ def log10(x)
398
+ if String === x
399
+ raise Opal.type_error(x, Float)
400
+ end
401
+
402
+ Math.checked :log10, Math.float!(x)
403
+ end
404
+
405
+ unless defined?(`Math.log2`)
406
+ %x{
407
+ Math.log2 = function(x) {
408
+ return Math.log(x) / Math.LN2;
409
+ }
410
+ }
411
+ end
412
+
413
+ def log2(x)
414
+ if String === x
415
+ raise Opal.type_error(x, Float)
416
+ end
417
+
418
+ Math.checked :log2, Math.float!(x)
419
+ end
420
+
421
+ def sin(x)
422
+ Math.checked :sin, Math.float!(x)
423
+ end
424
+
425
+ unless defined?(`Math.sinh`)
426
+ %x{
427
+ Math.sinh = function(x) {
428
+ return (Math.exp(x) - Math.exp(-x)) / 2;
429
+ }
430
+ }
431
+ end
432
+
433
+ def sinh(x)
434
+ Math.checked :sinh, Math.float!(x)
435
+ end
436
+
437
+ def sqrt(x)
438
+ Math.checked :sqrt, Math.float!(x)
439
+ end
440
+
441
+ def tan(x)
442
+ x = Math.float!(x)
443
+
444
+ if x.infinite?
445
+ return Float::NAN
446
+ end
447
+
448
+ Math.checked :tan, Math.float!(x)
449
+ end
450
+
451
+ unless defined?(`Math.tanh`)
452
+ %x{
453
+ Math.tanh = function(x) {
454
+ if (x == Infinity) {
455
+ return 1;
456
+ }
457
+ else if (x == -Infinity) {
458
+ return -1;
459
+ }
460
+ else {
461
+ return (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x));
462
+ }
463
+ }
464
+ }
465
+ end
466
+
467
+ def tanh(x)
468
+ Math.checked :tanh, Math.float!(x)
469
+ end
470
+ end