opal 0.3.11 → 0.3.15

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