opal 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
+