opal 0.3.2 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
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