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
@@ -0,0 +1,780 @@
1
+
2
+ require 'opal/ruby/ruby_parser'
3
+ require 'opal/ruby/nodes'
4
+
5
+ require 'strscan'
6
+
7
+ class Opal::RubyParser < Racc::Parser
8
+
9
+ class RubyLexingError < StandardError
10
+
11
+ end
12
+
13
+ def initialize(source, options = {})
14
+ @lex_state = :expr_beg
15
+
16
+ @cond = 0
17
+ @cmdarg = 0
18
+ @line_number = 1
19
+
20
+ @string_parse_stack = []
21
+
22
+ @scanner = StringScanner.new source
23
+ end
24
+
25
+ def parse!
26
+ do_parse
27
+ end
28
+
29
+ def next_token
30
+ t = get_next_token
31
+ # puts "returning token #{t.inspect}"
32
+ t[1] = { :value => t[1], :line => @line_number }
33
+ t
34
+ end
35
+
36
+ def cond_push(n)
37
+ @cond = (@cond << 1) | (n & 1)
38
+ end
39
+
40
+ def cond_pop
41
+ @cond = @cond >> 1
42
+ end
43
+
44
+ def cond_lexpop
45
+ @cond = (@cond >> 1) | (@cond & 1)
46
+ end
47
+
48
+ def cond?
49
+ (@cond & 1) != 0
50
+ end
51
+
52
+ def cmdarg_push(n)
53
+ @cmdarg = (@cmdarg << 1) | (n & 1)
54
+ end
55
+
56
+ def cmdarg_pop
57
+ @cmdarg = @cmdarg >> 1
58
+ end
59
+
60
+ def cmdarg_lexpop
61
+ @cmdarg = (@cmdarg >> 1) | (@cmdarg & 1)
62
+ end
63
+
64
+ def cmdarg?
65
+ (@cmdarg & 1) != 0
66
+ end
67
+
68
+ def push_string_parse(hash)
69
+ @string_parse_stack << hash
70
+ end
71
+
72
+ def pop_string_parse
73
+ @string_parse_stack.pop
74
+ end
75
+
76
+ def current_string_parse
77
+ @string_parse_stack.last
78
+ end
79
+
80
+ def next_string_token
81
+ str_parse, scanner = current_string_parse, @scanner
82
+
83
+ # everything bar single quote and lower case bare wrds can interpolate
84
+ interpolate = (str_parse[:beg] != "'" && str_parse[:beg] != '%w')
85
+
86
+ # see if we can read end of string/xstring/regecp markers
87
+ if scanner.scan /#{str_parse[:end]}/
88
+ pop_string_parse
89
+
90
+ if ['"', "'"].include? str_parse[:beg]
91
+ @lex_state = :expr_end
92
+ return :STRING_END, scanner.matched
93
+
94
+ elsif str_parse[:beg] == '`'
95
+ @lex_state = :expr_end
96
+ return :STRING_END, scanner.matched
97
+
98
+ elsif str_parse[:beg] == '/'
99
+ result = scanner.matched if scanner.scan(/\w+/)
100
+ @lex_state = :expr_end
101
+ return :REGEXP_END, result
102
+
103
+ else
104
+ @lex_state = :expr_end
105
+ return :STRING_END, scanner.matched
106
+ end
107
+ end
108
+
109
+ # not end of string, so we must be parsing contents
110
+ str_buffer = []
111
+
112
+ if scanner.scan(/#(\$\@)\w+/)
113
+ if interpolate
114
+ return :STRING_DVAR, scanner.matched.slice(2)
115
+ else
116
+ str_buffer << scanner.matched
117
+ end
118
+
119
+ elsif scanner.scan(/#\{/)
120
+ if interpolate
121
+ # we are into ruby code, so stop parsing content (for now)
122
+ str_parse[:content] = false
123
+ return :STRING_DBEG, scanner.matched
124
+ else
125
+ str_buffer << scanner.matched
126
+ end
127
+
128
+ # causes error, so we will just collect it later on with other text
129
+ elsif scanner.scan(/\#/)
130
+ str_buffer << '#'
131
+ end
132
+
133
+ add_string_content str_buffer, str_parse
134
+ complete_str = str_buffer.join ''
135
+ return :STRING_CONTENT, complete_str
136
+ end
137
+
138
+ def add_string_content(str_buffer, str_parse)
139
+ scanner = @scanner
140
+ # regexp for end of string/regexp
141
+ end_str_re = /#{str_parse[:end]}/
142
+ # can be interpolate
143
+ interpolate = ['"', '%W', '/', '`'].include? str_parse[:beg]
144
+
145
+ until scanner.eos?
146
+ c, handled = nil, true
147
+
148
+ if scanner.check end_str_re
149
+ # eos
150
+ break
151
+
152
+ elsif interpolate && scanner.check(/#(?=[\@\{])/)
153
+ break
154
+
155
+ elsif scanner.scan(/\\\\/)
156
+ c = scanner.matched
157
+
158
+ elsif scanner.scan(/\\/)
159
+ c = scanner.matched
160
+ c += scanner.matched if scanner.scan end_str_re
161
+
162
+ else
163
+ handled = false
164
+ end
165
+
166
+ unless handled
167
+ reg = Regexp.new "[^#{str_parse[:end]}\#\0\\\\]+|."
168
+ scanner.scan reg
169
+ c = scanner.matched
170
+ end
171
+
172
+ c ||= scanner.matched
173
+ str_buffer << c
174
+ end
175
+
176
+ raise "reached EOF while in string" if scanner.eos?
177
+ end
178
+
179
+ def get_next_token
180
+ string_scanner = current_string_parse
181
+
182
+ if string_scanner && string_scanner[:content]
183
+ return next_string_token
184
+ end
185
+
186
+ scanner, space_seen, cmd_start, c = @scanner, false, false, ''
187
+
188
+ loop do
189
+ if scanner.scan(/\ |\t|\r/)
190
+ space_seen = true
191
+ next
192
+
193
+ elsif scanner.scan(/(\n|#)/)
194
+ c = scanner.matched
195
+ if c == '#' then scanner.scan(/(.*)/) else @line_number += 1; end
196
+
197
+ scanner.scan(/(\n+)/)
198
+ @line_number += scanner.matched.length if scanner.matched
199
+
200
+ next if [:expr_beg, :expr_dot].include? @lex_state
201
+
202
+ cmd_start = true
203
+ @lex_state = :expr_beg
204
+ return ['\n', '\n']
205
+
206
+ elsif scanner.scan(/\;/)
207
+ @lex_state = :expr_beg
208
+ return [';', ';']
209
+
210
+ elsif scanner.scan(/\"/)
211
+ push_string_parse :beg => '"', :content => true, :end => '"'
212
+ return :STRING_BEG, scanner.matched
213
+
214
+ elsif scanner.scan(/\'/)
215
+ push_string_parse :beg => "'", :content => true, :end => "'"
216
+ return :STRING_BEG, scanner.matched
217
+
218
+ elsif scanner.scan(/\`/)
219
+ push_string_parse :beg => "`", :content => true, :end => "`"
220
+ return :XSTRING_BEG, scanner.matched
221
+
222
+ elsif scanner.scan(/\%[Ww]/)
223
+ start_word = scanner.scan(/./)
224
+ end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
225
+ push_string_parse :beg => start_word, :content => true, :end => end_word
226
+ return :WORDS_BEG, scanner.matched
227
+
228
+ elsif scanner.scan(/\%[Qq]/)
229
+ start_word = scanner.scan(/./)
230
+ end_word = { '(' => ')', '[' => ']', '{' => '}' }[start_word] || start_word
231
+ push_string_parse :beg => start_word, :content => true, :end => end_word
232
+ return :STRING_BEG, scanner.matched
233
+
234
+ elsif scanner.scan(/\//)
235
+ if [:expr_beg, :expr_mid].include? @lex_state
236
+ push_string_parse :beg => '/', :content => true, :end => '/'
237
+ return :REGEXP_BEG, scanner.matched
238
+ elsif scanner.scan(/\=/)
239
+ @lex_state = :expr_beg
240
+ return :OP_ASGN, '/'
241
+ elsif @lex_state == :expr_fname
242
+ @lex_state = :expr_end
243
+ end
244
+
245
+ return '/', '/'
246
+
247
+ elsif scanner.scan(/\%/)
248
+ @lex_state = @lex_state == :expr_fname ? :expr_end : :expr_beg
249
+ return '%', '%'
250
+
251
+ elsif scanner.scan(/\(/)
252
+ result = scanner.matched
253
+ if [:expr_beg, :expr_mid].include? @lex_state
254
+ result = :PAREN_BEG
255
+ elsif space_seen
256
+ result = '('
257
+ end
258
+
259
+ @lex_state = :expr_beg
260
+ cond_push 0
261
+ cmdarg_push 0
262
+
263
+ return result, scanner.matched
264
+
265
+ elsif scanner.scan(/\)/)
266
+ cond_lexpop
267
+ cmdarg_lexpop
268
+ @lex_state = :expr_end
269
+ return ')', scanner.matched
270
+
271
+ elsif scanner.scan(/\[/)
272
+ result = scanner.matched
273
+
274
+ if [:expr_fname, :expr_dot].include? @lex_state
275
+ @lex_state = :expr_arg
276
+ if scanner.scan(/\]=/)
277
+ return '[]=', '[]='
278
+ elsif scanner.scan(/\]/)
279
+ return '[]', '[]'
280
+ else
281
+ raise "Unexpected '[' token"
282
+ end
283
+ elsif [:expr_beg, :expr_mid].include?(@lex_state) || space_seen
284
+ @lex_state = :expr_beg
285
+ cond_push 0
286
+ cmdarg_push 0
287
+ return '[', scanner.matched
288
+ else
289
+ @lex_state = :expr_beg
290
+ cond_push 0
291
+ cmdarg_push 0
292
+ return '[@', scanner.matched
293
+ end
294
+
295
+ elsif scanner.scan(/\]/)
296
+ cond_lexpop
297
+ cmdarg_lexpop
298
+ @lex_state = :expr_end
299
+ return ']', scanner.matched
300
+
301
+ elsif scanner.scan(/\}/)
302
+ cond_lexpop
303
+ cmdarg_lexpop
304
+ @lex_state = :expr_end
305
+
306
+ current_string_parse[:content] = true if current_string_parse
307
+ return '}', scanner.matched
308
+
309
+ elsif scanner.scan(/\.\.\./)
310
+ @lex_state = :expr_beg
311
+ return '...', scanner.matched
312
+
313
+ elsif scanner.scan(/\.\./)
314
+ @lex_state = :expr_beg
315
+ return '..', scanner.matched
316
+
317
+ elsif scanner.scan(/\./)
318
+ @lex_state = :expr_dot unless @lex_state == :expr_fname
319
+ return '.', scanner.matched
320
+
321
+ elsif scanner.scan(/\*\*\=/)
322
+ @lex_state = :expr_beg
323
+ return :OP_ASGN, '**'
324
+
325
+ elsif scanner.scan(/\*\*/)
326
+ return '**', '**'
327
+
328
+ elsif scanner.scan(/\*\=/)
329
+ @lex_state = :expr_beg
330
+ return :OP_ASGN, '*'
331
+
332
+ elsif scanner.scan(/\*/)
333
+ result = scanner.matched
334
+ if @lex_state == :expr_fname
335
+ @lex_state = :expr_end
336
+ return '*', result
337
+ elsif space_seen && scanner.check(/\S/)
338
+ @lex_state = :expr_beg
339
+ return :SPLAT, result
340
+ elsif [:expr_beg, :expr_mid].include? @lex_state
341
+ @lex_state = :expr_beg
342
+ return :SPLAT, result
343
+ else
344
+ @lex_state = :expr_beg
345
+ return '*', result
346
+ end
347
+
348
+ elsif scanner.scan(/\:\:/)
349
+ if [:expr_beg, :expr_mid, :expr_class].include? @lex_state
350
+ @lex_state = :expr_beg
351
+ return '::@', scanner.matched
352
+ end
353
+
354
+ @lex_state = :expr_dot
355
+ return '::', scanner.matched
356
+
357
+ elsif scanner.scan(/\:/)
358
+ if [:expr_end, :expr_endarg].include?(@lex_state) || scanner.check(/\s/)
359
+ unless scanner.check(/\w/)
360
+ @lex_state = :expr_beg
361
+ return ':', ':'
362
+ end
363
+
364
+ @lex_state = :expr_fname
365
+ return :SYMBOL_BEG, ':'
366
+ end
367
+
368
+ if scanner.scan(/\'/)
369
+ push_string_parse :beg => "'", :content => true, :end => "'"
370
+ elsif scanner.scan(/\"/)
371
+ push_string_parse :beg => '"', :content => true, :end => '"'
372
+ end
373
+
374
+ @lex_state = :expr_fname
375
+ return :SYMBOL_BEG, ':'
376
+
377
+ elsif scanner.check(/\|/)
378
+ if scanner.scan(/\|\|\=/)
379
+ @lex_state = :expr_beg
380
+ return :OP_ASGN, '||'
381
+ elsif scanner.scan(/\|\|/)
382
+ @lex_state = :expr_beg
383
+ return '||', '||'
384
+ elsif scanner.scan(/\|\=/)
385
+ @lex_state = :expr_beg
386
+ return :OP_ASGN, '|'
387
+ elsif scanner.scan(/\|/)
388
+ if @lex_state == :expr_fname
389
+ @lex_state = :expr_end
390
+ return '|', scanner.matched
391
+ else
392
+ @lex_state = :expr_beg
393
+ return '|', scanner.matched
394
+ end
395
+ end
396
+
397
+ elsif scanner.scan(/\^/)
398
+ if @lex_state == :expr_fname
399
+ @lex_state = :expr_end
400
+ return '^', scanner.matched
401
+ end
402
+
403
+ @lex_state = :expr_beg
404
+ return '^', scanner.matched
405
+
406
+ elsif scanner.check(/\&/)
407
+ if scanner.scan(/\&\&\=/)
408
+ @lex_state = :expr_beg
409
+ return :OP_ASGN, '&&'
410
+ elsif scanner.scan(/\&\&/)
411
+ @lex_state = :expr_beg
412
+ return '&&', scanner.matched
413
+ elsif scanner.scan(/\&\=/)
414
+ @lex_state = :expr_beg
415
+ return :OP_ASGN, '&'
416
+ elsif scanner.scan(/\&/)
417
+ if space_seen && !scanner.check(/\s/) && @lex_state == :expr_cmdarg
418
+ return '&@', scanner.matched
419
+ elsif [:expr_beg, :expr_mid].include? @lex_state
420
+ return '&@', scanner.matched
421
+ else
422
+ return '&', scanner.matched
423
+ end
424
+ end
425
+
426
+ elsif scanner.check(/\</)
427
+ if scanner.scan(/\<\<\=/)
428
+ @lex_state = :expr_beg
429
+ return :OP_ASGN, '<<'
430
+ elsif scanner.scan(/\<\</)
431
+ if @lex_state == :expr_fname
432
+ @lex_state = :expr_end
433
+ return '<<', '<<'
434
+ elsif ![:expr_end, :expr_dot, :expr_endarg, :expr_class].include?(@lex_state) && space_seen
435
+ @lex_state = :expr_beg
436
+ return '<<', '<<'
437
+ end
438
+ @lex_state = :expr_beg
439
+ return '<<', '<<'
440
+ elsif scanner.scan(/\<\=\>/)
441
+ if @lex_state == :expr_fname
442
+ @lex_state = :expr_end
443
+ else
444
+ @lex_state = :expr_beg
445
+ end
446
+ return '<=>', '<=>'
447
+ elsif scanner.scan(/\<\=/)
448
+ if @lex_state == :expr_fname
449
+ @lex_state = :expr_end
450
+ else
451
+ @lex_state = :expr_beg
452
+ end
453
+ return '<=', '<='
454
+ elsif scanner.scan(/\</)
455
+ if @lex_state == :expr_fname
456
+ @lex_state = :expr_end
457
+ else
458
+ @lex_state = :expr_beg
459
+ end
460
+ return '<', '<'
461
+ end
462
+
463
+ elsif scanner.check(/\>/)
464
+ if scanner.scan(/\>\>\=/)
465
+ return :OP_ASGN, '>>'
466
+ elsif scanner.scan(/\>\>/)
467
+ return '>>', '>>'
468
+ elsif scanner.scan(/\>\=/)
469
+ if @lex_state == :expr_fname
470
+ @lex_state = :expr_end
471
+ else
472
+ @lex_state = :expr_beg
473
+ end
474
+ return '>=', scanner.matched
475
+ elsif scanner.scan(/\>/)
476
+ if @lex_state == :expr_fname
477
+ @lex_state = :expr_end
478
+ else
479
+ @lex_state = :expr_beg
480
+ end
481
+ return '>', '>'
482
+ end
483
+
484
+ elsif scanner.scan(/[+-]/)
485
+ result = scanner.matched
486
+ sign = result + '@'
487
+
488
+ if @lex_state == :expr_beg || @lex_state == :expr_mid
489
+ @lex_state = :expr_end
490
+ return [sign, sign]
491
+ elsif @lex_state == :expr_fname
492
+ @lex_state = :expr_end
493
+ return [:IDENTIFIER, result + scanner.matched] if scanner.scan(/@/)
494
+ return [result, result]
495
+ end
496
+
497
+ if scanner.scan(/\=/)
498
+ @lex_state = :expr_beg
499
+ return [:OP_ASGN, result]
500
+ end
501
+
502
+ @lex_state = :expr_beg
503
+ return [result, result]
504
+
505
+ elsif scanner.scan(/\?/)
506
+ @lex_state = :expr_beg if [:expr_end, :expr_endarg].include?(@lex_state)
507
+ return '?', scanner.matched
508
+
509
+ elsif scanner.scan(/\=\=\=/)
510
+ if @lex_state == :expr_fname
511
+ @lex_state = :expr_end
512
+ return '===', '==='
513
+ end
514
+ @lex_state = :expr_beg
515
+ return '===', '==='
516
+
517
+ elsif scanner.scan(/\=\=/)
518
+ if @lex_state == :expr_fname
519
+ @lex_state = :expr_end
520
+ return '==', '=='
521
+ end
522
+ @lex_state = :expr_beg
523
+ return '==', '=='
524
+
525
+ elsif scanner.scan(/\=\~/)
526
+ if @lex_state == :expr_fname
527
+ @lex_state = :expr_end
528
+ return '=~', '=~'
529
+ end
530
+ @lex_state = :expr_beg
531
+ return '=~', '=~'
532
+
533
+ elsif scanner.scan(/\=\>/)
534
+ @lex_state = :expr_beg
535
+ return '=>', '=>'
536
+
537
+ elsif scanner.scan(/\=/)
538
+ @lex_state = :expr_beg
539
+ return '=', '='
540
+
541
+ elsif scanner.scan(/\!\=/)
542
+ @lex_state = :expr_beg
543
+ return '!=', '!='
544
+
545
+ elsif scanner.scan(/\!\~/)
546
+ @lex_state = :expr_beg
547
+ return '!~', '!~'
548
+
549
+ elsif scanner.scan(/\!/)
550
+ @lex_state = :expr_beg
551
+ return '!', '!'
552
+
553
+ elsif scanner.scan(/\~/)
554
+ if @lex_state == :expr_fname
555
+ @lex_state = :expr_end
556
+ return '~', '~'
557
+ end
558
+ @lex_state = :expr_beg
559
+ return '~', '~'
560
+
561
+ elsif scanner.scan(/\$[\+\'\`\&!@\"~*$?\/\\:;=.,<>_]/)
562
+ @lex_state = :expr_end
563
+ return :GVAR, scanner.matched
564
+
565
+ elsif scanner.scan(/\$\w+/)
566
+ @lex_state = :expr_end
567
+ return :GVAR, scanner.matched
568
+
569
+ elsif scanner.scan(/\@\@\w*/)
570
+ @lex_state = :expr_end
571
+ return :CVAR, scanner.matched
572
+
573
+ elsif scanner.scan(/\@\w*/)
574
+ @lex_state = :expr_end
575
+ return :IVAR, scanner.matched
576
+
577
+ elsif scanner.scan(/\,/)
578
+ @lex_state = :expr_beg
579
+ return ',', scanner.matched
580
+
581
+ elsif scanner.scan(/\{/)
582
+ if [:expr_end, :expr_cmdarg].include? @lex_state
583
+ result = '{@'
584
+ elsif @lex_state == :expr_endarg
585
+ result = 'LBRACE_ARG'
586
+ else
587
+ result = '{'
588
+ end
589
+
590
+ @lex_state = :expr_beg
591
+ cond_push 0
592
+ cmdarg_push 0
593
+ return result, scanner.matched
594
+
595
+ elsif scanner.check(/[0-9]/)
596
+ @lex_state = :expr_end
597
+ if scanner.scan(/[\d_]+\.[\d_]+\b/)
598
+ return [:FLOAT, scanner.matched.gsub(/_/, '')]
599
+ elsif scanner.scan(/[\d_]+\b/)
600
+ return [:INTEGER, scanner.matched.gsub(/_/, '')]
601
+ elsif scanner.scan(/0(x|X)(\d|[a-f]|[A-F])+/)
602
+ return [:INTEGER, scanner.matched]
603
+ else
604
+ raise "Lexing error on numeric type: `#{scanner.peek 5}`"
605
+ end
606
+
607
+ elsif scanner.scan(/(\w)+[\?\!]?/)
608
+ case scanner.matched
609
+ when 'class'
610
+ if @lex_state == :expr_dot
611
+ @lex_state = :expr_end
612
+ return :IDENTIFIER, scanner.matched
613
+ end
614
+ @lex_state = :expr_class
615
+ return :CLASS, scanner.matched
616
+
617
+ when 'module'
618
+ return :IDENTIFIER, scanner.matched if @lex_state == :expr_dot
619
+ @lex_state = :expr_class
620
+ return :MODULE, scanner.matched
621
+
622
+ when 'def'
623
+ @lex_state = :expr_fname
624
+ return :DEF, scanner.matched
625
+
626
+ when 'end'
627
+ @lex_state = :expr_end
628
+ return :END, scanner.matched
629
+
630
+ when 'do'
631
+ if cond?
632
+ @lex_state = :expr_beg
633
+ return :DO_COND, scanner.matched
634
+ elsif cmdarg? && @lex_state != :expr_cmdarg
635
+ @lex_state = :expr_beg
636
+ return :DO_BLOCK, scanner.matched
637
+ elsif @lex_state == :expr_endarg
638
+ return :DO_BLOCK, scanner.matched
639
+ else
640
+ @lex_state = :expr_beg
641
+ return :DO, scanner.matched
642
+ end
643
+
644
+ when 'if'
645
+ return :IF, scanner.matched if @lex_state == :expr_beg
646
+ return :IF_MOD, scanner.matched
647
+
648
+ when 'unless'
649
+ return :UNLESS, scanner.matched if @lex_state == :expr_beg
650
+ return :UNLESS_MOD, scanner.matched
651
+
652
+ when 'else'
653
+ return :ELSE, scanner.matched
654
+
655
+ when 'elsif'
656
+ return :ELSIF, scanner.matched
657
+
658
+ when 'self'
659
+ @lex_state = :expr_end unless @lex_state == :expr_fname
660
+ return :SELF, scanner.matched
661
+
662
+ when 'true'
663
+ @lex_state = :expr_end
664
+ return :TRUE, scanner.matched
665
+
666
+ when 'false'
667
+ @lex_state = :expr_end
668
+ return :FALSE, scanner.matched
669
+
670
+ when 'nil'
671
+ @lex_state = :expr_end
672
+ return :NIL, scanner.matched
673
+
674
+ when '__LINE__'
675
+ @lex_state = :expr_end
676
+ return :LINE, @line_number.to_s
677
+
678
+ when '__FILE__'
679
+ @lex_state = :expr_end
680
+ return :FILE, scanner.matched
681
+
682
+ when 'begin'
683
+ @lex_state = :expr_beg
684
+ return :BEGIN, scanner.matched
685
+
686
+ when 'rescue'
687
+ return :IDENTIFIER, scanner.matched if [:expr_dot, :expr_fname].include? @lex_state
688
+ return :RESCUE, scanner.matched if @lex_state == :expr_beg
689
+ @lex_state = :expr_beg
690
+ return :RESCUE_MOD, scanner.matched
691
+
692
+ when 'ensure'
693
+ @lex_state = :expr_beg
694
+ return :ENSURE, scanner.matched
695
+
696
+ when 'case'
697
+ @lex_state = :expr_beg
698
+ return :CASE, scanner.matched
699
+
700
+ when 'when'
701
+ @lex_state = :expr_beg
702
+ return :WHEN, scanner.matched
703
+
704
+ when 'or'
705
+ @lex_state = :expr_beg
706
+ return :OR, scanner.matched
707
+
708
+ when 'and'
709
+ @lex_state = :expr_beg
710
+ return :AND, scanner.matched
711
+
712
+ when 'not'
713
+ @lex_state = :expr_beg
714
+ return :NOT, scanner.matched
715
+
716
+ when 'return'
717
+ @lex_state = :expr_mid
718
+ return :RETURN, scanner.matched
719
+
720
+ when 'next'
721
+ return :IDENTIFIER, scanner.matched if @lex_state == :expr_dot
722
+ @lex_state = :expr_mid
723
+ return :NEXT, scanner.matched
724
+
725
+ when 'break'
726
+ @lex_state = :expr_mid
727
+ return :BREAK, scanner.matched
728
+
729
+ when 'super'
730
+ @lex_state = :expr_arg
731
+ return :SUPER, scanner.matched
732
+
733
+ when 'then'
734
+ return :THEN, scanner.matched
735
+
736
+ when 'while'
737
+ return :WHILE, scanner.matched if @lex_state == :expr_beg
738
+ @lex_state = :expr_beg
739
+ return :WHILE_MOD, scanner.matched
740
+
741
+ when 'until'
742
+ return :WHILE, scanner.matched if @lex_state == :expr_beg
743
+ @lex_state = :expr_beg
744
+ return :UNTIL_MOD, scanner.matched
745
+
746
+ when 'block_given?'
747
+ @lex_state = :expr_end
748
+ return :BLOCK_GIVEN, scanner.matched
749
+
750
+ when 'yield'
751
+ @lex_state = :expr_arg
752
+ return :YIELD, scanner.matched
753
+ end
754
+
755
+ matched = scanner.matched
756
+ return :LABEL, matched if scanner.peek(2) != '::' && scanner.scan(/\:/)
757
+
758
+ if @lex_state == :expr_fname
759
+ if scanner.scan(/\=/)
760
+ @lex_state = :expr_end
761
+ return :IDENTIFIER, matched + scanner.matched
762
+ end
763
+ end
764
+
765
+ if [:expr_beg, :expr_dot, :expr_mid, :expr_arg, :expr_cmdarg].include? @lex_state
766
+ @lex_state = :expr_cmdarg
767
+ else
768
+ @lex_state = :expr_end
769
+ end
770
+
771
+ return [matched =~ /[A-Z]/ ? :CONSTANT : :IDENTIFIER, matched]
772
+
773
+ end
774
+ return [false, false] if scanner.eos?
775
+
776
+ raise RubyLexingError, "Unexpected content in parsing stream `#{scanner.peek 5}`"
777
+ end
778
+ end
779
+ end
780
+