opal 0.2.2 → 0.3.0

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 (325) hide show
  1. data/.gitignore +5 -10
  2. data/LICENSE +75 -0
  3. data/README.md +55 -3
  4. data/Rakefile +62 -139
  5. data/bin/opal +7 -10
  6. data/gems/core/README.md +5 -0
  7. data/gems/core/Rakefile +7 -0
  8. data/gems/core/core.gemspec +13 -0
  9. data/gems/core/lib/core.rb +33 -0
  10. data/gems/core/lib/core/array.rb +1470 -0
  11. data/gems/core/lib/core/basic_object.rb +15 -0
  12. data/gems/core/lib/core/class.rb +31 -0
  13. data/gems/core/lib/core/dir.rb +26 -0
  14. data/gems/core/lib/core/error.rb +43 -0
  15. data/gems/core/lib/core/false_class.rb +21 -0
  16. data/gems/core/lib/core/file.rb +54 -0
  17. data/gems/core/lib/core/hash.rb +725 -0
  18. data/gems/core/lib/core/kernel.rb +240 -0
  19. data/gems/core/lib/core/module.rb +98 -0
  20. data/gems/core/lib/core/nil_class.rb +41 -0
  21. data/gems/core/lib/core/numeric.rb +370 -0
  22. data/gems/core/lib/core/proc.rb +11 -0
  23. data/gems/core/lib/core/range.rb +17 -0
  24. data/gems/core/lib/core/regexp.rb +18 -0
  25. data/gems/core/lib/core/string.rb +328 -0
  26. data/gems/core/lib/core/symbol.rb +15 -0
  27. data/gems/core/lib/core/top_self.rb +8 -0
  28. data/gems/core/lib/core/true_class.rb +20 -0
  29. data/gems/core/lib/core/vm.rb +16 -0
  30. data/{opals/opal/opal → gems/core}/spec/core/array/append_spec.rb +0 -0
  31. data/{opals/opal/opal → gems/core}/spec/core/array/assoc_spec.rb +0 -0
  32. data/{opals/opal/opal → gems/core}/spec/core/array/at_spec.rb +0 -0
  33. data/{opals/opal/opal → gems/core}/spec/core/array/clear_spec.rb +1 -1
  34. data/{opals/opal/opal → gems/core}/spec/core/array/collect_bang_spec.rb +0 -0
  35. data/{opals/opal/opal → gems/core}/spec/core/array/collect_spec.rb +0 -0
  36. data/gems/core/spec/core/array/compact_spec.rb +41 -0
  37. data/{opals/opal/opal → gems/core}/spec/core/array/concat_spec.rb +0 -0
  38. data/{opals/opal/opal → gems/core}/spec/core/array/constructor_spec.rb +0 -0
  39. data/{opals/opal/opal → gems/core}/spec/core/array/each_spec.rb +0 -0
  40. data/{opals/opal/opal → gems/core}/spec/core/array/element_reference_spec.rb +0 -0
  41. data/{opals/opal/opal → gems/core}/spec/core/array/first_spec.rb +1 -1
  42. data/{opals/opal/opal → gems/core}/spec/core/array/include_spec.rb +0 -0
  43. data/gems/core/spec/core/array/join_spec.rb +6 -0
  44. data/gems/core/spec/core/array/last_spec.rb +51 -0
  45. data/gems/core/spec/core/array/length_spec.rb +6 -0
  46. data/{opals/opal/opal → gems/core}/spec/core/array/map_spec.rb +2 -0
  47. data/gems/core/spec/core/array/reverse_spec.rb +6 -0
  48. data/{opals/opal/opal → gems/core}/spec/core/builtin_constants/builtin_constants_spec.rb +0 -0
  49. data/{opals/opal/opal → gems/core}/spec/core/false/and_spec.rb +0 -0
  50. data/{opals/opal/opal → gems/core}/spec/core/false/inspect_spec.rb +0 -0
  51. data/{opals/opal/opal → gems/core}/spec/core/false/or_spec.rb +0 -0
  52. data/{opals/opal/opal → gems/core}/spec/core/false/to_s_spec.rb +0 -0
  53. data/{opals/opal/opal → gems/core}/spec/core/false/xor_spec.rb +0 -0
  54. data/{opals/opal/opal → gems/core}/spec/core/file/join_spec.rb +1 -1
  55. data/gems/core/spec/core/hash/assoc_spec.rb +32 -0
  56. data/{opals/opal/opal → gems/core}/spec/core/kernel/instance_eval_spec.rb +0 -0
  57. data/{opals/opal/opal → gems/core}/spec/core/kernel/loop_spec.rb +0 -0
  58. data/{opals/opal/opal → gems/core}/spec/core/kernel/raise_spec.rb +0 -0
  59. data/{opals/opal/opal → gems/core}/spec/core/module/attr_accessor_spec.rb +0 -0
  60. data/{opals/opal/opal → gems/core}/spec/core/number/lt_spec.rb +0 -0
  61. data/gems/core/spec/core/string/sub_spec.rb +24 -0
  62. data/{opals/opal/opal → gems/core}/spec/core/true/and_spec.rb +0 -0
  63. data/{opals/opal/opal → gems/core}/spec/core/true/inspect_spec.rb +0 -0
  64. data/{opals/opal/opal → gems/core}/spec/core/true/or_spec.rb +0 -0
  65. data/{opals/opal/opal → gems/core}/spec/core/true/to_s_spec.rb +0 -0
  66. data/{opals/opal/opal → gems/core}/spec/core/true/xor_spec.rb +0 -0
  67. data/{opals/opal/opal → gems/core}/spec/language/and_spec.rb +2 -3
  68. data/{opals/opal/opal → gems/core}/spec/language/array_spec.rb +21 -5
  69. data/gems/core/spec/language/block_spec.rb +38 -0
  70. data/{opals/opal/opal → gems/core}/spec/language/break_spec.rb +0 -0
  71. data/gems/core/spec/language/case_spec.rb +103 -0
  72. data/{opals/opal/opal → gems/core}/spec/language/def_spec.rb +11 -1
  73. data/{opals/opal/opal → gems/core}/spec/language/eigenclass_spec.rb +0 -0
  74. data/gems/core/spec/language/file_spec.rb +13 -0
  75. data/gems/core/spec/language/fixtures/block.rb +21 -0
  76. data/gems/core/spec/language/fixtures/super.rb +293 -0
  77. data/{opals/opal/opal → gems/core}/spec/language/hash_spec.rb +0 -0
  78. data/{opals/opal/opal → gems/core}/spec/language/if_spec.rb +0 -0
  79. data/{opals/opal/opal → gems/core}/spec/language/loop_spec.rb +0 -0
  80. data/gems/core/spec/language/metaclass_spec.rb +21 -0
  81. data/{opals/opal/opal → gems/core}/spec/language/method_spec.rb +60 -0
  82. data/{opals/opal/opal → gems/core}/spec/language/next_spec.rb +0 -0
  83. data/{opals/opal/opal → gems/core}/spec/language/or_spec.rb +0 -0
  84. data/{opals/opal/opal → gems/core}/spec/language/redo_spec.rb +0 -0
  85. data/gems/core/spec/language/regexp_spec.rb +26 -0
  86. data/{opals/opal/opal → gems/core}/spec/language/rescue_spec.rb +0 -0
  87. data/{opals/opal/opal → gems/core}/spec/language/return_spec.rb +0 -0
  88. data/{opals/opal/opal → gems/core}/spec/language/string_spec.rb +0 -0
  89. data/gems/core/spec/language/super_spec.rb +32 -0
  90. data/{opals/opal/opal → gems/core}/spec/language/until_spec.rb +47 -47
  91. data/gems/core/spec/language/variables_spec.rb +155 -0
  92. data/{opals/opal/opal → gems/core}/spec/language/while_spec.rb +47 -47
  93. data/{opals/opal/opal → gems/core}/spec/spec_helper.rb +1 -1
  94. data/gems/core_fs/README.md +19 -0
  95. data/gems/dev/Rakefile +5 -0
  96. data/gems/dev/lib/dev.js +99 -0
  97. data/gems/dev/lib/dev/generator.js +1264 -0
  98. data/gems/dev/lib/dev/parser.js +979 -0
  99. data/gems/dev/lib/dev/ruby_parser.js +1088 -0
  100. data/gems/dev/lib/dev/ruby_parser.y +1267 -0
  101. data/gems/dev/lib/dev/string_scanner.js +38 -0
  102. data/gems/dev/tools/racc2js/README.md +39 -0
  103. data/gems/dev/tools/racc2js/math_parser.js +222 -0
  104. data/gems/dev/tools/racc2js/math_parser.rb +133 -0
  105. data/gems/dev/tools/racc2js/math_parser.y +28 -0
  106. data/gems/dev/tools/racc2js/parser.js +218 -0
  107. data/gems/dev/tools/racc2js/racc2js.rb +153 -0
  108. data/gems/json/README.md +4 -0
  109. data/gems/json/json.gemspec +14 -0
  110. data/gems/json/lib/json.rb +64 -0
  111. data/gems/json/lib/json/ext.rb +51 -0
  112. data/{opals/opal/browser/lib/browser/json_parse.js → gems/json/lib/json/json2.js} +197 -37
  113. data/gems/ospec/README.md +0 -0
  114. data/gems/ospec/lib/ospec.rb +6 -0
  115. data/gems/ospec/lib/ospec/autorun.rb +3 -0
  116. data/gems/ospec/lib/ospec/dsl.rb +15 -0
  117. data/gems/ospec/lib/ospec/example.rb +11 -0
  118. data/gems/ospec/lib/ospec/example/before_and_after_hooks.rb +56 -0
  119. data/gems/ospec/lib/ospec/example/errors.rb +17 -0
  120. data/gems/ospec/lib/ospec/example/example_group.rb +12 -0
  121. data/gems/ospec/lib/ospec/example/example_group_factory.rb +21 -0
  122. data/gems/ospec/lib/ospec/example/example_group_hierarchy.rb +20 -0
  123. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/example/example_group_methods.rb +26 -68
  124. data/gems/ospec/lib/ospec/example/example_group_proxy.rb +14 -0
  125. data/gems/ospec/lib/ospec/example/example_methods.rb +46 -0
  126. data/gems/ospec/lib/ospec/example/example_proxy.rb +18 -0
  127. data/gems/ospec/lib/ospec/expectations.rb +19 -0
  128. data/gems/ospec/lib/ospec/expectations/errors.rb +8 -0
  129. data/gems/ospec/lib/ospec/expectations/fail_with.rb +8 -0
  130. data/gems/ospec/lib/ospec/expectations/handler.rb +27 -0
  131. data/gems/ospec/lib/ospec/matchers.rb +24 -0
  132. data/{opals/opal/Rakefile → gems/ospec/lib/ospec/matchers/be.rb} +0 -0
  133. data/gems/ospec/lib/ospec/matchers/generated_descriptions.rb +20 -0
  134. data/gems/ospec/lib/ospec/matchers/operator_matcher.rb +52 -0
  135. data/gems/ospec/lib/ospec/runner.rb +40 -0
  136. data/gems/ospec/lib/ospec/runner/example_group_runner.rb +44 -0
  137. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/formatter/html_formatter.rb +31 -40
  138. data/gems/ospec/lib/ospec/runner/formatter/terminal_formatter.rb +48 -0
  139. data/gems/ospec/lib/ospec/runner/options.rb +36 -0
  140. data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/reporter.rb +23 -55
  141. data/gems/ospec/ospec.gemspec +0 -0
  142. data/gems/rquery/README.md +9 -0
  143. data/gems/rquery/lib/rquery.rb +10 -0
  144. data/gems/rquery/lib/rquery/ajax.rb +4 -0
  145. data/gems/rquery/lib/rquery/css.rb +96 -0
  146. data/gems/rquery/lib/rquery/document.rb +25 -0
  147. data/gems/rquery/lib/rquery/element.rb +292 -0
  148. data/gems/rquery/lib/rquery/event.rb +108 -0
  149. data/gems/rquery/lib/rquery/jquery.js +8177 -0
  150. data/gems/rquery/lib/rquery/request.rb +138 -0
  151. data/gems/rquery/lib/rquery/response.rb +49 -0
  152. data/gems/rquery/rquery.gemspec +16 -0
  153. data/lib/opal.js +1597 -0
  154. data/lib/opal.rb +6 -69
  155. data/lib/opal/builder.rb +115 -0
  156. data/lib/opal/bundle.rb +131 -0
  157. data/lib/opal/command.rb +11 -0
  158. data/lib/opal/context.rb +69 -0
  159. data/lib/opal/context/console.rb +12 -0
  160. data/lib/opal/context/file_system.rb +19 -0
  161. data/lib/opal/context/loader.rb +117 -0
  162. data/lib/opal/gem.rb +153 -0
  163. data/lib/opal/ruby/nodes.rb +1302 -0
  164. data/lib/opal/ruby/parser.rb +780 -0
  165. data/lib/opal/ruby/ruby_parser.rb +5170 -0
  166. data/lib/opal/ruby/ruby_parser.y +1298 -0
  167. data/opal.gemspec +11 -256
  168. metadata +179 -240
  169. data/.gitmodules +0 -6
  170. data/Opalfile +0 -384
  171. data/VERSION +0 -1
  172. data/demos/apps/browser_demo/index.html +0 -11
  173. data/demos/apps/browser_demo/lib/browser_demo.rb +0 -31
  174. data/demos/apps/simple_opal/Opalfile +0 -13
  175. data/demos/apps/simple_opal/index.html +0 -11
  176. data/demos/apps/simple_opal/lib/app_controller.rb +0 -62
  177. data/demos/apps/simple_opal/lib/main_window.rb +0 -146
  178. data/demos/browser/request/index.html +0 -52
  179. data/demos/browser/request/request.rb +0 -48
  180. data/gen/browser/__PROJECT_NAME__/Rakefile +0 -12
  181. data/gen/browser/__PROJECT_NAME__/index.html +0 -11
  182. data/gen/browser/__PROJECT_NAME__/javascripts/opal.debug.js +0 -4687
  183. data/gen/browser/__PROJECT_NAME__/javascripts/opal.min.js +0 -175
  184. data/gen/browser/__PROJECT_NAME__/lib/__PROJECT_NAME__.rb +0 -1
  185. data/lib/opal/builders/base.rb +0 -50
  186. data/lib/opal/builders/css.rb +0 -46
  187. data/lib/opal/builders/javascript.rb +0 -44
  188. data/lib/opal/builders/opal.rb +0 -79
  189. data/lib/opal/builders/ruby.rb +0 -50
  190. data/lib/opal/builders/ruby/generate.rb +0 -1851
  191. data/lib/opal/builders/ruby/nodes.rb +0 -210
  192. data/lib/opal/builders/ruby/ruby.rb +0 -916
  193. data/lib/opal/builders/ruby/ruby_parser.rb +0 -6008
  194. data/lib/opal/builders/ruby/ruby_parser.rb.y +0 -1451
  195. data/lib/opal/models/build_item.rb +0 -104
  196. data/lib/opal/models/hash_struct.rb +0 -40
  197. data/lib/opal/models/project.rb +0 -252
  198. data/lib/opal/models/struct_accessors.rb +0 -58
  199. data/lib/opal/models/target.rb +0 -176
  200. data/lib/opal/opal/build.rb +0 -169
  201. data/lib/opal/opal/env/console.rb +0 -66
  202. data/lib/opal/opal/env/fs.rb +0 -98
  203. data/lib/opal/opal/env/object.rb +0 -48
  204. data/lib/opal/opal/environment.rb +0 -139
  205. data/lib/opal/opal/gen.rb +0 -62
  206. data/lib/opal/opal/opal.rb +0 -75
  207. data/lib/opal/opal/repl.rb +0 -38
  208. data/lib/opal/opalfile/dsl.rb +0 -62
  209. data/lib/opal/opalfile/opalfile.rb +0 -133
  210. data/lib/opal/opalfile/task.rb +0 -96
  211. data/lib/opal/opalfile/task_manager.rb +0 -63
  212. data/lib/opal/opalfile/task_scope.rb +0 -52
  213. data/lib/opal/rack/app_server.rb +0 -119
  214. data/lib/opal/rake/opal_task.rb +0 -34
  215. data/opals/opal/README.md +0 -37
  216. data/opals/opal/browser/Opalfile +0 -11
  217. data/opals/opal/browser/README.md +0 -146
  218. data/opals/opal/browser/SIZZLE_LICESNSE.txt +0 -148
  219. data/opals/opal/browser/lib/browser.rb +0 -118
  220. data/opals/opal/browser/lib/browser/builder.rb +0 -41
  221. data/opals/opal/browser/lib/browser/canvas_context.rb +0 -115
  222. data/opals/opal/browser/lib/browser/dimensions.rb +0 -50
  223. data/opals/opal/browser/lib/browser/document.rb +0 -146
  224. data/opals/opal/browser/lib/browser/element.rb +0 -487
  225. data/opals/opal/browser/lib/browser/element/attributes.rb +0 -88
  226. data/opals/opal/browser/lib/browser/element/css.rb +0 -290
  227. data/opals/opal/browser/lib/browser/element/form.rb +0 -146
  228. data/opals/opal/browser/lib/browser/event/dom_events.rb +0 -81
  229. data/opals/opal/browser/lib/browser/event/event.rb +0 -177
  230. data/opals/opal/browser/lib/browser/event/trigger_events.rb +0 -53
  231. data/opals/opal/browser/lib/browser/geometry.rb +0 -97
  232. data/opals/opal/browser/lib/browser/json.rb +0 -32
  233. data/opals/opal/browser/lib/browser/request/request.rb +0 -201
  234. data/opals/opal/browser/lib/browser/sizzle.js +0 -1068
  235. data/opals/opal/browser/lib/browser/string.rb +0 -42
  236. data/opals/opal/browser/lib/browser/touch.rb +0 -37
  237. data/opals/opal/browser/lib/browser/vml_context.js +0 -33
  238. data/opals/opal/browser/lib/browser/window.rb +0 -36
  239. data/opals/opal/browser/spec/browser/browser_detection_spec.rb +0 -7
  240. data/opals/opal/browser/spec/document/aref_spec.rb +0 -110
  241. data/opals/opal/browser/spec/document/ready_spec.rb +0 -16
  242. data/opals/opal/browser/spec/element/body_spec.rb +0 -11
  243. data/opals/opal/browser/spec/element/clear_spec.rb +0 -26
  244. data/opals/opal/browser/spec/element/empty_spec.rb +0 -29
  245. data/opals/opal/browser/spec/element/has_class_spec.rb +0 -40
  246. data/opals/opal/browser/spec/element/hidden_spec.rb +0 -23
  247. data/opals/opal/browser/spec/element/hide_spec.rb +0 -31
  248. data/opals/opal/browser/spec/element/remove_spec.rb +0 -25
  249. data/opals/opal/browser/spec/element/show_spec.rb +0 -31
  250. data/opals/opal/browser/spec/element/style_spec.rb +0 -69
  251. data/opals/opal/browser/spec/element/toggle_spec.rb +0 -31
  252. data/opals/opal/browser/spec/element/visible_spec.rb +0 -23
  253. data/opals/opal/browser/spec/spec_helper.rb +0 -1
  254. data/opals/opal/opal/Opalfile +0 -14
  255. data/opals/opal/opal/spec/core/array/compact_spec.rb +0 -15
  256. data/opals/opal/opal/spec/fixtures/super.rb +0 -70
  257. data/opals/opal/opal/spec/language/____temp_remove_this.rb +0 -12
  258. data/opals/opal/opal/spec/language/block_spec.rb +0 -18
  259. data/opals/opal/opal/spec/language/case_spec.rb +0 -103
  260. data/opals/opal/opal/spec/language/metaclass_spec.rb +0 -21
  261. data/opals/opal/opal/spec/language/super_spec.rb +0 -26
  262. data/opals/opal/runtime/Opalfile +0 -78
  263. data/opals/opal/runtime/README.md +0 -12
  264. data/opals/opal/runtime/docs/debugging.md +0 -51
  265. data/opals/opal/runtime/lib/array.rb +0 -1516
  266. data/opals/opal/runtime/lib/basic_object.rb +0 -49
  267. data/opals/opal/runtime/lib/class.rb +0 -54
  268. data/opals/opal/runtime/lib/dir.rb +0 -36
  269. data/opals/opal/runtime/lib/error.rb +0 -49
  270. data/opals/opal/runtime/lib/false_class.rb +0 -52
  271. data/opals/opal/runtime/lib/file.rb +0 -79
  272. data/opals/opal/runtime/lib/hash.rb +0 -791
  273. data/opals/opal/runtime/lib/io.rb +0 -39
  274. data/opals/opal/runtime/lib/kernel.rb +0 -288
  275. data/opals/opal/runtime/lib/match_data.rb +0 -36
  276. data/opals/opal/runtime/lib/module.rb +0 -109
  277. data/opals/opal/runtime/lib/nil_class.rb +0 -69
  278. data/opals/opal/runtime/lib/number.rb +0 -398
  279. data/opals/opal/runtime/lib/proc.rb +0 -77
  280. data/opals/opal/runtime/lib/range.rb +0 -63
  281. data/opals/opal/runtime/lib/regexp.rb +0 -111
  282. data/opals/opal/runtime/lib/ruby.rb +0 -30
  283. data/opals/opal/runtime/lib/string.rb +0 -328
  284. data/opals/opal/runtime/lib/symbol.rb +0 -40
  285. data/opals/opal/runtime/lib/top_self.rb +0 -33
  286. data/opals/opal/runtime/lib/true_class.rb +0 -45
  287. data/opals/opal/runtime/runtime/browser.js +0 -287
  288. data/opals/opal/runtime/runtime/debug.js +0 -180
  289. data/opals/opal/runtime/runtime/opal.js +0 -1008
  290. data/opals/opal/runtime/runtime/post_opal.js +0 -1
  291. data/opals/opal/runtime/runtime/pre_opal.js +0 -2
  292. data/opals/opal/runtime/runtime/server_side.js +0 -50
  293. data/opals/opal/spec/LICENSE.txt +0 -26
  294. data/opals/opal/spec/Opalfile +0 -5
  295. data/opals/opal/spec/bin/spec.rb +0 -43
  296. data/opals/opal/spec/lib/spec.rb +0 -33
  297. data/opals/opal/spec/lib/spec/dsl.rb +0 -41
  298. data/opals/opal/spec/lib/spec/example.rb +0 -35
  299. data/opals/opal/spec/lib/spec/example/before_and_after_hooks.rb +0 -81
  300. data/opals/opal/spec/lib/spec/example/errors.rb +0 -42
  301. data/opals/opal/spec/lib/spec/example/example_group.rb +0 -37
  302. data/opals/opal/spec/lib/spec/example/example_group_factory.rb +0 -43
  303. data/opals/opal/spec/lib/spec/example/example_group_hierarchy.rb +0 -45
  304. data/opals/opal/spec/lib/spec/example/example_group_proxy.rb +0 -41
  305. data/opals/opal/spec/lib/spec/example/example_methods.rb +0 -73
  306. data/opals/opal/spec/lib/spec/example/example_proxy.rb +0 -48
  307. data/opals/opal/spec/lib/spec/expectations.rb +0 -46
  308. data/opals/opal/spec/lib/spec/expectations/errors.rb +0 -35
  309. data/opals/opal/spec/lib/spec/expectations/fail_with.rb +0 -37
  310. data/opals/opal/spec/lib/spec/expectations/handler.rb +0 -48
  311. data/opals/opal/spec/lib/spec/matchers.rb +0 -50
  312. data/opals/opal/spec/lib/spec/matchers/be.rb +0 -26
  313. data/opals/opal/spec/lib/spec/matchers/generated_descriptions.rb +0 -47
  314. data/opals/opal/spec/lib/spec/matchers/operator_matcher.rb +0 -66
  315. data/opals/opal/spec/lib/spec/runner.rb +0 -48
  316. data/opals/opal/spec/lib/spec/runner/example_group_runner.rb +0 -71
  317. data/opals/opal/spec/lib/spec/runner/formatter/terminal_formatter.rb +0 -82
  318. data/opals/opal/spec/lib/spec/runner/options.rb +0 -63
  319. data/opals/opal/spec/resources/index.html +0 -25
  320. data/opals/opal/spec/resources/spec.css +0 -132
  321. data/spec/cherry_kit/iseq_spec.rb +0 -38
  322. data/spec/spec_helper.rb +0 -16
  323. data/spec/vienna_spec.rb +0 -7
  324. data/yard/index.html +0 -43
  325. data/yard/style.css +0 -765
@@ -1,1851 +0,0 @@
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