opal 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (306) hide show
  1. data/.gitignore +10 -1
  2. data/.gitmodules +0 -0
  3. data/Opalfile +371 -0
  4. data/README.md +45 -0
  5. data/Rakefile +237 -34
  6. data/VERSION +1 -1
  7. data/bin/opal +13 -0
  8. data/demos/apps/browser_demo/index.html +11 -0
  9. data/demos/apps/browser_demo/lib/browser_demo.rb +31 -0
  10. data/demos/apps/simple_opal/Opalfile +13 -0
  11. data/demos/apps/simple_opal/index.html +11 -0
  12. data/demos/apps/simple_opal/lib/app_controller.rb +62 -0
  13. data/demos/apps/simple_opal/lib/main_window.rb +146 -0
  14. data/demos/browser/request/index.html +52 -0
  15. data/demos/browser/request/request.rb +48 -0
  16. data/gen/browser/__PROJECT_NAME__/index.html +10 -0
  17. data/gen/browser/__PROJECT_NAME__/lib/__PROJECT_NAME__.rb +1 -0
  18. data/lib/opal.rb +48 -3
  19. data/lib/opal/builders/base.rb +50 -0
  20. data/lib/opal/builders/css.rb +46 -0
  21. data/lib/opal/builders/javascript.rb +44 -0
  22. data/lib/opal/builders/opal.rb +79 -0
  23. data/lib/opal/builders/ruby.rb +50 -0
  24. data/lib/opal/builders/ruby/generate.rb +1851 -0
  25. data/lib/opal/builders/ruby/nodes.rb +210 -0
  26. data/lib/opal/builders/ruby/ruby.rb +916 -0
  27. data/lib/opal/builders/ruby/ruby_parser.rb +6008 -0
  28. data/lib/opal/builders/ruby/ruby_parser.rb.y +1451 -0
  29. data/lib/opal/models/build_item.rb +104 -0
  30. data/lib/opal/models/hash_struct.rb +40 -0
  31. data/lib/opal/models/project.rb +215 -0
  32. data/lib/opal/models/struct_accessors.rb +58 -0
  33. data/lib/opal/models/target.rb +176 -0
  34. data/lib/opal/opal/env/console.rb +66 -0
  35. data/lib/opal/opal/env/fs.rb +98 -0
  36. data/lib/opal/opal/env/object.rb +48 -0
  37. data/lib/opal/opal/environment.rb +139 -0
  38. data/lib/opal/opal/gen.rb +62 -0
  39. data/lib/opal/opal/opal.rb +68 -0
  40. data/lib/opal/opal/repl.rb +38 -0
  41. data/lib/opal/opalfile/dsl.rb +62 -0
  42. data/lib/opal/opalfile/opalfile.rb +133 -0
  43. data/lib/opal/opalfile/task.rb +96 -0
  44. data/lib/opal/opalfile/task_manager.rb +63 -0
  45. data/lib/opal/opalfile/task_scope.rb +52 -0
  46. data/lib/opal/rack/app_server.rb +119 -0
  47. data/opals/aristo/README.md +16 -0
  48. data/opals/browser/Opalfile +11 -0
  49. data/opals/browser/README.md +146 -0
  50. data/opals/browser/SIZZLE_LICESNSE.txt +148 -0
  51. data/opals/browser/lib/browser.rb +118 -0
  52. data/opals/browser/lib/browser/builder.rb +41 -0
  53. data/opals/browser/lib/browser/canvas_context.rb +115 -0
  54. data/opals/browser/lib/browser/dimensions.rb +50 -0
  55. data/opals/browser/lib/browser/document.rb +146 -0
  56. data/opals/browser/lib/browser/element.rb +487 -0
  57. data/opals/browser/lib/browser/element/attributes.rb +88 -0
  58. data/opals/browser/lib/browser/element/css.rb +290 -0
  59. data/opals/browser/lib/browser/element/form.rb +146 -0
  60. data/opals/browser/lib/browser/event/dom_events.rb +81 -0
  61. data/opals/browser/lib/browser/event/event.rb +177 -0
  62. data/opals/browser/lib/browser/event/trigger_events.rb +53 -0
  63. data/opals/browser/lib/browser/geometry.rb +97 -0
  64. data/opals/browser/lib/browser/json.rb +32 -0
  65. data/opals/browser/lib/browser/json_parse.js +321 -0
  66. data/opals/browser/lib/browser/request/request.rb +201 -0
  67. data/opals/browser/lib/browser/sizzle.js +1068 -0
  68. data/opals/browser/lib/browser/string.rb +42 -0
  69. data/opals/browser/lib/browser/touch.rb +37 -0
  70. data/{runtime/yaml.js → opals/browser/lib/browser/vml_context.js} +8 -8
  71. data/opals/browser/lib/browser/window.rb +36 -0
  72. data/opals/browser/spec/browser/browser_detection_spec.rb +7 -0
  73. data/opals/browser/spec/document/aref_spec.rb +110 -0
  74. data/opals/browser/spec/document/ready_spec.rb +16 -0
  75. data/opals/browser/spec/element/body_spec.rb +11 -0
  76. data/opals/browser/spec/element/clear_spec.rb +26 -0
  77. data/opals/browser/spec/element/empty_spec.rb +29 -0
  78. data/opals/browser/spec/element/has_class_spec.rb +40 -0
  79. data/opals/browser/spec/element/hidden_spec.rb +23 -0
  80. data/opals/browser/spec/element/hide_spec.rb +31 -0
  81. data/opals/browser/spec/element/remove_spec.rb +25 -0
  82. data/opals/browser/spec/element/show_spec.rb +31 -0
  83. data/opals/browser/spec/element/style_spec.rb +69 -0
  84. data/opals/browser/spec/element/toggle_spec.rb +31 -0
  85. data/opals/browser/spec/element/visible_spec.rb +23 -0
  86. data/opals/browser/spec/spec_helper.rb +1 -0
  87. data/opals/cherry_kit/Opalfile +6 -0
  88. data/opals/cherry_kit/bin/cherry_kit.rb +11 -0
  89. data/opals/cherry_kit/lib/cherry_kit.rb +29 -0
  90. data/opals/foundation/Opalfile +11 -0
  91. data/opals/foundation/bin/foundation.rb +12 -0
  92. data/opals/foundation/lib/foundation.rb +32 -0
  93. data/opals/foundation/lib/foundation/__table_view_desktop/outline_view.rb +57 -0
  94. data/opals/foundation/lib/foundation/__table_view_desktop/table_column.rb +59 -0
  95. data/opals/foundation/lib/foundation/__table_view_desktop/table_header_view.rb +34 -0
  96. data/opals/foundation/lib/foundation/__table_view_desktop/table_view.rb +304 -0
  97. data/opals/foundation/lib/foundation/controllers/array_controller.rb +54 -0
  98. data/opals/foundation/lib/foundation/controllers/controller.rb +74 -0
  99. data/opals/foundation/lib/foundation/controllers/controller_selection_proxy.rb +67 -0
  100. data/opals/foundation/lib/foundation/controllers/object_controller.rb +145 -0
  101. data/opals/foundation/lib/foundation/controllers/view.rb +40 -0
  102. data/opals/foundation/lib/foundation/core/application.rb +476 -0
  103. data/opals/foundation/lib/foundation/core/attributes.rb +146 -0
  104. data/opals/foundation/lib/foundation/core/bindings.rb +125 -0
  105. data/opals/foundation/lib/foundation/core/builder.rb +101 -0
  106. data/opals/foundation/lib/foundation/core/event.rb +112 -0
  107. data/opals/foundation/lib/foundation/core/index_path.rb +49 -0
  108. data/opals/foundation/lib/foundation/core/index_set.rb +97 -0
  109. data/opals/foundation/lib/foundation/core/notification.rb +113 -0
  110. data/opals/foundation/lib/foundation/core/observable.rb +275 -0
  111. data/opals/foundation/lib/foundation/core/observable_array.rb +30 -0
  112. data/opals/foundation/lib/foundation/core/responder.rb +85 -0
  113. data/opals/foundation/lib/foundation/core/run_loop.rb +89 -0
  114. data/opals/foundation/lib/foundation/core/touch.rb +95 -0
  115. data/opals/foundation/lib/foundation/gestures/gesture_recognizer.rb +35 -0
  116. data/opals/foundation/lib/foundation/rendering/render_context.rb +100 -0
  117. data/opals/foundation/lib/foundation/rendering/renderer.rb +137 -0
  118. data/opals/foundation/lib/foundation/rendering/root_theme.rb +77 -0
  119. data/opals/foundation/lib/foundation/rendering/root_theme/button.rb +62 -0
  120. data/opals/foundation/lib/foundation/rendering/root_theme/control.rb +72 -0
  121. data/opals/foundation/lib/foundation/rendering/root_theme/label.rb +54 -0
  122. data/opals/foundation/lib/foundation/rendering/root_theme/scroller.rb +58 -0
  123. data/opals/foundation/lib/foundation/rendering/root_theme/slider.rb +72 -0
  124. data/opals/foundation/lib/foundation/rendering/root_theme/table_view.rb +97 -0
  125. data/opals/foundation/lib/foundation/rendering/root_theme/text_field.rb +55 -0
  126. data/opals/foundation/lib/foundation/rendering/root_theme/view.rb +81 -0
  127. data/opals/foundation/lib/foundation/rendering/theme.rb +38 -0
  128. data/opals/foundation/lib/foundation/table_view/cell.rb +39 -0
  129. data/opals/foundation/lib/foundation/table_view/table.rb +171 -0
  130. data/opals/foundation/lib/foundation/views/button.rb +63 -0
  131. data/opals/foundation/lib/foundation/views/checkbox.rb +28 -0
  132. data/opals/foundation/lib/foundation/views/clip.rb +47 -0
  133. data/opals/foundation/lib/foundation/views/control.rb +199 -0
  134. data/opals/foundation/lib/foundation/views/label.rb +54 -0
  135. data/opals/foundation/lib/foundation/views/scroll.rb +294 -0
  136. data/opals/foundation/lib/foundation/views/scroll_view_desktop.rb +152 -0
  137. data/opals/foundation/lib/foundation/views/scroller.rb +54 -0
  138. data/opals/foundation/lib/foundation/views/slider.rb +93 -0
  139. data/opals/foundation/lib/foundation/views/text_field.rb +83 -0
  140. data/opals/foundation/lib/foundation/views/view.rb +426 -0
  141. data/opals/foundation/lib/foundation/windows/window.rb +191 -0
  142. data/opals/foundation/resources/button/button.css +23 -0
  143. data/{runtime/init.js → opals/foundation/resources/foundation.css} +27 -33
  144. data/opals/foundation/resources/scroll/scroll.css +22 -0
  145. data/opals/foundation/resources/scroll_view/scroll_view.css +3 -0
  146. data/opals/foundation/resources/scroll_view/scroller.css +3 -0
  147. data/opals/foundation/resources/slider/regular/slider.css +3 -0
  148. data/opals/foundation/resources/slider/slider.css +27 -0
  149. data/opals/foundation/resources/table_view/outline_view.css +3 -0
  150. data/opals/foundation/resources/table_view/table_view.css +15 -0
  151. data/opals/foundation/resources/text_field/text_field.css +71 -0
  152. data/opals/foundation/spec/spec_helper.rb +1 -0
  153. data/opals/foundation/spec/system/attributes/get_attribute_spec.rb +69 -0
  154. data/opals/foundation/spec/system/attributes/get_path_spec.rb +44 -0
  155. data/opals/foundation/spec/system/attributes/set_path_spec.rb +24 -0
  156. data/opals/foundation/spec/system/attributes/set_spec.rb +58 -0
  157. data/opals/foundation/spec/system/bindings/bindings.rb +85 -0
  158. data/opals/foundation/spec/system/key_value_binding/bind_spec.rb +43 -0
  159. data/opals/foundation/spec/system/observable/dependant_keys_spec.rb +74 -0
  160. data/opals/foundation/spec/system/observable/observe_spec.rb +292 -0
  161. data/opals/foundation/spec/system/observable/remove_observer_spec.rb +60 -0
  162. data/opals/opal/Opalfile +14 -0
  163. data/opals/opal/spec/core/array/append_spec.rb +30 -0
  164. data/opals/opal/spec/core/array/assoc_spec.rb +29 -0
  165. data/opals/opal/spec/core/array/at_spec.rb +37 -0
  166. data/opals/opal/spec/core/array/clear_spec.rb +22 -0
  167. data/opals/opal/spec/core/array/collect_bang_spec.rb +27 -0
  168. data/opals/opal/spec/core/array/collect_spec.rb +27 -0
  169. data/opals/opal/spec/core/array/compact_spec.rb +15 -0
  170. data/opals/opal/spec/core/array/concat_spec.rb +15 -0
  171. data/opals/opal/spec/core/array/constructor_spec.rb +14 -0
  172. data/opals/opal/spec/core/array/each_spec.rb +9 -0
  173. data/opals/opal/spec/core/array/element_reference_spec.rb +4 -0
  174. data/opals/opal/spec/core/array/first_spec.rb +35 -0
  175. data/opals/opal/spec/core/array/include_spec.rb +9 -0
  176. data/opals/opal/spec/core/array/map_spec.rb +31 -0
  177. data/opals/opal/spec/core/builtin_constants/builtin_constants_spec.rb +7 -0
  178. data/opals/opal/spec/core/false/and_spec.rb +10 -0
  179. data/opals/opal/spec/core/false/inspect_spec.rb +6 -0
  180. data/opals/opal/spec/core/false/or_spec.rb +10 -0
  181. data/opals/opal/spec/core/false/to_s_spec.rb +6 -0
  182. data/opals/opal/spec/core/false/xor_spec.rb +10 -0
  183. data/opals/opal/spec/core/file/join_spec.rb +19 -0
  184. data/opals/opal/spec/core/kernel/instance_eval_spec.rb +0 -0
  185. data/opals/opal/spec/core/kernel/loop_spec.rb +24 -0
  186. data/opals/opal/spec/core/kernel/raise_spec.rb +0 -0
  187. data/opals/opal/spec/core/module/attr_accessor_spec.rb +28 -0
  188. data/opals/opal/spec/core/number/lt_spec.rb +12 -0
  189. data/opals/opal/spec/core/true/and_spec.rb +10 -0
  190. data/opals/opal/spec/core/true/inspect_spec.rb +6 -0
  191. data/opals/opal/spec/core/true/or_spec.rb +10 -0
  192. data/opals/opal/spec/core/true/to_s_spec.rb +6 -0
  193. data/opals/opal/spec/core/true/xor_spec.rb +10 -0
  194. data/opals/opal/spec/fixtures/super.rb +70 -0
  195. data/opals/opal/spec/language/____temp_remove_this.rb +12 -0
  196. data/opals/opal/spec/language/and_spec.rb +62 -0
  197. data/opals/opal/spec/language/array_spec.rb +52 -0
  198. data/opals/opal/spec/language/block_spec.rb +18 -0
  199. data/opals/opal/spec/language/break_spec.rb +36 -0
  200. data/opals/opal/spec/language/case_spec.rb +103 -0
  201. data/opals/opal/spec/language/def_spec.rb +11 -0
  202. data/opals/opal/spec/language/eigenclass_spec.rb +60 -0
  203. data/opals/opal/spec/language/hash_spec.rb +29 -0
  204. data/opals/opal/spec/language/if_spec.rb +54 -0
  205. data/opals/opal/spec/language/loop_spec.rb +11 -0
  206. data/opals/opal/spec/language/metaclass_spec.rb +21 -0
  207. data/opals/opal/spec/language/method_spec.rb +64 -0
  208. data/opals/opal/spec/language/next_spec.rb +25 -0
  209. data/opals/opal/spec/language/or_spec.rb +34 -0
  210. data/opals/opal/spec/language/redo_spec.rb +24 -0
  211. data/opals/opal/spec/language/rescue_spec.rb +20 -0
  212. data/opals/opal/spec/language/return_spec.rb +47 -0
  213. data/opals/opal/spec/language/string_spec.rb +25 -0
  214. data/opals/opal/spec/language/super_spec.rb +26 -0
  215. data/opals/opal/spec/language/until_spec.rb +157 -0
  216. data/opals/opal/spec/language/while_spec.rb +163 -0
  217. data/opals/opal/spec/spec_helper.rb +5 -0
  218. data/opals/runtime/Opalfile +68 -0
  219. data/opals/runtime/README.md +12 -0
  220. data/opals/runtime/docs/debugging.md +51 -0
  221. data/opals/runtime/lib/array.rb +1516 -0
  222. data/opals/runtime/lib/basic_object.rb +49 -0
  223. data/opals/runtime/lib/class.rb +54 -0
  224. data/opals/runtime/lib/dir.rb +36 -0
  225. data/opals/runtime/lib/error.rb +49 -0
  226. data/opals/runtime/lib/false_class.rb +52 -0
  227. data/opals/runtime/lib/file.rb +79 -0
  228. data/opals/runtime/lib/hash.rb +791 -0
  229. data/opals/runtime/lib/io.rb +39 -0
  230. data/opals/runtime/lib/kernel.rb +288 -0
  231. data/opals/runtime/lib/match_data.rb +36 -0
  232. data/opals/runtime/lib/module.rb +109 -0
  233. data/opals/runtime/lib/nil_class.rb +69 -0
  234. data/opals/runtime/lib/number.rb +398 -0
  235. data/opals/runtime/lib/proc.rb +77 -0
  236. data/opals/runtime/lib/range.rb +63 -0
  237. data/opals/runtime/lib/regexp.rb +111 -0
  238. data/opals/runtime/lib/ruby.rb +30 -0
  239. data/opals/runtime/lib/string.rb +328 -0
  240. data/opals/runtime/lib/symbol.rb +40 -0
  241. data/opals/runtime/lib/top_self.rb +33 -0
  242. data/opals/runtime/lib/true_class.rb +45 -0
  243. data/opals/runtime/runtime/browser.js +287 -0
  244. data/opals/runtime/runtime/debug.js +182 -0
  245. data/opals/runtime/runtime/opal.js +1010 -0
  246. data/opals/runtime/runtime/post_opal.js +1 -0
  247. data/opals/runtime/runtime/pre_opal.js +2 -0
  248. data/opals/runtime/runtime/server_side.js +50 -0
  249. data/opals/spec/LICENSE.txt +26 -0
  250. data/opals/spec/Opalfile +5 -0
  251. data/opals/spec/bin/spec.rb +43 -0
  252. data/opals/spec/lib/spec.rb +33 -0
  253. data/opals/spec/lib/spec/dsl.rb +41 -0
  254. data/opals/spec/lib/spec/example.rb +35 -0
  255. data/opals/spec/lib/spec/example/before_and_after_hooks.rb +81 -0
  256. data/opals/spec/lib/spec/example/errors.rb +42 -0
  257. data/opals/spec/lib/spec/example/example_group.rb +37 -0
  258. data/opals/spec/lib/spec/example/example_group_factory.rb +43 -0
  259. data/opals/spec/lib/spec/example/example_group_hierarchy.rb +45 -0
  260. data/opals/spec/lib/spec/example/example_group_methods.rb +142 -0
  261. data/opals/spec/lib/spec/example/example_group_proxy.rb +41 -0
  262. data/opals/spec/lib/spec/example/example_methods.rb +73 -0
  263. data/opals/spec/lib/spec/example/example_proxy.rb +48 -0
  264. data/opals/spec/lib/spec/expectations.rb +46 -0
  265. data/opals/spec/lib/spec/expectations/errors.rb +35 -0
  266. data/opals/spec/lib/spec/expectations/fail_with.rb +37 -0
  267. data/opals/spec/lib/spec/expectations/handler.rb +48 -0
  268. data/opals/spec/lib/spec/matchers.rb +50 -0
  269. data/opals/spec/lib/spec/matchers/be.rb +26 -0
  270. data/opals/spec/lib/spec/matchers/generated_descriptions.rb +47 -0
  271. data/opals/spec/lib/spec/matchers/operator_matcher.rb +66 -0
  272. data/opals/spec/lib/spec/runner.rb +48 -0
  273. data/opals/spec/lib/spec/runner/example_group_runner.rb +71 -0
  274. data/opals/spec/lib/spec/runner/formatter/html_formatter.rb +100 -0
  275. data/opals/spec/lib/spec/runner/formatter/terminal_formatter.rb +82 -0
  276. data/opals/spec/lib/spec/runner/options.rb +63 -0
  277. data/opals/spec/lib/spec/runner/reporter.rb +123 -0
  278. data/opals/spec/resources/index.html +25 -0
  279. data/opals/spec/resources/spec.css +132 -0
  280. data/spec/cherry_kit/iseq_spec.rb +38 -0
  281. data/spec/spec_helper.rb +16 -0
  282. data/spec/vienna_spec.rb +7 -0
  283. data/yard/index.html +43 -0
  284. data/yard/style.css +765 -0
  285. metadata +312 -49
  286. data/docs/jarv.rdoc +0 -27
  287. data/runtime/array.js +0 -153
  288. data/runtime/class.js +0 -469
  289. data/runtime/compar.js +0 -73
  290. data/runtime/dir.js +0 -115
  291. data/runtime/enum.js +0 -74
  292. data/runtime/file.js +0 -165
  293. data/runtime/gem.js +0 -241
  294. data/runtime/hash.js +0 -181
  295. data/runtime/load.js +0 -251
  296. data/runtime/module.js +0 -98
  297. data/runtime/number.js +0 -148
  298. data/runtime/object.js +0 -522
  299. data/runtime/opal.js +0 -200
  300. data/runtime/parse.js +0 -2218
  301. data/runtime/range.js +0 -56
  302. data/runtime/re.js +0 -91
  303. data/runtime/string.js +0 -199
  304. data/runtime/variable.js +0 -184
  305. data/runtime/vm.js +0 -1150
  306. data/tasks/build.rb +0 -16
@@ -0,0 +1,50 @@
1
+ #
2
+ # base.rb
3
+ # vienna
4
+ #
5
+ # Created by Adam Beynon.
6
+ # Copyright 2010 Adam Beynon.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files (the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #
26
+
27
+ module Vienna
28
+
29
+ module Builders
30
+
31
+ class Base
32
+
33
+ attr_reader :build_item
34
+
35
+ def initialize(build_item, dst)
36
+ @build_item = build_item
37
+ @dst_path = dst
38
+ end
39
+
40
+ # build the item
41
+ def build
42
+ end
43
+
44
+ def self.build(build_item, dst)
45
+ new(build_item, dst).build
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # css.rb
3
+ # vienna
4
+ #
5
+ # Created by Adam Beynon.
6
+ # Copyright 2010 Adam Beynon.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files (the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #
26
+
27
+ require File.join(File.dirname(__FILE__), 'base')
28
+
29
+ module Vienna
30
+
31
+ module Builders
32
+
33
+ class CSS < Base
34
+
35
+ def build
36
+ FileUtils.mkdir_p(File.dirname(@dst_path))
37
+
38
+ # puts "building to #{@dst_path}"
39
+
40
+ File.open(@dst_path, 'w') do |out|
41
+ out.write File.read(@build_item.source_path)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,44 @@
1
+ #
2
+ # javascript.rb
3
+ # vienna
4
+ #
5
+ # Created by Adam Beynon.
6
+ # Copyright 2010 Adam Beynon.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files (the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #
26
+
27
+ require File.join(File.dirname(__FILE__), 'base')
28
+
29
+ module Vienna
30
+
31
+ module Builders
32
+
33
+ class Javascript < Base
34
+
35
+ def build
36
+ FileUtils.mkdir_p(File.dirname(@dst_path))
37
+
38
+ File.open(@dst_path, 'w') do |out|
39
+ out.write File.read(@build_item.source_path)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,79 @@
1
+ #
2
+ # opal.rb
3
+ # vienna
4
+ #
5
+ # Created by Adam Beynon.
6
+ # Copyright 2010 Adam Beynon.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files (the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #
26
+
27
+ require File.join(File.dirname(__FILE__), 'base')
28
+
29
+ module Vienna
30
+
31
+ module Builders
32
+
33
+ class Opal < Base
34
+
35
+ def build
36
+ # puts "building opal to #{@build_item.build_path}"
37
+ source_items = @build_item.source_items
38
+ build_path = @build_item.build_path
39
+
40
+ FileUtils.mkdir_p File.dirname(build_path)
41
+
42
+ exec_sources = source_items.select do |item|
43
+ item.ext == 'rb' || item.ext == 'js'
44
+ end
45
+
46
+ File.open(build_path, 'w') do |out|
47
+ # opal definition and required attributes
48
+ out.puts %Q|opal.register({|
49
+ out.puts %Q| "name": "#{@build_item.target.target_name}",|
50
+ # executable sources
51
+ out.puts %Q| "files": {|
52
+ exec_sources.each_with_index do |item, index|
53
+ out.puts(",") if index > 0
54
+ contents = File.read(item.stage!.staging_path)
55
+ if item.ext == "rb"
56
+ out.write %Q| "#{item.filename}": #{contents}|
57
+ else
58
+ # must wrap javascript in function closure
59
+ out.write %Q| "#{item.filename}": function() {#{contents}}|
60
+ end
61
+ end
62
+ out.puts "\n }"
63
+
64
+
65
+ #
66
+ out.puts "});"
67
+ end
68
+
69
+ # source_items.each do |item|
70
+ # staged_path = item.stage!.staging_path
71
+ #
72
+ # puts staged_path
73
+ # puts item.ext
74
+ # end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,50 @@
1
+ #
2
+ # ruby.rb
3
+ # vienna
4
+ #
5
+ # Created by Adam Beynon.
6
+ # Copyright 2010 Adam Beynon.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files (the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #
26
+
27
+ require File.join(File.dirname(__FILE__), 'base')
28
+
29
+ module Vienna
30
+
31
+ module Builders
32
+
33
+ class Ruby < Base
34
+
35
+ # Build the ruby file.. here we actually cheat and use a completely
36
+ # differently parser/compiler
37
+ def build
38
+ # puts "building to #{@build_item.source_path}"
39
+ # Vienna::RubyParser.new(@build_item.source_path, @dst_path, "").build!
40
+ res = Vienna::RubyParser.new(@build_item.source_path, File.read(@build_item.source_path)).build!
41
+
42
+ FileUtils.mkdir_p(File.dirname(@dst_path))
43
+ File.open(@dst_path, 'w') do |out|
44
+ out.write res
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,1851 @@
1
+ #
2
+ # generate.rb
3
+ # vienna
4
+ #
5
+ # Created by Adam Beynon.
6
+ # Copyright 2009 Adam Beynon.
7
+ #
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files (the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #
26
+
27
+ require File.join(File.dirname(__FILE__), 'ruby_parser.rb')
28
+
29
+ module Vienna
30
+
31
+ class RubyParser < ::Racc::Parser
32
+
33
+
34
+ # ISEQ types
35
+ ISEQ_TYPE_TOP = 1
36
+ ISEQ_TYPE_METHOD = 2
37
+ ISEQ_TYPE_BLOCK = 3
38
+ ISEQ_TYPE_CLASS = 4
39
+ ISEQ_TYPE_RESCUE = 5
40
+ ISEQ_TYPE_ENSURE = 6
41
+ ISEQ_TYPE_EVAL = 7
42
+ ISEQ_TYPE_MAIN = 8
43
+ # opt args etc use this
44
+ ISEQ_TYPE_TEMP = 9
45
+
46
+
47
+
48
+ # Generate any type of statement with the given options
49
+ #
50
+ def generate_stmt stmt, context
51
+ return if stmt.is_a?(Array)
52
+ # puts stmt
53
+ case stmt.node
54
+ when :klass
55
+ generate_class stmt, context
56
+ when :module
57
+ generate_module stmt, context
58
+ when :class_shift
59
+ generate_class_shift stmt, context
60
+ when :def
61
+ generate_def stmt, context
62
+ when :numeric
63
+ generate_numeric stmt, context
64
+ when :call
65
+ generate_call stmt, context
66
+ when :super
67
+ generate_super stmt, context
68
+ when :identifier
69
+ generate_identifier stmt, context
70
+ when :ivar
71
+ generate_ivar stmt, context
72
+ when :cvar
73
+ generate_cvar stmt, context
74
+ when :constant
75
+ generate_constant stmt, context
76
+ when :symbol
77
+ generate_symbol stmt, context
78
+ when :self
79
+ generate_self stmt, context
80
+ when :true
81
+ generate_true stmt, context
82
+ when :false
83
+ generate_false stmt, context
84
+ when :nil
85
+ generate_nil stmt, context
86
+ when :if
87
+ generate_if stmt, context
88
+ when :unless
89
+ generate_if stmt, context
90
+ # when :if_mod
91
+ # generate_if_mod stmt, context
92
+ # when :unless_mod
93
+ # generate_if_mod stmt, context
94
+ when :string
95
+ generate_string stmt, context
96
+ when :xstring
97
+ generate_xstring stmt, context
98
+ when :array
99
+ generate_array stmt, context
100
+ when :assign
101
+ generate_assign stmt, context
102
+ when :assoc_list
103
+ generate_assoc_list stmt, context
104
+ when :op_asgn
105
+ generate_op_asgn stmt, context
106
+ when :lparen
107
+ generate_lparen stmt, context
108
+ when :return
109
+ generate_return stmt, context
110
+ when :break
111
+ generate_break stmt, context
112
+ when :colon2
113
+ generate_colon2 stmt, context
114
+ when :colon3
115
+ generate_colon3 stmt, context
116
+ when :case
117
+ generate_case stmt, context
118
+ when :yield
119
+ generate_yield stmt, context
120
+ when :orop
121
+ generate_orop stmt, context
122
+ when :andop
123
+ generate_andop stmt, context
124
+ when :not
125
+ generate_not stmt, context
126
+ when :tertiary
127
+ generate_tertiary stmt, context
128
+ when :dot2
129
+ generate_dot2 stmt, context
130
+ when :dot3
131
+ generate_dot3 stmt, context
132
+ when :__FILE__
133
+ generate__FILE__ stmt, context
134
+ when :__LINE__
135
+ generate__LINE__ stmt, context
136
+ when :opt_plus
137
+ generate_opt_plus stmt, context
138
+ when :opt_minus
139
+ generate_opt_minus stmt, context
140
+ when :opt_mult
141
+ generate_opt_mult stmt, context
142
+ when :opt_div
143
+ generate_opt_div stmt, context
144
+ when :opt_mod
145
+ generate_opt_mod stmt, context
146
+ when :block_given
147
+ generate_block_given stmt, context
148
+ when :regexp
149
+ generate_regexp stmt, context
150
+ when :alias
151
+ generate_alias stmt, context
152
+ when :begin
153
+ generate_begin stmt, context
154
+ when :aset_op_asgn
155
+ generate_aset_op_asgn stmt, context
156
+ when :gvar
157
+ generate_gvar stmt, context
158
+ when :while
159
+ generate_while stmt, context
160
+ when :until
161
+ generate_while stmt, context
162
+ when :lambda
163
+ generate_lambda stmt, context
164
+ when :words
165
+ generate_words stmt, context
166
+ when :next
167
+ generate_next stmt, context
168
+ when :redo
169
+ generate_redo stmt, context
170
+ else
171
+ write "\n[Unknown type for generate_stmt: #{stmt.inspect}]\n"
172
+ end
173
+ end
174
+
175
+ class Iseq
176
+
177
+ attr_accessor :type, :local_current
178
+
179
+ def initialize(type)
180
+ @type = type
181
+ # names => minimized names
182
+ @locals = { }
183
+ # arg name => minimized arg names
184
+ @args = { }
185
+ # arg types/names - these are all ordered
186
+ @norm_arg_names = []
187
+ @opt_arg_names = []
188
+ @rest_arg_name = nil
189
+ @post_arg_names = []
190
+ @block_arg_name = nil
191
+
192
+ @parent_iseq = nil
193
+
194
+ @opt_arg_str = {}
195
+
196
+ @local_current = "a"
197
+
198
+ @code = []
199
+
200
+
201
+ @should_handle_return = false
202
+ end
203
+
204
+ def method_id=(method_id)
205
+ @method_id = method_id
206
+ end
207
+
208
+ def method_id
209
+ if @method_id
210
+ @method_id
211
+ elsif @parent_iseq
212
+ @parent_iseq.method_id
213
+ else
214
+ nil
215
+ end
216
+ end
217
+
218
+ def new_temp_variable
219
+ id = "$#{@local_current}"
220
+ @local_current = @local_current.next
221
+ @locals[id] = id
222
+ id
223
+ end
224
+
225
+ # push "normal" arg name
226
+ def push_arg_name(name)
227
+ # id = @local_current
228
+ # @local_current = @local_current.next
229
+ # @args[name] = "_#{id}"
230
+ # @norm_arg_names.push name
231
+ # "_#{id}"
232
+ @args[name] = name
233
+ @norm_arg_names.push name
234
+ name
235
+ end
236
+
237
+ # push optional arg name, with the node for its default value
238
+ #
239
+ # ['a', ""] <- for example
240
+ def push_opt_arg(name, str)
241
+ # name = arg[0]
242
+ @args[name] = name
243
+ @opt_arg_names.push name
244
+ @opt_arg_str[name] = str
245
+ name
246
+ end
247
+
248
+ # push rest arg name
249
+ def push_rest_arg_name(name)
250
+ # id = @local_current
251
+ # @local_current = @local_current.next
252
+ @args[name] = name
253
+ @rest_arg_name = name
254
+ name
255
+ end
256
+
257
+ # post (notmal args at end) names
258
+ def push_post_arg_name(name)
259
+
260
+ end
261
+
262
+ # block.. not actually added to function
263
+ def push_block_arg_name(name)
264
+ @block_arg_name = name
265
+ end
266
+
267
+ def block_arg_name
268
+ @block_arg_name ||= '__block__'
269
+ end
270
+
271
+ def push_local_name(name)
272
+ # id = @local_current
273
+ # @local_current = @local_current.next
274
+ # @locals[name] = "_#{id}"
275
+ # "_#{id}"
276
+ @locals[name] = name
277
+ name
278
+ end
279
+
280
+ def lookup_local(name)
281
+ return nil if name == nil
282
+ if @locals.has_key?(name)
283
+ @locals[name]
284
+ elsif @args.has_key?(name)
285
+ @args[name]
286
+ elsif @block_arg_name == name
287
+ "__block__"
288
+ elsif @type == RubyParser::ISEQ_TYPE_BLOCK
289
+ @parent_iseq.lookup_local(name)
290
+ else
291
+ nil
292
+ end
293
+ end
294
+
295
+ def parent_iseq=(other)
296
+ @parent_iseq = other
297
+
298
+ if @type == RubyParser::ISEQ_TYPE_BLOCK
299
+ # @local_current = other.local_current
300
+ end
301
+ end
302
+
303
+ def tell_method_to_handle_return
304
+ if @type == RubyParser::ISEQ_TYPE_METHOD
305
+ @should_handle_return = true
306
+ elsif @parent_iseq
307
+ @parent_iseq.tell_method_to_handle_return
308
+ else
309
+ # should we throw error? return isnt in right place..?
310
+ end
311
+ end
312
+
313
+ def parent_iseq
314
+ @parent_iseq
315
+ end
316
+
317
+ def finalize
318
+ if @type == RubyParser::ISEQ_TYPE_BLOCK
319
+ # @parent_iseq.local_current = @local_current
320
+ end
321
+ end
322
+
323
+ def write(str)
324
+ @code << str
325
+ end
326
+
327
+ # r is array to append strings for outputting
328
+ def deal_with_method_args(r)
329
+ r << "function("
330
+
331
+ norm = @norm_arg_names.length
332
+ opt = @opt_arg_names.length
333
+ post = @post_arg_names.length
334
+ rest = @rest_arg_name
335
+
336
+ # Case 1: no args at all (block is dealt with seperately) - def a()
337
+ if norm == 0 && opt == 0 && post == 0 && rest.nil?
338
+ r << "){"
339
+
340
+ if RubyParser::ISEQ_TYPE_METHOD === @type || RubyParser::ISEQ_TYPE_BLOCK === @type
341
+ # r << "var self = this;"
342
+ end
343
+ # block..
344
+ if @block_arg_name != nil
345
+ r << "if (arguments.length > 0 && arguments[0].info & this.TP) {"
346
+ r << " var __block__ = arguments[0];"
347
+ r << "}"
348
+ end
349
+
350
+ # Case 2: just splat args - def a(*args)
351
+ elsif norm == 0 && opt == 0 && post == 0 && rest
352
+ r << "#{@args[@rest_arg_name]}"
353
+ r << "){"
354
+ if RubyParser::ISEQ_TYPE_METHOD === @type || RubyParser::ISEQ_TYPE_BLOCK === @type
355
+ # r << "var self = this;"
356
+ end
357
+ # block..
358
+ if @block_arg_name
359
+ r << %Q|
360
+ if (arguments.length > 0 && arguments[0].info & this.TP) {
361
+ var __block__ = arguments[arguments.length - 1];
362
+ #{@args[@rest_arg_name]} = Array.prototype.slice.call(arguments, arguments.length -1);
363
+ }
364
+ else {
365
+ #{@args[@rest_arg_name]} = Array.prototype.slice.call(arguments);
366
+ }|
367
+ else
368
+ r << %{#{@args[@rest_arg_name]}=Array.prototype.slice.call(arguments);}
369
+ end
370
+
371
+ # Case: one norm arg, rest splat args - def a(name, *args)
372
+ elsif norm == 1 && opt == 0 && post == 0 && rest
373
+ r << "#{@args[@norm_arg_names.first]}"
374
+ r << ",#{@args[@rest_arg_name]}"
375
+ r << "){"
376
+ if RubyParser::ISEQ_TYPE_METHOD === @type || RubyParser::ISEQ_TYPE_BLOCK === @type
377
+ # r << "var self = this;"
378
+ end
379
+ r << "#{@args[@norm_arg_names.first]}=arguments[0];"
380
+ r << %{#{@args[@rest_arg_name]}=Array.prototype.slice.call(arguments,1);}
381
+
382
+ # Case 3: just normal args (any number) - def a(l,m,n,o,p)
383
+ elsif norm > 0 && opt == 0 && post == 0 && rest.nil?
384
+ @norm_arg_names.each do |a|
385
+ r << "," unless a == @norm_arg_names.first
386
+ r << "#{@args[a]}"
387
+ end
388
+ r << "){"
389
+ if RubyParser::ISEQ_TYPE_METHOD === @type || RubyParser::ISEQ_TYPE_BLOCK === @type
390
+ # r << "var self = this;"
391
+ end
392
+ # block..
393
+ if @block_arg_name
394
+ length = @norm_arg_names.length
395
+ r << %Q|var __block__ =
396
+ (arguments[#{length}] && arguments[#{length}].info & this.TP)
397
+ ? arguments[#{length}] : this.n;|
398
+ end
399
+
400
+ # Case: optional args, nothing else; def (a=1); end
401
+ elsif norm == 0 && opt > 0 && post == 0 && rest.nil?
402
+ @opt_arg_names.each do |arg|
403
+ r << arg
404
+ r << ", " unless @opt_arg_names.last == arg
405
+ end
406
+ r << "){"
407
+ @opt_arg_names.each do |arg|
408
+ r << "if (#{arg} == undefined) {"
409
+ r << " #{arg} = #{@opt_arg_str[arg]};"
410
+ r << "}"
411
+ end
412
+
413
+ if @block_arg_name
414
+ length = @opt_arg_names.length
415
+ r << %Q|var __block__ =
416
+ (arguments[#{length}] && arguments[#{length}].info & this.TP)
417
+ ? arguments[#{length}] : this.n;|
418
+ end
419
+
420
+ # Case: some normal args, some optional, nothing else
421
+ elsif norm > 0 && opt > 0 && post == 0 && rest.nil?
422
+ @norm_arg_names.each do |a|
423
+ r << ', ' unless a == @norm_arg_names.first
424
+ r << @args[a]
425
+ end
426
+
427
+ @opt_arg_names.each do |arg|
428
+ r << ", "
429
+ r << arg
430
+ # write ", " unless
431
+ end
432
+ r << "){"
433
+ @opt_arg_names.each do |arg|
434
+ r << "if (#{arg} == undefined) {"
435
+ r << " #{arg} = #{@opt_arg_str[arg]};"
436
+ r << "}"
437
+ end
438
+
439
+ end
440
+ end
441
+
442
+ def to_s
443
+ r = ""
444
+
445
+ case @type
446
+ when RubyParser::ISEQ_TYPE_TOP
447
+ r << "(function(__FILE__){"
448
+ # locals
449
+ if @locals.length > 0
450
+ r << "var #{@locals.each_value.to_a.join(" = this.n,")} = this.n;"
451
+ end
452
+ r << @code.join("")
453
+ r << "})"
454
+
455
+ when RubyParser::ISEQ_TYPE_CLASS
456
+ r << "function(){"
457
+
458
+ # locals
459
+ if @locals.length > 0
460
+ r << "var #{@locals.each_value.to_a.join(" = this.n,")} = this.n;"
461
+ end
462
+ # code
463
+ r << @code.join("")
464
+
465
+ r << "}"
466
+
467
+ when RubyParser::ISEQ_TYPE_METHOD
468
+
469
+ deal_with_method_args(r)
470
+
471
+ # block arg name
472
+ if @block_arg_name != nil
473
+ # r << "var _ = opal_block; opal_block = nil;"
474
+ end
475
+
476
+ # see below
477
+ if @should_handle_return
478
+ r << "try {"
479
+ end
480
+
481
+ # locals
482
+ if @locals.length > 0
483
+ r << "var #{@locals.each_value.to_a.join(" = this.n,")} = this.n;"
484
+ end
485
+ # code
486
+ r << @code.join("")
487
+
488
+ # if we are a method, we might need to handle a block returning. In
489
+ # that case we will get it here in our method, and we simply need to
490
+ # return the return value...happy days. (rethrow error if its not what
491
+ # we need)
492
+ if @should_handle_return
493
+ r << "} catch(e) {"
494
+ r << "if (e.__keyword__ == 'return') {"
495
+ r << " return e.opal_value;"
496
+ r << "}"
497
+ r << "throw e;"
498
+ r << "}"
499
+
500
+ end
501
+
502
+ # always return nil as worst case scenario (should never get here?)
503
+ # r << "return #{NIL};"
504
+ r << "}"
505
+
506
+ when RubyParser::ISEQ_TYPE_BLOCK
507
+ r << "this.P("
508
+ deal_with_method_args(r)
509
+
510
+ # r << "if (arguments.callee.opal_self) {"
511
+ # r << " var __old_self__ = self;"
512
+ # r << " self = this;"
513
+ # r << "}"
514
+
515
+ # r << "var res = (function() {"
516
+
517
+ # locals
518
+ if @locals.length > 0
519
+ r << "var #{@locals.each_value.to_a.join(" = this.n,")} = this.n;"
520
+ end
521
+ # WTF? this should take "var $=$$;" but we get errors...huh!?!?
522
+ # r << "if($$!=nil){var$=$$;}"
523
+ # this seems to be the easiest way to do it, but its hela ugly
524
+ # r << "with({$:($$==nil?$:$$),_:(__==nil?_:__)}){"
525
+ r << @code.join("")
526
+
527
+ # r << "})();"
528
+
529
+ # r << "if (arguments.callee.opal_self) {"
530
+ # r << " self = __old_self__;"
531
+ # r << "}"
532
+
533
+ # r << "return res;"
534
+
535
+ r << "})"
536
+
537
+ when RubyParser::ISEQ_TYPE_TEMP
538
+ r << @code.join("")
539
+ end
540
+ r
541
+ end
542
+
543
+ end
544
+
545
+ # An optional argument iseq used for generating just the code for an optioan
546
+ # argument. This code is stored, then later used as/if needed. Basically,
547
+ # has a write method that self contains the code.
548
+ #
549
+ class OptionalArgumentIseq
550
+
551
+ end
552
+
553
+ def write(str)
554
+ @iseq_current.write str
555
+ end
556
+
557
+
558
+ # Convert ruby style id to js property id - everything is prepended a '$'
559
+ # This method is used also for generating call method strings. For this
560
+ # reason, the method looks at the method name for any non a-z characters
561
+ # which will mean that we cannot use a safe js name. For example, setter
562
+ # methods need to be wrapped =>
563
+ #
564
+ # self.something = 10
565
+ # # => self['$something='](10).
566
+ #
567
+ # We no longer just replace '=' with '$e' etc as this slows down the runtime
568
+ # when looking through methods, and using __send__() etc.
569
+ #
570
+ def mid_to_jsid(mid)
571
+ # everything needs to be prepended with '$'
572
+ mid = "$#{mid}"
573
+
574
+ if /[\!\=\?\+\-\*\/\^\&\%\@\|\[\]\<\>\~]/.match mid
575
+ # special characters, so we must wrap in []
576
+ "['#{mid}']"
577
+ else
578
+ # no special characters, so we can just return .mid
579
+ ".#{mid}"
580
+ end
581
+ # "$#{mid}".
582
+ # gsub(/\!/, "$b").
583
+ # gsub(/\=/, "$e").
584
+ # gsub(/\?/, "$q").
585
+ # gsub(/\+/, "$p").
586
+ # gsub(/\-/, "$m").
587
+ # gsub(/\|/, '$r').
588
+ # gsub(/\&/, "$a").
589
+ # gsub(/\</, "$l").
590
+ # gsub(/\>/, "$g").
591
+ # gsub(/\[/, "$z").
592
+ # gsub(/\]/, "$x").
593
+ # gsub(/\//, "$d").
594
+ # gsub(/\*/, "$t").
595
+ # gsub(/\@/, "$a").
596
+ # gsub(/\^/, "$o")
597
+ end
598
+
599
+ def generate_tree(tree)
600
+ top_iseq = iseq_stack_push(ISEQ_TYPE_TOP)
601
+ tree.each do |stmt|
602
+ generate_stmt stmt, :full_stmt => true, :last_stmt => tree.last == stmt
603
+ end
604
+ iseq_stack_pop
605
+ end
606
+
607
+ def iseq_stack_push type
608
+ @iseq_current = Iseq.new type
609
+ @iseq_stack << @iseq_current
610
+ @iseq_current
611
+ end
612
+
613
+ def iseq_stack_pop
614
+ iseq = @iseq_stack.last
615
+ @iseq_stack.pop
616
+ @iseq_current = @iseq_stack.last
617
+ # finalize (var locals etc)
618
+ iseq.finalize
619
+ iseq.to_s
620
+ end
621
+
622
+ def generate_class(cls, context)
623
+ write "return " if context[:last_stmt] and context[:full_stmt]
624
+
625
+ current_iseq = @iseq_current
626
+ class_iseq = iseq_stack_push(ISEQ_TYPE_CLASS)
627
+ class_iseq.parent_iseq = current_iseq
628
+
629
+ # do each bodystmt
630
+ cls.bodystmt[:compstmt].each do |b|
631
+ generate_stmt b, :full_stmt => true, :last_stmt => b == cls.bodystmt[:compstmt].last
632
+ end
633
+
634
+ write "return nil;" if cls.bodystmt.length == 0
635
+
636
+ iseq_stack_pop
637
+
638
+ write "#{SELF}.define_class("
639
+ # superclass
640
+ if cls.super_klass
641
+ generate_stmt cls.super_klass[:expr], :full_stmt => false
642
+ else
643
+ write "#{NIL}"
644
+ end
645
+ write %{,"#{cls.klass_name}",#{class_iseq},0)}
646
+
647
+ write ";\n" if context[:full_stmt]
648
+ end
649
+
650
+ def generate_module(cls, context)
651
+ write "return " if context[:last_stmt] and context[:full_stmt]
652
+
653
+ current_iseq = @iseq_current
654
+ class_iseq = iseq_stack_push(ISEQ_TYPE_CLASS)
655
+ class_iseq.parent_iseq = current_iseq
656
+
657
+ # do each bodystmt
658
+ cls.bodystmt[:compstmt].each do |b|
659
+ generate_stmt b, :full_stmt => true, :last_stmt => b == cls.bodystmt[:compstmt].last
660
+ end
661
+
662
+ write "return nil;" if cls.bodystmt.length == 0
663
+
664
+ iseq_stack_pop
665
+
666
+ write "#{SELF}.define_class(#{NIL},'#{cls.klass_name}',#{class_iseq},2)"
667
+
668
+ # write "vm$e($,"
669
+ # superclass - always nil for module
670
+ # write "nil"
671
+ # write %{,"#{cls.klass_name}",#{class_iseq},2)}
672
+
673
+ write ";\n" if context[:full_stmt]
674
+ end
675
+
676
+ def generate_class_shift(cls, context)
677
+ write "return " if context[:last_stmt] and context[:full_stmt]
678
+
679
+ current_iseq = @iseq_current
680
+ class_iseq = iseq_stack_push(ISEQ_TYPE_CLASS)
681
+ class_iseq.parent_iseq = current_iseq
682
+
683
+ # each bodystmt
684
+ cls[:bodystmt][:compstmt].each do |b|
685
+ generate_stmt b, :full_stmt => true, :last_stmt => b == cls[:bodystmt][:compstmt].last
686
+ end
687
+
688
+ write "return nil" if cls[:bodystmt][:compstmt].length == 0
689
+
690
+ iseq_stack_pop
691
+
692
+ write "#{SELF}.define_class(#{NIL},"
693
+
694
+ generate_stmt cls[:expr], :full_stmt => false
695
+ write ",#{class_iseq},1)"
696
+
697
+ write ";\n" if context[:full_stmt]
698
+ end
699
+
700
+ def generate_def(stmt, context)
701
+ # if stmt[:bodystmt][:opt_rescue]
702
+ # puts "a"
703
+ # end
704
+ # if stmt[:fname] == "execute"
705
+ # pp stmt[:bodystmt]
706
+ # end
707
+ # if stmt[:bodystmt].vn_opt_rescue
708
+ # puts stmt[:bodystmt].vn_opt_rescue
709
+ # end
710
+ # puts stmt
711
+ write "return " if context[:last_stmt] and context[:full_stmt]
712
+
713
+ is_singleton = stmt[:singleton] ? 'true' : 'false'
714
+
715
+ current_iseq = @iseq_current
716
+ def_iseq = iseq_stack_push(ISEQ_TYPE_METHOD)
717
+ def_iseq.parent_iseq = current_iseq
718
+ def_iseq.method_id = stmt[:fname]
719
+
720
+ # normal args
721
+ if stmt[:arglist].arg
722
+ stmt[:arglist].arg.each do |arg|
723
+ @iseq_current.push_arg_name arg[:value]
724
+ end
725
+ end
726
+
727
+ # opt args
728
+ if stmt[:arglist].opt
729
+ stmt[:arglist].opt.each do |opt|
730
+ opt_current_iseq = @iseq_current
731
+ opt_iseq = iseq_stack_push(ISEQ_TYPE_TEMP)
732
+ generate_stmt opt[1], {}
733
+ iseq_stack_pop
734
+ # puts "need to generate op: #{opt}"
735
+ @iseq_current.push_opt_arg opt[0], opt_iseq.to_s
736
+ end
737
+ # puts "opt args:"
738
+ # puts stmt[:arglist].opt
739
+ # puts "---------"
740
+ end
741
+
742
+ # rest args
743
+ if stmt[:arglist].rest
744
+ @iseq_current.push_rest_arg_name stmt[:arglist].rest
745
+ end
746
+
747
+ # block name..
748
+ if stmt[:arglist].block
749
+ @iseq_current.push_block_arg_name(stmt[:arglist].block)
750
+ end
751
+
752
+
753
+ # body statements
754
+ if stmt[:bodystmt][:compstmt].length > 0
755
+ stmt[:bodystmt][:compstmt].each do |s|
756
+ generate_stmt s, :full_stmt => true, :last_stmt => stmt[:bodystmt][:compstmt].last == s
757
+ end
758
+ else
759
+ # no bodystmts, return nil be default
760
+ write "return #{NIL};"
761
+ end
762
+ iseq_stack_pop
763
+
764
+ # define method
765
+
766
+ # base.. singleton or self
767
+ if stmt[:singleton]
768
+ generate_stmt stmt[:singleton], :full_stmt => false, :last_stmt => false
769
+ write ".dm("
770
+ else
771
+ write "#{SELF}.dm("
772
+ end
773
+
774
+ # FIXME: only write line in debug mode!
775
+ write %{"#{stmt[:fname]}",#{def_iseq},#{is_singleton}, #{stmt[:line_number]})}
776
+ write ";\n" if context[:full_stmt]
777
+ end
778
+
779
+ def generate_identifier(stmt, context)
780
+ write "return " if context[:full_stmt] and context[:last_stmt]
781
+ local = @iseq_current.lookup_local(stmt[:name])
782
+ if local
783
+ write local
784
+ else
785
+ # write %{vm$a($,"#{stmt[:name]}",[],nil,8)}
786
+ write "#{SELF}#{mid_to_jsid(stmt[:name])}()"
787
+ end
788
+
789
+ write ";\n" if context[:full_stmt]
790
+ end
791
+
792
+ def generate_call(call, context)
793
+ used_param = false
794
+
795
+ if context[:full_stmt] and context[:last_stmt]
796
+ # go all the way back to original recv
797
+ original_recv = call
798
+
799
+ while original_recv[:recv]
800
+ original_recv = original_recv[:recv]
801
+ end
802
+
803
+ # should we "donate" the return statement (need to for case, if, unless)
804
+
805
+ if [:case, :if, :unless].include? original_recv.node
806
+ original_recv[:donate_recv] = true
807
+ else
808
+ write "return "
809
+ end
810
+ end
811
+
812
+ # write "vm$a("
813
+ # receiver
814
+ if call[:recv]
815
+ call_bit = 0
816
+ generate_stmt call[:recv], :recv => true
817
+ else
818
+ call_bit = 8
819
+ # self as recv
820
+ write "#{SELF}"
821
+ end
822
+
823
+ # method id
824
+ write %{#{mid_to_jsid(call[:meth])}(}
825
+
826
+ # normal args - need to check for splats
827
+ is_splat = false
828
+ unless call[:call_args].nil? or call[:call_args][:args].nil?
829
+ call[:call_args][:args].each do |arg|
830
+ is_splat = true if arg.node == :splat
831
+ end
832
+ end
833
+
834
+ if is_splat
835
+ write "(function(){"
836
+ write "var a=[],b=nil;"
837
+ call[:call_args][:args].each do |arg|
838
+ # puts arg
839
+ if arg.node == :splat
840
+ write "b = "
841
+ generate_stmt arg[:val], :full_stmt => false
842
+ write ";"
843
+ write "for(var i = 0; i < b.length; i++){"
844
+ write "a.push(b[i]);"
845
+ write "};"
846
+ else
847
+ write "a.push("
848
+ generate_stmt arg, :full_stmt => false
849
+ write ");"
850
+ end
851
+ end
852
+ write "return a;})()"
853
+ else
854
+ # write "["
855
+ unless call[:call_args].nil? or call[:call_args][:args].nil?
856
+ call[:call_args][:args].each do |arg|
857
+ used_param = true
858
+ write "," unless call[:call_args][:args].first == arg
859
+ generate_stmt arg, :full_stmt => false
860
+ end
861
+ end
862
+
863
+ # assocs
864
+ if call[:call_args] and call[:call_args][:assocs]
865
+ used_param = true
866
+ write "," unless call[:call_args].nil? or call[:call_args][:args].nil?
867
+ write "vnH("
868
+ call[:call_args][:assocs].each do |assoc|
869
+ write "," unless call[:call_args][:assocs].first == assoc
870
+ generate_stmt assoc[:key], :full_stmt => false, :last_stmt => false
871
+ write ","
872
+ generate_stmt assoc[:value], :full_stmt => false, :last_stmt => false
873
+ end
874
+ write ")"
875
+ end
876
+
877
+ # write "]"
878
+ end
879
+ # write ","
880
+
881
+ # block
882
+ if call[:brace_block]
883
+ write "," if used_param
884
+ current_iseq = @iseq_current
885
+ block_iseq = iseq_stack_push(ISEQ_TYPE_BLOCK)
886
+ block_iseq.parent_iseq = current_iseq
887
+
888
+ # block arg names
889
+ if call[:brace_block][:params]
890
+ call[:brace_block][:params].each do |p|
891
+ # puts p
892
+ block_iseq.push_arg_name(p[:value]) unless p.is_a?(String)
893
+ end
894
+ end
895
+
896
+ # block stmts
897
+ if call[:brace_block][:stmt]
898
+ call[:brace_block][:stmt].each do |a|
899
+ generate_stmt a, :full_stmt => true, :last_stmt => call[:brace_block][:stmt].last == a
900
+ end
901
+ end
902
+
903
+ iseq_stack_pop
904
+
905
+ write block_iseq.to_s
906
+ # map(&:name)
907
+ elsif call[:call_args][:block_arg]
908
+ if used_param
909
+ write ","
910
+ else
911
+ used_param = true
912
+ end
913
+ generate_stmt call[:call_args][:block_arg][:arg], :full_stmt => false
914
+ write "==#{SELF}.n ? #{SELF}.n : "
915
+
916
+ generate_stmt call[:call_args][:block_arg][:arg], :full_stmt => false
917
+ write %{.$to_proc()}
918
+ else
919
+ # write "nil"
920
+ end
921
+ # write ","
922
+
923
+ # op flag
924
+ # write "#{call_bit})"
925
+
926
+ write ")"
927
+
928
+ write ";\n" if context[:full_stmt]
929
+ end
930
+
931
+ def generate_string(str, context)
932
+ write "return " if context[:last_stmt] and context[:full_stmt]
933
+
934
+ if str[:value].length == 0
935
+ write %{""}
936
+ elsif str[:value].length == 1
937
+ if str[:value][0].node == :string_content
938
+ write %{"#{str[:value][0][:value].gsub(/\"/, '\"')}"}
939
+ else
940
+ generate_stmt str[:value][0][:value][0], {}
941
+ write ".$to_s()"
942
+ end
943
+ else
944
+ write "["
945
+ str[:value].each do |s|
946
+ write "," unless str[:value].first == s
947
+ if s.node == :string_content
948
+ write %{"#{s[:value].gsub(/\"/, '\"')}"}
949
+ else
950
+ # write %{vm$a(}
951
+ generate_stmt s[:value][0], :full_stmt => false
952
+ write ".$to_s()"
953
+ # write %{,"to_s",[],nil,8)}
954
+ end
955
+ end
956
+ write "].join('')"
957
+ end
958
+
959
+ write ";\n" if context[:full_stmt]
960
+ end
961
+
962
+ def generate_xstring(str, context)
963
+ # write "return " if context[:last_stmt] and context[:full_stmt]
964
+
965
+ if str[:value].length == 0
966
+ write %{}
967
+ elsif str[:value].length == 1
968
+ write str[:value][0][:value]
969
+ else
970
+ str[:value].each do |s|
971
+ if s.node == :string_content
972
+ write s[:value]
973
+ else
974
+ generate_stmt s[:value][0], :full_stmt => false
975
+ end
976
+ end
977
+ end
978
+
979
+ # write ";\n" if context[:full_stmt]
980
+ end
981
+
982
+ def generate_constant(cnst, context)
983
+ write "return " if context[:last_stmt] and context[:full_stmt]
984
+ write "#{SELF}.const_get('#{cnst[:name]}')"
985
+ # write %{vm$b($,"#{cnst[:name]}")}
986
+ write ";\n" if context[:full_stmt]
987
+ end
988
+
989
+ def generate_assign(stmt, context)
990
+ should_return = context[:last_stmt] and context[:full_stmt]
991
+ param_seen = false
992
+ # LHS is a local identifier
993
+ if stmt[:lhs].node == :identifier
994
+ local = @iseq_current.lookup_local stmt[:lhs][:name]
995
+ unless local
996
+ local = @iseq_current.push_local_name(stmt[:lhs][:name])
997
+ end
998
+
999
+ if stmt[:rhs].node == :if || stmt[:rhs].node == :unless
1000
+ if_local_name = generate_stmt stmt[:rhs], {}
1001
+ write "return " if should_return
1002
+ write %{#{local}=#{if_local_name}}
1003
+ else
1004
+ write "return " if should_return
1005
+ write %{#{local}=}
1006
+ generate_stmt stmt[:rhs], {}
1007
+ end
1008
+ elsif stmt[:lhs].node == :ivar
1009
+ write "return " if should_return
1010
+ write %{#{SELF}.is("#{stmt[:lhs][:name]}",}
1011
+ generate_stmt stmt[:rhs], :full_stmt => false, :last_stmt => false
1012
+ write %{)}
1013
+ elsif stmt[:lhs].node == :constant
1014
+ write %{#{SELF}.const_set("#{stmt[:lhs][:name]}",}
1015
+ generate_stmt stmt[:rhs], :full_stmt => false, :last_stmt => false
1016
+ write %{)}
1017
+ elsif stmt[:lhs].node == :call
1018
+ write "return " if should_return
1019
+ # puts stmt
1020
+ # write %{vm$a(}
1021
+ # recv
1022
+ generate_stmt stmt[:lhs][:recv], :full_stmt => false
1023
+ # id
1024
+ write %{#{mid_to_jsid(stmt[:lhs][:meth] +'=')}(}
1025
+ # args
1026
+ if stmt[:lhs][:args] and stmt[:lhs][:args][:args]
1027
+ stmt[:lhs][:args][:args].each do |arg|
1028
+ param_seen = true
1029
+ write "," unless stmt[:lhs][:args][:args].first == arg
1030
+ generate_stmt arg, :full_stmt => false
1031
+ # write ","
1032
+ end
1033
+ end
1034
+ write "," if param_seen
1035
+ generate_stmt stmt[:rhs], :full_stmt => false
1036
+ write ")"
1037
+
1038
+ else
1039
+ puts stmt
1040
+ abort "bad lhs type"
1041
+ end
1042
+ write ";\n" if context[:full_stmt]
1043
+ end
1044
+
1045
+ # how we replace "self/this"
1046
+ SELF = "this"
1047
+ # how we replace nil
1048
+ NIL = "#{SELF}.n"
1049
+
1050
+ def generate_self(stmt, context)
1051
+ write "return " if context[:last_stmt] and context[:full_stmt]
1052
+ write "#{SELF}"
1053
+ write ";\n" if context[:full_stmt]
1054
+ end
1055
+
1056
+ def generate_symbol(sym, context)
1057
+ write "return " if context[:last_stmt] and context[:full_stmt]
1058
+ write %{#{SELF}.Y("#{sym[:name]}")}
1059
+ write ";\n" if context[:full_stmt]
1060
+ end
1061
+
1062
+ def generate_numeric(num, context)
1063
+ write "return " if context[:last_stmt] and context[:full_stmt]
1064
+ write "(" if context[:recv]
1065
+ write "#{num[:value]}"
1066
+ write ")" if context[:recv]
1067
+ write ";\n" if context[:full_stmt]
1068
+ end
1069
+
1070
+ def generate_ivar stmt, context
1071
+ write "return " if context[:full_stmt] and context[:last_stmt]
1072
+ # write "vm_ivarget($, '#{stmt[:name]}')"
1073
+ write "#{SELF}.ig('#{stmt[:name]}')"
1074
+ write ";\n" if context[:full_stmt]
1075
+ end
1076
+
1077
+ def generate_gvar(stmt, context)
1078
+ write "return " if context[:full_stmt] and context[:last_stmt]
1079
+ write "rb_gvar_get('#{stmt[:name]}')"
1080
+ write ";\n" if context[:full_stmt]
1081
+ end
1082
+
1083
+ def generate_yield stmt, context
1084
+ write "return " if context[:full_stmt] and context[:last_stmt]
1085
+
1086
+ # block_name = @iseq_current.block_arg_name
1087
+ block_name = '__block__'
1088
+
1089
+ # for now, normal args or a single *splat
1090
+ if stmt[:call_args] and stmt[:call_args][:args][0].node == :splat
1091
+ write "#{SELF}.rbYield(#{block_name},[])"
1092
+ else
1093
+ write "#{SELF}.rbYield(#{block_name},["
1094
+
1095
+ if stmt[:call_args] and stmt[:call_args][:args]
1096
+ stmt[:call_args][:args].each do |a|
1097
+ write "," unless stmt[:call_args][:args].first == a
1098
+ generate_stmt a, :full_stmt => false, :last_stmt => false
1099
+ end
1100
+ end
1101
+ write "])"
1102
+ end
1103
+
1104
+ write ";\n" if context[:full_stmt]
1105
+ end
1106
+
1107
+ def generate_block_given stmt, context
1108
+ write "return " if context[:last_stmt] and context[:full_stmt]
1109
+ write "((!__block__ || !__block__.r) ? #{SELF}.f : #{SELF}.t)"
1110
+ write ";\n" if context[:full_stmt]
1111
+ end
1112
+
1113
+ # def generate_if_mod(stmt, context)
1114
+ # # write "return " if context[:full_stmt] and context[:last_stmt]
1115
+ #
1116
+ # # write "(function(){"
1117
+ #
1118
+ # # if/unless mod
1119
+ # if stmt.node == :if_mod
1120
+ # write "if("
1121
+ # else
1122
+ # write "if(!"
1123
+ # end
1124
+ #
1125
+ # generate_stmt stmt[:expr], :full_stmt => false, :last_stmt => false
1126
+ # write ".r){"
1127
+ # generate_stmt stmt[:stmt], :full_stmt => true, :last_stmt => false
1128
+ # write "}"
1129
+ # # return nil as safety value
1130
+ # # write "return #{NIL};})()"
1131
+ # write ";\n" if context[:full_stmt]
1132
+ # end
1133
+
1134
+ def generate_array(ary, context)
1135
+ write "return " if context[:last_stmt] and context[:full_stmt]
1136
+ write "["
1137
+ if ary[:args]
1138
+ ary[:args].each do |a|
1139
+ write "," unless ary[:args].first == a
1140
+ generate_stmt a, :full_stmt => false, :last_stmt => false
1141
+ end
1142
+ end
1143
+ write "]"
1144
+ write ";\n" if context[:full_stmt]
1145
+ end
1146
+
1147
+ def generate_opt_plus(stmt, context)
1148
+ write "return " if context[:last_stmt] and context[:full_stmt]
1149
+ # write %{vm_optplus(}
1150
+ generate_stmt stmt[:recv], :recv => true
1151
+ write "#{mid_to_jsid('+')}("
1152
+ generate_stmt stmt[:call_args][:args][0], :full_stmt => false
1153
+ write ")"
1154
+ write ";\n" if context[:full_stmt]
1155
+ end
1156
+
1157
+ def generate_opt_minus(stmt, context)
1158
+ write "return " if context[:last_stmt] and context[:full_stmt]
1159
+ generate_stmt stmt[:recv], :last_stmt => false, :full_stmt => false
1160
+ write "#{mid_to_jsid('-')}("
1161
+ generate_stmt stmt[:call_args][:args][0], :full_stmt => false
1162
+ write ")"
1163
+ write ";\n" if context[:full_stmt]
1164
+ end
1165
+
1166
+ def generate_opt_mult(stmt, context)
1167
+ write "return " if context[:last_stmt] and context[:full_stmt]
1168
+ generate_stmt stmt[:recv], :last_stmt => false, :full_stmt => false
1169
+ write "#{mid_to_jsid('*')}("
1170
+ generate_stmt stmt[:call_args][:args][0], :full_stmt => false
1171
+ write ")"
1172
+ write ";\n" if context[:full_stmt]
1173
+ end
1174
+
1175
+ def generate_opt_div(stmt, context)
1176
+ write "return " if context[:last_stmt] and context[:full_stmt]
1177
+ generate_stmt stmt[:recv], :last_stmt => false, :full_stmt => false
1178
+ write "#{mid_to_jsid('/')}("
1179
+ generate_stmt stmt[:call_args][:args][0], :full_stmt => false
1180
+ write ")"
1181
+ write ";\n" if context[:full_stmt]
1182
+ end
1183
+
1184
+ def generate_nil(stmt, context)
1185
+ write "return " if context[:last_stmt] and context[:full_stmt]
1186
+ write NIL
1187
+ write ";\n" if context[:full_stmt]
1188
+ end
1189
+
1190
+ def generate_true(stmt, context)
1191
+ write "return " if context[:last_stmt] and context[:full_stmt]
1192
+ write "#{SELF}.t"
1193
+ write ";\n" if context[:full_stmt]
1194
+ end
1195
+
1196
+ def generate_false(stmt, context)
1197
+ write "return " if context[:last_stmt] and context[:full_stmt]
1198
+ write "#{SELF}.f"
1199
+ write ";\n" if context[:full_stmt]
1200
+ end
1201
+
1202
+ def generate_regexp(stmt, context)
1203
+ # puts stmt
1204
+ write "return " if context[:last_stmt] and context[:full_stmt]
1205
+ write "/"
1206
+ stmt[:value].each do |part|
1207
+ write part[:value]
1208
+ end
1209
+ write "/"
1210
+ # write %{/#{stmt[:value][0][:value]}/}
1211
+ write ";\n" if context[:full_stmt]
1212
+ end
1213
+
1214
+ def generate_dot2(stmt, context)
1215
+ # return #{self}.R(#{start}, #{ending}, #{exclusive}.r);
1216
+ write "return " if context[:last_stmt] and context[:full_stmt]
1217
+ write "#{SELF}.R("
1218
+ generate_stmt stmt[:start], :full_stmt => false
1219
+ write ","
1220
+ generate_stmt stmt[:ending], :full_stmt => false
1221
+ write ",true)"
1222
+ write ";\n" if context[:full_stmt]
1223
+ end
1224
+
1225
+ def generate_dot3(stmt, context)
1226
+ write "return " if context[:last_stmt] and context[:full_stmt]
1227
+ write "#{SELF}.R("
1228
+ generate_stmt stmt[:start], :full_stmt => false
1229
+ write ","
1230
+ generate_stmt stmt[:ending], :full_stmt => false
1231
+ write ",false)"
1232
+ write ";\n" if context[:full_stmt]
1233
+ end
1234
+
1235
+ def generate_alias(stmt, context)
1236
+ write "return " if context[:last_stmt] and context[:full_stmt]
1237
+ write "vm_alias($,"
1238
+ generate_stmt stmt[:lhs], :full_stmt => false
1239
+ write ","
1240
+ generate_stmt stmt[:rhs], :full_stmt => false
1241
+ write ")"
1242
+ write ";\n" if context[:full_stmt]
1243
+ end
1244
+
1245
+ def generate__FILE__ stmt, context
1246
+ write "return " if context[:last_stmt] and context[:full_stmt]
1247
+ write %{__FILE__}
1248
+ write ";\n" if context[:full_stmt]
1249
+ end
1250
+
1251
+ def generate__LINE__ stmt, context
1252
+ write "return " if context[:last_stmt] and context[:full_stmt]
1253
+ write %{0}
1254
+ write ";\n" if context[:full_stmt]
1255
+ end
1256
+ # primay::CONST
1257
+ def generate_colon2 stmt, context
1258
+ write "return " if context[:last_stmt] and context[:full_stmt]
1259
+ # write %{vm$b(}
1260
+ generate_stmt stmt[:lhs], :full_stmt => false
1261
+ write %{.const_get("#{stmt[:rhs]}")}
1262
+ write ";\n" if context[:full_stmt]
1263
+ end
1264
+
1265
+ def generate_colon3 stmt, context
1266
+
1267
+ end
1268
+
1269
+ def generate_if(stmt, context)
1270
+
1271
+ # if we are not a full stmt, then we must return the last stmt's value.
1272
+ # Each last stmt will save its value into this var name so it can be used
1273
+ # again outside. nil is default and implies we dont need to do this. This
1274
+ # method (generate_if) returns the temp variable name so the caller can
1275
+ # decide what to do with it
1276
+ return_value_name = nil
1277
+
1278
+ # whether or not the last stmt for each stmt should be returned. This is
1279
+ # only ever true when we are the last stmt, AND we are a full stmt
1280
+ should_return_last = (context[:last_stmt] && context[:full_stmt] ? true : false)
1281
+
1282
+ # keep track of if we did an else statement.. if we havent, then we might
1283
+ # need to add one as a default response.. just return nil..
1284
+ done_else_statement = false
1285
+
1286
+ unless context[:full_stmt]
1287
+ return_value_name = @iseq_current.new_temp_variable
1288
+ end
1289
+
1290
+ # if/unless clause
1291
+ if stmt.node == :if
1292
+ write "if("
1293
+ else # must be unless
1294
+ write "if(!"
1295
+ end
1296
+
1297
+ generate_stmt stmt[:expr], :recv => true
1298
+ write ".r){"
1299
+ stmt[:stmt].each do |s|
1300
+ is_last_stmt = false
1301
+ if stmt[:stmt].last == s
1302
+ if should_return_last
1303
+ is_last_stmt = true
1304
+ elsif return_value_name
1305
+ write "#{return_value_name} = "
1306
+ end
1307
+ end
1308
+ # alays return last stmt. we output inside a function context to capture
1309
+ # the return value so that this will not return from the function itself
1310
+ generate_stmt s, :full_stmt => true, :last_stmt => is_last_stmt
1311
+ end
1312
+ write "}"
1313
+
1314
+ # now onto the tail (elsif, else etc)
1315
+ if stmt[:tail]
1316
+ stmt[:tail].each do |t|
1317
+ if t.node == :elsif
1318
+ write "else if("
1319
+ generate_stmt t[:expr], :recv => true
1320
+ write ".r){"
1321
+ t[:stmt].each do |s|
1322
+ is_last_stmt = false
1323
+ if t[:stmt].last == s
1324
+ if should_return_last
1325
+ is_last_stmt = true
1326
+ # write "return "
1327
+ elsif return_value_name
1328
+ write "#{return_value_name} = "
1329
+ end
1330
+ end
1331
+ generate_stmt s, :full_stmt => true, :last_stmt => is_last_stmt
1332
+ end
1333
+ write "}"
1334
+ else # else node
1335
+ done_else_statement = true
1336
+ write "else{"
1337
+ t[:stmt].each do |s|
1338
+ is_last_stmt = false
1339
+ if t[:stmt].last == s
1340
+ if should_return_last
1341
+ is_last_stmt = true
1342
+ elsif return_value_name
1343
+ write "#{return_value_name} = "
1344
+ end
1345
+ end
1346
+ generate_stmt s, :full_stmt => true, :last_stmt => is_last_stmt
1347
+ end
1348
+ write "}"
1349
+ end
1350
+ end
1351
+ end
1352
+
1353
+ # did we encounter an else statement? make sure..
1354
+ unless done_else_statement
1355
+ write "else{"
1356
+ if should_return_last
1357
+ write "return "
1358
+ end
1359
+ write "#{NIL};"
1360
+ write "}"
1361
+ end
1362
+
1363
+ # so it can be used..
1364
+ return_value_name
1365
+ end
1366
+
1367
+ def generate_op_asgn(stmt, context)
1368
+ # resulting stmt
1369
+ result = nil
1370
+ # if || or &&, then treat differently... everything else is simply a call
1371
+ # node :call, :recv => val[1], :meth => '-@', :call_args => { :args => []}
1372
+
1373
+ if stmt[:lhs].node == :identifier
1374
+ # adam += 20
1375
+ # => adam = adam + 20
1376
+ name = stmt[:lhs][:name]
1377
+ recv = node(:identifier, :name => name)
1378
+ lhs = node(:identifier, :name => name)
1379
+
1380
+ elsif stmt[:lhs].node == :ivar
1381
+
1382
+ name = stmt[:lhs][:name]
1383
+ recv = node(:ivar, :name => name)
1384
+ lhs = node(:ivar, :name => name)
1385
+
1386
+ elsif stmt[:lhs].node == :call
1387
+
1388
+ recv = stmt[:lhs]
1389
+ lhs = stmt[:lhs]
1390
+
1391
+ end
1392
+
1393
+ if stmt[:op] == '||'
1394
+ rhs = node(:assign, :lhs => lhs, :rhs => stmt[:rhs])
1395
+ result = node(:orop, :lhs => lhs, :rhs => rhs)
1396
+ else
1397
+ # should be generic
1398
+ rhs = node(:call, :recv => recv, :meth => stmt[:op], :call_args => { :args => [stmt[:rhs]]})
1399
+ # rhs = node(:call, :recv => node(:identifier, :name => name), :meth => stmt[:op], :call_args => { :args => [stmt[:rhs]]})
1400
+ result = node(:assign, :lhs => lhs, :rhs => rhs)
1401
+ end
1402
+
1403
+
1404
+ generate_stmt result, context
1405
+
1406
+
1407
+
1408
+ # end new
1409
+
1410
+
1411
+
1412
+ # puts result
1413
+ # generate_stmt result, {}
1414
+
1415
+ # if stmt[:lhs].node == :ivarpa
1416
+
1417
+ # puts stmt
1418
+ # write "return " if context[:full_stmt] and context[:last_stmt]
1419
+
1420
+ # if stmt[:lhs].node == :ivar
1421
+ # if stmt[:op] == "||"
1422
+ # rhs = node(:assign, :lhs => stmt[:lhs], :rhs => stmt[:rhs])
1423
+ # generate_stmt(node(:orop, :lhs => stmt[:lhs], :rhs => rhs), {})
1424
+ # # write "(function(){var a;"
1425
+ # # write "if(!RTEST(a = vm_ivarget($,'#{stmt[:lhs][:name]}'))){"
1426
+ # # write "return vm_ivarset($,'#{stmt[:lhs][:name]}',"
1427
+ # # generate_stmt stmt[:rhs], :full_stmt => false
1428
+ # # write ");}"
1429
+ # # write "return a;"
1430
+ # # write "})()"
1431
+ # elsif stmt[:op] == "+"
1432
+ # write "vm_ivarset($,'#{stmt[:lhs][:name]}',vm_optplus("
1433
+ # write "vm_ivarget($,'#{stmt[:lhs][:name]}'),"
1434
+ # generate_stmt stmt[:rhs], :full_stmt => false
1435
+ # write "))"
1436
+ # elsif stmt[:op] == "-"
1437
+ # write "vm_ivarset($,'#{stmt[:lhs][:name]}',vm_optminus("
1438
+ # write "vm_ivarget($,'#{stmt[:lhs][:name]}'),"
1439
+ # generate_stmt stmt[:rhs], :full_stmt => false
1440
+ # write "))"
1441
+ # elsif stmt[:op] == "*"
1442
+ # write "vm_ivarset($,'#{stmt[:lhs][:name]}',vm_optmult("
1443
+ # write "vm_ivarget($,'#{stmt[:lhs][:name]}'),"
1444
+ # generate_stmt stmt[:rhs], :full_stmt => false
1445
+ # write "))"
1446
+ # elsif stmt[:op] == "/"
1447
+ # write "vm_ivarset($,'#{stmt[:lhs][:name]}',vm_optdiv("
1448
+ # write "vm_ivarget($,'#{stmt[:lhs][:name]}'),"
1449
+ # generate_stmt stmt[:rhs], :full_stmt => false
1450
+ # write "))"
1451
+ # else
1452
+ # abort "bas op type for op_asgn"
1453
+ # end
1454
+ # else
1455
+ # abort "bad LHS for op_asgn"
1456
+ # end
1457
+
1458
+ # write ";\n" if context[:full_stmt]
1459
+ end
1460
+
1461
+ # yuck!
1462
+ def generate_case stmt, context
1463
+ # if stmt[:donate_recv]
1464
+ # write "DONATABLE RECV"
1465
+ # end
1466
+
1467
+ # first get our case value (if method call, we dont want to call it for
1468
+ # every comparison, so store it ina temp variable for later use)
1469
+ case_var_name = @iseq_current.new_temp_variable
1470
+
1471
+ # if we are not a full stmt, then we might need to store return value
1472
+ case_result = context[:full_stmt] ? nil : @iseq_current.new_temp_variable
1473
+
1474
+ # if we simply return the last stmt..
1475
+ is_last = context[:last_stmt] && context[:full_stmt]
1476
+
1477
+ # make sure we do the else part
1478
+ done_else = false
1479
+
1480
+ write "#{case_var_name} = "
1481
+
1482
+ if stmt[:expr]
1483
+ generate_stmt stmt[:expr], :full_stmt => false, :last_stmt => false
1484
+ write ";"
1485
+ else
1486
+ write "#{SELF}.t;"
1487
+ end
1488
+
1489
+ # write "(function($c){"
1490
+ stmt[:body].each do |c|
1491
+ if c.node == :when
1492
+ # clauses
1493
+ if stmt[:body].first == c
1494
+ write "if"
1495
+ else
1496
+ write "else if"
1497
+ end
1498
+ write "("
1499
+ c[:args].each do |a|
1500
+ write " || " unless c[:args].first == a
1501
+
1502
+ generate_stmt a, :recv => true
1503
+ # ruby truthiness test to make sure result is truthy
1504
+ write "#{mid_to_jsid('===')}(#{case_var_name}).r"
1505
+ # write ",'===',[$c],nil,0)"
1506
+ end
1507
+ write") {"
1508
+ c[:stmt].each do |s|
1509
+ # assign to variable? (for non full stmts)
1510
+ if c[:stmt].last == s && case_result
1511
+ write "#{case_result} = "
1512
+ end
1513
+
1514
+ generate_stmt s, :full_stmt => true, :last_stmt => is_last && c[:stmt].last == s
1515
+ end
1516
+ write "}"
1517
+ else # it is an else, so anything else goes
1518
+ done_else = true
1519
+
1520
+ write "else {"
1521
+ c[:stmt].each do |s|
1522
+ if c[:stmt].last == s && case_result
1523
+ write "#{case_result} = "
1524
+ end
1525
+ generate_stmt s, :full_stmt => true, :last_stmt => is_last && c[:stmt].last == s
1526
+ end
1527
+ write "}"
1528
+ end
1529
+ end
1530
+
1531
+ unless done_else
1532
+ write "else {"
1533
+
1534
+ if case_result
1535
+ write "#{case_result} = "
1536
+ else
1537
+ write "return " if is_last
1538
+ end
1539
+
1540
+ write NIL
1541
+ write ";"
1542
+ write "}"
1543
+ end
1544
+
1545
+ # do we need to return for a call stmt later on?
1546
+ write "return " if stmt[:donate_recv]
1547
+
1548
+ # if we need to return our result...
1549
+ if case_result
1550
+ write case_result
1551
+ end
1552
+ end
1553
+
1554
+ def generate_orop(stmt, context)
1555
+ write "return " if context[:full_stmt] and context[:last_stmt]
1556
+ write "#{SELF}.o("
1557
+ generate_stmt stmt[:lhs], :full_stmt => false
1558
+ # write ".o("
1559
+ write ",function(){"
1560
+ generate_stmt stmt[:rhs], :full_stmt => true, :last_stmt => true
1561
+ write "})"
1562
+
1563
+ write ";\n" if context[:full_stmt]
1564
+ end
1565
+
1566
+ def generate_andop(stmt, context)
1567
+ write "return " if context[:full_stmt] and context[:last_stmt]
1568
+ write "#{SELF}.a("
1569
+ generate_stmt stmt[:lhs], :full_stmt => false
1570
+ # write ".o("
1571
+ write ",function(){"
1572
+ generate_stmt stmt[:rhs], :full_stmt => true, :last_stmt => true
1573
+ write "})"
1574
+
1575
+ write ";\n" if context[:full_stmt]
1576
+ end
1577
+
1578
+ def generate_assoc_list stmt, context
1579
+ write "return " if context[:full_stmt] and context[:last_stmt]
1580
+ write "vnH("
1581
+ stmt[:list].each do |assoc|
1582
+ write "," unless stmt[:list].first == assoc
1583
+ generate_stmt assoc[:key], :full_stmt => false, :last_stmt => false
1584
+ write ","
1585
+ generate_stmt assoc[:value], :full_stmt => false, :last_stmt => false
1586
+ end
1587
+ write ")"
1588
+ write ";\n" if context[:full_stmt]
1589
+ end
1590
+
1591
+ def generate_begin(stmt, context)
1592
+ if stmt[:stmt][:opt_rescue]
1593
+ write "try{"
1594
+ stmt[:stmt][:compstmt].each do |s|
1595
+ generate_stmt s, :full_stmt => true, :last_stmt => (context[:last_stmt] && stmt[:stmt][:compstmt].last == s)
1596
+ end
1597
+ # puts stmt[:stmt][:opt_rescue]
1598
+ write "}"
1599
+ write "catch(e) {"
1600
+ if stmt[:stmt][:opt_rescue][:var]
1601
+ local = @iseq_current.lookup_local(stmt[:stmt][:opt_rescue][:var][:name])
1602
+ unless local
1603
+ local = @iseq_current.push_local_name(stmt[:stmt][:opt_rescue][:var][:name])
1604
+ end
1605
+ # write "#{local} = e;"
1606
+ # make sure we are using a opal error
1607
+ write %Q|
1608
+ if (e.mid2jsid) {
1609
+ #{local} = e;
1610
+ } else {
1611
+ #{local} = #{SELF}.rbNativeError(e);
1612
+ }
1613
+ |
1614
+ # write "console.log('catch');console.log(e.klass);"
1615
+ if stmt[:stmt][:opt_rescue][:stmt]
1616
+ stmt[:stmt][:opt_rescue][:stmt].each do |s|
1617
+ generate_stmt s, :full_stmt => true
1618
+ end
1619
+ end
1620
+ end
1621
+ write "}"
1622
+ else
1623
+ stmt[:stmt][:compstmt].each do |stmt|
1624
+ generate_stmt stmt, :full_stmt => true, :last_stmt => false
1625
+ end
1626
+ end
1627
+ end
1628
+
1629
+ def generate_return(stmt, context)
1630
+
1631
+ if @iseq_current.type == RubyParser::ISEQ_TYPE_BLOCK
1632
+ # if we are inside a block, we must rbReturn (i.e. throw an error to
1633
+ # return to escape blocks etc, see opal.js). Also, we must tell the
1634
+ # nearset method from iseq_current that it contains a block/proc so
1635
+ # it can provide a simple try/catch statement to try and catch it if it
1636
+ # returns.
1637
+
1638
+ @iseq_current.tell_method_to_handle_return
1639
+
1640
+ write "#{SELF}.rbReturn("
1641
+ # puts stmt
1642
+ if stmt[:call_args] and stmt[:call_args][:args]
1643
+ if stmt[:call_args][:args].length == 1
1644
+ generate_stmt stmt[:call_args][:args].first, :full_stmt => false
1645
+ else
1646
+ abort "generate_return multiple args not yet done"
1647
+ end
1648
+ else
1649
+ write "#{NIL}"
1650
+ end
1651
+
1652
+ write ");\n" if context[:full_stmt]
1653
+ else
1654
+ # assume we are in a method... if so, carry on as normal
1655
+ write "return "
1656
+ # puts stmt
1657
+ if stmt[:call_args] and stmt[:call_args][:args]
1658
+ if stmt[:call_args][:args].length == 1
1659
+ generate_stmt stmt[:call_args][:args].first, :full_stmt => false
1660
+ else
1661
+ abort "generate_return multiple args not yet done"
1662
+ end
1663
+ else
1664
+ write "#{NIL}"
1665
+ end
1666
+
1667
+ write ";\n" if context[:full_stmt]
1668
+ end
1669
+ end
1670
+
1671
+ def generate_lparen(stmt, context)
1672
+ write "return " if context[:last_stmt] and context[:full_stmt]
1673
+ write "("
1674
+ if stmt[:stmt] and stmt[:stmt][0]
1675
+ generate_stmt stmt[:stmt][0], :full_stmt => false
1676
+ else
1677
+ write "#{NIL}"
1678
+ end
1679
+ write ")"
1680
+ write ";\n" if context[:full_stmt]
1681
+ end
1682
+
1683
+ def generate_aset_op_asgn(stmt, context)
1684
+ write "return " if context[:full_stmt] and context[:last_stmt]
1685
+ if stmt[:recv].node == :identifier
1686
+ abort "unsupported. currently"
1687
+ else
1688
+ abort "bad recv node for aset_op_asgn (#{stmt[:recv]})"
1689
+ end
1690
+ write ";\n" if context[:full_stmt]
1691
+ end
1692
+
1693
+ def generate_not(stmt, context)
1694
+ write "return " if context[:full_stmt] and context[:last_stmt]
1695
+ generate_stmt stmt[:expr], :full_stmt => false
1696
+ write "#{mid_to_jsid('!')}()"
1697
+ write ";\n" if context[:full_stmt]
1698
+ end
1699
+
1700
+ def generate_super(stmt, context)
1701
+ write "return " if context[:full_stmt] and context[:last_stmt]
1702
+ write %{#{SELF}.opal_super(arguments.callee, }
1703
+
1704
+ # args, depends on is super has parens etc, simple for now: parens
1705
+ if stmt[:call_args] and stmt[:call_args][:args]
1706
+ write "["
1707
+ stmt[:call_args][:args].each do |arg|
1708
+ write "," unless arg == stmt[:call_args][:args].first
1709
+ generate_stmt arg, :full_stmt => false
1710
+ end
1711
+ write "]"
1712
+
1713
+ elsif stmt[:inherit]
1714
+ write "Array.prototype.slice.call(arguments)"
1715
+ else
1716
+ write "[]"
1717
+ end
1718
+
1719
+ write ")"
1720
+ write ";\n" if context[:full_stmt]
1721
+ end
1722
+
1723
+ def generate_break(stmt, context)
1724
+ write "#{SELF}.rbBreak("
1725
+ if stmt[:call_args] and stmt[:call_args][:args]
1726
+ stmt[:call_args][:args].each do |arg|
1727
+ write "," unless stmt[:call_args][:args].first == arg
1728
+ generate_stmt arg, :full_stmt => false
1729
+ end
1730
+ end
1731
+ write ");"
1732
+ end
1733
+
1734
+ def generate_next(stmt, context)
1735
+ write "#{SELF}.rbNext("
1736
+ if stmt[:call_args] and stmt[:call_args][:args]
1737
+ stmt[:call_args][:args].each do |arg|
1738
+ write "," unless stmt[:call_args][:args].first == arg
1739
+ generate_stmt arg, :full_stmt => false
1740
+ end
1741
+ end
1742
+ write ")"
1743
+
1744
+ write ";" if context[:full_stmt]
1745
+ end
1746
+
1747
+ def generate_tertiary(stmt, context)
1748
+ write "return " if context[:full_stmt] and context[:last_stmt]
1749
+ write "("
1750
+ generate_stmt stmt[:expr], :full_stmt => false
1751
+ write ").r ? "
1752
+ generate_stmt stmt[:true], :full_stmt => false
1753
+ write " : "
1754
+ generate_stmt stmt[:false], :full_stmt => false
1755
+ write ";\n" if context[:full_stmt]
1756
+ end
1757
+
1758
+ def generate_while(stmt, context)
1759
+
1760
+
1761
+
1762
+ write "#{SELF}.rbWhile(function(){"
1763
+ if stmt.node == :while
1764
+ write "return ("
1765
+ else
1766
+ # until..
1767
+ write "return (!("
1768
+ end
1769
+
1770
+ generate_stmt stmt[:expr], {}
1771
+
1772
+ if stmt.node == :while
1773
+ write ".r);"
1774
+ else
1775
+ # until..
1776
+ write ".r));"
1777
+ end
1778
+
1779
+ # generate_stmt stmt[:expr], {}
1780
+
1781
+ write "}, function() {"
1782
+
1783
+ stmt[:stmt].each do |stmt|
1784
+ generate_stmt stmt, :full_stmt => true
1785
+ end
1786
+
1787
+ # write "}"
1788
+
1789
+ write "})"
1790
+
1791
+ write ";\n" if context[:full_stmt]
1792
+ end
1793
+
1794
+
1795
+
1796
+
1797
+ def generate_lambda(stmt, context)
1798
+ write "return " if context[:last_stmt] && context[:full_stmt]
1799
+
1800
+ write "#{SELF}.L(function() {"
1801
+
1802
+ stmt[:body].each do |stmt|
1803
+ generate_stmt stmt, :full_stmt => true
1804
+ end
1805
+
1806
+ write "})"
1807
+
1808
+ write ";\n" if context[:full_stmt]
1809
+ end
1810
+
1811
+ def generate_words(stmt, context)
1812
+ write "return " if context[:last_stmt] and context[:full_stmt]
1813
+
1814
+ done_first = false
1815
+
1816
+ write "["
1817
+ stmt[:list].first.each do |list|
1818
+ if list.node == :string_content
1819
+ str = list[:value]
1820
+ str = str.strip! || str
1821
+ str.split(' ').each do |part|
1822
+ if done_first
1823
+ write ", '#{part}'"
1824
+ else
1825
+ done_first = true
1826
+ write "'#{part}'"
1827
+ end
1828
+ end
1829
+ else
1830
+ if done_first
1831
+ write ", "
1832
+ else
1833
+ done_first = true
1834
+ end
1835
+ # puts list
1836
+ generate_stmt list[:value].first, {}
1837
+ write '.$to_s()'
1838
+ end
1839
+ end
1840
+
1841
+ write "]"
1842
+ write ";\n" if context[:full_stmt]
1843
+ end
1844
+
1845
+
1846
+ def generate_redo(stmt, context)
1847
+ write "#{SELF}.rbRedo()"
1848
+ write ";" if context[:full_stmt]
1849
+ end
1850
+ end
1851
+ end