opal 0.3.11 → 0.3.15

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 (282) hide show
  1. data/.gitignore +13 -0
  2. data/Gemfile +10 -0
  3. data/LICENSE +20 -0
  4. data/README.md +11 -116
  5. data/Rakefile +126 -0
  6. data/bin/opal +1 -2
  7. data/docs/spec_runner.html +16 -0
  8. data/index.html +434 -0
  9. data/lib/opal.rb +14 -15
  10. data/lib/opal/builder.rb +46 -148
  11. data/lib/opal/command.rb +45 -115
  12. data/lib/opal/context.rb +139 -78
  13. data/lib/opal/dependency_builder.rb +34 -0
  14. data/lib/opal/environment.rb +92 -0
  15. data/lib/opal/parser/grammar.rb +4915 -0
  16. data/lib/opal/{parser.y → parser/grammar.y} +430 -284
  17. data/lib/opal/parser/lexer.rb +1329 -0
  18. data/lib/opal/parser/parser.rb +1460 -0
  19. data/lib/opal/parser/scope.rb +140 -0
  20. data/lib/opal/parser/sexp.rb +17 -0
  21. data/lib/opal/version.rb +2 -1
  22. data/opal.gemspec +23 -0
  23. data/opal.js +3149 -4162
  24. data/runtime/README.md +25 -0
  25. data/runtime/corelib/alpha.rb +10 -0
  26. data/runtime/corelib/array.rb +962 -0
  27. data/runtime/corelib/basic_object.rb +66 -0
  28. data/runtime/corelib/boolean.rb +44 -0
  29. data/runtime/corelib/class.rb +43 -0
  30. data/runtime/corelib/comparable.rb +25 -0
  31. data/runtime/corelib/complex.rb +2 -0
  32. data/runtime/corelib/dir.rb +29 -0
  33. data/runtime/corelib/enumerable.rb +316 -0
  34. data/runtime/corelib/enumerator.rb +80 -0
  35. data/runtime/corelib/error.rb +25 -0
  36. data/runtime/corelib/file.rb +80 -0
  37. data/runtime/corelib/hash.rb +503 -0
  38. data/runtime/corelib/io.rb +44 -0
  39. data/runtime/corelib/kernel.rb +237 -0
  40. data/runtime/corelib/load_order +29 -0
  41. data/runtime/corelib/match_data.rb +37 -0
  42. data/runtime/corelib/module.rb +171 -0
  43. data/runtime/corelib/native.rb +50 -0
  44. data/runtime/corelib/nil_class.rb +47 -0
  45. data/runtime/corelib/numeric.rb +219 -0
  46. data/runtime/corelib/object.rb +21 -0
  47. data/runtime/corelib/proc.rb +42 -0
  48. data/runtime/corelib/range.rb +38 -0
  49. data/runtime/corelib/rational.rb +16 -0
  50. data/runtime/corelib/regexp.rb +63 -0
  51. data/runtime/corelib/string.rb +185 -0
  52. data/runtime/corelib/struct.rb +97 -0
  53. data/runtime/corelib/time.rb +196 -0
  54. data/runtime/corelib/top_self.rb +7 -0
  55. data/runtime/gemlib/alpha.rb +5 -0
  56. data/runtime/gemlib/kernel.rb +17 -0
  57. data/runtime/gemlib/load_order +2 -0
  58. data/runtime/kernel/class.js +256 -0
  59. data/runtime/kernel/debug.js +42 -0
  60. data/runtime/kernel/init.js +114 -0
  61. data/runtime/kernel/load_order +5 -0
  62. data/runtime/kernel/loader.js +151 -0
  63. data/runtime/kernel/runtime.js +414 -0
  64. data/runtime/spec/README.md +34 -0
  65. data/runtime/spec/core/array/allocate_spec.rb +15 -0
  66. data/runtime/spec/core/array/append_spec.rb +31 -0
  67. data/runtime/spec/core/array/assoc_spec.rb +29 -0
  68. data/runtime/spec/core/array/at_spec.rb +38 -0
  69. data/runtime/spec/core/array/clear_spec.rb +22 -0
  70. data/runtime/spec/core/array/collect_spec.rb +3 -0
  71. data/runtime/spec/core/array/compact_spec.rb +42 -0
  72. data/runtime/spec/core/array/concat_spec.rb +21 -0
  73. data/runtime/spec/core/array/constructor_spec.rb +24 -0
  74. data/runtime/spec/core/array/count_spec.rb +11 -0
  75. data/runtime/spec/core/array/delete_at_spec.rb +31 -0
  76. data/runtime/spec/core/array/delete_if_spec.rb +24 -0
  77. data/runtime/spec/core/array/delete_spec.rb +26 -0
  78. data/runtime/spec/core/array/each_index_spec.rb +33 -0
  79. data/runtime/spec/core/array/each_spec.rb +11 -0
  80. data/runtime/spec/core/array/element_reference_spec.rb +136 -0
  81. data/runtime/spec/core/array/element_set_spec.rb +7 -0
  82. data/runtime/spec/core/array/empty_spec.rb +10 -0
  83. data/runtime/spec/core/array/eql_spec.rb +3 -0
  84. data/runtime/spec/core/array/equal_value_spec.rb +3 -0
  85. data/runtime/spec/core/array/fetch_spec.rb +26 -0
  86. data/runtime/spec/core/array/first_spec.rb +54 -0
  87. data/runtime/spec/core/array/fixtures/classes.rb +8 -0
  88. data/runtime/spec/core/array/flatten_spec.rb +41 -0
  89. data/runtime/spec/core/array/include_spec.rb +20 -0
  90. data/runtime/spec/core/array/insert_spec.rb +59 -0
  91. data/runtime/spec/core/array/last_spec.rb +57 -0
  92. data/runtime/spec/core/array/length_spec.rb +3 -0
  93. data/runtime/spec/core/array/map_spec.rb +3 -0
  94. data/runtime/spec/core/array/plus_spec.rb +16 -0
  95. data/runtime/spec/core/array/pop_spec.rb +79 -0
  96. data/runtime/spec/core/array/push_spec.rb +19 -0
  97. data/runtime/spec/core/array/rassoc_spec.rb +12 -0
  98. data/runtime/spec/core/array/reject_spec.rb +54 -0
  99. data/runtime/spec/core/array/replace_spec.rb +3 -0
  100. data/runtime/spec/core/array/reverse_each_spec.rb +18 -0
  101. data/runtime/spec/core/array/reverse_spec.rb +9 -0
  102. data/runtime/spec/core/array/shared/collect.rb +53 -0
  103. data/runtime/spec/core/array/shared/eql.rb +19 -0
  104. data/runtime/spec/core/array/shared/length.rb +6 -0
  105. data/runtime/spec/core/array/shared/replace.rb +31 -0
  106. data/runtime/spec/core/class/new_spec.rb +19 -0
  107. data/runtime/spec/core/enumerable/all_spec.rb +102 -0
  108. data/runtime/spec/core/enumerable/any_spec.rb +115 -0
  109. data/runtime/spec/core/enumerable/collect_spec.rb +3 -0
  110. data/runtime/spec/core/enumerable/count_spec.rb +29 -0
  111. data/runtime/spec/core/enumerable/detect_spec.rb +3 -0
  112. data/runtime/spec/core/enumerable/find_spec.rb +3 -0
  113. data/runtime/spec/core/enumerable/fixtures/classes.rb +26 -0
  114. data/runtime/spec/core/enumerable/shared/collect.rb +12 -0
  115. data/runtime/spec/core/enumerable/shared/entries.rb +7 -0
  116. data/runtime/spec/core/enumerable/shared/find.rb +49 -0
  117. data/runtime/spec/core/enumerable/to_a_spec.rb +7 -0
  118. data/runtime/spec/core/false/and_spec.rb +11 -0
  119. data/runtime/spec/core/false/inspect_spec.rb +7 -0
  120. data/runtime/spec/core/false/or_spec.rb +11 -0
  121. data/runtime/spec/core/false/to_s_spec.rb +7 -0
  122. data/runtime/spec/core/false/xor_spec.rb +11 -0
  123. data/runtime/spec/core/hash/allocate_spec.rb +15 -0
  124. data/runtime/spec/core/hash/assoc_spec.rb +29 -0
  125. data/runtime/spec/core/hash/clear_spec.rb +21 -0
  126. data/runtime/spec/core/hash/clone_spec.rb +12 -0
  127. data/runtime/spec/core/hash/default_spec.rb +6 -0
  128. data/runtime/spec/core/hash/delete_if_spec.rb +15 -0
  129. data/runtime/spec/core/hash/element_reference_spec.rb +16 -0
  130. data/runtime/spec/core/hash/element_set_spec.rb +8 -0
  131. data/runtime/spec/core/hash/new_spec.rb +13 -0
  132. data/runtime/spec/core/matchdata/to_a_spec.rb +7 -0
  133. data/runtime/spec/core/nil/and_spec.rb +12 -0
  134. data/runtime/spec/core/nil/inspect_spec.rb +8 -0
  135. data/runtime/spec/core/nil/nil_spec.rb +8 -0
  136. data/runtime/spec/core/nil/or_spec.rb +12 -0
  137. data/runtime/spec/core/nil/to_a_spec.rb +8 -0
  138. data/runtime/spec/core/nil/to_f_spec.rb +12 -0
  139. data/runtime/spec/core/nil/to_i_spec.rb +12 -0
  140. data/runtime/spec/core/nil/to_s_spec.rb +8 -0
  141. data/runtime/spec/core/nil/xor_spec.rb +12 -0
  142. data/runtime/spec/core/numeric/equal_value_spec.rb +11 -0
  143. data/runtime/spec/core/object/is_a_spec.rb +2 -0
  144. data/runtime/spec/core/object/shared/kind_of.rb +0 -0
  145. data/runtime/spec/core/regexp/match_spec.rb +23 -0
  146. data/runtime/spec/core/regexp/shared/match.rb +11 -0
  147. data/runtime/spec/core/symbol/to_proc_spec.rb +8 -0
  148. data/runtime/spec/core/true/and_spec.rb +11 -0
  149. data/runtime/spec/core/true/inspect_spec.rb +7 -0
  150. data/runtime/spec/core/true/or_spec.rb +11 -0
  151. data/runtime/spec/core/true/to_s_spec.rb +7 -0
  152. data/runtime/spec/core/true/xor_spec.rb +11 -0
  153. data/runtime/spec/language/alias_spec.rb +25 -0
  154. data/runtime/spec/language/and_spec.rb +62 -0
  155. data/runtime/spec/language/array_spec.rb +68 -0
  156. data/runtime/spec/language/block_spec.rb +105 -0
  157. data/runtime/spec/language/break_spec.rb +49 -0
  158. data/runtime/spec/language/case_spec.rb +165 -0
  159. data/runtime/spec/language/defined_spec.rb +80 -0
  160. data/runtime/spec/language/ensure_spec.rb +82 -0
  161. data/runtime/spec/language/fixtures/block.rb +19 -0
  162. data/runtime/spec/language/fixtures/break.rb +39 -0
  163. data/runtime/spec/language/fixtures/defined.rb +9 -0
  164. data/runtime/spec/language/fixtures/ensure.rb +37 -0
  165. data/runtime/spec/language/fixtures/next.rb +46 -0
  166. data/runtime/spec/language/fixtures/send.rb +36 -0
  167. data/runtime/spec/language/fixtures/super.rb +43 -0
  168. data/runtime/spec/language/hash_spec.rb +43 -0
  169. data/runtime/spec/language/if_spec.rb +278 -0
  170. data/runtime/spec/language/loop_spec.rb +32 -0
  171. data/runtime/spec/language/next_spec.rb +128 -0
  172. data/runtime/spec/language/or_spec.rb +65 -0
  173. data/runtime/spec/language/predefined_spec.rb +21 -0
  174. data/runtime/spec/language/regexp/interpolation_spec.rb +9 -0
  175. data/runtime/spec/language/regexp_spec.rb +7 -0
  176. data/runtime/spec/language/send_spec.rb +105 -0
  177. data/runtime/spec/language/string_spec.rb +4 -0
  178. data/runtime/spec/language/super_spec.rb +18 -0
  179. data/runtime/spec/language/symbol_spec.rb +41 -0
  180. data/runtime/spec/language/undef_spec.rb +16 -0
  181. data/runtime/spec/language/unless_spec.rb +44 -0
  182. data/runtime/spec/language/until_spec.rb +137 -0
  183. data/runtime/spec/language/variables_spec.rb +28 -0
  184. data/runtime/spec/language/versions/hash_1.9.rb +20 -0
  185. data/runtime/spec/language/while_spec.rb +175 -0
  186. data/runtime/spec/library/stringscanner/scan_spec.rb +36 -0
  187. data/runtime/spec/opal/forwardable/def_instance_delegator_spec.rb +49 -0
  188. data/runtime/spec/opal/opal/defined_spec.rb +15 -0
  189. data/runtime/spec/opal/opal/function_spec.rb +11 -0
  190. data/runtime/spec/opal/opal/native_spec.rb +16 -0
  191. data/runtime/spec/opal/opal/null_spec.rb +10 -0
  192. data/runtime/spec/opal/opal/number_spec.rb +11 -0
  193. data/runtime/spec/opal/opal/object_spec.rb +16 -0
  194. data/runtime/spec/opal/opal/string_spec.rb +11 -0
  195. data/runtime/spec/opal/opal/typeof_spec.rb +9 -0
  196. data/runtime/spec/opal/opal/undefined_spec.rb +10 -0
  197. data/runtime/spec/opal/true/case_compare_spec.rb +12 -0
  198. data/runtime/spec/opal/true/class_spec.rb +10 -0
  199. data/runtime/spec/spec_helper.rb +25 -0
  200. data/runtime/stdlib/base64.rb +91 -0
  201. data/runtime/stdlib/date.rb +4 -0
  202. data/{stdlib → runtime/stdlib}/dev.rb +0 -0
  203. data/runtime/stdlib/forwardable.rb +33 -0
  204. data/runtime/stdlib/optparse.rb +0 -0
  205. data/runtime/stdlib/pp.rb +6 -0
  206. data/{stdlib → runtime/stdlib}/racc/parser.rb +0 -0
  207. data/runtime/stdlib/rbconfig.rb +0 -0
  208. data/runtime/stdlib/si.rb +17 -0
  209. data/runtime/stdlib/strscan.rb +53 -0
  210. data/runtime/stdlib/uri.rb +111 -0
  211. data/runtime/stdlib/uri/common.rb +1014 -0
  212. data/runtime/stdlib/uri/ftp.rb +261 -0
  213. data/runtime/stdlib/uri/generic.rb +1599 -0
  214. data/runtime/stdlib/uri/http.rb +106 -0
  215. data/runtime/stdlib/uri/https.rb +22 -0
  216. data/runtime/stdlib/uri/ldap.rb +260 -0
  217. data/runtime/stdlib/uri/ldaps.rb +20 -0
  218. data/runtime/stdlib/uri/mailto.rb +280 -0
  219. data/spec/builder/build_source_spec.rb +52 -0
  220. data/spec/builder/fixtures/build_source/adam.rb +0 -0
  221. data/spec/builder/fixtures/build_source/bar/a.rb +0 -0
  222. data/spec/builder/fixtures/build_source/bar/wow/b.rb +0 -0
  223. data/spec/builder/fixtures/build_source/bar/wow/cow/c.rb +0 -0
  224. data/spec/builder/fixtures/build_source/beynon.rb +0 -0
  225. data/spec/builder/fixtures/build_source/charles.js +0 -0
  226. data/spec/builder/fixtures/build_source/foo/a.rb +0 -0
  227. data/spec/builder/fixtures/build_source/foo/b.rb +0 -0
  228. data/spec/builder/fixtures/build_source/foo/x.js +0 -0
  229. data/spec/builder/fixtures/build_source/foo/y.js +0 -0
  230. data/spec/builder/output_path_spec.rb +50 -0
  231. data/spec/grammar/alias_spec.rb +26 -0
  232. data/spec/grammar/and_spec.rb +13 -0
  233. data/spec/grammar/array_spec.rb +22 -0
  234. data/spec/grammar/attrasgn_spec.rb +28 -0
  235. data/spec/grammar/begin_spec.rb +38 -0
  236. data/spec/grammar/block_spec.rb +12 -0
  237. data/spec/grammar/break_spec.rb +17 -0
  238. data/spec/grammar/call_spec.rb +58 -0
  239. data/spec/grammar/class_spec.rb +35 -0
  240. data/spec/grammar/const_spec.rb +13 -0
  241. data/spec/grammar/cvar_spec.rb +11 -0
  242. data/spec/grammar/def_spec.rb +60 -0
  243. data/spec/grammar/false_spec.rb +17 -0
  244. data/spec/grammar/file_spec.rb +7 -0
  245. data/spec/grammar/gvar_spec.rb +13 -0
  246. data/spec/grammar/hash_spec.rb +17 -0
  247. data/spec/grammar/iasgn_spec.rb +9 -0
  248. data/spec/grammar/if_spec.rb +26 -0
  249. data/spec/grammar/iter_spec.rb +59 -0
  250. data/spec/grammar/ivar_spec.rb +9 -0
  251. data/spec/grammar/lasgn_spec.rb +8 -0
  252. data/spec/grammar/line_spec.rb +8 -0
  253. data/spec/grammar/lvar_spec.rb +38 -0
  254. data/spec/grammar/module_spec.rb +27 -0
  255. data/spec/grammar/nil_spec.rb +17 -0
  256. data/spec/grammar/not_spec.rb +27 -0
  257. data/spec/grammar/op_asgn1_spec.rb +23 -0
  258. data/spec/grammar/op_asgn2_spec.rb +23 -0
  259. data/spec/grammar/or_spec.rb +13 -0
  260. data/spec/grammar/return_spec.rb +17 -0
  261. data/spec/grammar/sclass_spec.rb +20 -0
  262. data/spec/grammar/self_spec.rb +17 -0
  263. data/spec/grammar/str_spec.rb +96 -0
  264. data/spec/grammar/super_spec.rb +20 -0
  265. data/spec/grammar/true_spec.rb +17 -0
  266. data/spec/grammar/undef_spec.rb +15 -0
  267. data/spec/grammar/unless_spec.rb +13 -0
  268. data/spec/grammar/while_spec.rb +15 -0
  269. data/spec/grammar/xstr_spec.rb +116 -0
  270. data/spec/grammar/yield_spec.rb +20 -0
  271. data/spec/spec_helper.rb +9 -0
  272. metadata +346 -21
  273. data/lib/opal/bundle.rb +0 -34
  274. data/lib/opal/lexer.rb +0 -902
  275. data/lib/opal/nodes.rb +0 -2150
  276. data/lib/opal/parser.rb +0 -4894
  277. data/lib/opal/rake/bundle_task.rb +0 -63
  278. data/opal-parser.js +0 -8343
  279. data/stdlib/strscan.rb +0 -52
  280. data/templates/init/Rakefile +0 -7
  281. data/templates/init/index.html +0 -17
  282. data/templates/init/lib/__NAME__.rb +0 -2
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ .DS_Store
2
+ doc
3
+ /tmp
4
+ *.gem
5
+ .yardoc
6
+ /vendor
7
+ .bundle
8
+ Gemfile.lock
9
+ pkg/*
10
+ /runtime/*.js
11
+ /*.js
12
+ /docs/_site
13
+ /gh-pages
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source :rubygems
2
+
3
+ # Specify your gem's dependencies in opal.gemspec
4
+ gemspec
5
+
6
+ gem "rake"
7
+
8
+ group :test do
9
+ gem "opal-spec"
10
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (C) 2011 by Adam Beynon
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
20
+
data/README.md CHANGED
@@ -1,122 +1,17 @@
1
1
  Opal
2
2
  ====
3
3
 
4
- Opal is a partial implementation of ruby designed to run in any
5
- javascript environment. The runtime is written in javascript, with all
6
- core libraries written directly in ruby with inline javascript to make
7
- them as fast as possible.
4
+ Opal is a ruby to javascript compiler. Opal aims to take ruby files and generate
5
+ efficient javascript that maintains rubys features. Opal will, by default,
6
+ generate fast and efficient code in preference to keeping all ruby features.
8
7
 
9
- Wherever possible ruby objects are mapped directly onto their native
10
- javascript counterparts to speed up the generated code and to improve
11
- interopability with existing javascript libraries.
8
+ Opal comes with an implementation of the ruby corelib, written in ruby, that
9
+ uses a bundled runtime (written in javascript) that tie all the features
10
+ together. Whenever possible Opal bridges to native javascript features under
11
+ the hood. The Opal gem includes the compiler used to convert ruby sources
12
+ into javascript.
12
13
 
13
- The opal compiler is a source-to-source compiler which outputs
14
- javascript which can then run on the core runtime.
15
-
16
- Opal does not aim to be 100% comaptible with other ruby implementations,
17
- but does so where the generated code can be efficient on all modern web
18
- browsers - including older versions of IE and mobile devices.
19
-
20
- Installing opal
21
- ----------
22
-
23
- Install the gem:
24
-
25
- ```
26
- $ gem install opal
27
- ```
28
-
29
- The `opal` command should then be available. To run the simple repl use:
30
-
31
- ```
32
- opal irb
33
- ```
34
-
35
- Usage
36
- -----
37
-
38
- The quickest way to get opal running is to use the project generator.
39
- Simply run the command:
40
-
41
- ```
42
- opal init my_project
43
- ```
44
-
45
- replacing "my_project" with any name. This will make a "my_project"
46
- directory with a Rakefile, html document and libs needed for running
47
- opal in the browser.
48
-
49
- ### Using opal in the browser
50
-
51
- Opal runs directly in the browser, and is distributed as two files,
52
- `opal.js` and `opal-parser.js`. To just run precompiled code, just the
53
- `opal.js` runtime is required which includes the runtime and opals
54
- implementation of the ruby core library (pre compiled).
55
-
56
- To evaluate ruby code directly in the browser, `opal-parser.js` is also
57
- required which will also load any ruby code found in script tags.
58
-
59
- ### Bundle
60
-
61
- The Rakefile has a task to build your ruby project, so just run:
62
-
63
- ```
64
- rake bundle
65
- ```
66
-
67
- Open `index.html` in a browser, and now it should run. Edit, build and
68
- run to suit.
69
-
70
- Project structure
71
- -----------------
72
-
73
- This repo contains the code for the opal gem as well as the opal core
74
- library and runtime. Files inside `bin/` and `lib/` are the files that
75
- are used as part of the gem and run directly on your ruby environment.
76
-
77
- `corelib/` contains opal's core library implementation and is not used
78
- directly by the gem. These files are precompiled during development
79
- ready to be used in the gem or in a browser.
80
-
81
- `runtime/` contains opal's runtime written in javascript. It is not used
82
- directly by the gem, but is built ready to use in the js contexts that
83
- opal runs.
84
-
85
- `stdlib/` contains the stdlib files that opal comes packaged with. The
86
- gem does use these, but only as required. Opal does not include the full
87
- opal stdlib, and some parts are actually written in javascript for
88
- optimal performance. These can be `require()` at runtime.
89
-
90
- `opal.js` and `opal-parser.js` are included in the gem, but not the
91
- source repo. They are the latest built versions of opal and its parser
92
- which are built before the gem is published.
93
-
94
- Differences from ruby
95
- ---------------------
96
-
97
- ### Optional method\_missing
98
-
99
- To optimize method dispatch, `method_missing` is, by default, turned off
100
- in opal. It can easily be enabled by passing `:method_missing => true`
101
- in the parser options.
102
-
103
- ### Immutable strings and removed symbols
104
-
105
- All strings in opal are immutable to make them easier to map onto
106
- javascript strings. In opal a ruby string compiles directly into a js
107
- string without a wrapper so that they can be passed back between code
108
- bases easily. Also, symbol syntax is maintained, but all symbols just
109
- compile into javascript strings. The `Symbol` class is also therefore
110
- removed.
111
-
112
- ### Unified Numeric class
113
-
114
- All numbers in opal are members of the `Numeric` class. The `Integer`
115
- and `Float` classes are removed.
116
-
117
- ### Unified Boolean class
118
-
119
- Both `true` and `false` compile into their native javascript
120
- counterparts which means that they both become instances of the
121
- `Boolean` class and opal removes the `TrueClass` and `FalseClass`.
14
+ For docs, visit the website:
15
+ [http://adambeynon.github.com/opal](http://adambeynon.github.com/opal)
122
16
 
17
+ Join the IRC channel on Freenode: `#opal`.
data/Rakefile ADDED
@@ -0,0 +1,126 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'opal'
4
+ require 'fileutils'
5
+ require 'opal/version'
6
+
7
+ namespace :browser do
8
+ desc "Build opal runtime to opal.js"
9
+ task :opal do
10
+ File.open("opal.js", 'w+') { |o| o.write build_runtime false }
11
+ end
12
+
13
+ desc "Build opal debug runtime to opal.debug.js"
14
+ task :debug do
15
+ File.open("opal.debug.js", 'w+') { |o| o.write build_runtime true }
16
+ end
17
+
18
+ desc "Tests for browser to opal.test.js"
19
+ task :test do
20
+ Opal::Builder.new('runtime/spec', :join => 'opal.test.js').build
21
+ end
22
+
23
+ desc "Build dependencies into runtime/"
24
+ task :dependencies do
25
+ Opal::DependencyBuilder.new(:out => 'runtime').build
26
+ end
27
+ end
28
+
29
+ desc "Build opal and debug opal into runtime/"
30
+ task :browser => [:'browser:opal', :'browser:debug']
31
+
32
+ desc "Run opal specs (from runtime/spec/*)"
33
+ task :test => :browser do
34
+ Opal::Context.runner 'runtime/spec/**/*.rb'
35
+ end
36
+
37
+ desc "Check file sizes for core builds"
38
+ task :sizes do
39
+ sizes 'runtime/opal.js'
40
+ sizes 'runtime/opal.debug.js'
41
+ end
42
+
43
+ desc "Rebuild grammar.rb for opal parser"
44
+ task :parser do
45
+ %x(racc -l lib/opal/parser/grammar.y -o lib/opal/parser/grammar.rb)
46
+ end
47
+
48
+ namespace :docs do
49
+ task :clone do
50
+ if File.exists? 'gh-pages'
51
+ Dir.chdir('gh-pages') { sh 'git pull origin gh-pages' }
52
+ else
53
+ FileUtils.mkdir_p 'gh-pages'
54
+ Dir.chdir('gh-pages') do
55
+ sh 'git clone git@github.com:/adambeynon/opal.git .'
56
+ sh 'git checkout gh-pages'
57
+ end
58
+ end
59
+ end
60
+
61
+ desc "Copy required files into gh-pages dir"
62
+ task :copy => :browser do
63
+ %w[opal.js opal.debug.js index.html].each do |f|
64
+ FileUtils.cp f, "gh-pages/#{f}"
65
+ end
66
+ end
67
+ end
68
+
69
+ HEADER = <<-HEADER
70
+ /*!
71
+ * opal v#{Opal::VERSION}
72
+ * http://adambeynon.github.com/opal
73
+ *
74
+ * Copyright 2012, Adam Beynon
75
+ * Released under the MIT license
76
+ */
77
+ HEADER
78
+
79
+ def build_runtime debug = false
80
+ rborder = File.read('runtime/corelib/load_order').strip.split
81
+ rbcore = rborder.map { |c| File.read "runtime/corelib/#{c}.rb" }
82
+ jsorder = File.read('runtime/kernel/load_order').strip.split
83
+ jscore = jsorder.map { |c| File.read "runtime/kernel/#{c}.js" }
84
+
85
+ parser = Opal::Parser.new :debug => debug
86
+ parsed = parser.parse rbcore.join("\n"), '(corelib)'
87
+ methods = Opal::Parser::METHOD_NAMES.map { |f, t| "'#{f}': 'm$#{t}$'" }
88
+ result = []
89
+
90
+ result << '(function(undefined) {'
91
+ result << jscore.join
92
+ result << "var method_names = {#{methods.join ', '}};"
93
+ result << "var reverse_method_names = {}; for (var id in method_names) {"
94
+ result << "reverse_method_names[method_names[id]] = id;}"
95
+ result << parsed
96
+ result << '}).call(this);'
97
+
98
+ HEADER + result.join("\n")
99
+ end
100
+
101
+ def sizes file
102
+ o = File.read file
103
+ m = uglify o
104
+ g = gzip m
105
+
106
+ puts "#{file}:"
107
+ puts "development: #{o.size}, minified: #{m.size}, gzipped: #{g.size}"
108
+ end
109
+
110
+ # Used for uglifying source to minify
111
+ def uglify(str)
112
+ IO.popen('uglifyjs -nc', 'r+') do |i|
113
+ i.puts str
114
+ i.close_write
115
+ return i.read
116
+ end
117
+ end
118
+
119
+ # Gzip code to check file size
120
+ def gzip(str)
121
+ IO.popen('gzip -f', 'r+') do |i|
122
+ i.puts str
123
+ i.close_write
124
+ return i.read
125
+ end
126
+ end
data/bin/opal CHANGED
@@ -1,7 +1,6 @@
1
- #!/usr/bin/env ruby
1
+ #! /usr/bin/env ruby
2
2
 
3
3
  require 'opal'
4
4
  require 'opal/command'
5
5
 
6
6
  Opal::Command.new ARGV
7
-
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
5
+
6
+ <title>Opal Spec Runner</title>
7
+ </head>
8
+ <body>
9
+ <script src="../opal.debug.js"></script>
10
+ <script src="../opal-spec.js"></script>
11
+ <script src="../opal.test.js"></script>
12
+ <script>
13
+ opal.main('/runtime/spec/spec_helper.rb');
14
+ </script>
15
+ </body>
16
+ </html>
data/index.html ADDED
@@ -0,0 +1,434 @@
1
+ <!DOCTYPE HTML>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
5
+
6
+ <title>Opal</title>
7
+ <style>
8
+ body {
9
+ line-height: 22px;
10
+ font-size: 14px;
11
+ font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
12
+ }
13
+
14
+ .content {
15
+ padding: 50px 50px 50px 50px;
16
+ width: 650px;
17
+ }
18
+
19
+ p {
20
+ width: 650px;
21
+ }
22
+
23
+ pre, code {
24
+ font-family: "Bitstream Vera Sans Mono", Monaco, "Lucida Console", monospace;
25
+ font-size: 12px;
26
+ }
27
+
28
+ pre {
29
+ line-height: 17px;
30
+ color: #444444;
31
+ white-space: pre;
32
+ padding: 3px 0px 3px 12px;
33
+ margin: 0px 0px 8px;
34
+
35
+ background: #FAFAFA;
36
+ -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
37
+ -webkit-border-radius: 3px;
38
+ -moz-border-radius: 3px;
39
+ border-radius: 3px;
40
+ border: 1px solid #DDDDDD;
41
+ }
42
+
43
+ code {
44
+ background-color: #FAFAFA;
45
+ padding: 1px;
46
+ color: #444444;
47
+ border: 1px solid #DEDEDE;
48
+ }
49
+
50
+ pre code {
51
+ border: none;
52
+ padding: 0px;
53
+ }
54
+
55
+ a {
56
+ color: #212121;
57
+ }
58
+ </style>
59
+ </head>
60
+ <body>
61
+ <div class="content">
62
+ <h1 id='opal'>Opal</h1>
63
+
64
+ <p>
65
+ <strong>Opal is a ruby to javascript compiler</strong>. Opal aims to
66
+ take ruby files and generate efficient javascript that maintains rubys
67
+ features. Opal will, by default, generate fast and efficient code in
68
+ preference to keeping all ruby features.
69
+ </p>
70
+
71
+ <p>
72
+ Opal comes with an implementation of the ruby corelib, written in ruby,
73
+ that uses a bundled runtime (written in javascript) that tie all the
74
+ features together. Whenever possible Opal bridges to native javascript
75
+ features under the hood. The Opal gem includes the compiler used to
76
+ convert ruby sources into javascript.
77
+ </p>
78
+
79
+ <p>
80
+ Opal is <a href='http://github.com/adambeynon/opal'>hosted on github</a>,
81
+ and there is a Freenode IRC channel at <code>#opal</code>.
82
+ </p>
83
+
84
+ <h2 id='downloads'>Downloads</h2>
85
+
86
+ <p>
87
+ The Opal runtime and corelib are distributed here, and are required to
88
+ run any code generated by opal.
89
+ </p>
90
+
91
+ <p>
92
+ <strong>Production</strong> version to be used in real apps/sites.
93
+ </p>
94
+
95
+ <p>
96
+ <a href='http://adambeynon.github.com/opal/opal.js'>
97
+ Production version 0.3.15
98
+ </a>
99
+ <em>(120kb Uncompressed, 13.7kb Minified And Gzipped)</em>
100
+ </p>
101
+
102
+ <p>
103
+ <strong>Debug</strong> version adds a lot of additional debug code.
104
+ See the debug section below.
105
+ </p>
106
+
107
+ <p>
108
+ <a href='http://adambeynon.github.com/opal/opal.debug.js'>
109
+ Debug version 0.3.15
110
+ </a>
111
+ <em>(183kb Uncompressed)</em>
112
+ </p>
113
+
114
+ <h2 id='installation'>Installation</h2>
115
+
116
+ <p>Opal comes distributed as a gem, so either install with:</p>
117
+
118
+ <pre><code>gem install opal</code></pre>
119
+
120
+ <p>Or add to your Gemfile:</p>
121
+
122
+ <pre><code>gem &quot;opal&quot;</code></pre>
123
+
124
+ <h2 id='usage'>Usage</h2>
125
+
126
+ <p>
127
+ Opal provides an <code>opal</code> command which can be used to
128
+ compile ruby sources into javascript. These can then be used in
129
+ any browser/javascript environment. Opal also comes with the
130
+ ability to run files direcly using
131
+ <a href='http://github.com/cowboyd/therubyracer'>therubyracer</a>,
132
+ which is a gem to embed v8 into ruby. This also allows Opal to provide
133
+ a REPL to run ruby code directly against the Opal runtime.
134
+ </p>
135
+
136
+ <h3 id='repl'>REPL</h3>
137
+
138
+ <p>To run the ruby repl, simply run:</p>
139
+
140
+ <pre><code>opal</code></pre>
141
+
142
+ <p>from the command line. To exit, type <code>exit</code>.</p>
143
+
144
+ <h3 id='running_a_ruby_file'>Running a ruby file</h3>
145
+
146
+ <p>
147
+ Opal can compile/eval any ruby file inside the v8 context by simply
148
+ passing a path to run:
149
+ </p>
150
+
151
+ <pre><code>opal path/to/file.rb</code></pre>
152
+
153
+ <p>Try running some code with <code>puts</code> statements.</p>
154
+
155
+ <h3 id='compiling_ruby_sources'>Compiling Ruby Sources</h3>
156
+
157
+ <p>If you have a ruby source <code>foo.rb</code>:</p>
158
+
159
+ <pre>
160
+ # foo.rb
161
+
162
+ puts "Wow, running ruby"
163
+ </pre>
164
+
165
+ <p>Compile it into <code>foo.js</code> using:</p>
166
+
167
+ <pre>
168
+ opal -c foo.rb
169
+ </pre>
170
+
171
+ <p>
172
+ The generated code includes a wrapper which will register the
173
+ file with opal. Opal maintains an internal file system to make
174
+ <code>require()</code> work as expected. You will see this in
175
+ the output:
176
+ </p>
177
+
178
+ <pre>
179
+ // foo.js
180
+ opal.file('foo.rb', function() {
181
+ // compiled ruby code
182
+ });
183
+ </pre>
184
+
185
+ <p>
186
+ This file is not enough to run by itself. It depends on
187
+ <code>opal.js</code> which can be downloaded above. Finally,
188
+ compiling a ruby source creates a wrapper around the code which
189
+ will register the file with the opal runtime. To actually load
190
+ this code, you can use the <code>main()</code> function:
191
+ </p>
192
+
193
+ <pre>
194
+ opal.main('foo');
195
+ </pre>
196
+
197
+ <p>These files can be added to a HTML page:</p>
198
+
199
+ <pre>
200
+ &lt;!DOCTYPE html&gt;
201
+ &lt;html&gt;
202
+ &lt;head&gt;
203
+ &lt;script src="opal.js"&gt;&lt;/script&gt;
204
+ &lt;script src="foo.js"&gt;&lt;/script&gt;
205
+ &lt;script&gt;
206
+ opal.main('foo');
207
+ &lt;/script&gt;
208
+ &lt;/head&gt;
209
+ &lt;body&gt;
210
+
211
+ &lt;/body&gt;
212
+ &lt;/html&gt;
213
+ </pre>
214
+
215
+ <p>Open this file and check out the browsers' console.</p>
216
+
217
+ <h2 id='generated_code'>Generated Code</h2>
218
+
219
+ <p>
220
+ The Opal compiler is a source-to-source compiler; it reads in ruby
221
+ code and ouputs javascript code. The generated code makes use of native
222
+ javascript features when possible, and all code is output to the same
223
+ line number as the source. This, along with correctly indented output,
224
+ makes debugging very easy.
225
+ </p>
226
+
227
+ <h3 id='ruby_literals'>Ruby Literals</h3>
228
+
229
+ <h4 id='literals'>Literals</h4>
230
+
231
+ <p>
232
+ <strong>self</strong> is always compiled to <code>this</code> in
233
+ javascript which makes the generated code a lot cleaner to use. All
234
+ methods, blocks, classes, modules and top level code correctly have
235
+ their <code>this</code> value set.
236
+ </p>
237
+
238
+ <p>
239
+ <strong>true</strong> and <strong>false</strong> are also compiled into
240
+ their native javascript equivalents. This makes interacting with
241
+ external libraries a lot easier as there is no need to convert to
242
+ special ruby values.
243
+ </p>
244
+
245
+ <p>
246
+ <strong>nil</strong> is compiled into a special ruby object (an instance
247
+ of NilClass). A real object is used (instead of null and undefined) as
248
+ this allows nil to receive method calls which is a crucial ruby feature
249
+ which Opal maintains.
250
+ </p>
251
+
252
+ <h4 id='strings'>Strings</h4>
253
+
254
+ <p>
255
+ Ruby strings are compiled directly into javascript strings, for
256
+ performance as well as readability. This has the side affect that Opal
257
+ does not support mutable strings - all strings are immutable.
258
+ </p>
259
+
260
+ <h4 id='symbols'>Symbols</h4>
261
+
262
+ <p>
263
+ For performance reasons, Symbols compile into the string equivalents.
264
+ Opal supports the symbol syntax(es), but does not have a real Symbol
265
+ class. The Symbol constant is just an alias of String. Strings and
266
+ Symbols can be used in Opal interchangeably.
267
+ </p>
268
+
269
+ <h4 id='numbers'>Numbers</h4>
270
+
271
+ <p>
272
+ In Opal there is a single class for all numbers; <code>Numeric</code>.
273
+ To keep Opal as performant as possible, native javascript strings are
274
+ used. This has the side effect that all numbers must be an instance of
275
+ a single class. Most relevant methods from <code>Integer</code>,
276
+ <code>Float</code> and <code>Numeric</code> are implemented on this
277
+ class.
278
+ </p>
279
+
280
+ <h4 id='arrays'>Arrays</h4>
281
+
282
+ <p>Ruby arrays compile straight into javascript array literals.</p>
283
+
284
+ <h4 id='hash'>Hash</h4>
285
+
286
+ <p>
287
+ There is a special constructor available inside generated sources,
288
+ <code>$hash</code> which is used to create hash instances.
289
+ </p>
290
+
291
+ <h4 id='range'>Range</h4>
292
+
293
+ <p>
294
+ Similarly to hashes, the <code>$range</code> constructor can be used
295
+ to create new range instances.
296
+ </p>
297
+
298
+ <h3 id='ruby_methods'>Ruby Methods</h3>
299
+
300
+ <p>
301
+ A ruby method is just a function in the generated code. These functions
302
+ are added to the constructor&#8217;s prototypes so they are called just
303
+ like any other javascript function. All ruby methods are defined with
304
+ an <code>m$</code> prefix which isolates them from any javascript
305
+ function/property on the receiver.
306
+ </p>
307
+
308
+ <h4 id='method_calls'>Method Calls</h4>
309
+
310
+ <p>
311
+ All arguments are added to regular javascript function calls with the
312
+ addition of a block argument. If a block is given, then it will be the
313
+ first argument in the call. If no block is given then the first argument
314
+ will be null. This block argument is invisible to the ruby code.
315
+ </p>
316
+
317
+ <p>The following ruby code:</p>
318
+
319
+ <pre>
320
+ do_something 1, 2, 3
321
+ self.length
322
+ [1, 2, 3].push 5
323
+ </pre>
324
+
325
+ <p>Will therefore compile into the following easy to read javascript:</p>
326
+
327
+ <pre>
328
+ this.m$do_something(null, 1, 2, 3);
329
+ this.m$length();
330
+ [1, 2, 3].m$push(null, 5);
331
+ </pre>
332
+
333
+ <p>
334
+ There are of course some special characters valid as ruby names that are
335
+ not valid as javascript identifiers. These are specially encoded to keep
336
+ the generated javascript sane:
337
+ </p>
338
+
339
+ <pre>
340
+ this.loaded? # =&gt; this.m$loaded$p()
341
+ this.load! # =&gt; this.m$load$b()
342
+ this.loaded = true # =&gt; this.m$loaded$e(null, true)
343
+ </pre>
344
+
345
+ <p>Call arguments with splats are also supported.</p>
346
+
347
+ <pre>
348
+ this.push *[1, 2, 3]
349
+ # =&gt; this.m$push.apply(this, [null].concat([1, 2, 3])
350
+ </pre>
351
+
352
+ <p>When a block argument is given, it will be added as the first call arg.</p>
353
+
354
+ <pre>
355
+ describe &quot;some test&quot; do; ... end
356
+ # =&gt; this.m$describe(function() { ... }, &quot;some test&quot;)
357
+ </pre>
358
+
359
+ <h4 id='method_definitions'>Method Definitions</h4>
360
+
361
+ <p>
362
+ Methods are implemented as regular javascript functions. Assuming the
363
+ following method definition defined inside a class body:
364
+ </p>
365
+
366
+ <pre>
367
+ def to_s
368
+ inspect
369
+ end
370
+ </pre>
371
+
372
+ <p>
373
+ This would generate the following javascript (<code>$proto</code> will
374
+ be explained in the Class documentation):
375
+ </p>
376
+
377
+ <pre>
378
+ $proto.m$to_s = function() {
379
+ return this.m$inspect();
380
+ };
381
+ </pre>
382
+
383
+ <p>
384
+ The defined name retains the <code>m$</code> prefix outlined above,
385
+ and the <code>self</code> value for the method is <code>this</code>,
386
+ which will be the receiver.
387
+ </p>
388
+
389
+ <p>Normal arguments, splat args and optional args are all supported:</p>
390
+
391
+ <pre>
392
+ def norm(a, b, c)
393
+
394
+ end
395
+
396
+ def opt(a, b = 100)
397
+
398
+ end
399
+
400
+ def rest(a, *b)
401
+
402
+ end
403
+ </pre>
404
+
405
+ <p>
406
+ The generated code includes an empty block definition
407
+ <code>$block</code> which will not be used as this method does not
408
+ yield to a block:
409
+ </p>
410
+
411
+ <pre>
412
+ $proto.m$norm = function($block, a, b, c) {
413
+ return nil;
414
+ };
415
+
416
+ $proto.m$opt = function($block, a, b) {
417
+ if (b === undefined) b = 10;
418
+ return nil;
419
+ };
420
+
421
+ $proto.m$rest = function($block, a, b) {
422
+ b = Array.prototype.slice.call(arguments, 2);
423
+ return nil;
424
+ };
425
+ </pre>
426
+
427
+ <h2 id="change_log">Change Log</h2>
428
+
429
+ <h3>0.3.15</h3>
430
+
431
+ <p>Initial Release.</p>
432
+ </div>
433
+ </body>
434
+ </html>