opal 0.3.2 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +85 -127
- data/bin/opal +3 -3
- data/lib/core.rb +114 -0
- data/{gems/core/lib → lib}/core/array.rb +68 -187
- data/{gems/core/lib → lib}/core/basic_object.rb +22 -5
- data/lib/core/class.rb +38 -0
- data/{gems/core/lib → lib}/core/dir.rb +1 -1
- data/lib/core/enumerable.rb +33 -0
- data/{gems/core/lib → lib}/core/error.rb +1 -4
- data/{gems/core/lib → lib}/core/false_class.rb +0 -0
- data/{gems/core/lib → lib}/core/file.rb +11 -3
- data/{gems/core/lib → lib}/core/hash.rb +12 -0
- data/{gems/core/lib → lib}/core/kernel.rb +114 -86
- data/lib/core/match_data.rb +33 -0
- data/lib/core/module.rb +97 -0
- data/{gems/core/lib → lib}/core/nil_class.rb +0 -0
- data/{gems/core/lib → lib}/core/numeric.rb +5 -0
- data/{gems/core/lib → lib}/core/object.rb +0 -0
- data/{gems/core/lib → lib}/core/proc.rb +13 -3
- data/{gems/core/lib → lib}/core/range.rb +10 -0
- data/{gems/core/lib → lib}/core/regexp.rb +33 -1
- data/{gems/core/lib → lib}/core/string.rb +25 -10
- data/{gems/core/lib → lib}/core/symbol.rb +3 -3
- data/{gems/core/lib → lib}/core/top_self.rb +0 -0
- data/{gems/core/lib → lib}/core/true_class.rb +0 -0
- data/lib/dev.rb +169 -0
- data/{gems/ospec/lib → lib}/ospec.rb +1 -0
- data/lib/ospec/autorun.rb +8 -0
- data/{gems/ospec/lib → lib}/ospec/dsl.rb +2 -2
- data/{gems/ospec/lib → lib}/ospec/example.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/example/before_and_after_hooks.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/example/errors.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/example/example_group.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/example/example_group_factory.rb +0 -3
- data/{gems/ospec/lib → lib}/ospec/example/example_group_hierarchy.rb +4 -3
- data/{gems/ospec/lib → lib}/ospec/example/example_group_methods.rb +1 -1
- data/{gems/ospec/lib → lib}/ospec/example/example_group_proxy.rb +3 -2
- data/{gems/ospec/lib → lib}/ospec/example/example_methods.rb +1 -1
- data/{gems/ospec/lib → lib}/ospec/example/example_proxy.rb +7 -7
- data/{gems/ospec/lib → lib}/ospec/expectations.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/expectations/errors.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/expectations/fail_with.rb +4 -3
- data/{gems/ospec/lib → lib}/ospec/expectations/handler.rb +6 -0
- data/lib/ospec/helpers/scratch.rb +18 -0
- data/{gems/ospec/lib → lib}/ospec/matchers.rb +2 -2
- data/{gems/ospec/lib → lib}/ospec/matchers/be.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/matchers/generated_descriptions.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/matchers/operator_matcher.rb +2 -0
- data/lib/ospec/matchers/raise_error.rb +38 -0
- data/lib/ospec/runner.rb +90 -0
- data/{gems/ospec/lib → lib}/ospec/runner/example_group_runner.rb +10 -13
- data/lib/ospec/runner/formatter/html_formatter.rb +139 -0
- data/{gems/ospec/lib → lib}/ospec/runner/formatter/terminal_formatter.rb +0 -0
- data/{gems/ospec/lib → lib}/ospec/runner/options.rb +1 -3
- data/{gems/ospec/lib → lib}/ospec/runner/reporter.rb +0 -9
- data/lib/racc/parser.rb +165 -0
- data/lib/strscan.rb +52 -0
- data/{lib → opal_lib}/opal.rb +2 -0
- data/opal_lib/opal/build_methods.rb +51 -0
- data/opal_lib/opal/builder.rb +164 -0
- data/opal_lib/opal/bundle.rb +70 -0
- data/opal_lib/opal/command.rb +68 -0
- data/{lib → opal_lib}/opal/context.rb +21 -9
- data/{lib → opal_lib}/opal/context/console.rb +0 -2
- data/opal_lib/opal/context/file_system.rb +34 -0
- data/{lib → opal_lib}/opal/context/loader.rb +26 -8
- data/opal_lib/opal/gem.rb +84 -0
- data/{lib → opal_lib}/opal/rake/builder_task.rb +2 -2
- data/opal_lib/opal/rake/spec_task.rb +32 -0
- data/{lib → opal_lib}/opal/ruby/nodes.rb +730 -109
- data/{lib → opal_lib}/opal/ruby/parser.rb +90 -23
- data/opal_lib/opal/ruby/ruby_parser.rb +4862 -0
- data/opal_lib/opal/ruby/ruby_parser.y +1454 -0
- data/opal_lib/opal/version.rb +4 -0
- data/runtime/class.js +359 -0
- data/runtime/debug.js +84 -0
- data/runtime/fs.js +199 -0
- data/runtime/init.js +558 -0
- data/runtime/loader.js +351 -0
- data/runtime/module.js +109 -0
- data/runtime/post.js +10 -0
- data/runtime/pre.js +7 -0
- data/runtime/runtime.js +351 -0
- metadata +88 -175
- data/.gitignore +0 -7
- data/Changelog +0 -31
- data/LICENSE +0 -75
- data/Rakefile +0 -86
- data/gems/core/README.md +0 -14
- data/gems/core/Rakefile +0 -8
- data/gems/core/core.gemspec +0 -13
- data/gems/core/lib/core.rb +0 -34
- data/gems/core/lib/core/class.rb +0 -31
- data/gems/core/lib/core/module.rb +0 -100
- data/gems/core/lib/core/vm.rb +0 -16
- data/gems/core/spec/core/array/append_spec.rb +0 -30
- data/gems/core/spec/core/array/assoc_spec.rb +0 -29
- data/gems/core/spec/core/array/at_spec.rb +0 -37
- data/gems/core/spec/core/array/clear_spec.rb +0 -22
- data/gems/core/spec/core/array/collect_bang_spec.rb +0 -27
- data/gems/core/spec/core/array/collect_spec.rb +0 -27
- data/gems/core/spec/core/array/compact_spec.rb +0 -41
- data/gems/core/spec/core/array/concat_spec.rb +0 -15
- data/gems/core/spec/core/array/constructor_spec.rb +0 -14
- data/gems/core/spec/core/array/each_spec.rb +0 -9
- data/gems/core/spec/core/array/element_reference_spec.rb +0 -4
- data/gems/core/spec/core/array/first_spec.rb +0 -35
- data/gems/core/spec/core/array/include_spec.rb +0 -9
- data/gems/core/spec/core/array/join_spec.rb +0 -6
- data/gems/core/spec/core/array/last_spec.rb +0 -51
- data/gems/core/spec/core/array/length_spec.rb +0 -6
- data/gems/core/spec/core/array/map_spec.rb +0 -33
- data/gems/core/spec/core/array/reverse_spec.rb +0 -6
- data/gems/core/spec/core/builtin_constants/builtin_constants_spec.rb +0 -7
- data/gems/core/spec/core/false/and_spec.rb +0 -10
- data/gems/core/spec/core/false/inspect_spec.rb +0 -6
- data/gems/core/spec/core/false/or_spec.rb +0 -10
- data/gems/core/spec/core/false/to_s_spec.rb +0 -6
- data/gems/core/spec/core/false/xor_spec.rb +0 -10
- data/gems/core/spec/core/file/join_spec.rb +0 -19
- data/gems/core/spec/core/hash/assoc_spec.rb +0 -32
- data/gems/core/spec/core/kernel/instance_eval_spec.rb +0 -0
- data/gems/core/spec/core/kernel/loop_spec.rb +0 -24
- data/gems/core/spec/core/kernel/raise_spec.rb +0 -0
- data/gems/core/spec/core/module/attr_accessor_spec.rb +0 -28
- data/gems/core/spec/core/number/lt_spec.rb +0 -12
- data/gems/core/spec/core/string/sub_spec.rb +0 -24
- data/gems/core/spec/core/true/and_spec.rb +0 -10
- data/gems/core/spec/core/true/inspect_spec.rb +0 -6
- data/gems/core/spec/core/true/or_spec.rb +0 -10
- data/gems/core/spec/core/true/to_s_spec.rb +0 -6
- data/gems/core/spec/core/true/xor_spec.rb +0 -10
- data/gems/core/spec/language/and_spec.rb +0 -61
- data/gems/core/spec/language/array_spec.rb +0 -68
- data/gems/core/spec/language/block_spec.rb +0 -38
- data/gems/core/spec/language/break_spec.rb +0 -36
- data/gems/core/spec/language/case_spec.rb +0 -103
- data/gems/core/spec/language/def_spec.rb +0 -21
- data/gems/core/spec/language/eigenclass_spec.rb +0 -60
- data/gems/core/spec/language/file_spec.rb +0 -13
- data/gems/core/spec/language/fixtures/block.rb +0 -21
- data/gems/core/spec/language/fixtures/super.rb +0 -293
- data/gems/core/spec/language/hash_spec.rb +0 -29
- data/gems/core/spec/language/if_spec.rb +0 -54
- data/gems/core/spec/language/loop_spec.rb +0 -11
- data/gems/core/spec/language/metaclass_spec.rb +0 -21
- data/gems/core/spec/language/method_spec.rb +0 -124
- data/gems/core/spec/language/next_spec.rb +0 -25
- data/gems/core/spec/language/or_spec.rb +0 -34
- data/gems/core/spec/language/redo_spec.rb +0 -24
- data/gems/core/spec/language/regexp_spec.rb +0 -26
- data/gems/core/spec/language/rescue_spec.rb +0 -20
- data/gems/core/spec/language/return_spec.rb +0 -47
- data/gems/core/spec/language/string_spec.rb +0 -25
- data/gems/core/spec/language/super_spec.rb +0 -32
- data/gems/core/spec/language/until_spec.rb +0 -157
- data/gems/core/spec/language/variables_spec.rb +0 -155
- data/gems/core/spec/language/while_spec.rb +0 -163
- data/gems/core/spec/spec_helper.rb +0 -5
- data/gems/core_fs/README.md +0 -19
- data/gems/dev/Rakefile +0 -5
- data/gems/dev/lib/dev.js +0 -99
- data/gems/dev/lib/dev/generator.js +0 -1264
- data/gems/dev/lib/dev/parser.js +0 -979
- data/gems/dev/lib/dev/ruby_parser.js +0 -1088
- data/gems/dev/lib/dev/ruby_parser.y +0 -1267
- data/gems/dev/lib/dev/string_scanner.js +0 -38
- data/gems/dev/tools/racc2js/README.md +0 -39
- data/gems/dev/tools/racc2js/math_parser.js +0 -222
- data/gems/dev/tools/racc2js/math_parser.rb +0 -133
- data/gems/dev/tools/racc2js/math_parser.y +0 -28
- data/gems/dev/tools/racc2js/parser.js +0 -218
- data/gems/dev/tools/racc2js/racc2js.rb +0 -153
- data/gems/json/README.md +0 -4
- data/gems/json/json.gemspec +0 -14
- data/gems/json/lib/json.rb +0 -64
- data/gems/json/lib/json/ext.rb +0 -51
- data/gems/json/lib/json/json2.js +0 -481
- data/gems/ospec/README.md +0 -0
- data/gems/ospec/lib/ospec/autorun.rb +0 -3
- data/gems/ospec/lib/ospec/runner.rb +0 -40
- data/gems/ospec/lib/ospec/runner/formatter/html_formatter.rb +0 -91
- data/gems/ospec/ospec.gemspec +0 -0
- data/gems/rquery/README.md +0 -9
- data/gems/rquery/lib/rquery.rb +0 -10
- data/gems/rquery/lib/rquery/ajax.rb +0 -4
- data/gems/rquery/lib/rquery/css.rb +0 -96
- data/gems/rquery/lib/rquery/document.rb +0 -25
- data/gems/rquery/lib/rquery/element.rb +0 -292
- data/gems/rquery/lib/rquery/event.rb +0 -108
- data/gems/rquery/lib/rquery/jquery.js +0 -8177
- data/gems/rquery/lib/rquery/request.rb +0 -138
- data/gems/rquery/lib/rquery/response.rb +0 -49
- data/gems/rquery/rquery.gemspec +0 -16
- data/lib/opal.js +0 -1597
- data/lib/opal/builder.rb +0 -117
- data/lib/opal/bundle.rb +0 -131
- data/lib/opal/command.rb +0 -11
- data/lib/opal/context/file_system.rb +0 -19
- data/lib/opal/gem.rb +0 -153
- data/lib/opal/ruby/ruby_parser.rb +0 -5170
- data/lib/opal/ruby/ruby_parser.y +0 -1298
- data/opal.gemspec +0 -15
data/README.md
CHANGED
@@ -3,166 +3,124 @@ Opal: Ruby runtime for javascript
|
|
3
3
|
|
4
4
|
**Homepage**: [http://opalscript.org](http://opalscript.org)
|
5
5
|
**Github**: [http://github.com/adambeynon/opal](http://github.com/adambeynon/opal)
|
6
|
-
**Documentation**: [http://adambeynon.github.com/opal/index.html](http://adambeynon.github.com/opal/index.html)
|
7
6
|
|
8
7
|
Description
|
9
8
|
-----------
|
10
9
|
|
11
|
-
Opal is a
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
Opal is a Ruby runtime and standard library designed to run directly on
|
11
|
+
top of javascript. It can be run within the browser or on the command
|
12
|
+
line through the bundled build tools. Opal includes a parser/compiler
|
13
|
+
that builds ruby ahead of time directly into javascript that runs with
|
14
|
+
the bundled runtime.
|
15
|
+
|
16
|
+
Features
|
17
|
+
--------
|
18
|
+
|
19
|
+
* Full method\_missing support for all objects and classes
|
20
|
+
* Debug mode to provide stack traces and arg checking
|
21
|
+
* Private and public method support
|
22
|
+
* Full operator overloading (`[]`, `[]=`, `+`, `-`, `==`, etc)
|
23
|
+
* Toll free bridges to javascript objects (`String`, `Number`, `Array`
|
24
|
+
etc)
|
25
|
+
* Inline javascript within ruby code using backticks
|
26
|
+
* In browser loading of `<script type="text/ruby></script>` tags
|
27
|
+
* Generated code is clean and maintains line numbers to ease debugging
|
28
|
+
* super(), metaclasses, eigenclasses, blocks, yield, block\_given?,
|
29
|
+
ranges, arg count errors, lambda, singletons, etc....
|
16
30
|
|
17
31
|
Installation
|
18
32
|
------------
|
19
33
|
|
20
|
-
|
34
|
+
The best way to get started with opal is to clone this repo and use the
|
35
|
+
`opal` bin file directly:
|
21
36
|
|
22
|
-
$
|
37
|
+
$ git clone git://github.com/adambeynon/opal.git
|
23
38
|
|
24
|
-
|
25
|
-
|
39
|
+
Although opal is distributed as a gem, the latest gem release is mostly
|
40
|
+
incompatible with the loading and runtime system for opal, so until a
|
41
|
+
newer gem is released (0.3.5), it is best to stick with the repo.
|
42
|
+
|
43
|
+
### Try without installing
|
44
|
+
|
45
|
+
Browser can be used inside a repl on the
|
46
|
+
[http://opalscript.org](http://opalscript.org) homepage which gives an
|
47
|
+
IRB style interface for running ruby code which is compiled and
|
48
|
+
evaluated within the browser (no plugins!).
|
49
|
+
|
50
|
+
Alternatively the opal runtime and opal parser can be downloaded
|
51
|
+
directly from the `extras` directory in this repository.
|
26
52
|
|
27
53
|
Usage
|
28
54
|
-----
|
29
55
|
|
30
|
-
|
31
|
-
|
56
|
+
Opal can be used within in the browser, or on the command line using the
|
57
|
+
build tools. A Nodejs environment is also partially implemented.
|
32
58
|
|
33
|
-
|
59
|
+
### Browser
|
34
60
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
simply type:
|
61
|
+
To run within the browser, you can either use the latest build version
|
62
|
+
on the opal website, or clone the build tools as above, and then run the
|
63
|
+
following task in this directory:
|
39
64
|
|
40
|
-
$ opal
|
65
|
+
$ rake opal
|
41
66
|
|
42
|
-
|
67
|
+
This will place a non minified version ready to run within the browser
|
68
|
+
into `extras/opal.js`
|
43
69
|
|
44
|
-
|
70
|
+
#### Compiling ruby sources
|
45
71
|
|
46
|
-
|
47
|
-
|
48
|
-
|
72
|
+
To run ruby code in the browser, ruby must either be precompiled to
|
73
|
+
javascript using these build tools, or the `opal_dev.js` file can parse
|
74
|
+
and compile ruby code referenced in html `script` tags that use the
|
75
|
+
`text/ruby` type.
|
49
76
|
|
50
|
-
|
77
|
+
### Command line
|
51
78
|
|
52
|
-
|
53
|
-
|
54
|
-
|
79
|
+
Opal is bundled with a set of build tools available in the `opalite/`
|
80
|
+
directory. These are available when running opal from the command line
|
81
|
+
or including it from ruby sources.
|
55
82
|
|
56
|
-
|
83
|
+
#### Ruby repl
|
57
84
|
|
58
|
-
|
59
|
-
t.files = 'ruby/**/*.rb'
|
60
|
-
t.out = 'js/ruby_code.js'
|
61
|
-
end
|
85
|
+
To run the repl, clone this repo as directed above and run:
|
62
86
|
|
63
|
-
|
64
|
-
best required. The `files` will take an array, or a single string, and
|
65
|
-
can be globs. It is important to use relative paths here not absolute
|
66
|
-
paths. This will be default create a rake task called `opal` in your
|
67
|
-
rakefile, but you can rename it by passing another name into `new`. To
|
68
|
-
compile the javascript run:
|
87
|
+
$ bin/opal irb
|
69
88
|
|
70
|
-
|
89
|
+
This will act like any other repl to try out commands. The repl relies
|
90
|
+
on `therubyracer` as its javascript engine.
|
71
91
|
|
72
|
-
|
73
|
-
|
74
|
-
the latest `opal.js` file first.
|
92
|
+
Running tests
|
93
|
+
-------------
|
75
94
|
|
76
|
-
|
95
|
+
Opal uses a subset of the `rubyspec` specs for ruby until it reaches a
|
96
|
+
mature enough state to just use rubyspec directly. These tests are found
|
97
|
+
in the `spec/` folder. They can be run either through the command line,
|
98
|
+
or built ready to open in the browser.
|
77
99
|
|
78
|
-
|
79
|
-
file in the `files` array when the file is loaded in the browser. The
|
80
|
-
`main` option allows you to specify another file:
|
100
|
+
### Running in the browser
|
81
101
|
|
82
|
-
|
83
|
-
t.files = ['ruby/file_1.rb', 'ruby/file_2.rb', 'ruby/file_3.rb']
|
84
|
-
t.out = 'out.js'
|
85
|
-
t.main = 'ruby/file_2.rb'
|
86
|
-
end
|
102
|
+
To run in the browser, first build the specs (compile into js ready):
|
87
103
|
|
88
|
-
|
104
|
+
$ rake opal_spec
|
89
105
|
|
90
|
-
|
91
|
-
|
92
|
-
modified. Observe the command line after using this task:
|
106
|
+
This will build the specs into `extras/` so open `extras/opal.spec.html`
|
107
|
+
in any browser to see how the specs run.
|
93
108
|
|
94
|
-
|
95
|
-
t.files = 'ruby/*.rb'
|
96
|
-
t.out = 'my_code.js'
|
97
|
-
t.watch = true
|
98
|
-
end
|
109
|
+
### Running on command line
|
99
110
|
|
100
|
-
|
101
|
-
|
111
|
+
The opal binary has a `spec` flag which can be passed one or any number
|
112
|
+
of specs. For example, to run the `and` and `&&` specs from this repo,
|
113
|
+
run:
|
114
|
+
|
115
|
+
$ bin/opal spec spec/language/and_spec.rb
|
116
|
+
|
117
|
+
Between gem releases every spec will pass. The master branch in this
|
118
|
+
repo may contain broken specs, but these will be fixed before the next
|
119
|
+
gem release and version bump.
|
120
|
+
|
121
|
+
Examples
|
122
|
+
--------
|
102
123
|
|
103
|
-
|
104
|
-
|
105
|
-
included in the standard ruby installation. To aid this, the actual opal
|
106
|
-
gem includes several gems that offer the basic features. These gems are:
|
107
|
-
|
108
|
-
**core**
|
109
|
-
|
110
|
-
The core gem offers the ruby core library. It is mostly written in ruby,
|
111
|
-
but has a large proportion of inline javascript to make it as performant
|
112
|
-
as possible. Many of the classes are toll-free bridged to native
|
113
|
-
javascript objects, including Array, String, Numeric and Proc. Read the
|
114
|
-
[core library documentation](http://adambeynon.github.com/opal/gems/core/index.html)
|
115
|
-
for more information.
|
116
|
-
|
117
|
-
**dev**
|
118
|
-
|
119
|
-
The dev gem contains a ruby parser and compiler written in javascript.
|
120
|
-
It is a clone of the default opal parser written in ruby. This gem is in
|
121
|
-
the process of being replaced with the pure ruby version, which will be
|
122
|
-
compiled into javascript for this gem. This gem can be loaded into
|
123
|
-
javascript to allow in browser compilation of ruby sources from external
|
124
|
-
files or through html `script` tags.
|
125
|
-
|
126
|
-
**json**
|
127
|
-
|
128
|
-
The json gem included methods for parsing json strings and then
|
129
|
-
generating json objects from a string of json code. This gem aims to be
|
130
|
-
API compatible with the standard json library. Similarly to that
|
131
|
-
library, json objects are mapped to Hash, Array, true, false, nil,
|
132
|
-
String and Numeric as appropriate. See the
|
133
|
-
[JSON documentation](http://adambeynon.github.com/opal/gems/json/index.html)
|
134
|
-
for the full api.
|
135
|
-
|
136
|
-
**rquery**
|
137
|
-
|
138
|
-
RQuery is a port/abstraction of the jQuery javascript library for DOM
|
139
|
-
manipulation. jQuery is actually included as part of the gem, and top
|
140
|
-
level classes like Element, Document and Request are used to interact
|
141
|
-
with the document and elements. The api tries to stay as close to the
|
142
|
-
jquery interface as possible, but adds appropriate ruby syntax features
|
143
|
-
on top. See the [rquery documentation](http://adambeynon.github.com/opal/gems/rquery/index.html)
|
144
|
-
for the full api.
|
145
|
-
|
146
|
-
**ospec**
|
147
|
-
|
148
|
-
OSpec is a minimal clone of the ruby rspec library. It implements the
|
149
|
-
core features available in rspec, and works both from the command line
|
150
|
-
and in browser. The core, json and rquery gems all have tests/specs
|
151
|
-
written ready for ospec. See the [ospec guide](http://adambeynon.github.com/opal/gems/ospec/index.html)
|
152
|
-
to get started.
|
153
|
-
|
154
|
-
Changelog
|
155
|
-
---------
|
156
|
-
|
157
|
-
- **31 March 2011**: 0.3.2 Release
|
158
|
-
- Added BuilderTask for easy building for simple projects.
|
159
|
-
- Amended build options in Builder to support new rake task.
|
160
|
-
|
161
|
-
- **30 March 2011**: 0.3.1 Release
|
162
|
-
- Fix to make `opal` an executable
|
163
|
-
|
164
|
-
- **30 March 2011**: 0.3.0 Release
|
165
|
-
- Major redesign of build tools to use v8 for server side opal
|
166
|
-
- Split all opal packages into actual gems
|
167
|
-
- File and Dir classes for both browser and v8 gem runtimes
|
124
|
+
Examples can be found in the `examples/` directory in this repo, and
|
125
|
+
rely on `extras/opal.js` being created using the above commands.
|
168
126
|
|
data/bin/opal
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
opal_lib = File.expand_path('../../opal_lib', __FILE__)
|
4
|
+
$:.unshift opal_lib unless $:.include? opal_lib
|
5
5
|
|
6
6
|
require 'opal'
|
7
7
|
require 'opal/command'
|
8
8
|
|
9
|
-
Opal::Command.
|
9
|
+
Opal::Command.start
|
10
10
|
|
data/lib/core.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
class Module
|
2
|
+
|
3
|
+
def private(*args)
|
4
|
+
`$rb.private_methods(self, args);`
|
5
|
+
self
|
6
|
+
end
|
7
|
+
|
8
|
+
def public(*args)
|
9
|
+
`$rb.public_methods(self, args);`
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def include(*mods)
|
14
|
+
`var i = mods.length - 1, mod;
|
15
|
+
while (i >= 0) {
|
16
|
+
mod = mods[i];
|
17
|
+
#{`mod`.append_features self};
|
18
|
+
#{`mod`.included self};
|
19
|
+
i--;
|
20
|
+
}
|
21
|
+
return self;`
|
22
|
+
end
|
23
|
+
|
24
|
+
def append_features(mod)
|
25
|
+
`$rb.include_module(mod, self);`
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def included(mod)
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module Kernel
|
35
|
+
private
|
36
|
+
|
37
|
+
# Try to load the library or file named `path`. An error is thrown if the
|
38
|
+
# path cannot be resolved.
|
39
|
+
#
|
40
|
+
# @param [String] path The path to load
|
41
|
+
# @return [true, false]
|
42
|
+
def require(path)
|
43
|
+
`$rb.require(path) ? Qtrue : Qfalse;`
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
# Prints the message to `STDOUT`.
|
48
|
+
#
|
49
|
+
# @param [Array<Object>] args Objects to print using `to_s`
|
50
|
+
# @return [nil]
|
51
|
+
def puts(*a)
|
52
|
+
$stdout.puts *a
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class << $stdout
|
58
|
+
# FIXME: Should this really be here? We only need to override this when we
|
59
|
+
# are in the browser context as we don't have native access to file
|
60
|
+
# descriptors etc
|
61
|
+
def puts(*a)
|
62
|
+
`for (var i = 0, ii = a.length; i < ii; i++) {
|
63
|
+
console.log(#{`a[i]`.to_s}.toString());
|
64
|
+
}`
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Object
|
70
|
+
include Kernel
|
71
|
+
end
|
72
|
+
|
73
|
+
class Symbol
|
74
|
+
def to_s
|
75
|
+
`return self.toString();`
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class String
|
80
|
+
def to_s
|
81
|
+
`return self.toString();`
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
require 'core/basic_object'
|
86
|
+
require 'core/object'
|
87
|
+
require 'core/module'
|
88
|
+
require 'core/class'
|
89
|
+
require 'core/kernel'
|
90
|
+
require 'core/top_self'
|
91
|
+
require 'core/nil_class'
|
92
|
+
require 'core/true_class'
|
93
|
+
require 'core/false_class'
|
94
|
+
require 'core/enumerable'
|
95
|
+
require 'core/array'
|
96
|
+
require 'core/numeric'
|
97
|
+
require 'core/hash'
|
98
|
+
require 'core/error'
|
99
|
+
require 'core/string'
|
100
|
+
require 'core/symbol'
|
101
|
+
require 'core/proc'
|
102
|
+
require 'core/range'
|
103
|
+
require 'core/regexp'
|
104
|
+
require 'core/match_data'
|
105
|
+
require 'core/file'
|
106
|
+
require 'core/dir'
|
107
|
+
|
108
|
+
`var platform = opal.platform;`
|
109
|
+
RUBY_PLATFORM = `platform.platform`
|
110
|
+
RUBY_ENGINE = `platform.engine`
|
111
|
+
RUBY_VERSION = `platform.version`
|
112
|
+
|
113
|
+
ARGV = `platform.argv`
|
114
|
+
|
@@ -1,55 +1,5 @@
|
|
1
|
-
# Arrays are ordered collections, indexed by integers starting at `0`.
|
2
|
-
# Indexes may be negative, where `-1` represents the last item in the
|
3
|
-
# array, `-2` the last but one, etc. Arrays may be constructed by using a
|
4
|
-
# method like {Array.[]}, or by using an array literal:
|
5
|
-
#
|
6
|
-
# Array[1, 2, 3, 4, 5] # => [1, 2, 3, 4, 5]
|
7
|
-
# ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"]
|
8
|
-
#
|
9
|
-
# Implementation details
|
10
|
-
# ----------------------
|
11
|
-
#
|
12
|
-
# Ruby arrays are toll-free bridged to native javascript arrays, meaning
|
13
|
-
# that anywhere that a ruby array is required, a normal javascript array
|
14
|
-
# may be passed instead. The {Array} class infact makes use of a lot of
|
15
|
-
# the standard javascript functions on array prototypes to make its
|
16
|
-
# functionality as fast as possible.
|
17
|
-
#
|
18
|
-
# Due to the fact that arrays may be constructed in a javascript
|
19
|
-
# environment, and then passed through to a ruby method, Opal cannot
|
20
|
-
# guarantee that an array will not have a bad value. Bad values are
|
21
|
-
# those which ruby cannot send messages to, and therefore is an object
|
22
|
-
# that will raise an error when it is accessed by methods in {Array}, or
|
23
|
-
# any other object accessing an arrays elements. Bad values from
|
24
|
-
# javascript include the native `true`, `false`, `null` and `undefined`
|
25
|
-
# values from javascript, as well as any object literal.
|
26
|
-
#
|
27
|
-
# Ruby compatibility
|
28
|
-
# ------------------
|
29
|
-
#
|
30
|
-
# As instances of {Array} are actually javascript arrays, they can
|
31
|
-
# perform all the same functionality as Rubyspec defines arrays should.
|
32
|
-
# While not 100% of methods are currently implemented, the missing
|
33
|
-
# methods are being added quickly. All implemented methods are listed in
|
34
|
-
# this file. Any method that is only partially implemented also contains
|
35
|
-
# a list of restrictions in its description.
|
36
|
-
#
|
37
|
-
# The main area of partialy implemented methods are the enumerating
|
38
|
-
# methods like {#each}, {#each\_index} and {#reverse\_each}. Rubyspec
|
39
|
-
# defines that they should return an Enumerator if no block is passed to
|
40
|
-
# that method. Currently this does not happen, and `self` is returned
|
41
|
-
# with no side effects.
|
42
|
-
#
|
43
|
-
# Custom subclasses of {Array} may also be defined, and this is
|
44
|
-
# implemented in {.allocate}, when the array is created using {.new}.
|
45
|
-
# Internally a native javascript array is still used, but its class and
|
46
|
-
# method table are swizzled.
|
47
|
-
#
|
48
|
-
# Finally the {Array} class does not include the Enumerable module. Its
|
49
|
-
# methods are mostly implemented directly on the Array class. The
|
50
|
-
# Enumerable module will be added shortly, and the relevant methods
|
51
|
-
# moved back into that module.
|
52
1
|
class Array
|
2
|
+
# include Enumerable
|
53
3
|
|
54
4
|
# Returns a new array populated with the given objects.
|
55
5
|
#
|
@@ -57,24 +7,30 @@ class Array
|
|
57
7
|
#
|
58
8
|
# Array['a', 'b', 'c'] # => ['a', 'b', 'c']
|
59
9
|
#
|
60
|
-
# **FIXME** should support custom subclasses
|
61
|
-
#
|
62
10
|
# @param [Object] objs
|
63
11
|
# @return [Array]
|
64
12
|
def self.[](*objs)
|
65
|
-
|
13
|
+
`var ary = #{allocate};
|
14
|
+
ary.splice.apply(ary, [0, 0].concat(objs));
|
15
|
+
return ary;`
|
66
16
|
end
|
67
17
|
|
68
|
-
# **FIXME** should support custom subclasses
|
69
18
|
def self.allocate
|
70
|
-
[]
|
19
|
+
`var arr = [];
|
20
|
+
arr.$klass = self;
|
21
|
+
arr.$m = self.$m_tbl;
|
22
|
+
return arr;`
|
71
23
|
end
|
72
24
|
|
73
|
-
def initialize(
|
74
|
-
`
|
75
|
-
|
25
|
+
def initialize(len, fill = nil)
|
26
|
+
`var ary = self;
|
27
|
+
|
28
|
+
for (var i = 0; i < len; i++) {
|
29
|
+
ary[i] = fill;
|
76
30
|
}
|
77
31
|
|
32
|
+
ary.length = len;
|
33
|
+
|
78
34
|
return self;`
|
79
35
|
end
|
80
36
|
|
@@ -132,9 +88,7 @@ class Array
|
|
132
88
|
`return self.length;`
|
133
89
|
end
|
134
90
|
|
135
|
-
|
136
|
-
`return self.length;`
|
137
|
-
end
|
91
|
+
alias_method :size, :length
|
138
92
|
|
139
93
|
# Yields the block once for each element in `self`, passing that element as
|
140
94
|
# a parameter.
|
@@ -153,39 +107,23 @@ class Array
|
|
153
107
|
#
|
154
108
|
# @return [Array] returns the receiver
|
155
109
|
def each
|
156
|
-
|
157
|
-
try {
|
158
|
-
#{yield `self[i]`};
|
159
|
-
} catch (e) {
|
160
|
-
switch (e.$keyword) {
|
161
|
-
case 2:
|
162
|
-
return e.$value;
|
163
|
-
default:
|
164
|
-
throw e;
|
165
|
-
}
|
166
|
-
}
|
167
|
-
}
|
110
|
+
raise "Array#each no block given" unless block_given?
|
168
111
|
|
169
|
-
|
112
|
+
`for (var i = 0, len = self.length; i < len; i++) {`
|
113
|
+
yield `self[i]`
|
114
|
+
`}`
|
115
|
+
self
|
170
116
|
end
|
171
117
|
|
172
118
|
# Similar to {#each}, but also passes in the current element index to the
|
173
119
|
# block.
|
174
120
|
def each_with_index
|
175
|
-
|
176
|
-
try {
|
177
|
-
#{yield `self[i]`, `i`};
|
178
|
-
} catch (e) {
|
179
|
-
switch (e.$keyword) {
|
180
|
-
case 2:
|
181
|
-
return e.$value;
|
182
|
-
default:
|
183
|
-
throw e;
|
184
|
-
}
|
185
|
-
}
|
186
|
-
}
|
121
|
+
raise "Array#each_with_index no block given" unless block_given?
|
187
122
|
|
188
|
-
|
123
|
+
`for (var i = 0, len = self.length; i < len; i++) {
|
124
|
+
#{ yield `self[i]`, `i` };
|
125
|
+
}`
|
126
|
+
self
|
189
127
|
end
|
190
128
|
|
191
129
|
# Same as {#each}, but passes the index of the element instead of the
|
@@ -205,20 +143,12 @@ class Array
|
|
205
143
|
#
|
206
144
|
# @return [Array] returns receiver
|
207
145
|
def each_index
|
208
|
-
|
209
|
-
try {
|
210
|
-
#{yield `i`};
|
211
|
-
} catch (e) {
|
212
|
-
switch (e.$keyword) {
|
213
|
-
case 2:
|
214
|
-
return e.$value;
|
215
|
-
default:
|
216
|
-
throw e;
|
217
|
-
}
|
218
|
-
}
|
219
|
-
}
|
146
|
+
raise "Array#each_index no block given" unless block_given?
|
220
147
|
|
221
|
-
|
148
|
+
`for (var i = 0, len = self.length; i < len; i++) {`
|
149
|
+
yield `i`
|
150
|
+
`}`
|
151
|
+
self
|
222
152
|
end
|
223
153
|
|
224
154
|
# Append - pushes the given object(s) onto the end of this array. This
|
@@ -234,10 +164,9 @@ class Array
|
|
234
164
|
# @param [Object] obj the object(s) to push onto the array
|
235
165
|
# @return [Array] returns the receiver
|
236
166
|
def push(*objs)
|
237
|
-
`for (var i = 0,
|
167
|
+
`for (var i = 0, ii = objs.length; i < ii; i++) {
|
238
168
|
self.push(objs[i]);
|
239
169
|
}
|
240
|
-
|
241
170
|
return self;`
|
242
171
|
end
|
243
172
|
|
@@ -256,7 +185,7 @@ class Array
|
|
256
185
|
# @param [Object] obj the object to look for
|
257
186
|
# @return [Numeric, nil] result
|
258
187
|
def index(obj)
|
259
|
-
`for (var i = 0,
|
188
|
+
`for (var i = 0, len = self.length; i < len; i++) {
|
260
189
|
if (#{`self[i]` == obj}.$r) {
|
261
190
|
return i;
|
262
191
|
}
|
@@ -276,7 +205,7 @@ class Array
|
|
276
205
|
# @param [Array] other the array to concat with
|
277
206
|
# @return [Array] returns new concatenated array
|
278
207
|
def +(other)
|
279
|
-
`return self.concat(other);`
|
208
|
+
`return self.slice(0).concat(other.slice());`
|
280
209
|
end
|
281
210
|
|
282
211
|
# Difference. Creates a new array that is a copy of the original array,
|
@@ -392,19 +321,11 @@ class Array
|
|
392
321
|
def select
|
393
322
|
`var result = [], arg;
|
394
323
|
|
395
|
-
for (var i = 0
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
}
|
401
|
-
} catch (e) {
|
402
|
-
switch (e.$keyword) {
|
403
|
-
case 2:
|
404
|
-
return e.$value;
|
405
|
-
default:
|
406
|
-
throw e;
|
407
|
-
}
|
324
|
+
for (var i = 0, ii = self.length; i < ii; i++) {
|
325
|
+
arg = self[i];
|
326
|
+
|
327
|
+
if (#{yield `arg`}.$r) {
|
328
|
+
result.push(arg);
|
408
329
|
}
|
409
330
|
}
|
410
331
|
|
@@ -422,25 +343,18 @@ class Array
|
|
422
343
|
#
|
423
344
|
# @return [Array] new array
|
424
345
|
def collect
|
346
|
+
raise "Array#collect no block given" unless block_given?
|
347
|
+
|
425
348
|
`var result = [];
|
426
349
|
|
427
|
-
for (var i = 0
|
428
|
-
|
429
|
-
result.push(#{yield `self[i]`});
|
430
|
-
} catch (e) {
|
431
|
-
switch (e.$keyword) {
|
432
|
-
case 2:
|
433
|
-
return e.$value;
|
434
|
-
default:
|
435
|
-
throw e;
|
436
|
-
}
|
437
|
-
}
|
350
|
+
for (var i = 0, ii = self.length; i < ii; i++) {
|
351
|
+
result.push(#{ yield `self[i]` });
|
438
352
|
}
|
439
353
|
|
440
354
|
return result;`
|
441
355
|
end
|
442
356
|
|
443
|
-
|
357
|
+
alias_method :map, :collect
|
444
358
|
|
445
359
|
# Yields the block once for each element of `self`, replacing the element with
|
446
360
|
# the value returned by the block. See also `Enumerable#collect`.
|
@@ -455,17 +369,8 @@ class Array
|
|
455
369
|
#
|
456
370
|
# @return [Array] returns the receiver
|
457
371
|
def collect!
|
458
|
-
`for (var i = 0
|
459
|
-
|
460
|
-
self[i] = #{yield `self[i]`};
|
461
|
-
} catch (e) {
|
462
|
-
switch (e.$keyword) {
|
463
|
-
case 2:
|
464
|
-
return e.$value;
|
465
|
-
default:
|
466
|
-
throw e;
|
467
|
-
}
|
468
|
-
}
|
372
|
+
`for (var i = 0, ii = self.length; i < ii; i++) {
|
373
|
+
self[i] = #{yield `self[i]`};
|
469
374
|
}
|
470
375
|
|
471
376
|
return self;`
|
@@ -632,25 +537,17 @@ class Array
|
|
632
537
|
#
|
633
538
|
# @return [Array] returns amended receiver
|
634
539
|
def delete_if
|
635
|
-
`for (var i = 0
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
}
|
641
|
-
} catch (e) {
|
642
|
-
switch(e.$keyword) {
|
643
|
-
case 2:
|
644
|
-
return e.$value;
|
645
|
-
default:
|
646
|
-
throw e;
|
647
|
-
}
|
540
|
+
`for (var i = 0, ii = self.length; i < ii; i++) {
|
541
|
+
if (#{yield `self[i]`}.$r) {
|
542
|
+
self.splice(i, 1);
|
543
|
+
i--;
|
544
|
+
ii = self.length;
|
648
545
|
}
|
649
546
|
}
|
650
|
-
|
651
547
|
return self;`
|
652
548
|
end
|
653
549
|
|
550
|
+
|
654
551
|
# Drop first `n` elements from receiver, and returns remaining elements in
|
655
552
|
# array.
|
656
553
|
#
|
@@ -1013,7 +910,6 @@ class Array
|
|
1013
910
|
for (var i = 0; i < self.length; i++) {
|
1014
911
|
test = self[i];
|
1015
912
|
if (test.hasOwnProperty('length') && test[1] != undefined) {
|
1016
|
-
console.log("trying " + i);
|
1017
913
|
if (#{`test[1]` == obj}.$r) return test;
|
1018
914
|
}
|
1019
915
|
}
|
@@ -1127,17 +1023,10 @@ class Array
|
|
1127
1023
|
#
|
1128
1024
|
# @return [Array] returns the receiver
|
1129
1025
|
def reverse_each
|
1130
|
-
`
|
1131
|
-
|
1132
|
-
|
1133
|
-
}
|
1134
|
-
switch (e.$keyword) {
|
1135
|
-
case 2:
|
1136
|
-
return e['@exit_value'];
|
1137
|
-
default:
|
1138
|
-
throw e;
|
1139
|
-
}
|
1140
|
-
}
|
1026
|
+
`var ary = self, len = ary.length;
|
1027
|
+
|
1028
|
+
for (var i = len - 1; i >= 0; i--) {
|
1029
|
+
#{yield `ary[i]`};
|
1141
1030
|
}
|
1142
1031
|
|
1143
1032
|
return self;`
|
@@ -1295,23 +1184,14 @@ class Array
|
|
1295
1184
|
#
|
1296
1185
|
# @return [Array] new array with elements
|
1297
1186
|
def take_while
|
1298
|
-
`var result = [];
|
1299
|
-
|
1300
|
-
for (var i = 0; i < self.length; i++) {
|
1301
|
-
try {
|
1302
|
-
if (#{yield `self[i]`}.$r) {
|
1303
|
-
result.push(self[i]);
|
1304
|
-
} else {
|
1305
|
-
break;
|
1306
|
-
}
|
1307
|
-
} catch (e) {
|
1308
|
-
switch (e.$keyword) {
|
1309
|
-
case 2:
|
1310
|
-
return e['@exit_value'];
|
1187
|
+
`var result = [], arg;
|
1311
1188
|
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1189
|
+
for (var i = 0, ii = self.length; i < ii; i++) {
|
1190
|
+
arg = self[i];
|
1191
|
+
if (#{yield `arg`}.$r) {
|
1192
|
+
result.push(self[i]);
|
1193
|
+
} else {
|
1194
|
+
break;
|
1315
1195
|
}
|
1316
1196
|
}
|
1317
1197
|
|
@@ -1490,7 +1370,7 @@ class Array
|
|
1490
1370
|
# @param [Numeric] length last index
|
1491
1371
|
# @return [Array, Object, nil] result
|
1492
1372
|
def [](index, length = `undefined`)
|
1493
|
-
`var size =
|
1373
|
+
`var ary = self, size = ary.length;
|
1494
1374
|
|
1495
1375
|
if (index < 0) index += size;
|
1496
1376
|
|
@@ -1498,9 +1378,9 @@ class Array
|
|
1498
1378
|
|
1499
1379
|
if (length != undefined) {
|
1500
1380
|
if (length <= 0) return [];
|
1501
|
-
return
|
1381
|
+
return ary.slice(index, index + length);
|
1502
1382
|
} else {
|
1503
|
-
return
|
1383
|
+
return ary[index];
|
1504
1384
|
}`
|
1505
1385
|
end
|
1506
1386
|
|
@@ -1508,7 +1388,8 @@ class Array
|
|
1508
1388
|
#
|
1509
1389
|
# **TODO** need to expand functionlaity.
|
1510
1390
|
def []=(index, value)
|
1511
|
-
`
|
1391
|
+
`if (index < 0) index += self.length;
|
1392
|
+
return self[index] = value;`
|
1512
1393
|
end
|
1513
1394
|
end
|
1514
1395
|
|