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,210 @@
1
+ #
2
+ # nodes.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
+ def node_args(arg, opt, rest, post, block)
34
+ Vienna::RubyParser::RArgsNode.new arg, opt, rest, post, block
35
+ end
36
+
37
+ def node_module(options)
38
+ Vienna::RubyParser::RModule.new options
39
+ end
40
+
41
+ def node_class(options)
42
+ Vienna::RubyParser::RClass.new options
43
+ end
44
+
45
+ def node_bodystmt(compstmt, opt_rescue, opt_else, opt_ensure)
46
+ # puts opt_rescue
47
+ # # if opt_rescue
48
+ # # puts opt_rescue
49
+ # # end
50
+ #
51
+ # compstmt.instance_eval do
52
+ # @vn_opt_rescue = opt_rescue
53
+ # @vn_opt_else = opt_else
54
+ # @vn_opt_ensure = opt_ensure
55
+ #
56
+ # def vn_opt_rescue; @vn_opt_rescue; end
57
+ # def vn_opt_else; @vn_opt_else; end
58
+ # def vn_opt_ensure; @vn_opt_ensure; end
59
+ #
60
+ # end
61
+ #
62
+ # # if compstmt.vn_opt_rescue
63
+ # # puts compstmt.vn_opt_rescue
64
+ # end
65
+
66
+ {
67
+ :compstmt => compstmt,
68
+ :opt_rescue => opt_rescue,
69
+ :opt_else => opt_else,
70
+ :opt_ensure => opt_ensure
71
+ }
72
+ end
73
+
74
+ # instance level def
75
+ def node_def(*args)
76
+
77
+ end
78
+
79
+ # singleton level def
80
+ def node_defs(*args)
81
+
82
+ end
83
+
84
+ # generic node, for use anywhere...
85
+ def node type, options={}
86
+ Vienna::RubyParser::RNode.new type, options
87
+ end
88
+
89
+ class RArgsNode
90
+
91
+ attr_reader :arg, :opt, :rest, :post, :block
92
+
93
+ def initialize(a,o,r,p,b)
94
+ @arg = a
95
+ @opt = o
96
+ @rest = r
97
+ @post = p
98
+ @block = b
99
+ end
100
+
101
+ # for generator
102
+ def to_s
103
+ arg_size
104
+ end
105
+
106
+ def arg_size
107
+ @arg ? @arg.length : 0
108
+ end
109
+
110
+ def opt_size
111
+ @opt ? @opt.length : 0
112
+ end
113
+
114
+ def rest_size
115
+ @rest ? 1 : 0
116
+ end
117
+
118
+ def post_size
119
+ @post ? @post.length : 0
120
+ end
121
+
122
+ def block_size
123
+ @block ? @block.length : 0
124
+ end
125
+ end
126
+
127
+ class RModule
128
+
129
+ attr_accessor :bodystmt
130
+
131
+ def initialize options
132
+ @bodystmt = options[:body]
133
+ @cpath = options[:cpath]
134
+ # puts options[:cpath]
135
+ end
136
+
137
+ def node
138
+ :module
139
+ end
140
+
141
+ def js_name
142
+ @js_name ||= "m#{@cpath[:cname]}"
143
+ end
144
+
145
+ def klass_name
146
+ @klass_name ||= @cpath[:cname]
147
+ end
148
+
149
+ def super_klass
150
+ "cObject"
151
+ end
152
+ end
153
+
154
+ class RClass
155
+
156
+ attr_accessor :bodystmt
157
+
158
+ def initialize options
159
+ @cpath = options[:cpath]
160
+ @superclass = options[:superclass]
161
+ @bodystmt = options[:bodystmt]
162
+ end
163
+
164
+ def node
165
+ :klass
166
+ end
167
+
168
+ def js_name
169
+ @js_name ||= "c#{@cpath[:cname]}"
170
+ end
171
+
172
+ def klass_name
173
+ @klass_name ||= @cpath[:cname]
174
+ end
175
+
176
+ def super_klass
177
+ @superclass
178
+ end
179
+ end
180
+
181
+ class RNode
182
+
183
+ def initialize(node, options={})
184
+ @node = node
185
+ @options = options
186
+ end
187
+
188
+ def [](id)
189
+ @options[id]
190
+ end
191
+
192
+ def []=(id, val)
193
+ @options[id] = val
194
+ end
195
+
196
+ def node
197
+ @node
198
+ end
199
+
200
+ def to_s
201
+ "('#{@node}' #{@options.inspect})"
202
+ end
203
+
204
+ def inspect
205
+ "('#{@node}' #{@options.inspect})"
206
+ end
207
+ end
208
+
209
+ end
210
+ end
@@ -0,0 +1,916 @@
1
+ #
2
+ # ruby.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
+ require 'strscan'
29
+
30
+ # puts Vienna::RubyParser
31
+
32
+ class Vienna::RubyParser < Racc::Parser
33
+
34
+ # Used for lex_state enum, possible values:
35
+ # :EXPR_BEG
36
+ # :EXPR_END
37
+ # :EXPR_ENDARG
38
+ # :EXPR_ARG
39
+ # :EXPR_CMDARG
40
+ # :EXPR_MID
41
+ # :EXPR_FNAME
42
+ # :EXPR_DOT
43
+ # :EXPR_CLASS
44
+ # :EXPR_VALUE
45
+ attr_accessor :lex_state
46
+
47
+ attr_accessor :string_parse
48
+
49
+ # last read token
50
+ attr_accessor :token
51
+
52
+ # string scanner used for parser
53
+ attr_reader :scanner
54
+
55
+ attr_reader :requirements
56
+
57
+
58
+ def self.parse(file_name)
59
+ new(file_name)
60
+ end
61
+
62
+ # Rewrite to simply return the "compiled" source as a string. This will make
63
+ # testing incredibly easy.
64
+ def initialize(build_name, str, options = {})
65
+ @iseq_type = options[:iseq_type] || :top
66
+ @source = build_name
67
+ @build_path = build_name
68
+ @build_name = build_name
69
+ @scanner = StringScanner.new str
70
+
71
+ # in debug mode we tell def's what their linenumber is
72
+ @line_number = 1
73
+ # current def's linenumber
74
+ @current_def_linenumber = 0
75
+ # For generate:
76
+ @iseq_stack = []
77
+ end
78
+
79
+ # def initialize(source, dest, project)
80
+ # @source = source
81
+ # @destination = dest
82
+ # @project = project
83
+ # @requirements = []
84
+ # @current_self = ['VN.self']
85
+ # @current_self_stack_counter = 0
86
+ # @context_var_stack = []
87
+ # # Array of arrays
88
+ # @nametable = []
89
+ #
90
+ # File.open(@source) do |f|
91
+ # @scanner = StringScanner.new(f.read)
92
+ # end
93
+ #
94
+ # # do_parse
95
+ # end
96
+
97
+ def build!
98
+ # puts "building #@source"
99
+ do_parse
100
+ # this will return the needed string
101
+ res = generate_tree @parser_result unless @parser_result.nil?
102
+ res
103
+ end
104
+
105
+ # This should simpy parse the given string, and return a syntax tree.
106
+ # This method is heavily used for parsing ruby code within other contexts,
107
+ # for example: processing strings containing ruby: "bob is #{@bob.to_a}"
108
+ def self.parse_to_tree str
109
+ return nil
110
+ end
111
+
112
+ # parse the inpit file, to a destination file, using the given project
113
+ def self.parse_to_file source, destination, project
114
+
115
+ end
116
+
117
+ def js_replacement_function_name(name)
118
+ @project.js_replacement_function_name(name)
119
+ end
120
+
121
+
122
+ # the id for the given string when used at runtime
123
+ def js_id_for_string(str)
124
+ @project.js_id_for_string(str)
125
+ end
126
+
127
+ # the id for the given symbol when used at runtime
128
+ def js_id_for_symbol(sym)
129
+ @project.js_id_for_symbol(sym)
130
+ end
131
+
132
+ def js_id_for_ivar(ivar)
133
+ @project.js_id_for_ivar(ivar)
134
+ end
135
+
136
+ def js_id_for_const(const)
137
+ @project.js_id_for_const(const)
138
+ end
139
+
140
+
141
+ # Parse the input, and return a string as output
142
+ # def self.parse str
143
+
144
+ # end
145
+
146
+ # def write(str)
147
+ # @output_file.write str
148
+ # end
149
+
150
+ # Push new context onto the nametable (var lookup)
151
+ #
152
+ def push_nametable
153
+ @nametable << []
154
+ end
155
+
156
+ # Pop current context from nametable
157
+ #
158
+ def pop_nametable
159
+ @nametable.pop()
160
+ end
161
+
162
+ # Check if variable is named in nametable
163
+ #
164
+ def nametable_include?(name)
165
+ @nametable.each do |n|
166
+ return true if n.include? name
167
+ end
168
+ false
169
+ end
170
+
171
+ # Add into current context of nametable
172
+ #
173
+ def add_to_nametable(name)
174
+ @nametable.last << name
175
+ end
176
+
177
+
178
+ def push_current_self
179
+ @current_self_stack_counter += 1
180
+ @current_self << "$VN_#{@current_self_stack_counter}"
181
+ end
182
+
183
+ def pop_current_self
184
+ @current_self_stack_counter -= 1
185
+ @current_self.pop
186
+ end
187
+
188
+ def current_self_start_def
189
+ @current_self << 'self'
190
+ end
191
+
192
+ def current_self_end_def
193
+ @current_self.pop
194
+ end
195
+
196
+ # The JS var holding the 'self' within the current code context
197
+ def current_self
198
+ # @current_self_in_def ? 'this' : "$_vn_#{@current_self}"
199
+ @current_self.last
200
+ end
201
+
202
+ # Context for declared variables.... if an identifier isnt in this list,
203
+ # thenis is assumed to be a method name for the current self
204
+ def push_context_stack
205
+ @context_var_stack << []
206
+ end
207
+
208
+ def pop_context_stack
209
+ @context_var_stack.pop
210
+ end
211
+
212
+ def add_to_context_stack str
213
+ @context_var_stack.last << str
214
+ end
215
+
216
+
217
+
218
+
219
+ # returns the next token (token/value array)
220
+ def next_token
221
+ t = get_next_token
222
+ # puts "#{t[0]} : #{t[1]} (#{self.lex_state})"
223
+ return t
224
+ end
225
+
226
+ # Returns serialized tokens for strings. these could be dvars, contents or
227
+ # the end of string markers, and these must be returned as appropriate.
228
+ #
229
+ # TODO:
230
+ # - implement as stack, so strings contained within the embedded ruby code
231
+ # of other strings can be accessed. string_parse_push, string_parse_pop etc
232
+ #
233
+ #
234
+ #
235
+ def get_next_string_token
236
+ string_type = string_parse[:type]
237
+ string_beg = string_parse[:beg]
238
+
239
+ allow_new_lines = [:words, :xstring].include? string_type
240
+ interpolate = !(string_type == :squote)
241
+
242
+ # Read end of string/xstring/regexp markers
243
+ if scanner.scan(/#{Regexp.escape string_beg}/)
244
+ if string_type == :dquote or string_type == :squote
245
+ self.string_parse = nil
246
+ self.lex_state = :EXPR_END
247
+ return [:tSTRING_END, scanner.matched]
248
+ elsif string_type == :words
249
+ self.string_parse = nil
250
+ self.lex_state = :EXPR_END
251
+ return [:tSTRING_END, scanner.matched]
252
+ elsif string_type == :regexp
253
+ self.string_parse = nil
254
+ self.lex_state = :EXPR_END
255
+ return [:tREGEXP_END, scanner.matched]
256
+ else # assume to be an xstring
257
+ self.string_parse = nil
258
+ self.lex_state = :EXPR_END
259
+ return [:tXSTRING_END, scanner.matched]
260
+ end
261
+ end
262
+
263
+ # not end of string, so must be contents..
264
+
265
+ str_buffer = []
266
+
267
+ case
268
+ when scanner.scan(/#(\$|\@)/)
269
+ if interpolate
270
+ return [:tSTRING_DVAR, scanner.matched]
271
+ else
272
+ str_buffer << scanner.matched
273
+ end
274
+ when scanner.scan(/#\{/)
275
+ if interpolate
276
+ string_parse[:content] = false
277
+ return [:tSTRING_DBEG, scanner.matched]
278
+ else
279
+ str_buffer << scanner.matched
280
+ end
281
+ when scanner.scan(/#/)
282
+ str_buffer << '#'
283
+
284
+ # catch regecp error..
285
+ if string_type == :regexp && scanner.peek(1) == '/'
286
+ # raise "error catching!"
287
+ return [:tSTRING_CONTENT, str_buffer.join]
288
+ end
289
+ end
290
+
291
+ # add string content here
292
+
293
+ # scanner.scan(/(.|\s)/)
294
+
295
+ # xstrings can have new lines: normal strings cant, so exlcude \n from normal strings
296
+ re = (allow_new_lines) ? /[^#{Regexp.escape(string_beg)}\#\0]+|./ : /[^#{Regexp.escape(string_beg)}\#\0\n]+|./
297
+
298
+ # puts re
299
+ scanner.scan(re)
300
+ # puts scanner.matched
301
+ # abort @source
302
+
303
+
304
+ str_buffer << scanner.matched
305
+ full_buffer = str_buffer.join
306
+ @line_number += full_buffer.count("\n")
307
+
308
+ return [:tSTRING_CONTENT, full_buffer]
309
+
310
+ end
311
+
312
+
313
+ # Next token
314
+ #
315
+ def get_next_token
316
+ c = ''
317
+ space_seen = false
318
+ cmd_state = 0
319
+ last_state = lex_state
320
+
321
+ return get_next_string_token if string_parse && string_parse[:content] == true
322
+
323
+ loop do
324
+ # puts "starting loop with: #{self.lex_state}"
325
+ if scanner.scan(/\ |\t|\r/)
326
+ space_seen = true
327
+ next
328
+ elsif scanner.scan(/\n|#/)
329
+ c = scanner.matched
330
+ scanner.scan(/.*\n/) if c == '#'
331
+ # puts self.lex_state
332
+ scanner.scan(/\n+/)
333
+
334
+ @line_number += 1
335
+
336
+ @line_number += scanner.matched.length if scanner.matched
337
+
338
+ if [:EXPR_BEG, :EXPR_FNAME, :EXPR_DOT, :EXPR_CLASS].include? lex_state then
339
+ # puts 'hell yeah!'
340
+ # @line_number += scanner.matched.length
341
+ next
342
+ else
343
+ # puts 'well, i dnno'
344
+ end
345
+
346
+ # scanner.scan(/\n+/)
347
+ self.lex_state = :EXPR_BEG
348
+ return ['\n', '\n']
349
+
350
+ # ']', ')', '}'
351
+ elsif scanner.scan(/\]/)
352
+ self.lex_state = :EXPR_END
353
+ return [']', scanner.matched]
354
+ elsif scanner.scan(/\)/)
355
+ self.lex_state = :EXPR_END
356
+ return [')', scanner.matched]
357
+ elsif scanner.scan(/\}/)
358
+ self.lex_state = :EXPR_END
359
+ if string_parse
360
+ string_parse[:content] = true
361
+ end
362
+ return ['}', scanner.matched]
363
+
364
+ # '...', '..', '.'
365
+ elsif scanner.scan(/\.\.\./)
366
+ self.lex_state = :EXPR_BEG
367
+ return [:tDOT3, scanner.matched]
368
+ elsif scanner.scan(/\.\./)
369
+ self.lex_state = :EXPR_BEG
370
+ return [:tDOT2, scanner.matched]
371
+ elsif scanner.scan(/\./)
372
+ self.lex_state = :EXPR_DOT unless self.lex_state == :EXPR_FNAME
373
+ return ['.', scanner.matched]
374
+
375
+ # ','
376
+ elsif scanner.scan(/\,/)
377
+ self.lex_state = :EXPR_BEG
378
+ return [',', scanner.matched]
379
+
380
+ # '('
381
+ elsif scanner.scan(/\(/)
382
+ result = '('
383
+ if lex_state == :EXPR_BEG || lex_state == :EXPR_MID
384
+ result = :tLPAREN
385
+ elsif space_seen
386
+ if lex_state == :EXPR_CMDARG
387
+ result = :tLPAREN_ARG
388
+ elsif lex_state == :EXPR_ARG
389
+ # throw warning to not put space before arguments
390
+ result = :tLPAREN2
391
+ end
392
+ end
393
+ self.lex_state = :EXPR_BEG
394
+ return [result, scanner.matched]
395
+
396
+ # '===', '==', '=~', '=>', '='
397
+ elsif scanner.scan(/\=\=\=/)
398
+ return [:tEQQ, scanner.matched]
399
+ elsif scanner.scan(/\=\=/)
400
+ self.lex_state = :EXPR_BEG
401
+ return [:tEQ, scanner.matched]
402
+ elsif scanner.scan(/\=\~/)
403
+ return [:tMATCH, scanner.matched]
404
+ elsif scanner.scan(/\=\>/)
405
+ # puts self.lex_state
406
+ self.lex_state = :EXPR_BEG
407
+ return [:tASSOC, scanner.matched]
408
+ elsif scanner.scan(/\=/)
409
+ self.lex_state = :EXPR_BEG
410
+ return ['=', scanner.matched]
411
+
412
+ # Class variables
413
+ elsif scanner.scan(/\@\@\w*/)
414
+ self.lex_state = :EXPR_END
415
+ return [:tCVAR, scanner.matched]
416
+
417
+ # Instance variables
418
+ elsif scanner.scan(/\@\w*/)
419
+ self.lex_state = :EXPR_END
420
+ return [:tIVAR, scanner.matched]
421
+
422
+
423
+
424
+ # Strings, in order: double, single, xstring
425
+ elsif scanner.scan(/\"/)
426
+ self.string_parse = { :type => :dquote, :beg => '"', :content => true }
427
+ return [:tSTRING_BEG, scanner.matched]
428
+
429
+ elsif scanner.scan(/\'/)
430
+ self.string_parse = { :type => :squote, :beg => "'", :content => true }
431
+ return [:tSTRING_BEG, scanner.matched]
432
+
433
+ elsif scanner.scan(/\`/)
434
+ self.string_parse = { :type => :xstring, :beg => '`', :content => true }
435
+ return [:tXSTRING_BEG, scanner.matched]
436
+
437
+ elsif scanner.scan(/\%W/)
438
+ start_word = scanner.scan(/./)
439
+ end_start_word = {'(' => ')', '[' => ']', '{' => '}'}[start_word]
440
+ end_start_word ||= start_word
441
+
442
+ self.string_parse = { :type => :words, :beg => end_start_word, :content => true}
443
+ return [:tWORDS_BEG, scanner.matched]
444
+
445
+
446
+ elsif scanner.scan(/\=/)
447
+ return [:tSTRING_BEG, scanner.matched]
448
+ elsif scanner.scan(/\:\:/)
449
+ if lex_state == :EXPR_BEG || lex_state == :EXPR_MID || lex_state == :EXPR_CLASS
450
+ self.lex_state = :EXPR_BEG
451
+ return [:tCOLON3, scanner.matched]
452
+ end
453
+ self.lex_state = :EXPR_DOT
454
+ return [:tCOLON2, scanner.matched]
455
+ elsif scanner.scan(/\:/)
456
+ if lex_state == :EXPR_END || lex_state == :EXPR_ENDARG || scanner.check(/\s/)
457
+
458
+ # FIXME: hack for tertiary if statements.....
459
+ unless scanner.check(/\w/)
460
+ return [':', scanner.matched]
461
+ end
462
+ # END HACK
463
+
464
+
465
+
466
+
467
+ # puts "#{lex_state} ===== #{scanner.check(/\w/)}"
468
+ self.lex_state = :EXPR_BEG
469
+ return [:tSYMBEG, scanner.matched]
470
+ end
471
+
472
+ # FIXME: space_seen hack... ? : syaye,emts might not have space...
473
+ # if space_seen && scanner.check(/\W/)
474
+ # return [':', scanner.matched]
475
+ # else
476
+
477
+
478
+ if scanner.scan(/\"/)
479
+ self.string_parse = { :type => :dquote, :beg => '"', :content => true }
480
+ # return [:tSTRING_BEG, scanner.matched]
481
+ end
482
+
483
+ self.lex_state = :EXPR_FNAME
484
+ # puts "here for symbeg #{scanner.peek(8)}"
485
+ return [:tSYMBEG, ':']
486
+ # end
487
+ # Parse a number.
488
+ elsif scanner.check(/[0-9]/)
489
+ self.lex_state = :EXPR_END
490
+ if scanner.scan(/[\d_]+\.[\d_]+\b/)
491
+ return [:tFLOAT, scanner.matched.gsub(/_/, '')]
492
+ elsif scanner.scan(/[\d_]+\b/)
493
+ return [:tINTEGER, scanner.matched.gsub(/_/, '')]
494
+ elsif scanner.scan(/0(x|X)(\d|[a-f]|[A-F])+/)
495
+ return [:tINTEGER, scanner.matched]
496
+ else
497
+ puts "error: unexpected number type: #{scanner.peek(10)}"
498
+ end
499
+
500
+ elsif scanner.scan(/\[/)
501
+ result = scanner.matched
502
+
503
+ if lex_state == :EXPR_FNAME || lex_state == :EXPR_DOT
504
+ self.lex_state = :EXPR_ARG
505
+ case
506
+ when scanner.scan(/\]\=/)
507
+ return [:tASET, '[]=']
508
+ when scanner.scan(/\]/)
509
+ return [:tAREF, '[]']
510
+ else
511
+ puts "error - unexpected '[' token"
512
+ end
513
+ # space_seen allows for method calls with an array as first param - otherwise it
514
+ # thinks its calling the method []
515
+ elsif lex_state == :EXPR_BEG || lex_state == :EXPR_MID || space_seen
516
+ self.lex_state = :EXPR_BEG
517
+ return [:tLBRACK, scanner.matched]
518
+ end
519
+ # puts 'HMHMHMHMHMHMHMHMHH'
520
+ # puts lex_state
521
+ self.lex_state = :EXPR_BEG
522
+ return ['[', scanner.matched]
523
+ elsif scanner.scan(/\'(\\.|[^\'])*\'/)
524
+ self.lex_state = :EXPR_END
525
+ return [:tSTRING, scanner.matched[1..-2].gsub(/\\\\/, "\\").gsub(/\\'/, "'")]
526
+ elsif scanner.check(/\|/)
527
+ if scanner.scan(/\|\|\=/)
528
+ self.lex_state = :EXPR_BEG
529
+ return [:tOP_ASGN, '||']
530
+ elsif scanner.scan(/\|\|/)
531
+ self.lex_state = :EXPR_BEG
532
+ return [:tOROP, scanner.matched]
533
+ elsif scanner.scan(/\|\=/)
534
+ self.lex_state = :EXPR_BEG
535
+ return [:tOP_ASSIGN, scanner.matched]
536
+ elsif scanner.scan(/\|/)
537
+ self.lex_state = :EXPR_BEG
538
+ return ['|', scanner.matched]
539
+ end
540
+ elsif scanner.scan(/\{/)
541
+ # puts "{ lex state is #{self.lex_state}"
542
+ result = if (self.lex_state == :EXPR_END) || (self.lex_state == :EXPR_CMDARG)
543
+ '{' # primary block
544
+ elsif (self.lex_state == :EXPR_ENDARG)
545
+ :tLBRACE_ARG # expr block
546
+ else
547
+ :tLBRACE # hash
548
+ end
549
+ # puts "returning #{result}"
550
+ return [result, scanner.matched]
551
+ # +/- as methods/unary etc
552
+ elsif scanner.scan(/[+-]/)
553
+ result = scanner.matched
554
+ sign = (result == "+") ? :tUPLUS : :tUMINUS
555
+ # if this is a func name def, or a method of an object ( def +(other))
556
+ # puts self.lex_state
557
+ if self.lex_state == :EXPR_FNAME || self.lex_state == :EXPR_DOT
558
+ self.lex_state = :EXPR_ARG
559
+ if scanner.scan(/@/)
560
+ return [sign, "#{result}@"]
561
+ else
562
+ return [sign, result]
563
+ end
564
+ end
565
+ # += or -=
566
+ if scanner.scan(/\=/)
567
+ self.lex_state = :EXPR_BEG
568
+ return [:tOP_ASGN, "#{result}"]
569
+ end
570
+
571
+ if lex_state == :EXPR_BEG || lex_state == :EXPR_MID
572
+ self.lex_state = :EXPR_BEG
573
+ return [sign, result]
574
+ end
575
+ self.lex_state = :EXPR_BEG
576
+ return [result, result]
577
+
578
+ elsif scanner.scan(/\//)
579
+ if lex_state == :EXPR_BEG || lex_state == :EXPR_MID
580
+ self.string_parse = { :type => :regexp,:beg => '/', :content => true }
581
+ return [:tREGEXP_BEG, scanner.matched]
582
+ end
583
+
584
+ self.lex_state = :EXPR_BEG
585
+ return ['/', scanner.matched]
586
+
587
+ elsif scanner.scan(/\*\*\=/)
588
+ self.lex_state = :EXPR_BEG
589
+ return [:tOP_ASGN, '**']
590
+ elsif scanner.scan(/\*\*/)
591
+ return [:tPOW, '**']
592
+ elsif scanner.scan(/\*\=/)
593
+ self.lex_state = :EXPR_BEG
594
+ return [:tOP_ASGN, '*']
595
+ elsif scanner.scan(/\*/)
596
+ result = if lex_state == :EXPR_FNAME
597
+ self.lex_state = :EXPR_BEG
598
+ '*'
599
+ elsif space_seen && scanner.check(/\S/)
600
+ :tSTAR
601
+ elsif lex_state == :EXPR_BEG || lex_state == :EXPR_MID
602
+ :tSTAR
603
+ else
604
+ self.lex_state = :EXPR_BEG
605
+ '*'
606
+ end
607
+ return [result, scanner.matched]
608
+ elsif scanner.scan(/\!\=/)
609
+ self.lex_state = :EXPR_BEG
610
+ return [:tNEQ, '!=']
611
+ elsif scanner.scan(/\!\~/)
612
+ self.lex_state = :EXPR_BEG
613
+ return [:tNMATCH, '!~']
614
+ elsif scanner.scan(/\!/)
615
+ self.lex_state = :EXPR_BEG
616
+ # puts 'HERE""""'
617
+ return ['!', '!']
618
+
619
+ elsif scanner.scan(/\<\=\>/)
620
+ return [:tCMP, '<=>']
621
+ elsif scanner.scan(/\<\=/)
622
+ return [:tLEQ, '<=']
623
+ elsif scanner.scan(/\<\<\=/)
624
+ self.lex_state = :EXPR_BEG
625
+ return [:tOP_ASGN, '<<']
626
+ elsif scanner.scan(/\<\</)
627
+ if (! [:EXPR_END, :EXPR_DOT, :EXPR_ENDARG, :EXPR_CLASS].include?(lex_state) && space_seen)
628
+ self.lex_state = :EXPR_BEG
629
+ return [:tLSHFT, '<<']
630
+ end
631
+ # self.lex_state = :EXPR_BEG
632
+ self.lex_state = :EXPR_BEG
633
+ # puts "HERE on ERROR"
634
+ return [:tLSHFT, '<<']
635
+ elsif scanner.scan(/\</)
636
+ self.lex_state = :EXPR_BEG
637
+ return ['<', '<']
638
+
639
+ elsif scanner.scan(/\>\=/)
640
+ return [:tGEQ, '>=']
641
+ elsif scanner.scan(/\>\>\=/)
642
+ self.lex_state = :EXPR_BEG
643
+ return [:tOP_ASGN, '>>']
644
+ elsif scanner.scan(/\>\>/)
645
+ return [:tRSHFT, '>>']
646
+ elsif scanner.scan(/\>/)
647
+ self.lex_state = :EXPR_BEG
648
+ return ['>', '>']
649
+
650
+ elsif scanner.scan(/\`/)
651
+ case self.lex_state
652
+ when :EXPR_FNAME
653
+ self.lex_state = :EXPR_END
654
+ return [:tBACK_REF2, '`']
655
+ when :EXPR_DOT
656
+ self.lex_state = :EXPR_ARG
657
+ return [:tBACK_REF2, '`']
658
+ end
659
+ return [:tXSTRING_BEG, '`']
660
+
661
+ elsif scanner.scan(/\?/)
662
+ if lex_state == :EXPR_END || lex_state == :EXPR_ENDARG
663
+ self.lex_state = :EXPR_BEG
664
+
665
+ end
666
+ return ['?', '?']
667
+ # if scanner.check(/\s|\v/)
668
+ # unless lex_state == :EXPR_ARG
669
+
670
+ elsif scanner.scan(/\&\&\=/)
671
+ self.lex_state = :EXPR_BEG
672
+ return [:tOP_ASGN, '&&']
673
+ elsif scanner.scan(/\&\&/)
674
+ self.lex_state = :EXPR_BEG
675
+ return [:tANDOP, '&&']
676
+ elsif scanner.scan(/\&\=/)
677
+ self.lex_state = :EXPR_BEG
678
+ return [:tOP_ASGN, '&']
679
+ elsif scanner.scan(/\&/)
680
+ # puts self.lex_state
681
+ result = if space_seen && !scanner.check(/\s/)
682
+ if self.lex_state == :EXPR_CMDARG
683
+ :tAMPER
684
+ else
685
+ '&'
686
+ end
687
+ # puts "first for amper #{scanner.peek(20)}"
688
+ # warning: & as prefix
689
+ # :tAMPER
690
+ # '&'
691
+ elsif lex_state == :EXPR_BEG || lex_state == :EXPR_MID
692
+ # puts "got amper here..#{scanner.peek(10)}"
693
+ # used to be tAMPER
694
+ :tAMPER
695
+ else
696
+ # puts "last amper: #{scanner.peek(20)}"
697
+ '&'
698
+ end
699
+
700
+ return [result, '&']
701
+
702
+ elsif scanner.scan(/\^\=/)
703
+ self.lex_state = :EXPR_BEG
704
+ return [:tOP_ASGN, '^']
705
+ elsif scanner.scan(/\^/)
706
+ return ['^', '^']
707
+ elsif scanner.scan(/\;/)
708
+ self.lex_state = :EXPR_BEG
709
+ return [';', ';']
710
+ elsif scanner.scan(/\~/)
711
+ self.lex_state = :EXPR_BEG
712
+ return ['~', '~']
713
+
714
+ elsif scanner.scan(/\\/)
715
+ if scanner.scan(/\n/)
716
+ space_seen = true
717
+ next
718
+ end
719
+ # error: backslash only allowed before newline
720
+
721
+ elsif scanner.scan(/\%/)
722
+ if scanner.scan(/\=/)
723
+ self.lex_state = :EXPR_BEG
724
+ return [:tOP_ASGN, '%']
725
+ else
726
+ return ['%', '%']
727
+ end
728
+ if scanner.scan(/(\$_)(\w+)/)
729
+ end
730
+
731
+ elsif scanner.scan(/\$\:/)
732
+ # puts "found dollar sign"
733
+ return [:tGVAR, scanner.matched]
734
+
735
+ elsif scanner.scan(/\w+[\?\!]?/)
736
+ case scanner.matched
737
+ when 'def'
738
+ # puts "#{@source} def on line #{@line_number}"
739
+ @current_def_linenumber = @line_number
740
+ self.lex_state = :EXPR_FNAME
741
+ return [:kDEF, scanner.matched]
742
+ when 'end'
743
+ self.lex_state = :EXPR_END
744
+ return [:kEND, scanner.matched]
745
+ when 'class'
746
+ return [:tIDENTIFIER, scanner.matched] if self.lex_state == :EXPR_DOT
747
+ self.lex_state = :EXPR_CLASS
748
+ return [:kCLASS, scanner.matched]
749
+ when 'module'
750
+ self.lex_state = :EXPR_BEG
751
+ return [:kMODULE, scanner.matched]
752
+ when 'do'
753
+ # puts "do lex state is #{self.lex_state}"
754
+ if lex_state == :EXPR_ENDARG
755
+ self.lex_state = :EXPR_BEG
756
+ return [:kDO_BLOCK, scanner.matched]
757
+ end
758
+ # this might be wrong
759
+ # if lex_state == :EXPR_CMDARG
760
+ # return [:kDO_BLOCK, scanner.matched]
761
+ # end
762
+ self.lex_state = :EXPR_BEG
763
+ return [:kDO, scanner.matched]
764
+ when 'if'
765
+ return [:kIF, scanner.matched] if lex_state == :EXPR_BEG
766
+ self.lex_state = :EXPR_BEG
767
+ return [:kIF_MOD, scanner.matched]
768
+ when 'while'
769
+ return [:kWHILE, scanner.matched] if lex_state == :EXPR_BEG
770
+ self.lex_state = :EXPR_BEG
771
+ return [:kWHILE_MOD, scanner.matched]
772
+ when 'until'
773
+ return [:kUNTIL, scanner.matched] if lex_state == :EXPR_BEG
774
+ self.lex_state = :EXPR_BEG
775
+ return [:kUNTIL_MOD, scanner.matched]
776
+ when 'lambda'
777
+ self.lex_state = :EXPR_BEG
778
+ return [:tLAMBDA, scanner.matched]
779
+ when 'then'
780
+ # self.lex_state =
781
+ return [:kTHEN, scanner.matched]
782
+ when 'else'
783
+ return [:kELSE, scanner.matched]
784
+ when 'elsif'
785
+ return [:kELSIF, scanner.matched]
786
+ when 'unless'
787
+ return [:kUNLESS, scanner.matched] if lex_state == :EXPR_BEG
788
+ self.lex_state = :EXPR_BEG
789
+ return [:kUNLESS_MOD, scanner.matched]
790
+ when 'self'
791
+ self.lex_state = :EXPR_END unless self.lex_state == :EXPR_FNAME
792
+ return [:kSELF, scanner.matched]
793
+ when 'super'
794
+ self.lex_state = :EXPR_ARG
795
+ return [:kSUPER, scanner.matched]
796
+ when 'true'
797
+ self.lex_state = :EXPR_END
798
+ return [:kTRUE, scanner.matched]
799
+ when 'block_given?'
800
+ self.lex_state = :EXPR_END
801
+ return [:kBLOCK_GIVEN, scanner.matched]
802
+ when 'false'
803
+ self.lex_state = :EXPR_END
804
+ return [:kFALSE, scanner.matched]
805
+ when 'nil'
806
+ self.lex_state = :EXPR_END
807
+ return [:kNIL, scanner.matched]
808
+ when 'or'
809
+ self.lex_state = :EXPR_BEG
810
+ return [:kOR, scanner.matched]
811
+ when 'and'
812
+ self.lex_state = :EXPR_BEG
813
+ return [:kAND, scanner.matched]
814
+ when 'return'
815
+ self.lex_state = :EXPR_MID
816
+ return [:kRETURN, scanner.matched]
817
+ when 'break'
818
+ self.lex_state = :EXPR_MID
819
+ return [:kBREAK, scanner.matched]
820
+ when 'next'
821
+ return [:tIDENTIFIER, scanner.matched] if self.lex_state == :EXPR_DOT
822
+ self.lex_state = :EXPR_MID
823
+ return [:kNEXT, scanner.matched]
824
+ when 'redo'
825
+ self.lex_state = :EXPR_MID
826
+ return [:kREDO, scanner.matched]
827
+ when 'case'
828
+ self.lex_state = :EXPR_BEG
829
+ return [:kCASE, scanner.matched]
830
+ when 'when'
831
+ self.lex_state = :EXPR_BEG
832
+ return [:kWHEN, scanner.matched]
833
+ when 'not'
834
+ self.lex_state = :EXPR_BEG
835
+ return [:kNOT, scanner.matched]
836
+ when 'yield'
837
+ self.lex_state = :EXPR_ARG
838
+ return [:kYIELD, scanner.matched]
839
+ when '__FILE__'
840
+ self.lex_state = :EXPR_END
841
+ return [:k__FILE__, scanner.matched]
842
+ when '__LINE__'
843
+ self.lex_state = :EXPR_END
844
+ return [:k__LINE__, scanner.matched]
845
+ when 'alias'
846
+ self.lex_state = :EXPR_BEG
847
+ return [:kALIAS, scanner.matched]
848
+ when 'begin'
849
+ self.lex_state = :EXPR_BEG
850
+ return [:kBEGIN, scanner.matched]
851
+ when 'rescue'
852
+ self.lex_state = :EXPR_MID
853
+ return [:kRESCUE, scanner.matched]
854
+ when 'ensure'
855
+ self.lex_state = :EXPR_BEG
856
+ return [:kENSURE, scanner.matched]
857
+ end
858
+
859
+ matched = scanner.matched
860
+
861
+ # labels
862
+ # avoid us picking up a mod/class divide name
863
+ if scanner.peek(2) != '::' and scanner.scan(/\:/)
864
+ # puts "LABEL!!!!! #{matched + scanner.matched}"
865
+ # puts self.lex_state
866
+ return [:tLABEL, matched + scanner.matched]
867
+ end
868
+
869
+
870
+ if self.lex_state == :EXPR_FNAME then
871
+ # puts "it is fname #{scanner.peek(8)}"
872
+ if scanner.scan(/=(?:(?![~>=])|(?==>))/) then
873
+ self.lex_state = :EXPR_END
874
+ return [:tIDENTIFIER, matched + scanner.matched]
875
+ end
876
+ end
877
+
878
+
879
+ if [:EXPR_BEG, :EXPR_DOT, :EXPR_MID, :EXPR_ARG, :EXPR_CMDARG].include?(self.lex_state)
880
+ self.lex_state = :EXPR_CMDARG
881
+ else
882
+ self.lex_state = :EXPR_END
883
+ end
884
+
885
+ # self.lex_state = :EXPR_END
886
+ return [matched =~ /^[A-Z]/ ? :tCONSTANT : :tIDENTIFIER, matched]
887
+
888
+ else
889
+
890
+ return [false, false]
891
+ # puts 'here'
892
+ # return [:kDEF, 'def']
893
+ end # end of if/elsif/elsif... clauses
894
+ end # end of loop
895
+
896
+
897
+ end
898
+
899
+ def on_error(error_token_id, error_value, value_stack)
900
+ token_name = token_to_str(error_token_id)
901
+ # token_name.downcase!
902
+ token = error_value.to_s.inspect
903
+
904
+ str = "#{@source}:#{@line_number}: - parse error on "
905
+ str << token_name << ' ' unless token_name == token
906
+ str << token
907
+ # @tokens.error(str)
908
+ puts str
909
+ end
910
+
911
+
912
+ def testObjc
913
+ anObj.set :age => 10
914
+ my_weight = anObject.get(:age)
915
+ end
916
+ end