opal 0.3.2 → 0.3.6

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 (203) hide show
  1. data/README.md +85 -127
  2. data/bin/opal +3 -3
  3. data/lib/core.rb +114 -0
  4. data/{gems/core/lib → lib}/core/array.rb +68 -187
  5. data/{gems/core/lib → lib}/core/basic_object.rb +22 -5
  6. data/lib/core/class.rb +38 -0
  7. data/{gems/core/lib → lib}/core/dir.rb +1 -1
  8. data/lib/core/enumerable.rb +33 -0
  9. data/{gems/core/lib → lib}/core/error.rb +1 -4
  10. data/{gems/core/lib → lib}/core/false_class.rb +0 -0
  11. data/{gems/core/lib → lib}/core/file.rb +11 -3
  12. data/{gems/core/lib → lib}/core/hash.rb +12 -0
  13. data/{gems/core/lib → lib}/core/kernel.rb +114 -86
  14. data/lib/core/match_data.rb +33 -0
  15. data/lib/core/module.rb +97 -0
  16. data/{gems/core/lib → lib}/core/nil_class.rb +0 -0
  17. data/{gems/core/lib → lib}/core/numeric.rb +5 -0
  18. data/{gems/core/lib → lib}/core/object.rb +0 -0
  19. data/{gems/core/lib → lib}/core/proc.rb +13 -3
  20. data/{gems/core/lib → lib}/core/range.rb +10 -0
  21. data/{gems/core/lib → lib}/core/regexp.rb +33 -1
  22. data/{gems/core/lib → lib}/core/string.rb +25 -10
  23. data/{gems/core/lib → lib}/core/symbol.rb +3 -3
  24. data/{gems/core/lib → lib}/core/top_self.rb +0 -0
  25. data/{gems/core/lib → lib}/core/true_class.rb +0 -0
  26. data/lib/dev.rb +169 -0
  27. data/{gems/ospec/lib → lib}/ospec.rb +1 -0
  28. data/lib/ospec/autorun.rb +8 -0
  29. data/{gems/ospec/lib → lib}/ospec/dsl.rb +2 -2
  30. data/{gems/ospec/lib → lib}/ospec/example.rb +0 -0
  31. data/{gems/ospec/lib → lib}/ospec/example/before_and_after_hooks.rb +0 -0
  32. data/{gems/ospec/lib → lib}/ospec/example/errors.rb +0 -0
  33. data/{gems/ospec/lib → lib}/ospec/example/example_group.rb +0 -0
  34. data/{gems/ospec/lib → lib}/ospec/example/example_group_factory.rb +0 -3
  35. data/{gems/ospec/lib → lib}/ospec/example/example_group_hierarchy.rb +4 -3
  36. data/{gems/ospec/lib → lib}/ospec/example/example_group_methods.rb +1 -1
  37. data/{gems/ospec/lib → lib}/ospec/example/example_group_proxy.rb +3 -2
  38. data/{gems/ospec/lib → lib}/ospec/example/example_methods.rb +1 -1
  39. data/{gems/ospec/lib → lib}/ospec/example/example_proxy.rb +7 -7
  40. data/{gems/ospec/lib → lib}/ospec/expectations.rb +0 -0
  41. data/{gems/ospec/lib → lib}/ospec/expectations/errors.rb +0 -0
  42. data/{gems/ospec/lib → lib}/ospec/expectations/fail_with.rb +4 -3
  43. data/{gems/ospec/lib → lib}/ospec/expectations/handler.rb +6 -0
  44. data/lib/ospec/helpers/scratch.rb +18 -0
  45. data/{gems/ospec/lib → lib}/ospec/matchers.rb +2 -2
  46. data/{gems/ospec/lib → lib}/ospec/matchers/be.rb +0 -0
  47. data/{gems/ospec/lib → lib}/ospec/matchers/generated_descriptions.rb +0 -0
  48. data/{gems/ospec/lib → lib}/ospec/matchers/operator_matcher.rb +2 -0
  49. data/lib/ospec/matchers/raise_error.rb +38 -0
  50. data/lib/ospec/runner.rb +90 -0
  51. data/{gems/ospec/lib → lib}/ospec/runner/example_group_runner.rb +10 -13
  52. data/lib/ospec/runner/formatter/html_formatter.rb +139 -0
  53. data/{gems/ospec/lib → lib}/ospec/runner/formatter/terminal_formatter.rb +0 -0
  54. data/{gems/ospec/lib → lib}/ospec/runner/options.rb +1 -3
  55. data/{gems/ospec/lib → lib}/ospec/runner/reporter.rb +0 -9
  56. data/lib/racc/parser.rb +165 -0
  57. data/lib/strscan.rb +52 -0
  58. data/{lib → opal_lib}/opal.rb +2 -0
  59. data/opal_lib/opal/build_methods.rb +51 -0
  60. data/opal_lib/opal/builder.rb +164 -0
  61. data/opal_lib/opal/bundle.rb +70 -0
  62. data/opal_lib/opal/command.rb +68 -0
  63. data/{lib → opal_lib}/opal/context.rb +21 -9
  64. data/{lib → opal_lib}/opal/context/console.rb +0 -2
  65. data/opal_lib/opal/context/file_system.rb +34 -0
  66. data/{lib → opal_lib}/opal/context/loader.rb +26 -8
  67. data/opal_lib/opal/gem.rb +84 -0
  68. data/{lib → opal_lib}/opal/rake/builder_task.rb +2 -2
  69. data/opal_lib/opal/rake/spec_task.rb +32 -0
  70. data/{lib → opal_lib}/opal/ruby/nodes.rb +730 -109
  71. data/{lib → opal_lib}/opal/ruby/parser.rb +90 -23
  72. data/opal_lib/opal/ruby/ruby_parser.rb +4862 -0
  73. data/opal_lib/opal/ruby/ruby_parser.y +1454 -0
  74. data/opal_lib/opal/version.rb +4 -0
  75. data/runtime/class.js +359 -0
  76. data/runtime/debug.js +84 -0
  77. data/runtime/fs.js +199 -0
  78. data/runtime/init.js +558 -0
  79. data/runtime/loader.js +351 -0
  80. data/runtime/module.js +109 -0
  81. data/runtime/post.js +10 -0
  82. data/runtime/pre.js +7 -0
  83. data/runtime/runtime.js +351 -0
  84. metadata +88 -175
  85. data/.gitignore +0 -7
  86. data/Changelog +0 -31
  87. data/LICENSE +0 -75
  88. data/Rakefile +0 -86
  89. data/gems/core/README.md +0 -14
  90. data/gems/core/Rakefile +0 -8
  91. data/gems/core/core.gemspec +0 -13
  92. data/gems/core/lib/core.rb +0 -34
  93. data/gems/core/lib/core/class.rb +0 -31
  94. data/gems/core/lib/core/module.rb +0 -100
  95. data/gems/core/lib/core/vm.rb +0 -16
  96. data/gems/core/spec/core/array/append_spec.rb +0 -30
  97. data/gems/core/spec/core/array/assoc_spec.rb +0 -29
  98. data/gems/core/spec/core/array/at_spec.rb +0 -37
  99. data/gems/core/spec/core/array/clear_spec.rb +0 -22
  100. data/gems/core/spec/core/array/collect_bang_spec.rb +0 -27
  101. data/gems/core/spec/core/array/collect_spec.rb +0 -27
  102. data/gems/core/spec/core/array/compact_spec.rb +0 -41
  103. data/gems/core/spec/core/array/concat_spec.rb +0 -15
  104. data/gems/core/spec/core/array/constructor_spec.rb +0 -14
  105. data/gems/core/spec/core/array/each_spec.rb +0 -9
  106. data/gems/core/spec/core/array/element_reference_spec.rb +0 -4
  107. data/gems/core/spec/core/array/first_spec.rb +0 -35
  108. data/gems/core/spec/core/array/include_spec.rb +0 -9
  109. data/gems/core/spec/core/array/join_spec.rb +0 -6
  110. data/gems/core/spec/core/array/last_spec.rb +0 -51
  111. data/gems/core/spec/core/array/length_spec.rb +0 -6
  112. data/gems/core/spec/core/array/map_spec.rb +0 -33
  113. data/gems/core/spec/core/array/reverse_spec.rb +0 -6
  114. data/gems/core/spec/core/builtin_constants/builtin_constants_spec.rb +0 -7
  115. data/gems/core/spec/core/false/and_spec.rb +0 -10
  116. data/gems/core/spec/core/false/inspect_spec.rb +0 -6
  117. data/gems/core/spec/core/false/or_spec.rb +0 -10
  118. data/gems/core/spec/core/false/to_s_spec.rb +0 -6
  119. data/gems/core/spec/core/false/xor_spec.rb +0 -10
  120. data/gems/core/spec/core/file/join_spec.rb +0 -19
  121. data/gems/core/spec/core/hash/assoc_spec.rb +0 -32
  122. data/gems/core/spec/core/kernel/instance_eval_spec.rb +0 -0
  123. data/gems/core/spec/core/kernel/loop_spec.rb +0 -24
  124. data/gems/core/spec/core/kernel/raise_spec.rb +0 -0
  125. data/gems/core/spec/core/module/attr_accessor_spec.rb +0 -28
  126. data/gems/core/spec/core/number/lt_spec.rb +0 -12
  127. data/gems/core/spec/core/string/sub_spec.rb +0 -24
  128. data/gems/core/spec/core/true/and_spec.rb +0 -10
  129. data/gems/core/spec/core/true/inspect_spec.rb +0 -6
  130. data/gems/core/spec/core/true/or_spec.rb +0 -10
  131. data/gems/core/spec/core/true/to_s_spec.rb +0 -6
  132. data/gems/core/spec/core/true/xor_spec.rb +0 -10
  133. data/gems/core/spec/language/and_spec.rb +0 -61
  134. data/gems/core/spec/language/array_spec.rb +0 -68
  135. data/gems/core/spec/language/block_spec.rb +0 -38
  136. data/gems/core/spec/language/break_spec.rb +0 -36
  137. data/gems/core/spec/language/case_spec.rb +0 -103
  138. data/gems/core/spec/language/def_spec.rb +0 -21
  139. data/gems/core/spec/language/eigenclass_spec.rb +0 -60
  140. data/gems/core/spec/language/file_spec.rb +0 -13
  141. data/gems/core/spec/language/fixtures/block.rb +0 -21
  142. data/gems/core/spec/language/fixtures/super.rb +0 -293
  143. data/gems/core/spec/language/hash_spec.rb +0 -29
  144. data/gems/core/spec/language/if_spec.rb +0 -54
  145. data/gems/core/spec/language/loop_spec.rb +0 -11
  146. data/gems/core/spec/language/metaclass_spec.rb +0 -21
  147. data/gems/core/spec/language/method_spec.rb +0 -124
  148. data/gems/core/spec/language/next_spec.rb +0 -25
  149. data/gems/core/spec/language/or_spec.rb +0 -34
  150. data/gems/core/spec/language/redo_spec.rb +0 -24
  151. data/gems/core/spec/language/regexp_spec.rb +0 -26
  152. data/gems/core/spec/language/rescue_spec.rb +0 -20
  153. data/gems/core/spec/language/return_spec.rb +0 -47
  154. data/gems/core/spec/language/string_spec.rb +0 -25
  155. data/gems/core/spec/language/super_spec.rb +0 -32
  156. data/gems/core/spec/language/until_spec.rb +0 -157
  157. data/gems/core/spec/language/variables_spec.rb +0 -155
  158. data/gems/core/spec/language/while_spec.rb +0 -163
  159. data/gems/core/spec/spec_helper.rb +0 -5
  160. data/gems/core_fs/README.md +0 -19
  161. data/gems/dev/Rakefile +0 -5
  162. data/gems/dev/lib/dev.js +0 -99
  163. data/gems/dev/lib/dev/generator.js +0 -1264
  164. data/gems/dev/lib/dev/parser.js +0 -979
  165. data/gems/dev/lib/dev/ruby_parser.js +0 -1088
  166. data/gems/dev/lib/dev/ruby_parser.y +0 -1267
  167. data/gems/dev/lib/dev/string_scanner.js +0 -38
  168. data/gems/dev/tools/racc2js/README.md +0 -39
  169. data/gems/dev/tools/racc2js/math_parser.js +0 -222
  170. data/gems/dev/tools/racc2js/math_parser.rb +0 -133
  171. data/gems/dev/tools/racc2js/math_parser.y +0 -28
  172. data/gems/dev/tools/racc2js/parser.js +0 -218
  173. data/gems/dev/tools/racc2js/racc2js.rb +0 -153
  174. data/gems/json/README.md +0 -4
  175. data/gems/json/json.gemspec +0 -14
  176. data/gems/json/lib/json.rb +0 -64
  177. data/gems/json/lib/json/ext.rb +0 -51
  178. data/gems/json/lib/json/json2.js +0 -481
  179. data/gems/ospec/README.md +0 -0
  180. data/gems/ospec/lib/ospec/autorun.rb +0 -3
  181. data/gems/ospec/lib/ospec/runner.rb +0 -40
  182. data/gems/ospec/lib/ospec/runner/formatter/html_formatter.rb +0 -91
  183. data/gems/ospec/ospec.gemspec +0 -0
  184. data/gems/rquery/README.md +0 -9
  185. data/gems/rquery/lib/rquery.rb +0 -10
  186. data/gems/rquery/lib/rquery/ajax.rb +0 -4
  187. data/gems/rquery/lib/rquery/css.rb +0 -96
  188. data/gems/rquery/lib/rquery/document.rb +0 -25
  189. data/gems/rquery/lib/rquery/element.rb +0 -292
  190. data/gems/rquery/lib/rquery/event.rb +0 -108
  191. data/gems/rquery/lib/rquery/jquery.js +0 -8177
  192. data/gems/rquery/lib/rquery/request.rb +0 -138
  193. data/gems/rquery/lib/rquery/response.rb +0 -49
  194. data/gems/rquery/rquery.gemspec +0 -16
  195. data/lib/opal.js +0 -1597
  196. data/lib/opal/builder.rb +0 -117
  197. data/lib/opal/bundle.rb +0 -131
  198. data/lib/opal/command.rb +0 -11
  199. data/lib/opal/context/file_system.rb +0 -19
  200. data/lib/opal/gem.rb +0 -153
  201. data/lib/opal/ruby/ruby_parser.rb +0 -5170
  202. data/lib/opal/ruby/ruby_parser.y +0 -1298
  203. 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 ruby runtime and set of core libraries designed to run
12
- directly on top of javascript. It supports the gem packaging system for
13
- building ruby ready for the browser. It also uses therubyracer to
14
- provide a command line REPL and environment for running ruby server-side
15
- inside a javascript context.
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
- Opal is distributed as a gem, so install with:
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
- $ gem install opal
37
+ $ git clone git://github.com/adambeynon/opal.git
23
38
 
24
- Alternativley, you may just clone this git repo. No building is
25
- neccessary.
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
- The opal build tools can be used in three ways. As a simple repl, the
31
- bundler tasks and the simple build tasks.
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
- **1. opal Command-line tool**
59
+ ### Browser
34
60
 
35
- In its current form, the `opal` executable is very simple - it provides
36
- a simple ruby repl that uses therubyracer to provide an embedable
37
- javascript context. If you have installed the gem, to run the REPL,
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
- or if you have cloned this repository, type:
67
+ This will place a non minified version ready to run within the browser
68
+ into `extras/opal.js`
43
69
 
44
- $ bin/opal
70
+ #### Compiling ruby sources
45
71
 
46
- The REPL can be used like any other repl, and internally each command is
47
- being compiled into javascript, and run in the context which opal is
48
- already loaded into.
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
- **2. Builder Rake Task**
77
+ ### Command line
51
78
 
52
- To build simple ruby files (without a .gemspec) is to use the
53
- BuilderTask class in a rake file. This can be done by adding the
54
- following to a `Rakefile`:
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
- require 'opal'
83
+ #### Ruby repl
57
84
 
58
- Opal::Rake::BuilderTask.new do |t|
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
- When using the rake task, the `files` and `out` optional are usually
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
- $ rake opal
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
- The out file will now contain the compiled ruby code. Run this in a
73
- browser by including it into a html document, but make sure to include
74
- the latest `opal.js` file first.
92
+ Running tests
93
+ -------------
75
94
 
76
- **Main file**
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
- By default the builder task will automatically load the first listed
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
- Opal::Rake::BuilderTask.new do |t|
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
- **File watching**
104
+ $ rake opal_spec
89
105
 
90
- To save manually compiling each time you change a file, the `watch`
91
- option can be set to automatically recompile everytime a listed file is
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
- Opal::Rake::BuilderTask.new do |t|
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
- Built-in gems
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
- Opal uses gems as the main means of distributing and building code ready
104
- for the browser. Opal uses its own gem system, and cannot access gems
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
- lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
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.ruby_repl
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
- objs
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(*objs)
74
- `for (var i = 0, length = objs.length; i < length; i++) {
75
- self.push(objs[i]);
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
- def size
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
- `for (var i = 0, length = self.length; i < length; i++) {
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
- return self;`
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
- `for (var i = 0, length = self.length; i < length; i++) {
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
- return self;`
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
- `for (var i = 0, length = self.length; i < length; i++) {
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
- return self;`
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, length = objs.length; i < length; i++) {
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, length = self.length; i < length; i++) {
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; i < self.length; i++) {
396
- try {
397
- arg = self[i];
398
- if (#{yield `arg`}.$r) {
399
- result.push(arg);
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; i < self.length; i++) {
428
- try {
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
- # alias_method 'map', 'collect'
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; i < self.length; i++) {
459
- try {
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; i < self.length; i++) {
636
- try {
637
- if (#{yield `self[i]`}.$r) {
638
- self.splice(i, 1);
639
- i--;
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
- `for (var i = self.length - 1; i >= 0; i--) {
1131
- try {
1132
- #{yield `self[i]`};
1133
- } catch (e) {
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
- default:
1313
- throw e;
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 = self.length;
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 self.slice(index, index + length);
1381
+ return ary.slice(index, index + length);
1502
1382
  } else {
1503
- return self[index];
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
- `return self[index] = value;`
1391
+ `if (index < 0) index += self.length;
1392
+ return self[index] = value;`
1512
1393
  end
1513
1394
  end
1514
1395