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.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/.gitmodules +3 -3
- data/.jshintrc +17 -20
- data/.travis.yml +22 -11
- data/CHANGELOG.md +51 -1
- data/CODE_OF_CONDUCT.md +15 -0
- data/CONTRIBUTING.md +125 -9
- data/Gemfile +1 -1
- data/Guardfile +2 -2
- data/README.md +95 -29
- data/Rakefile +1 -1
- data/benchmark/benchmarks +103 -0
- data/benchmark/bm_array_flatten.rb +9 -0
- data/benchmark/bm_array_intersection_numbers.rb +7 -0
- data/benchmark/bm_array_intersection_objects.rb +7 -0
- data/benchmark/bm_array_intersection_strings.rb +7 -0
- data/benchmark/bm_array_join_ary.rb +9 -0
- data/benchmark/bm_array_minus_numbers.rb +7 -0
- data/benchmark/bm_array_minus_objects.rb +7 -0
- data/benchmark/bm_array_minus_strings.rb +7 -0
- data/benchmark/bm_array_union_numbers.rb +7 -0
- data/benchmark/bm_array_union_objects.rb +7 -0
- data/benchmark/bm_array_union_strings.rb +7 -0
- data/benchmark/bm_array_uniq_bang_numbers.rb +5 -0
- data/benchmark/bm_array_uniq_bang_objects.rb +5 -0
- data/benchmark/bm_array_uniq_bang_strings.rb +5 -0
- data/benchmark/bm_array_uniq_numbers.rb +5 -0
- data/benchmark/bm_array_uniq_objects.rb +5 -0
- data/benchmark/bm_array_uniq_strings.rb +5 -0
- data/benchmark/bm_dispatch_bind_table.rb +57 -0
- data/benchmark/bm_dispatch_code_gen.rb +65 -0
- data/benchmark/bm_dispatch_code_gen_if.rb +64 -0
- data/benchmark/bm_dispatch_hardcoded.rb +44 -0
- data/benchmark/bm_dispatch_send.rb +38 -0
- data/benchmark/bm_dispatch_send_table.rb +57 -0
- data/benchmark/bm_hash_assoc_object.rb +11 -0
- data/benchmark/bm_hash_assoc_string.rb +9 -0
- data/benchmark/bm_hash_clone_object.rb +9 -0
- data/benchmark/bm_hash_clone_string.rb +9 -0
- data/benchmark/bm_hash_delete_object.rb +11 -0
- data/benchmark/bm_hash_delete_string.rb +9 -0
- data/benchmark/bm_hash_each_key_object.rb +9 -0
- data/benchmark/bm_hash_each_key_string.rb +9 -0
- data/benchmark/bm_hash_each_object.rb +9 -0
- data/benchmark/bm_hash_each_string.rb +9 -0
- data/benchmark/bm_hash_each_value_object.rb +9 -0
- data/benchmark/bm_hash_each_value_string.rb +9 -0
- data/benchmark/bm_hash_element_reference_object.rb +11 -0
- data/benchmark/bm_hash_element_reference_string.rb +9 -0
- data/benchmark/bm_hash_element_set_object.rb +5 -0
- data/benchmark/bm_hash_element_set_string.rb +5 -0
- data/benchmark/bm_hash_equal_value_object.rb +14 -0
- data/benchmark/bm_hash_equal_value_string.rb +11 -0
- data/benchmark/bm_hash_fetch_object.rb +11 -0
- data/benchmark/bm_hash_fetch_string.rb +9 -0
- data/benchmark/bm_hash_flatten_object.rb +9 -0
- data/benchmark/bm_hash_flatten_string.rb +9 -0
- data/benchmark/bm_hash_has_key_object.rb +11 -0
- data/benchmark/bm_hash_has_key_string.rb +9 -0
- data/benchmark/bm_hash_has_value_object.rb +9 -0
- data/benchmark/bm_hash_has_value_string.rb +9 -0
- data/benchmark/bm_hash_hash_object.rb +9 -0
- data/benchmark/bm_hash_hash_string.rb +9 -0
- data/benchmark/bm_hash_inspect_object.rb +9 -0
- data/benchmark/bm_hash_inspect_string.rb +9 -0
- data/benchmark/bm_hash_invert_object.rb +9 -0
- data/benchmark/bm_hash_invert_string.rb +9 -0
- data/benchmark/bm_hash_keep_if_object.rb +9 -0
- data/benchmark/bm_hash_keep_if_string.rb +9 -0
- data/benchmark/bm_hash_key_object.rb +9 -0
- data/benchmark/bm_hash_key_string.rb +9 -0
- data/benchmark/bm_hash_keys_object.rb +9 -0
- data/benchmark/bm_hash_keys_string.rb +9 -0
- data/benchmark/bm_hash_literal_mixed_large.rb +3 -0
- data/benchmark/bm_hash_literal_mixed_small.rb +3 -0
- data/benchmark/bm_hash_literal_object_large.rb +4 -0
- data/benchmark/bm_hash_literal_object_small.rb +3 -0
- data/benchmark/bm_hash_literal_string_large.rb +4 -0
- data/benchmark/bm_hash_literal_string_small.rb +3 -0
- data/benchmark/bm_hash_merge_object.rb +22 -0
- data/benchmark/bm_hash_merge_string.rb +18 -0
- data/benchmark/bm_hash_rassoc_object.rb +9 -0
- data/benchmark/bm_hash_rassoc_string.rb +9 -0
- data/benchmark/bm_hash_rehash_object.rb +9 -0
- data/benchmark/bm_hash_rehash_string.rb +9 -0
- data/benchmark/bm_hash_reject_bang_object.rb +9 -0
- data/benchmark/bm_hash_reject_bang_string.rb +9 -0
- data/benchmark/bm_hash_reject_object.rb +9 -0
- data/benchmark/bm_hash_reject_string.rb +9 -0
- data/benchmark/bm_hash_replace_object.rb +18 -0
- data/benchmark/bm_hash_replace_string.rb +14 -0
- data/benchmark/bm_hash_select_bang_object.rb +9 -0
- data/benchmark/bm_hash_select_bang_string.rb +9 -0
- data/benchmark/bm_hash_select_object.rb +9 -0
- data/benchmark/bm_hash_select_string.rb +9 -0
- data/benchmark/bm_hash_shift_object.rb +10 -0
- data/benchmark/bm_hash_shift_string.rb +10 -0
- data/benchmark/bm_hash_to_a_object.rb +9 -0
- data/benchmark/bm_hash_to_a_string.rb +9 -0
- data/benchmark/bm_hash_to_h_object.rb +10 -0
- data/benchmark/bm_hash_to_h_string.rb +10 -0
- data/benchmark/bm_hash_values_object.rb +9 -0
- data/benchmark/bm_hash_values_string.rb +9 -0
- data/benchmark/run.rb +48 -0
- data/bin/opal-mspec +1 -1
- data/bin/opal-repl +4 -4
- data/docs/compiled_ruby.md +214 -56
- data/docs/configuring_gems.md +2 -2
- data/docs/faq.md +2 -2
- data/docs/getting_started.md +19 -2
- data/docs/jquery.md +5 -5
- data/docs/opal_parser.md +53 -0
- data/docs/unsupported_features.md +2 -2
- data/docs/upgrading.md +22 -0
- data/docs/using_sprockets.md +15 -0
- data/examples/rack/config.ru +13 -0
- data/examples/sinatra/config.ru +4 -5
- data/lib/mspec/opal/runner.rb +54 -11
- data/lib/opal.rb +1 -1
- data/lib/opal/builder.rb +1 -1
- data/lib/opal/builder_processors.rb +1 -1
- data/lib/opal/cli.rb +17 -13
- data/lib/opal/cli_options.rb +1 -1
- data/lib/opal/compiler.rb +12 -0
- data/lib/opal/config.rb +4 -0
- data/lib/opal/nodes/arglist.rb +5 -7
- data/lib/opal/nodes/call.rb +6 -1
- data/lib/opal/nodes/call_special.rb +74 -0
- data/lib/opal/nodes/def.rb +35 -28
- data/lib/opal/nodes/definitions.rb +3 -5
- data/lib/opal/nodes/for.rb +13 -0
- data/lib/opal/nodes/helpers.rb +15 -1
- data/lib/opal/nodes/if.rb +5 -5
- data/lib/opal/nodes/iter.rb +6 -1
- data/lib/opal/nodes/literal.rb +1 -1
- data/lib/opal/nodes/logic.rb +2 -2
- data/lib/opal/nodes/masgn.rb +1 -2
- data/lib/opal/nodes/module.rb +2 -1
- data/lib/opal/nodes/rescue.rb +10 -1
- data/lib/opal/nodes/scope.rb +8 -2
- data/lib/opal/nodes/singleton_class.rb +1 -1
- data/lib/opal/nodes/top.rb +11 -0
- data/lib/opal/nodes/variables.rb +4 -4
- data/lib/opal/parser.rb +21 -3
- data/lib/opal/parser/grammar.rb +3115 -2961
- data/lib/opal/parser/grammar.y +29 -6
- data/lib/opal/parser/lexer.rb +18 -8
- data/lib/opal/sprockets.rb +85 -0
- data/lib/opal/sprockets/processor.rb +11 -35
- data/lib/opal/sprockets/server.rb +3 -15
- data/lib/opal/version.rb +2 -2
- data/opal.gemspec +4 -4
- data/opal/README.md +9 -0
- data/opal/corelib/array.rb +433 -181
- data/opal/corelib/basic_object.rb +48 -4
- data/opal/corelib/boolean.rb +15 -6
- data/opal/corelib/class.rb +6 -5
- data/opal/corelib/comparable.rb +12 -0
- data/opal/corelib/complex.rb +282 -0
- data/opal/corelib/constants.rb +9 -0
- data/opal/corelib/enumerable.rb +83 -34
- data/opal/corelib/enumerator.rb +3 -1
- data/opal/corelib/error.rb +49 -10
- data/opal/corelib/file.rb +1 -0
- data/opal/corelib/hash.rb +353 -577
- data/opal/corelib/helpers.rb +20 -0
- data/opal/corelib/kernel.rb +114 -59
- data/opal/corelib/math.rb +470 -0
- data/opal/corelib/method.rb +11 -2
- data/opal/corelib/module.rb +96 -96
- data/opal/corelib/{nil_class.rb → nil.rb} +20 -1
- data/opal/corelib/number.rb +751 -0
- data/opal/corelib/numeric.rb +77 -437
- data/opal/corelib/proc.rb +81 -1
- data/opal/corelib/process.rb +27 -0
- data/opal/corelib/rational.rb +358 -0
- data/opal/corelib/regexp.rb +156 -27
- data/opal/corelib/runtime.js +724 -335
- data/opal/corelib/string.rb +93 -104
- data/opal/corelib/string/encoding.rb +177 -0
- data/opal/corelib/string/inheritance.rb +2 -0
- data/opal/corelib/struct.rb +105 -18
- data/opal/corelib/time.rb +267 -146
- data/opal/corelib/unsupported.rb +216 -0
- data/opal/corelib/variables.rb +0 -6
- data/opal/opal.rb +8 -22
- data/opal/opal/base.rb +9 -0
- data/opal/opal/mini.rb +17 -0
- data/spec/README.md +1 -1
- data/spec/filters/bugs/array.rb +38 -136
- data/spec/filters/bugs/{basic_object.rb → basicobject.rb} +14 -15
- data/spec/filters/bugs/class.rb +6 -12
- data/spec/filters/bugs/complex.rb +3 -0
- data/spec/filters/bugs/date.rb +162 -10
- data/spec/filters/bugs/enumerable.rb +31 -58
- data/spec/filters/bugs/enumerator.rb +42 -0
- data/spec/filters/bugs/exception.rb +66 -10
- data/spec/filters/bugs/float.rb +17 -0
- data/spec/filters/bugs/hash.rb +11 -97
- data/spec/filters/bugs/inheritance.rb +5 -0
- data/spec/filters/bugs/integer.rb +28 -0
- data/spec/filters/bugs/kernel.rb +304 -12
- data/spec/filters/bugs/language.rb +133 -399
- data/spec/filters/bugs/language_opal.rb +88 -0
- data/spec/filters/bugs/module.rb +203 -62
- data/spec/filters/bugs/numeric.rb +32 -0
- data/spec/filters/bugs/proc.rb +39 -0
- data/spec/filters/bugs/range.rb +148 -0
- data/spec/filters/bugs/regexp.rb +168 -0
- data/spec/filters/bugs/set.rb +46 -3
- data/spec/filters/bugs/singleton.rb +1 -2
- data/spec/filters/bugs/string.rb +59 -90
- data/spec/filters/bugs/strscan.rb +80 -0
- data/spec/filters/bugs/struct.rb +10 -20
- data/spec/filters/bugs/time.rb +17 -184
- data/spec/filters/bugs/unboundmethod.rb +22 -0
- data/spec/filters/unsupported/array.rb +163 -0
- data/spec/filters/unsupported/basicobject.rb +14 -0
- data/spec/filters/unsupported/bignum.rb +46 -0
- data/spec/filters/unsupported/class.rb +4 -0
- data/spec/filters/unsupported/delegator.rb +5 -0
- data/spec/filters/unsupported/enumerable.rb +11 -0
- data/spec/filters/unsupported/enumerator.rb +8 -9
- data/spec/filters/unsupported/fixnum.rb +14 -0
- data/spec/filters/unsupported/float.rb +41 -7
- data/spec/filters/unsupported/freeze.rb +45 -0
- data/spec/filters/unsupported/hash.rb +50 -0
- data/spec/filters/unsupported/integer.rb +3 -0
- data/spec/filters/unsupported/kernel.rb +31 -0
- data/spec/filters/unsupported/language.rb +17 -0
- data/spec/filters/unsupported/matchdata.rb +30 -0
- data/spec/filters/unsupported/math.rb +3 -0
- data/spec/filters/unsupported/module.rb +5 -3
- data/spec/filters/unsupported/pathname.rb +3 -0
- data/spec/filters/unsupported/privacy.rb +136 -0
- data/spec/filters/unsupported/proc.rb +3 -0
- data/spec/filters/unsupported/regexp.rb +59 -0
- data/spec/filters/unsupported/set.rb +4 -0
- data/spec/filters/unsupported/{marshal.rb → singleton.rb} +4 -2
- data/spec/filters/unsupported/{mutable_strings.rb → string.rb} +456 -336
- data/spec/filters/unsupported/struct.rb +3 -0
- data/spec/filters/unsupported/symbol.rb +5 -0
- data/spec/filters/unsupported/taint.rb +16 -0
- data/spec/filters/unsupported/thread.rb +5 -0
- data/spec/filters/unsupported/time.rb +197 -16
- data/spec/lib/cli_spec.rb +14 -4
- data/spec/lib/compiler_spec.rb +9 -1
- data/spec/lib/parser/call_spec.rb +18 -0
- data/spec/lib/parser/not_spec.rb +2 -8
- data/spec/lib/sprockets_spec.rb +24 -0
- data/spec/opal/core/array/intersection_spec.rb +38 -0
- data/spec/opal/core/array/minus_spec.rb +38 -0
- data/spec/opal/core/array/union_spec.rb +38 -0
- data/spec/opal/core/array/uniq_spec.rb +49 -0
- data/spec/opal/core/exception_spec.rb +7 -0
- data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +3 -0
- data/spec/opal/core/hash/internals_spec.rb +332 -0
- data/spec/opal/core/helpers_spec.rb +14 -0
- data/spec/opal/core/kernel/freeze_spec.rb +1 -1
- data/spec/opal/core/kernel/raise_spec.rb +13 -0
- data/spec/opal/core/kernel/require_tree_spec.rb +9 -0
- data/spec/opal/core/language/class_spec.rb +55 -0
- data/spec/opal/core/language/fixtures/send.rb +1 -0
- data/spec/opal/core/language/keyword_arguments_spec.rb +11 -0
- data/spec/opal/core/language/send_spec.rb +5 -0
- data/spec/opal/core/method/to_proc_spec.rb +28 -0
- data/spec/opal/core/module/name_spec.rb +0 -17
- data/spec/opal/core/runtime/bridged_classes_spec.rb +2 -2
- data/spec/opal/core/runtime/eval_spec.rb +1 -1
- data/spec/opal/core/runtime/method_missing_spec.rb +6 -0
- data/spec/opal/core/runtime_spec.rb +51 -0
- data/spec/opal/stdlib/js_spec.rb +66 -0
- data/spec/opal/stdlib/native/hash_spec.rb +36 -0
- data/spec/rubyspecs +152 -273
- data/spec/spec_helper.rb +10 -11
- data/stdlib/base64.rb +9 -9
- data/stdlib/benchmark.rb +551 -4
- data/stdlib/console.rb +94 -0
- data/stdlib/date.rb +1 -1
- data/stdlib/encoding.rb +1 -170
- data/stdlib/js.rb +56 -0
- data/stdlib/json.rb +9 -14
- data/stdlib/math.rb +1 -370
- data/stdlib/native.rb +133 -63
- data/stdlib/nodejs/file.rb +5 -0
- data/stdlib/nodejs/fileutils.rb +13 -6
- data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/README.md +1 -1
- data/stdlib/opal-parser.rb +1 -2
- data/stdlib/ostruct.rb +65 -6
- data/stdlib/pp.rb +2 -4
- data/stdlib/rbconfig.rb +1 -3
- data/stdlib/strscan.rb +164 -28
- data/tasks/benchmarking.rake +88 -0
- data/tasks/testing.rake +181 -55
- data/{lib/mspec/opal/special_calls.rb → tasks/testing/mspec_special_calls.rb} +1 -1
- data/{lib/mspec/opal/sprockets.js → tasks/testing/phantomjs1-sprockets.js} +17 -6
- data/test/opal/test_keyword.rb +590 -0
- data/vendored-minitest/minitest.rb +2 -2
- data/vendored-minitest/test/unit.rb +5 -0
- metadata +229 -62
- data/benchmarks/operators.rb +0 -11
- data/benchmarks/prova.js.rb +0 -13
- data/docs/libraries.md +0 -36
- data/lib/mspec/opal/new.html.erb +0 -1
- data/lib/mspec/opal/rake_task.rb +0 -248
- data/opal/corelib/match_data.rb +0 -128
- data/spec/filters/bugs/math.rb +0 -95
- data/spec/filters/bugs/nil.rb +0 -7
- data/spec/filters/bugs/opal.rb +0 -9
- data/spec/filters/bugs/regular_expressions.rb +0 -41
- data/spec/filters/bugs/stringscanner.rb +0 -33
- data/spec/filters/unsupported/encoding.rb +0 -102
- data/spec/filters/unsupported/frozen.rb +0 -92
- data/spec/filters/unsupported/hash_compare_by_identity.rb +0 -16
- data/spec/filters/unsupported/integer_size.rb +0 -59
- data/spec/filters/unsupported/method_added.rb +0 -10
- data/spec/filters/unsupported/private_constants.rb +0 -30
- data/spec/filters/unsupported/private_methods.rb +0 -55
- data/spec/filters/unsupported/random.rb +0 -4
- data/spec/filters/unsupported/rational_numbers.rb +0 -4
- data/spec/filters/unsupported/regular_expressions.rb +0 -137
- data/spec/filters/unsupported/ruby_exe.rb +0 -5
- data/spec/filters/unsupported/symbols.rb +0 -17
- data/spec/filters/unsupported/tainted.rb +0 -180
- data/spec/filters/unsupported/trusted.rb +0 -88
- data/stdlib/process.rb +0 -10
- data/tasks/documenting.rake +0 -37
data/opal/corelib/method.rb
CHANGED
@@ -27,11 +27,16 @@ class Method
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def to_proc
|
30
|
-
|
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: #{@
|
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
|
|
data/opal/corelib/module.rb
CHANGED
@@ -2,12 +2,12 @@ class Module
|
|
2
2
|
def self.new(&block)
|
3
3
|
%x{
|
4
4
|
function AnonModule(){}
|
5
|
-
var klass
|
6
|
-
klass.$$name
|
7
|
-
klass.$$class
|
8
|
-
klass.$$dep
|
9
|
-
klass.$$
|
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
|
49
|
-
|
50
|
-
|
51
|
-
body = self.$$proto['$' + oldname];
|
53
|
+
def <=(other)
|
54
|
+
equal?(other) or self < other
|
55
|
+
end
|
52
56
|
|
53
|
-
|
54
|
-
|
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
|
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
|
-
|
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(
|
110
|
+
var body = (function(ivar) {
|
108
111
|
return function() {
|
109
|
-
|
112
|
+
if (this[ivar] == null) {
|
113
|
+
return nil;
|
114
|
+
}
|
115
|
+
else {
|
116
|
+
return this[ivar];
|
117
|
+
}
|
110
118
|
};
|
111
|
-
})(
|
119
|
+
})(ivar);
|
112
120
|
|
113
121
|
// initialize the instance variable as nil
|
114
|
-
proto[
|
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(
|
147
|
+
var body = (function(ivar){
|
139
148
|
return function(value) {
|
140
|
-
return this[
|
149
|
+
return this[ivar] = value;
|
141
150
|
}
|
142
|
-
})(
|
151
|
+
})(ivar);
|
143
152
|
|
144
153
|
// initialize the instance variable as nil
|
145
|
-
proto[
|
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
|
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
|
-
|
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 &&
|
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
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
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
|
-
|
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(
|
319
|
-
|
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 (
|
390
|
+
if (prop.charAt(0) !== '$') {
|
374
391
|
continue;
|
375
392
|
}
|
376
393
|
|
377
|
-
if (
|
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.$$
|
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],
|
487
|
+
var meth = methods[i],
|
488
|
+
id = '$' + meth,
|
489
|
+
func = self.$$proto[id];
|
462
490
|
|
463
|
-
self
|
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
|
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(
|
549
|
-
|
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
|