opal 0.3.21 → 0.3.22

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 (297) hide show
  1. data/.travis.yml +1 -4
  2. data/Gemfile +9 -4
  3. data/README.md +10 -589
  4. data/Rakefile +51 -19
  5. data/config.ru +17 -0
  6. data/core/array.rb +42 -34
  7. data/core/basic_object.rb +4 -4
  8. data/core/browser.js +31 -0
  9. data/core/class.rb +7 -7
  10. data/core/enumerable.rb +65 -69
  11. data/core/erb.rb +30 -0
  12. data/core/error.rb +2 -3
  13. data/core/hash.rb +47 -18
  14. data/core/kernel.rb +15 -16
  15. data/core/load_order +2 -1
  16. data/core/module.rb +19 -37
  17. data/core/numeric.rb +4 -2
  18. data/core/object.rb +4 -0
  19. data/core/proc.rb +6 -3
  20. data/core/racc.rb +215 -0
  21. data/core/regexp.rb +16 -21
  22. data/core/runtime.js +141 -153
  23. data/core/string.rb +41 -19
  24. data/core/strscan.rb +61 -0
  25. data/core/time.rb +1 -5
  26. data/docs/index.md +616 -0
  27. data/docs/post.html +2 -8
  28. data/docs/pre.html +29 -26
  29. data/docs/try.html +52 -0
  30. data/lib/opal.rb +33 -3
  31. data/lib/opal/builder.rb +14 -34
  32. data/lib/opal/erb_parser.rb +19 -0
  33. data/lib/opal/grammar.rb +7 -3
  34. data/lib/opal/grammar.y +3 -0
  35. data/lib/opal/lexer.rb +16 -8
  36. data/lib/opal/parser.rb +156 -119
  37. data/lib/opal/rake_task.rb +2 -2
  38. data/lib/opal/scope.rb +9 -10
  39. data/lib/opal/version.rb +1 -1
  40. data/{test → spec}/core/array/allocate_spec.rb +0 -0
  41. data/{test → spec}/core/array/append_spec.rb +0 -0
  42. data/{test → spec}/core/array/assoc_spec.rb +0 -0
  43. data/{test → spec}/core/array/at_spec.rb +0 -0
  44. data/{test → spec}/core/array/clear_spec.rb +0 -0
  45. data/{test → spec}/core/array/clone_spec.rb +0 -0
  46. data/{test → spec}/core/array/collect_spec.rb +0 -0
  47. data/{test → spec}/core/array/compact_spec.rb +0 -0
  48. data/{test → spec}/core/array/concat_spec.rb +0 -0
  49. data/{test → spec}/core/array/constructor_spec.rb +0 -0
  50. data/{test → spec}/core/array/count_spec.rb +0 -0
  51. data/{test → spec}/core/array/delete_at_spec.rb +0 -0
  52. data/{test → spec}/core/array/delete_if_spec.rb +0 -0
  53. data/{test → spec}/core/array/delete_spec.rb +0 -0
  54. data/{test → spec}/core/array/each_index_spec.rb +0 -0
  55. data/{test → spec}/core/array/each_spec.rb +0 -0
  56. data/{test → spec}/core/array/element_reference_spec.rb +0 -0
  57. data/{test → spec}/core/array/empty_spec.rb +0 -0
  58. data/{test → spec}/core/array/eql_spec.rb +0 -0
  59. data/{test → spec}/core/array/fetch_spec.rb +0 -0
  60. data/{test → spec}/core/array/first_spec.rb +0 -0
  61. data/{test → spec}/core/array/flatten_spec.rb +0 -0
  62. data/{test → spec}/core/array/include_spec.rb +0 -0
  63. data/{test → spec}/core/array/insert_spec.rb +0 -0
  64. data/{test → spec}/core/array/last_spec.rb +0 -0
  65. data/{test → spec}/core/array/length_spec.rb +0 -0
  66. data/{test → spec}/core/array/map_spec.rb +0 -0
  67. data/{test → spec}/core/array/minus_spec.rb +0 -0
  68. data/{test → spec}/core/array/plus_spec.rb +0 -0
  69. data/{test → spec}/core/array/pop_spec.rb +0 -0
  70. data/{test → spec}/core/array/push_spec.rb +0 -0
  71. data/{test → spec}/core/array/rassoc_spec.rb +0 -0
  72. data/{test → spec}/core/array/reject_spec.rb +0 -0
  73. data/{test → spec}/core/array/replace_spec.rb +0 -0
  74. data/{test → spec}/core/array/reverse_each_spec.rb +0 -0
  75. data/{test → spec}/core/array/reverse_spec.rb +0 -0
  76. data/{test → spec}/core/array/size_spec.rb +0 -0
  77. data/{test → spec}/core/array/to_ary_spec.rb +0 -0
  78. data/{test → spec}/core/array/uniq_spec.rb +0 -0
  79. data/{test → spec}/core/array/zip_spec.rb +0 -0
  80. data/{test → spec}/core/class/fixtures/classes.rb +0 -0
  81. data/{test → spec}/core/class/new_spec.rb +3 -0
  82. data/{test → spec}/core/enumerable/all_spec.rb +3 -0
  83. data/{test → spec}/core/enumerable/any_spec.rb +0 -0
  84. data/{test → spec}/core/enumerable/collect_spec.rb +0 -0
  85. data/{test → spec}/core/enumerable/count_spec.rb +0 -0
  86. data/{test → spec}/core/enumerable/detect_spec.rb +0 -0
  87. data/{test → spec}/core/enumerable/drop_spec.rb +0 -0
  88. data/{test → spec}/core/enumerable/drop_while_spec.rb +0 -0
  89. data/{test → spec}/core/enumerable/each_with_index_spec.rb +0 -0
  90. data/{test → spec}/core/enumerable/each_with_object_spec.rb +0 -0
  91. data/{test → spec}/core/enumerable/entries_spec.rb +0 -0
  92. data/{test → spec}/core/enumerable/find_all_spec.rb +0 -0
  93. data/{test → spec}/core/enumerable/find_index_spec.rb +0 -0
  94. data/{test → spec}/core/enumerable/find_spec.rb +0 -0
  95. data/{test → spec}/core/enumerable/first_spec.rb +0 -0
  96. data/{test → spec}/core/enumerable/fixtures/classes.rb +0 -0
  97. data/{test → spec}/core/enumerable/grep_spec.rb +0 -0
  98. data/{test → spec}/core/enumerable/take_spec.rb +0 -0
  99. data/{test → spec}/core/enumerable/to_a_spec.rb +0 -0
  100. data/{test → spec}/core/false/and_spec.rb +0 -0
  101. data/{test → spec}/core/false/inspect_spec.rb +0 -0
  102. data/{test → spec}/core/false/or_spec.rb +0 -0
  103. data/{test → spec}/core/false/to_s_spec.rb +0 -0
  104. data/{test → spec}/core/false/xor_spec.rb +0 -0
  105. data/{test → spec}/core/hash/allocate_spec.rb +0 -0
  106. data/{test → spec}/core/hash/assoc_spec.rb +0 -0
  107. data/{test → spec}/core/hash/clear_spec.rb +0 -0
  108. data/{test → spec}/core/hash/clone_spec.rb +0 -0
  109. data/{test → spec}/core/hash/default_spec.rb +0 -0
  110. data/{test → spec}/core/hash/delete_if_spec.rb +0 -0
  111. data/{test → spec}/core/hash/each_key_spec.rb +0 -0
  112. data/{test → spec}/core/hash/each_pair_spec.rb +0 -0
  113. data/{test → spec}/core/hash/each_spec.rb +0 -0
  114. data/{test → spec}/core/hash/each_value_spec.rb +0 -0
  115. data/{test → spec}/core/hash/element_reference_spec.rb +14 -1
  116. data/{test → spec}/core/hash/element_set_spec.rb +0 -0
  117. data/{test → spec}/core/hash/empty_spec.rb +0 -0
  118. data/{test → spec}/core/hash/fetch_spec.rb +0 -0
  119. data/{test → spec}/core/hash/flatten_spec.rb +0 -0
  120. data/{test → spec}/core/hash/has_key_spec.rb +0 -0
  121. data/{test → spec}/core/hash/has_value_spec.rb +0 -0
  122. data/{test → spec}/core/hash/include_spec.rb +0 -0
  123. data/{test → spec}/core/hash/index_spec.rb +0 -0
  124. data/{test → spec}/core/hash/indexes_spec.rb +0 -0
  125. data/{test → spec}/core/hash/indices_spec.rb +0 -0
  126. data/{test → spec}/core/hash/invert_spec.rb +0 -0
  127. data/{test → spec}/core/hash/keep_if_spec.rb +0 -0
  128. data/{test → spec}/core/hash/key_spec.rb +0 -0
  129. data/{test → spec}/core/hash/keys_spec.rb +0 -0
  130. data/{test → spec}/core/hash/length_spec.rb +0 -0
  131. data/{test → spec}/core/hash/member_spec.rb +0 -0
  132. data/{test → spec}/core/hash/merge_spec.rb +0 -0
  133. data/{test → spec}/core/hash/new_spec.rb +8 -0
  134. data/{test → spec}/core/hash/rassoc_spec.rb +0 -0
  135. data/{test → spec}/core/hash/replace_spec.rb +0 -0
  136. data/{test → spec}/core/hash/select_spec.rb +0 -0
  137. data/{test → spec}/core/hash/shift_spec.rb +0 -0
  138. data/{test → spec}/core/hash/size_spec.rb +0 -0
  139. data/{test → spec}/core/hash/update_spec.rb +0 -0
  140. data/{test → spec}/core/hash/value_spec.rb +0 -0
  141. data/{test → spec}/core/hash/values_at_spec.rb +0 -0
  142. data/{test → spec}/core/hash/values_spec.rb +0 -0
  143. data/{test → spec}/core/kernel/define_singleton_method_spec.rb +0 -0
  144. data/{test → spec}/core/kernel/eql_spec.rb +0 -0
  145. data/{test → spec}/core/kernel/equal_value_spec.rb +0 -0
  146. data/{test → spec}/core/kernel/loop_spec.rb +0 -0
  147. data/{test → spec}/core/kernel/nil_spec.rb +0 -0
  148. data/{test → spec}/core/kernel/proc_spec.rb +4 -0
  149. data/{test → spec}/core/kernel/rand_spec.rb +0 -0
  150. data/{test → spec}/core/kernel/respond_to_spec.rb +0 -0
  151. data/{test → spec}/core/kernel/send_spec.rb +0 -0
  152. data/{test → spec}/core/kernel/tap_spec.rb +0 -0
  153. data/{test → spec}/core/kernel/to_s_spec.rb +0 -0
  154. data/{test → spec}/core/matchdata/to_a_spec.rb +0 -0
  155. data/{test → spec}/core/nil/and_spec.rb +0 -0
  156. data/{test → spec}/core/nil/inspect_spec.rb +0 -0
  157. data/{test → spec}/core/nil/nil_spec.rb +0 -0
  158. data/{test → spec}/core/nil/or_spec.rb +0 -0
  159. data/{test → spec}/core/nil/to_a_spec.rb +0 -0
  160. data/{test → spec}/core/nil/to_f_spec.rb +0 -0
  161. data/{test → spec}/core/nil/to_i_spec.rb +0 -0
  162. data/{test → spec}/core/nil/to_s_spec.rb +0 -0
  163. data/{test → spec}/core/nil/xor_spec.rb +0 -0
  164. data/{test → spec}/core/numeric/equal_value_spec.rb +0 -0
  165. data/spec/core/proc/proc_tricks_spec.rb +7 -0
  166. data/{test → spec}/core/range/begin_spec.rb +0 -0
  167. data/{test → spec}/core/range/case_compare_spec.rb +0 -0
  168. data/{test → spec}/core/range/end_spec.rb +0 -0
  169. data/{test → spec}/core/regexp/match_spec.rb +0 -0
  170. data/{test → spec}/core/string/capitalize_spec.rb +0 -0
  171. data/{test → spec}/core/string/casecmp_spec.rb +0 -0
  172. data/{test → spec}/core/string/chomp_spec.rb +0 -0
  173. data/{test → spec}/core/string/chop_spec.rb +0 -0
  174. data/{test → spec}/core/string/chr_spec.rb +0 -0
  175. data/{test → spec}/core/string/comparison_spec.rb +0 -0
  176. data/{test → spec}/core/string/downcase_spec.rb +0 -0
  177. data/{test → spec}/core/string/element_reference_spec.rb +14 -2
  178. data/{test → spec}/core/string/empty_spec.rb +0 -0
  179. data/{test → spec}/core/string/end_with_spec.rb +0 -0
  180. data/{test → spec}/core/string/fixtures/classes.rb +0 -0
  181. data/{test → spec}/core/string/gsub_spec.rb +0 -0
  182. data/{test → spec}/core/string/include_spec.rb +0 -0
  183. data/{test → spec}/core/string/intern_spec.rb +0 -0
  184. data/{test → spec}/core/string/length_spec.rb +0 -0
  185. data/{test → spec}/core/string/lstrip_spec.rb +0 -0
  186. data/{test → spec}/core/string/match_spec.rb +0 -0
  187. data/{test → spec}/core/string/next_spec.rb +0 -0
  188. data/{test → spec}/core/string/ord_spec.rb +0 -0
  189. data/{test → spec}/core/string/partition_spec.rb +0 -0
  190. data/{test → spec}/core/string/reverse_spec.rb +0 -0
  191. data/{test → spec}/core/string/rstrip_spec.rb +0 -0
  192. data/{test → spec}/core/string/size_spec.rb +0 -0
  193. data/{test → spec}/core/string/slice_spec.rb +4 -1
  194. data/{test → spec}/core/string/split_spec.rb +0 -0
  195. data/{test → spec}/core/string/start_with_spec.rb +0 -0
  196. data/{test → spec}/core/string/strip_spec.rb +0 -0
  197. data/{test → spec}/core/string/sub_spec.rb +0 -0
  198. data/{test → spec}/core/string/succ_spec.rb +0 -0
  199. data/{test → spec}/core/string/sum_spec.rb +0 -0
  200. data/{test → spec}/core/string/swapcase_spec.rb +0 -0
  201. data/{test → spec}/core/string/to_a_spec.rb +0 -0
  202. data/{test → spec}/core/string/to_f_spec.rb +0 -0
  203. data/{test → spec}/core/string/to_i_spec.rb +0 -0
  204. data/{test → spec}/core/string/to_s_spec.rb +0 -0
  205. data/{test → spec}/core/string/to_str_spec.rb +0 -0
  206. data/{test → spec}/core/string/to_sym_spec.rb +0 -0
  207. data/{test → spec}/core/string/upcase_spec.rb +0 -0
  208. data/{test → spec}/core/symbol/to_proc_spec.rb +0 -0
  209. data/{test → spec}/core/time/at_spec.rb +0 -0
  210. data/{test → spec}/core/time/day_spec.rb +0 -0
  211. data/{test → spec}/core/time/friday_spec.rb +0 -0
  212. data/{test → spec}/core/time/hour_spec.rb +0 -0
  213. data/{test → spec}/core/time/min_spec.rb +0 -0
  214. data/{test → spec}/core/time/monday_spec.rb +0 -0
  215. data/{test → spec}/core/time/month_spec.rb +0 -0
  216. data/{test → spec}/core/time/now_spec.rb +0 -0
  217. data/{test → spec}/core/time/saturday_spec.rb +0 -0
  218. data/{test → spec}/core/true/and_spec.rb +0 -0
  219. data/{test → spec}/core/true/inspect_spec.rb +0 -0
  220. data/{test → spec}/core/true/or_spec.rb +0 -0
  221. data/{test → spec}/core/true/to_s_spec.rb +0 -0
  222. data/{test → spec}/core/true/xor_spec.rb +0 -0
  223. data/spec/grammar/lvar_spec.rb +2 -1
  224. data/spec/grammar/str_spec.rb +1 -1
  225. data/spec/grammar/xstr_spec.rb +1 -1
  226. data/{test → spec}/index.html +3 -3
  227. data/{test → spec}/language/alias_spec.rb +0 -0
  228. data/{test → spec}/language/and_spec.rb +0 -0
  229. data/{test → spec}/language/array_spec.rb +0 -0
  230. data/{test → spec}/language/block_spec.rb +0 -0
  231. data/{test → spec}/language/break_spec.rb +0 -0
  232. data/{test → spec}/language/case_spec.rb +0 -0
  233. data/{test → spec}/language/defined_spec.rb +0 -0
  234. data/{test → spec}/language/ensure_spec.rb +2 -2
  235. data/{test → spec}/language/fixtures/next.rb +0 -0
  236. data/{test → spec}/language/fixtures/yield.rb +0 -0
  237. data/{test → spec}/language/hash_spec.rb +0 -0
  238. data/{test → spec}/language/if_spec.rb +0 -0
  239. data/{test → spec}/language/literal_lambda_spec.rb +0 -0
  240. data/{test → spec}/language/loop_spec.rb +0 -0
  241. data/{test → spec}/language/metaclass_spec.rb +0 -0
  242. data/{test → spec}/language/next_spec.rb +2 -0
  243. data/{test → spec}/language/or_spec.rb +0 -0
  244. data/{test → spec}/language/predefined_spec.rb +0 -0
  245. data/{test → spec}/language/regexp_spec.rb +0 -0
  246. data/{test → spec}/language/send_spec.rb +0 -0
  247. data/{test → spec}/language/singleton_class_spec.rb +0 -0
  248. data/{test → spec}/language/super_spec.rb +0 -0
  249. data/{test → spec}/language/symbol_spec.rb +0 -0
  250. data/{test → spec}/language/undef_spec.rb +0 -0
  251. data/{test → spec}/language/unless_spec.rb +0 -0
  252. data/{test → spec}/language/until_spec.rb +0 -0
  253. data/{test → spec}/language/variables_spec.rb +0 -0
  254. data/{test → spec}/language/while_spec.rb +0 -0
  255. data/{test → spec}/language/yield_spec.rb +2 -0
  256. data/{test → spec}/opal/array/subclassing_spec.rb +0 -0
  257. data/{test → spec}/opal/array/to_json_spec.rb +0 -0
  258. data/{test → spec}/opal/boolean/singleton_class_spec.rb +0 -0
  259. data/{test → spec}/opal/boolean/to_json_spec.rb +0 -0
  260. data/{test → spec}/opal/class/bridge_class_spec.rb +0 -0
  261. data/spec/opal/erb/erb_spec.rb +15 -0
  262. data/{test → spec}/opal/exception/subclassing_spec.rb +0 -0
  263. data/{test → spec}/opal/hash/to_json_spec.rb +0 -0
  264. data/spec/opal/hash/to_native_spec.rb +5 -0
  265. data/{test → spec}/opal/json/parse_spec.rb +0 -0
  266. data/{test → spec}/opal/kernel/to_json_spec.rb +0 -0
  267. data/{test → spec}/opal/nil/to_json_spec.rb +0 -0
  268. data/{test → spec}/opal/numeric/to_json_spec.rb +0 -0
  269. data/{test → spec}/opal/runtime/call_spec.rb +0 -0
  270. data/{test → spec}/opal/runtime/class_hierarchy_spec.rb +0 -0
  271. data/{test → spec}/opal/runtime/def_spec.rb +0 -0
  272. data/{test → spec}/opal/runtime/defined_spec.rb +0 -0
  273. data/{test → spec}/opal/runtime/method_missing_spec.rb +3 -3
  274. data/{test → spec}/opal/runtime/super_spec.rb +0 -0
  275. data/{test → spec}/opal/string/subclassing_spec.rb +0 -0
  276. data/{test → spec}/opal/string/to_json_spec.rb +0 -0
  277. data/spec/opal/strscan/check_spec.rb +13 -0
  278. data/spec/opal/strscan/scan_spec.rb +33 -0
  279. data/spec/parser/simple_spec.rb +44 -0
  280. data/spec/spec_helper.rb +7 -7
  281. metadata +487 -497
  282. data/core/dir.rb +0 -89
  283. data/core/file.rb +0 -85
  284. data/spec/browser_spec.rb +0 -28
  285. data/spec/builder/fixtures/build_source/adam.rb +0 -0
  286. data/spec/builder/fixtures/build_source/bar/a.rb +0 -0
  287. data/spec/builder/fixtures/build_source/bar/wow/b.rb +0 -0
  288. data/spec/builder/fixtures/build_source/bar/wow/cow/c.rb +0 -0
  289. data/spec/builder/fixtures/build_source/beynon.rb +0 -0
  290. data/spec/builder/fixtures/build_source/charles.js +0 -0
  291. data/spec/builder/fixtures/build_source/foo/a.rb +0 -0
  292. data/spec/builder/fixtures/build_source/foo/b.rb +0 -0
  293. data/spec/builder/fixtures/build_source/foo/x.js +0 -0
  294. data/spec/builder/fixtures/build_source/foo/y.js +0 -0
  295. data/spec/builder/lib_name_for_spec.rb +0 -19
  296. data/test/index.min.html +0 -12
  297. data/test/spec_helper.rb +0 -4
data/docs/post.html CHANGED
@@ -1,9 +1,3 @@
1
- </section>
2
- <footer>
3
- <p><small>Hosted on <a href="https://pages.github.com">GitHub Pages</a> using the Dinky theme</small></p>
4
- </footer>
5
- </div>
6
- <!--[if !IE]><script>fixScale(document);</script><!--<![endif]-->
7
-
8
- </body>
1
+ </div>
2
+ </body>
9
3
  </html>
data/docs/pre.html CHANGED
@@ -1,32 +1,35 @@
1
1
  <!doctype html>
2
2
  <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="chrome=1">
6
- <title>Opal by adambeynon</title>
3
+ <head>
4
+ <title>Opal: Ruby to Javascript compiler</title>
7
5
 
8
- <link rel="stylesheet" href="stylesheets/styles.css">
9
- <link rel="stylesheet" href="stylesheets/pygment_trac.css">
10
- <script src="javascripts/scale.fix.js"></script>
11
- <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
12
- <!--[if lt IE 9]>
13
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
14
- <![endif]-->
15
- </head>
16
- <body>
17
- <div class="wrapper">
18
- <header>
19
- <h1 class="header">Opal</h1>
20
- <p class="header">Ruby runtime and library on top of Javascript</p>
6
+ <link href="/stylesheets/bootstrap.css" rel="stylesheet">
7
+ <link href="/stylesheets/pygment_trac.css" rel="stylesheet">
8
+ <style>
9
+ body {
10
+ padding-top: 92px;
11
+ }
21
12
 
22
- <ul>
23
- <li class="download"><a class="buttons" href="https://github.com/adambeynon/opal/zipball/master">Download ZIP</a></li>
24
- <li class="download"><a class="buttons" href="https://github.com/adambeynon/opal/tarball/master">Download TAR</a></li>
25
- <li><a class="buttons github" href="https://github.com/adambeynon/opal">View On GitHub</a></li>
13
+ .main-title {
14
+ padding-bottom: 32px;
15
+ }
16
+ </style>
17
+ </head>
18
+ <body>
19
+ <!-- nav -->
20
+ <div class="navbar navbar-fixed-top">
21
+ <div class="navbar-inner">
22
+ <div class="container">
23
+ <a class="brand" href="http://opalrb.org">
24
+ Opal
25
+ </a>
26
+ <ul class="nav">
27
+ <li><a href="/index.html">Home</a></li>
28
+ <li><a href="/try.html">Try Opal</a></li>
26
29
  </ul>
30
+ </div>
31
+ </div>
32
+ </div>
27
33
 
28
- <p class="header">This project is maintained by <a class="header name" href="https://github.com/adambeynon">adambeynon</a></p>
29
-
30
-
31
- </header>
32
- <section>
34
+ <!-- body -->
35
+ <div class="container">
data/docs/try.html ADDED
@@ -0,0 +1,52 @@
1
+ <div class="row-fluid" id="wrapper">
2
+ <div id="editor_wrapper" class="span6">
3
+ <div id="editor"></div>
4
+ <br />
5
+ <a href="#" id="run_code" class="btn btn-primary">Compile</a>
6
+ </div>
7
+
8
+ <div id="viewer_wrapper" class="span6">
9
+ <div id="viewer"></div>
10
+ </div>
11
+ </div>
12
+
13
+
14
+ <script src="/javascripts/codemirror.js"></script>
15
+ <script src="/javascripts/ruby.js"></script>
16
+ <script src="/javascripts/javascript.js"></script>
17
+ <link href="/stylesheets/codemirror.css" rel="stylesheet">
18
+ <script src="/opal.js"></script>
19
+ <script src="/opal-parser.js"></script>
20
+
21
+ <script>
22
+ var viewer = CodeMirror(document.getElementById("viewer"), {
23
+ lineNumbers: true,
24
+ mode: "javascript",
25
+ readOnly: true
26
+ });
27
+ var editor = CodeMirror(document.getElementById("editor"), {
28
+ lineNumbers: true,
29
+ mode: "ruby",
30
+ tabMode: "shift"
31
+ });
32
+
33
+ var run = document.getElementById('run_code');
34
+
35
+ if (run.addEventListener) {
36
+ run.addEventListener('click', compile, false);
37
+ }
38
+ else {
39
+ run.attachEvent('onclick', compile);
40
+ }
41
+ // Initialize
42
+ editor.setValue("[1, 2, 3, 4].each do |a|\n puts a\nend\n\nclass Foo\n attr_reader :name\nend\n\nadam = Foo.new\nadam.name = 'Adam Beynon'\nputs adam.name");
43
+ // Functions to update editor and viewer content
44
+ function compile() {
45
+ try {
46
+ viewer.setValue(Opal.Opal.Parser.$new().$parse(editor.getValue()));
47
+ }
48
+ catch (err) {
49
+ }
50
+ return false;
51
+ }
52
+ </script>
data/lib/opal.rb CHANGED
@@ -1,4 +1,15 @@
1
+ unless Symbol.instance_methods.include?(:[])
2
+ unless String == Symbol
3
+ class Symbol
4
+ def []key
5
+ to_s[key]
6
+ end
7
+ end
8
+ end
9
+ end
10
+
1
11
  require 'opal/parser'
12
+ require 'opal/erb_parser'
2
13
  require 'opal/builder'
3
14
  require 'opal/version'
4
15
 
@@ -25,7 +36,26 @@ module Opal
25
36
  #
26
37
  # @return [String] returns opal runtime/corelib as a string
27
38
  def self.runtime
28
- Builder.runtime
39
+ core_dir = Opal.core_dir
40
+ load_order = File.join core_dir, 'load_order'
41
+ corelib = File.read(load_order).strip.split.map do |c|
42
+ File.read File.join(core_dir, "#{c}.rb")
43
+ end
44
+
45
+ runtime = File.read(File.join core_dir, 'runtime.js')
46
+ corelib = Opal.parse corelib.join("\n"), '(corelib)'
47
+
48
+ [
49
+ "// Opal v#{Opal::VERSION}",
50
+ "// http://opalrb.org",
51
+ "// Copyright 2012, Adam Beynon",
52
+ "// Released under the MIT License",
53
+ "(function(undefined) {",
54
+ runtime,
55
+ "Opal.version = #{ Opal::VERSION.inspect };",
56
+ corelib,
57
+ "}).call(this);"
58
+ ].join("\n")
29
59
  end
30
60
 
31
61
  # Build gem with given name to a string.
@@ -40,7 +70,7 @@ module Opal
40
70
  # @return [String] returns built gem
41
71
  def self.build_gem(name)
42
72
  spec = Gem::Specification.find_by_name name
43
- Builder.build(:files => spec.require_paths, :dir => spec.full_gem_path)
73
+ Builder.new(:files => spec.require_paths, :dir => spec.full_gem_path).build
44
74
  end
45
75
 
46
76
  # Build the given files. Files should be a string of either a full
@@ -52,7 +82,7 @@ module Opal
52
82
  # @param [String] files files to build
53
83
  # @return [String]
54
84
  def self.build_files(files)
55
- Builder.build(:files => files)
85
+ Builder.new(:files => files).build
56
86
  end
57
87
 
58
88
  def self.opal_dir
data/lib/opal/builder.rb CHANGED
@@ -1,33 +1,9 @@
1
- require 'fileutils'
1
+ require 'opal/parser'
2
2
 
3
3
  module Opal
4
- class Builder
5
- def self.runtime
6
- core_dir = Opal.core_dir
7
- load_order = File.join core_dir, 'load_order'
8
- corelib = File.read(load_order).strip.split.map do |c|
9
- File.read File.join(core_dir, "#{c}.rb")
10
- end
11
-
12
- runtime = File.read(File.join core_dir, 'runtime.js')
13
- corelib = Opal.parse corelib.join("\n"), '(corelib)'
14
-
15
- [
16
- "// Opal v#{Opal::VERSION}",
17
- "// http://opalrb.org",
18
- "// Copyright 2012, Adam Beynon",
19
- "// Released under the MIT License",
20
- "(function(undefined) {",
21
- runtime,
22
- "Opal.version = #{ Opal::VERSION.inspect };",
23
- corelib,
24
- "}).call(this);"
25
- ].join("\n")
26
- end
27
4
 
28
- def self.build(opts)
29
- self.new(opts).build
30
- end
5
+ # Used to build gems/libs/directories of opal code
6
+ class Builder
31
7
 
32
8
  def initialize(options = {})
33
9
  @sources = Array(options[:files])
@@ -54,8 +30,8 @@ module Opal
54
30
  sources.each do |s|
55
31
  s = File.join @dir, s
56
32
  if File.directory? s
57
- files.push *Dir[File.join s, '**/*.{rb,js}']
58
- elsif File.extname(s) == '.rb' or File.extname(s) == ".js"
33
+ files.push *Dir[File.join(s, '**/*.{rb,js,erb}')]
34
+ elsif %w(.rb .js .erb).include? File.extname(s)
59
35
  files << s
60
36
  end
61
37
  end
@@ -92,9 +68,13 @@ module Opal
92
68
  parser_name = parser_name_for file
93
69
 
94
70
  if File.extname(file) == '.rb'
95
- code = @parser.parse File.read(file), parser_name
71
+ code = @parser.parse File.read(file), lib_name
96
72
  @requires[lib_name] = @parser.requires
97
- else
73
+ elsif File.extname(file) == '.erb'
74
+ template_name = File.basename(file).chomp(File.extname(file))
75
+ code = Opal::ERBParser.new.parse File.read(file), template_name
76
+ @requires[lib_name] = []
77
+ else # javascript
98
78
  code = "function() {\n #{ File.read file }\n}"
99
79
  @requires[lib_name] = []
100
80
  end
@@ -103,13 +83,13 @@ module Opal
103
83
  end
104
84
 
105
85
  def parser_name_for(file)
106
- file.sub /^#{@dir}\//, ''
86
+ file.sub(/^#{@dir}\//, '')
107
87
  end
108
88
 
109
89
  def lib_name_for(file)
110
- file = file.sub /^#{@dir}\//, ''
90
+ file = file.sub(/^#{@dir}\//, '')
111
91
  file = file.chomp File.extname(file)
112
- file.sub /^lib\//, ''
92
+ file.sub(/^(lib|spec)\//, '')
113
93
  end
114
94
  end
115
95
  end
@@ -0,0 +1,19 @@
1
+ require 'opal/parser'
2
+
3
+ module Opal
4
+ class ERBParser
5
+
6
+ def parse(str, name = 'erb')
7
+ Parser.new.parse compile(str, name)
8
+ end
9
+
10
+ def compile(str, name)
11
+ res = "ERB.new('#{name}') do\nout = []\nout.<<(\"" +
12
+ str.gsub(/<%=([\s\S]+?)%>/) do
13
+ "\")\nout.<<(" + $1.gsub(/\\'/, "'") + ")\nout.<<(\""
14
+ end.gsub(/<%([\s\S]+?)%>/) do
15
+ "\")\n" + $1 + "\nout.<<(\""
16
+ end + "\")\nout.join\nend"
17
+ end
18
+ end
19
+ end
data/lib/opal/grammar.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # DO NOT MODIFY!!!!
3
- # This file is automatically generated by Racc 1.4.8
3
+ # This file is automatically generated by Racc 1.4.9
4
4
  # from Racc grammer file "".
5
5
  #
6
6
 
@@ -2045,7 +2045,7 @@ racc_reduce_table = [
2045
2045
  3, 163, :_reduce_206,
2046
2046
  3, 163, :_reduce_207,
2047
2047
  3, 163, :_reduce_208,
2048
- 3, 163, :_reduce_none,
2048
+ 3, 163, :_reduce_209,
2049
2049
  5, 163, :_reduce_210,
2050
2050
  1, 163, :_reduce_none,
2051
2051
  1, 160, :_reduce_none,
@@ -3609,7 +3609,11 @@ def _reduce_208(val, _values, result)
3609
3609
  result
3610
3610
  end
3611
3611
 
3612
- # reduce 209 omitted
3612
+ def _reduce_209(val, _values, result)
3613
+ result = s(:defined, val[2])
3614
+
3615
+ result
3616
+ end
3613
3617
 
3614
3618
  def _reduce_210(val, _values, result)
3615
3619
  result = s(:if, val[0], val[2], val[4])
data/lib/opal/grammar.y CHANGED
@@ -569,6 +569,9 @@ arg:
569
569
  result.line = val[0].line
570
570
  }
571
571
  | DEFINED opt_nl arg
572
+ {
573
+ result = s(:defined, val[2])
574
+ }
572
575
  | arg '?' arg ':' arg
573
576
  {
574
577
  result = s(:if, val[0], val[2], val[4])
data/lib/opal/lexer.rb CHANGED
@@ -1,10 +1,18 @@
1
1
  require 'opal/grammar'
2
2
  require 'strscan'
3
3
 
4
+ class Array
5
+ attr_accessor :line
6
+ attr_accessor :end_line
7
+ end
8
+
4
9
  module Opal
5
- class Grammar < Racc::Parser
10
+ Sexp = ::Array
6
11
 
7
- class OpalParseError < StandardError; end
12
+ # Any exceptions with parsing of file will raise this error
13
+ class OpalParseError < Exception; end
14
+
15
+ class Grammar < Racc::Parser
8
16
 
9
17
  attr_reader :line
10
18
 
@@ -18,14 +26,13 @@ module Opal
18
26
  @string_parse_stack = []
19
27
  end
20
28
 
21
- def s *parts
22
- sexp = parts
29
+ def s(*parts)
30
+ sexp = Sexp.new(parts)
23
31
  sexp.line = @line
24
32
  sexp
25
33
  end
26
34
 
27
- def parse source, file = '(string)'
28
- #puts "============"
35
+ def parse(source, file = '(string)')
29
36
  @file = file
30
37
  @scanner = StringScanner.new source
31
38
  push_scope
@@ -90,7 +97,7 @@ module Opal
90
97
  end
91
98
  end
92
99
 
93
- def new_body compstmt, res, els, ens
100
+ def new_body(compstmt, res, els, ens)
94
101
  s = compstmt || s(:block)
95
102
 
96
103
  if compstmt
@@ -444,7 +451,6 @@ module Opal
444
451
  def next_token
445
452
  t = get_next_token
446
453
  # puts "returning token #{t.inspect}"
447
- # t[1] = { :value => t[1], :line => @line }
448
454
  t
449
455
  end
450
456
 
@@ -625,6 +631,8 @@ module Opal
625
631
  "\n"
626
632
  elsif scanner.scan(/r/)
627
633
  "\r"
634
+ elsif scanner.scan(/\n/)
635
+ "\n"
628
636
  else
629
637
  # escaped char doesnt need escaping, so just return it
630
638
  scanner.scan(/./)
data/lib/opal/parser.rb CHANGED
@@ -2,13 +2,7 @@ require 'opal/lexer'
2
2
  require 'opal/grammar'
3
3
  require 'opal/scope'
4
4
 
5
- class Array
6
- attr_accessor :line
7
- attr_accessor :end_line
8
- end
9
-
10
5
  module Opal
11
- class OpalParseError < Exception; end
12
6
 
13
7
  class Parser
14
8
  INDENT = ' '
@@ -32,25 +26,20 @@ module Opal
32
26
 
33
27
  attr_reader :requires
34
28
 
35
- def self.parse(str)
36
- self.new.parse str
37
- end
38
-
39
- def initialize(opts = {})
40
- @debug = true if opts[:debug]
41
- end
42
-
43
29
  def parse(source, file = '(file)')
44
- @file = file
30
+ @grammar = Grammar.new
45
31
  @requires = []
32
+ @file = file
33
+ @line = 1
34
+ @indent = ''
35
+ @unique = 0
36
+
46
37
  @helpers = {
47
- :breaker => true,
48
- :slice => true,
49
- :mm => true
38
+ :breaker => true,
39
+ :slice => true,
40
+ :mm => true
50
41
  }
51
42
 
52
- @grammar = Grammar.new
53
- reset
54
43
  top @grammar.parse(source, file)
55
44
  end
56
45
 
@@ -67,22 +56,16 @@ module Opal
67
56
  end
68
57
 
69
58
  def s(*parts)
70
- sexp = parts
59
+ sexp = Sexp.new(parts)
71
60
  sexp.line = @line
72
61
  sexp
73
62
  end
74
63
 
75
- def reset
76
- @line = 1
77
- @indent = ''
78
- @unique = 0
79
- end
80
-
81
64
  def mid_to_jsid(mid)
82
65
  if RESERVED.include?(mid) or /\=|\+|\-|\*|\/|\!|\?|\<|\>|\&|\||\^|\%|\~|\[/ =~ mid.to_s
83
- "['#{mid}']"
66
+ "['$#{mid}']"
84
67
  else
85
- '.' + mid
68
+ '.$' + mid
86
69
  end
87
70
  end
88
71
 
@@ -104,7 +87,7 @@ module Opal
104
87
  vars << "self = __opal.top"
105
88
  vars << "__scope = __opal"
106
89
  vars << "nil = __opal.nil"
107
- vars << "def = #{current_self}.$k.prototype" if @scope.defines_defn
90
+ vars << "def = #{current_self}._klass.prototype" if @scope.defines_defn
108
91
  vars.concat @helpers.keys.map { |h| "__#{h} = __opal.#{h}" }
109
92
 
110
93
  code = "#{INDENT}var #{vars.join ', '};\n" + INDENT + @scope.to_vars + "\n" + code
@@ -140,6 +123,12 @@ module Opal
140
123
  res
141
124
  end
142
125
 
126
+ # Should be overriden in custom parsers to handle a require
127
+ # statement.
128
+ def handle_require(arglist)
129
+ "/* require statement removed */"
130
+ end
131
+
143
132
  # Used when we enter a while statement. This pushes onto the current
144
133
  # scope's while stack so we know how to handle break, next etc.
145
134
  #
@@ -227,14 +216,49 @@ module Opal
227
216
 
228
217
  until sexp.empty?
229
218
  stmt = sexp.shift
219
+ type = stmt.first
220
+
221
+ # find any inline yield statements
222
+ if yasgn = find_inline_yield(stmt)
223
+ result << "#{process(yasgn, level)};"
224
+ end
225
+
230
226
  expr = expression?(stmt) and LEVEL.index(level) < LEVEL.index(:list)
231
227
  code = process(stmt, level)
232
- result << (expr ? "#{code};" : code)
228
+ result << (expr ? "#{code};" : code) unless code == ""
233
229
  end
234
230
 
235
231
  result.join(@scope.class_scope? ? "\n\n#@indent" : "\n#@indent")
236
232
  end
237
233
 
234
+ def find_inline_yield(stmt)
235
+ found = nil
236
+ case stmt.first
237
+ when :js_return
238
+ found = find_inline_yield stmt[1]
239
+ when :array
240
+ stmt[1..-1].each_with_index do |el, idx|
241
+ if el.first == :yield
242
+ found = el
243
+ stmt[idx+1] = s(:js_tmp, '__yielded')
244
+ end
245
+ end
246
+ when :call
247
+ arglist = stmt[3]
248
+ arglist[1..-1].each_with_index do |el, idx|
249
+ if el.first == :yield
250
+ found = el
251
+ arglist[idx+1] = s(:js_tmp, '__yielded')
252
+ end
253
+ end
254
+ end
255
+
256
+ if found
257
+ @scope.add_temp '__yielded' unless @scope.has_temp? '__yielded'
258
+ s(:yasgn, '__yielded', found)
259
+ end
260
+ end
261
+
238
262
  def process_scope(sexp, level)
239
263
  stmt = sexp.shift
240
264
  if stmt
@@ -266,8 +290,8 @@ module Opal
266
290
  l = process recv, :expr
267
291
  r = process arg, :expr
268
292
 
269
- "(%s = %s, %s = %s, typeof(%s) === 'number' ? %s %s %s : %s.$m%s(%s, %s))" %
270
- [a, l, b, r, a, a, meth.to_s, b, a, mid, a, b]
293
+ "(%s = %s, %s = %s, typeof(%s) === 'number' ? %s %s %s : %s%s(%s))" %
294
+ [a, l, b, r, a, a, meth.to_s, b, a, mid, b]
271
295
  end
272
296
  end
273
297
  end
@@ -336,7 +360,8 @@ module Opal
336
360
  str = sexp.shift
337
361
  if str == @file
338
362
  @uses_file = true
339
- "'FILE'"
363
+ # "'FILE'"
364
+ @file.inspect
340
365
  else
341
366
  str.inspect
342
367
  end
@@ -356,9 +381,11 @@ module Opal
356
381
  when :call
357
382
  mid = mid_to_jsid part[2].to_s
358
383
  recv = part[1] ? process(part[1], :expr) : current_self
359
- "(#{recv}.$m#{mid} ? 'method' : nil)"
384
+ "(#{recv}#{mid} ? 'method' : nil)"
360
385
  when :xstr
361
386
  "(typeof(#{process part, :expression}) !== 'undefined')"
387
+ when :colon2
388
+ "false"
362
389
  else
363
390
  raise "bad defined? part: #{part[0]}"
364
391
  end
@@ -412,7 +439,7 @@ module Opal
412
439
 
413
440
  if splat
414
441
  params << splat
415
- code += "#{splat} = __slice.call(arguments, #{len});"
442
+ code += "#{splat} = __slice.call(arguments, #{len - 1});"
416
443
  end
417
444
 
418
445
  if block_arg
@@ -431,7 +458,7 @@ module Opal
431
458
  code += "\n#@indent" + process(body, :stmt)
432
459
 
433
460
  if @scope.defines_defn
434
- @scope.add_temp 'def = (self._isObject ? self.$m : self.$m_tbl)'
461
+ @scope.add_temp "def = (#{current_self}._isObject ? #{current_self} : #{current_self}.prototype)"
435
462
  end
436
463
 
437
464
  code = "\n#@indent#{@scope.to_vars}\n#@indent#{code}"
@@ -451,7 +478,7 @@ module Opal
451
478
  end
452
479
 
453
480
  def js_block_args(sexp)
454
- ['self'] + sexp.map do |arg|
481
+ sexp.map do |arg|
455
482
  a = arg[1].to_sym
456
483
  a = "#{a}$".to_sym if RESERVED.include? a.to_s
457
484
  @scope.add_arg a
@@ -530,60 +557,56 @@ module Opal
530
557
  when :alias_native
531
558
  return handle_alias_native(sexp) if @scope.class_scope?
532
559
  when :require
560
+ # return handle_require(arglist)
533
561
  path = arglist[1]
534
562
 
535
563
  if path and path[0] == :str
536
- path_name = path[1].sub(/^opal\//, '')
537
- @requires << path_name
538
- return ""
539
- else
540
- # warn "Opal cannot do dynamic requires"
541
- return ""
564
+ @requires << path[1]
542
565
  end
566
+
567
+ return "//= require #{path[1]}"
543
568
  end
544
569
 
545
570
  splat = arglist[1..-1].any? { |a| a.first == :splat }
546
571
 
547
- if Array === arglist.last and arglist.last.first == :block_pass
572
+ if Sexp === arglist.last and arglist.last.first == :block_pass
548
573
  block = process s(:js_tmp, process(arglist.pop, :expr)), :expr
549
574
  elsif iter
550
575
  block = iter
551
576
  end
552
577
 
553
- recv ||= [:self]
578
+ recv ||= s(:self)
554
579
 
555
580
  if block
556
- tmpproc = @scope.new_temp
581
+ tmprecv = @scope.new_temp
557
582
  elsif splat and recv != [:self] and recv[0] != :lvar
558
- tmpproc = @scope.new_temp
583
+ tmprecv = @scope.new_temp
559
584
  end
560
585
 
561
586
  args = ""
562
587
 
563
- with_temp do |tmprecv|
564
- recv_code = process recv, :recv
588
+ recv_code = process recv, :recv
565
589
 
566
- arglist.insert 1, s(:js_tmp, tmprecv)
567
- args = process arglist, :expr
590
+ args = process arglist, :expr
568
591
 
569
- result = if block
570
- dispatch = "(%s = %s, %s.$m%s._p = %s, %s.$m%s" %
571
- [tmprecv, recv_code, tmprecv, mid, block, tmprecv, mid]
592
+ result = if block
593
+ dispatch = "(%s = %s, %s%s._p = %s, %s%s" %
594
+ [tmprecv, recv_code, tmprecv, mid, block, tmprecv, mid]
572
595
 
573
- if splat
574
- "%s.apply(null, %s))" % [dispatch, args]
575
- else
576
- "%s(%s))" % [dispatch, args]
577
- end
596
+ if splat
597
+ "%s.apply(null, %s))" % [dispatch, args]
578
598
  else
579
- m_missing = " || __mm(#{meth.to_s.inspect})" if @debug
580
- dispatch = "((#{tmprecv} = #{recv_code}).$m#{mid}#{ m_missing })"
581
- splat ? "#{dispatch}.apply(null, #{args})" : "#{dispatch}(#{args})"
599
+ "%s(%s))" % [dispatch, args]
582
600
  end
583
-
584
- @scope.queue_temp tmpproc if tmpproc
585
- result
601
+ else
602
+ # m_missing = " || __mm(#{meth.to_s.inspect})"
603
+ # dispatch = "((#{tmprecv} = #{recv_code}).$m#{mid}#{ m_missing })"
604
+ # splat ? "#{dispatch}.apply(null, #{args})" : "#{dispatch}(#{args})"
605
+ dispatch = tmprecv ? "(#{tmprecv} = #{recv_code})#{mid}" : "#{recv_code}#{mid}"
606
+ splat ? "#{dispatch}.apply(#{tmprecv || recv_code}, #{args})" : "#{dispatch}(#{args})"
586
607
  end
608
+
609
+ result
587
610
  end
588
611
 
589
612
  # s(:arglist, [arg [, arg ..]])
@@ -656,7 +679,7 @@ module Opal
656
679
  indent do
657
680
  in_scope(:class) do
658
681
  @scope.name = name
659
- @scope.add_temp "#{ @scope.proto } = #{name}.prototype", "#{ @scope.m_tbl } = #{name}.$m_tbl", "__scope = #{name}._scope"
682
+ @scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
660
683
  @scope.donates_methods = true
661
684
  body = process body, :stmt
662
685
  code = @indent + @scope.to_vars + "\n\n#@indent" + body
@@ -685,7 +708,7 @@ module Opal
685
708
 
686
709
  call = s(:call, recv, :singleton_class, s(:arglist))
687
710
 
688
- "(function(self){#{ code }})(#{ process call, :expr })"
711
+ "(function(){#{ code }}).call(#{ process call, :expr })"
689
712
  end
690
713
 
691
714
  # s(:module, cid, body)
@@ -711,7 +734,7 @@ module Opal
711
734
  indent do
712
735
  in_scope(:module) do
713
736
  @scope.name = name
714
- @scope.add_temp "#{ @scope.m_tbl } = #{name}.$m_tbl", "__scope = #{name}._scope"
737
+ @scope.add_temp "#{ @scope.proto } = #{name}.prototype", "__scope = #{name}._scope"
715
738
  @scope.donates_methods = true
716
739
  body = process body, :stmt
717
740
  code = @indent + @scope.to_vars + "\n\n#@indent" + body + "\n#@indent" + @scope.to_donate_methods
@@ -734,7 +757,7 @@ module Opal
734
757
  # FIXME: maybe add this to donate(). it will be undefined, so
735
758
  # when added to includees it will actually undefine methods there
736
759
  # too.
737
- "delete #{ @scope.m_tbl }#{jsid}"
760
+ "delete #{ @scope.proto }#{jsid}"
738
761
  end
739
762
 
740
763
  # s(:defn, mid, s(:args), s(:scope))
@@ -772,21 +795,21 @@ module Opal
772
795
  uses_super = nil
773
796
 
774
797
  # opt args if last arg is sexp
775
- opt = args.pop if Array === args.last
798
+ opt = args.pop if Sexp === args.last
776
799
 
777
800
  # block name &block
778
- if args.last.to_s[0] == '&'
801
+ if args.last.to_s.start_with? '&'
779
802
  block_name = args.pop[1..-1].to_sym
780
803
  end
781
804
 
782
805
  # splat args *splat
783
- if args.last.to_s[0] == '*'
806
+ if args.last.to_s.start_with? '*'
784
807
  if args.last == :*
785
808
  args.pop
786
809
  else
787
810
  splat = args[-1].to_s[1..-1].to_sym
788
811
  args[-1] = splat
789
- len = args.length - 1
812
+ len = args.length - 2
790
813
  end
791
814
  end
792
815
 
@@ -845,28 +868,24 @@ module Opal
845
868
 
846
869
  if recvr
847
870
  if smethod
848
- @scope.smethods << mid.to_s
849
- "#{ comment }#{ @scope.name }.$m#{jsid} = #{defcode}"
871
+ @scope.smethods << "$#{mid}"
872
+ "#{ comment }#{ @scope.name }#{jsid} = #{defcode}"
850
873
  else
851
- # "#{ recv }#{ jsid } = #{ defcode }"
852
- @helpers[:defs] = true
853
- "__defs(#{recv}, #{mid.to_s.inspect}, #{defcode})"
874
+ "#{ recv }#{ jsid } = #{ defcode }"
854
875
  end
855
876
  elsif @scope.class_scope?
856
- @scope.methods << mid.to_s
877
+ @scope.methods << "$#{mid}"
857
878
  if uses_super
858
879
  @scope.add_temp uses_super
859
- uses_super = "#{uses_super} = #{@scope.m_tbl}#{jsid};\n#@indent"
880
+ uses_super = "#{uses_super} = #{@scope.proto}#{jsid};\n#@indent"
860
881
  end
861
- "#{ comment }#{uses_super}#{ @scope.m_tbl }#{jsid} = #{defcode}"
882
+ "#{ comment }#{uses_super}#{ @scope.proto }#{jsid} = #{defcode}"
862
883
  elsif @scope.type == :iter
863
884
  "def#{jsid} = #{defcode}"
864
885
  elsif @scope.type == :top
865
- @helpers[:defs] = true
866
- "__defs(#{current_self}, #{mid.to_s.inspect}, #{defcode})"
886
+ "#{ current_self }#{ jsid } = #{ defcode }"
867
887
  else
868
- @helpers[:defs] = true
869
- "__defs(#{current_self}, #{mid.to_s.inspect}, #{defcode})"
888
+ "def#{jsid} = #{defcode}"
870
889
  end
871
890
  end
872
891
 
@@ -887,7 +906,7 @@ module Opal
887
906
  end
888
907
 
889
908
  def process_args(exp, level)
890
- args = ['self']
909
+ args = []
891
910
 
892
911
  until exp.empty?
893
912
  a = exp.shift.to_sym
@@ -912,8 +931,10 @@ module Opal
912
931
  @scope.name
913
932
  elsif @scope.top?
914
933
  'self'
915
- else
934
+ elsif @scope.top?
916
935
  'self'
936
+ else # def, iter
937
+ 'this'
917
938
  end
918
939
  end
919
940
 
@@ -1046,11 +1067,11 @@ module Opal
1046
1067
  old = mid_to_jsid exp[1][1].to_s
1047
1068
 
1048
1069
  if [:class, :module].include? @scope.type
1049
- @scope.methods << new
1050
- "%s%s = %s%s" % [@scope.m_tbl, new, @scope.m_tbl, old]
1070
+ @scope.methods << "$#{exp[0][1].to_s}"
1071
+ "%s%s = %s%s" % [@scope.proto, new, @scope.proto, old]
1051
1072
  else
1052
1073
  current = current_self
1053
- "%s.$m_tbl%s = %s.$m_tbl%s" % [current, new, current, old]
1074
+ "%s.prototype%s = %s.prototype%s" % [current, new, current, old]
1054
1075
  end
1055
1076
  end
1056
1077
 
@@ -1066,7 +1087,7 @@ module Opal
1066
1087
  len = rhs.length - 1 # we are guaranteed an array of this length
1067
1088
  code = ["#{tmp} = #{process rhs, :expr}"]
1068
1089
  elsif rhs[0] == :to_ary
1069
- code = ["#{tmp} = [#{process rhs[1], :expr}]"]
1090
+ code = ["((#{tmp} = #{process rhs[1], :expr})._isArray ? #{tmp} : (#{tmp} = [#{tmp}]))"]
1070
1091
  elsif rhs[0] == :splat
1071
1092
  code = ["#{tmp} = #{process rhs[1], :expr}"]
1072
1093
  else
@@ -1302,7 +1323,7 @@ module Opal
1302
1323
  tmp = @scope.new_temp
1303
1324
 
1304
1325
  if t = js_truthy_optimize(lhs)
1305
- return "(#{tmp} = #{t} ? #{process rhs, :expr} : #{tmp})".tap {
1326
+ return "((#{tmp} = #{t}) ? #{process rhs, :expr} : #{tmp})".tap {
1306
1327
  @scope.queue_temp tmp
1307
1328
  }
1308
1329
  end
@@ -1310,7 +1331,7 @@ module Opal
1310
1331
  @scope.queue_temp tmp
1311
1332
 
1312
1333
  "(%s = %s, %s !== false && %s !== nil ? %s : %s)" %
1313
- [tmp, process(lhs, :expr), tmp, tmp, process(rhs, :expr), tmp]
1334
+ [tmp, process(lhs, :expr), tmp, tmp, process(rhs, :expr), tmp]
1314
1335
  end
1315
1336
 
1316
1337
  # s(:or, lhs, rhs)
@@ -1318,18 +1339,15 @@ module Opal
1318
1339
  lhs = sexp[0]
1319
1340
  rhs = sexp[1]
1320
1341
  t = nil
1321
- tmp = @scope.new_temp
1322
1342
 
1323
- if t = js_truthy_optimize(lhs)
1324
- return "(#{tmp} = #{t} ? #{tmp} : #{process rhs, :expr})".tap {
1325
- @scope.queue_temp tmp
1326
- }
1343
+ with_temp do |tmp|
1344
+ # if t = js_truthy_optimize(lhs)
1345
+ # "((%s = %s) ? %s : %s)" % [tmp, t, tmp, process(rhs, :expr)]
1346
+ # else
1347
+ "((%s = %s), %s !== false && %s !== nil ? %s : %s)" %
1348
+ [tmp, process(lhs, :expr), tmp, tmp, tmp, process(rhs, :expr)]
1349
+ # end
1327
1350
  end
1328
-
1329
- @scope.queue_temp tmp
1330
-
1331
- "(%s = %s, %s !== false && %s !== nil ? %s : %s)" %
1332
- [tmp, process(lhs, :expr), tmp, tmp, tmp, process(rhs, :expr)]
1333
1351
  end
1334
1352
 
1335
1353
  # s(:yield, arg1, arg2)
@@ -1339,18 +1357,31 @@ module Opal
1339
1357
  if level == :stmt
1340
1358
  "if (#{call} === __breaker) return __breaker.$v"
1341
1359
  else
1342
- call
1360
+ with_temp do |tmp|
1361
+ "(((#{tmp} = #{call}) === __breaker) ? __breaker.$v : #{tmp})"
1362
+ end
1343
1363
  end
1344
1364
  end
1345
1365
 
1366
+ # special opal yield assign, for `a = yield(arg1, arg2)` to assign
1367
+ # to a temp value to make yield expr into stmt.
1368
+ #
1369
+ # level will always be stmt as its the reason for this to exist
1370
+ #
1371
+ # s(:yasgn, :a, s(:yield, arg1, arg2))
1372
+ def process_yasgn(sexp, level)
1373
+ call = handle_yield_call s(*sexp[1][1..-1]), :stmt
1374
+ "if ((%s = %s) === __breaker) return __breaker.$v" % [sexp[0], call]
1375
+ end
1376
+
1346
1377
  # Created by `#returns()` for when a yield statement should return
1347
1378
  # it's value (its last in a block etc).
1348
1379
  def process_returnable_yield(sexp, level)
1349
1380
  call = handle_yield_call sexp, level
1350
1381
 
1351
1382
  with_temp do |tmp|
1352
- "return %s = #{call}, %s === __breaker ? %s : %s" %
1353
- [tmp, tmp, tmp, tmp]
1383
+ "return %s = %s, %s === __breaker ? %s : %s" %
1384
+ [tmp, call, tmp, tmp, tmp]
1354
1385
  end
1355
1386
  end
1356
1387
 
@@ -1358,12 +1389,12 @@ module Opal
1358
1389
  @scope.uses_block!
1359
1390
 
1360
1391
  splat = sexp.any? { |s| s.first == :splat }
1361
- sexp.unshift s(:js_tmp, '__context') # self
1392
+ sexp.unshift s(:js_tmp, '__context') unless splat # self
1362
1393
  args = process_arglist sexp, level
1363
1394
 
1364
1395
  y = @scope.block_name || '__yield'
1365
1396
 
1366
- splat ? "#{y}.apply(null, #{args})" : "#{y}(#{args})"
1397
+ splat ? "#{y}.apply(__context, #{args})" : "#{y}.call(#{args})"
1367
1398
  end
1368
1399
 
1369
1400
  def process_break(exp, level)
@@ -1421,7 +1452,7 @@ module Opal
1421
1452
  until arg.empty?
1422
1453
  a = arg.shift
1423
1454
 
1424
- if a.first == :when # when inside another when means a splat of values
1455
+ if a.first == :splat # when inside another when means a splat of values
1425
1456
  call = s(:call, s(:js_tmp, "$splt[i]"), :===, s(:arglist, s(:js_tmp, "$case")))
1426
1457
  splt = "(function($splt) {for(var i = 0; i < $splt.length; i++) {"
1427
1458
  splt += "if (#{process call, :expr}) { return true; }"
@@ -1488,7 +1519,7 @@ module Opal
1488
1519
  #
1489
1520
  # s(:super, arg1, arg2, ...)
1490
1521
  def process_super(sexp, level)
1491
- args = ['self']
1522
+ args = []
1492
1523
  until sexp.empty?
1493
1524
  args << process(sexp.shift, :expr)
1494
1525
  end
@@ -1506,23 +1537,28 @@ module Opal
1506
1537
  def js_super args
1507
1538
  if @scope.def_in_class?
1508
1539
  mid = @scope.mid.to_s
1509
- # jsid = mid_to_jsid @scope.mid.to_s
1510
- @scope.uses_super = "super_#{mid}"
1511
- "super_#{mid}.apply(null, #{ args })"
1540
+ sid = "super_#{unique_temp}"
1541
+
1542
+ @scope.uses_super = sid
1543
+ "#{sid}.apply(#{current_self}, #{ args })"
1512
1544
 
1513
1545
  elsif @scope.type == :def
1514
1546
  identity = @scope.identify!
1515
1547
  cls_name = @scope.parent.name
1516
1548
  jsid = mid_to_jsid @scope.mid.to_s
1517
- base = @scope.defs ? '' : ".$m_tbl"
1549
+ # base = @scope.defs ? '' : ".prototype"
1518
1550
 
1519
- "%s.$s%s%s.apply(this, %s)" % [cls_name, base, jsid, args]
1551
+ # "%s._super%s%s.apply(this, %s)" % [cls_name, base, jsid, args]
1552
+ if @scope.defs
1553
+ "%s._super%s.apply(this, %s)" % [cls_name, jsid, args]
1554
+ else
1555
+ "#{current_self}._klass._super.prototype%s.apply(#{current_self}, %s)" % [jsid, args]
1556
+ end
1520
1557
 
1521
1558
  elsif @scope.type == :iter
1522
1559
  chain, defn, mid = @scope.get_super_chain
1523
1560
  trys = chain.map { |c| "#{c}._sup" }.join ' || '
1524
- "(#{trys} || this.$k.$s.$m_tbl[#{mid}]).apply(this, #{args})"
1525
-
1561
+ "(#{trys} || this._klass._super.prototype[#{mid}]).apply(this, #{args})"
1526
1562
  else
1527
1563
  raise "Cannot call super() from outside a method block"
1528
1564
  end
@@ -1601,6 +1637,7 @@ module Opal
1601
1637
  def process_resbody(exp, level)
1602
1638
  args = exp[0]
1603
1639
  body = exp[1]
1640
+
1604
1641
  body = process(body || s(:nil), level)
1605
1642
  types = args[1..-2]
1606
1643
 
@@ -1612,7 +1649,7 @@ module Opal
1612
1649
  }.join ', '
1613
1650
  err = "true" if err.empty?
1614
1651
 
1615
- if Array === args.last and [:lasgn, :iasgn].include? args.last.first
1652
+ if Sexp === args.last and [:lasgn, :iasgn].include? args.last.first
1616
1653
  val = args.last
1617
1654
  val[2] = s(:js_tmp, "$err")
1618
1655
  val = process(val, :expr) + ";"