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
data/runtime/opal.js DELETED
@@ -1,200 +0,0 @@
1
- /*
2
- * opal.js
3
- * opal
4
- *
5
- * Created by Adam Beynon.
6
- * Copyright 2010 Adam Beynon.
7
- *
8
- * Permission is hereby granted, free of charge, to any person obtaining a copy
9
- * of this software and associated documentation files (the "Software"), to deal
10
- * in the Software without restriction, including without limitation the rights
11
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- * copies of the Software, and to permit persons to whom the Software is
13
- * furnished to do so, subject to the following conditions:
14
- *
15
- * The above copyright notice and this permission notice shall be included in
16
- * all copies or substantial portions of the Software.
17
- *
18
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- * THE SOFTWARE.
25
- */
26
-
27
-
28
- // temp..
29
- var nil;
30
-
31
- /**
32
- nodes etc
33
- */
34
-
35
- var NOEX_PUBLIC = 0,
36
- NOEX_NOSUPER = 1,
37
- NOEX_PRIVATE = 2,
38
- NOEX_PROTECTED = 4,
39
- NOEX_MASK = 6,
40
- NOEX_BASIC = 8;
41
-
42
-
43
- function require() {
44
-
45
- };
46
-
47
- // Boolean test. false if null, undefined, nil, or false
48
- function RTEST(val) {
49
- return (val != null && val != undefined && val != nil && val != false) ? true : false;
50
- };
51
-
52
- /**
53
- Performs an 'or op' with lhs and rhs
54
- */
55
- function ORTEST(lhs, rhs) {
56
- if (lhs == null || lhs == undefined) lhs = nil;
57
- if (rhs == null || rhs == undefined) rhs = nil;
58
-
59
- if (lhs == nil || lhs == false) {
60
- return rhs;
61
- }
62
- return lhs;
63
- };
64
-
65
- /**
66
- Performs an 'and op' with lhs and rhs
67
- */
68
- function ANDTEST(lhs, rhs) {
69
- if (lhs == null || lhs == undefined) lhs = nil;
70
- if (rhs == null || rhs == undefined) rhs = nil;
71
-
72
- if (lhs == nil || lhs == false) {
73
- return nil;
74
- }
75
- return rhs;
76
- };
77
-
78
- function NOTTEST(expr) {
79
- if (expr == null || expr == undefined || expr == nil || expr == false) return true;
80
- return false;
81
- };
82
-
83
- /**
84
- Fix for browsers not having console
85
- */
86
- // if (typeof console === 'undefined') {
87
- // var console = console || window.console || { };
88
- // console.log = console.info = console.warn = console.error = function() { };
89
- // }
90
-
91
- function RObject(klass, type) {
92
- this.klass = klass;
93
- this.flags = type;
94
- this.iv_tbl = { };
95
- return this;
96
- }
97
-
98
- function RClass(klass, super_klass) {
99
- this.klass = klass ;
100
- this.sup = super_klass ;
101
- this.flags = T_CLASS ;
102
- this.m_tbl = { };
103
- this.iv_tbl = { };
104
- return this;
105
- };
106
-
107
- function RHash() {
108
- this.klass = nil;
109
- this.flags = nil;
110
- this.ifnone = nil;
111
- // ordered keys
112
- this.keys = [];
113
- // keys.to_s => values
114
- this.dict = { };
115
- return this;
116
- }
117
-
118
- // Types
119
- var T_CLASS = 1,
120
- T_MODULE = 2,
121
- T_OBJECT = 4,
122
- T_BOOLEAN = 8,
123
- T_STRING = 16,
124
- T_ARRAY = 32,
125
- T_NUMBER = 64,
126
- T_PROC = 128,
127
- T_SYMBOL = 256,
128
- T_HASH = 512,
129
- T_ICLASS = 1024;
130
-
131
- // Flags
132
- var FL_SINGLETON = 2056;
133
-
134
- function FL_TEST(x, f) {
135
- return x.flags & f;
136
- }
137
-
138
- function FL_SET(x, f) {
139
- x.flags |= f;
140
- }
141
-
142
- function FL_UNSET(x, f) {
143
- x.flags &= (~f);
144
- }
145
-
146
- rb_class_tbl = { } ; // all classes are stored here
147
- rb_global_tbl = { } ; // globals are stored here
148
-
149
- function rb_gvar_get(id) {
150
-
151
- };
152
-
153
- function rb_gvar_set(id, val) {
154
-
155
- };
156
-
157
-
158
- function boot_defclass(id, super_class) {
159
- var o = rb_class_boot(super_class);
160
- rb_name_class(o, id);
161
- rb_class_tbl[id] = o;
162
- rb_const_set((rb_cObject ? rb_cObject : o), id, o);
163
- return o;
164
- };
165
-
166
- boot_defmetametaclass = function(klass, metametaclass) {
167
- klass.klass.klass = metametaclass;
168
- };
169
-
170
- obj_alloc = function(klass) {
171
- // console.log('in base.js, obj_alloc ' + arguments.length);
172
- // var obj = klass.$('allocate', []);
173
- var obj = VN$(klass, 'allocate');
174
- return obj;
175
- };
176
-
177
- class_allocate_instance = function() {
178
- // console.log('doing VN.class_allocate_instance');
179
- var obj = new RObject(this, T_OBJECT) ;
180
- return obj;
181
- };
182
-
183
- obj_dummy = function() {
184
- return nil ;
185
- };
186
-
187
- equal = function(obj) {
188
- if (obj == this) return true ;
189
- var result = this.$funcall('==', [obj]);
190
- if (result) return true ;
191
- return false ;
192
- };
193
-
194
- eql = function(obj) {
195
- return this.$funcall('==', [obj]);
196
- };
197
-
198
- obj_equal = function(obj) {
199
- return (obj == this) ? true : false ;
200
- };
data/runtime/parse.js DELETED
@@ -1,2218 +0,0 @@
1
- /*
2
- * parse.js
3
- * opal
4
- *
5
- * Created by Adam Beynon.
6
- * Copyright 2010 Adam Beynon.
7
- *
8
- * Permission is hereby granted, free of charge, to any person obtaining a copy
9
- * of this software and associated documentation files (the "Software"), to deal
10
- * in the Software without restriction, including without limitation the rights
11
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- * copies of the Software, and to permit persons to whom the Software is
13
- * furnished to do so, subject to the following conditions:
14
- *
15
- * The above copyright notice and this permission notice shall be included in
16
- * all copies or substantial portions of the Software.
17
- *
18
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- * THE SOFTWARE.
25
- */
26
-
27
-
28
- // lex states
29
- var EXPR_BEG = 0, EXPR_END = 1, EXPR_ENDARG = 2, EXPR_ARG = 3,
30
- EXPR_CMDARG = 4, EXPR_MID = 5, EXPR_FNAME = 6, EXPR_DOT = 7,
31
- EXPR_CLASS = 8, EXPR_VALUE = 9;
32
-
33
- // keywords
34
- var kCLASS = 0, kMODULE = 1, kDEF = 2, kUNDEF = 3,
35
- kBEGIN = 4, kRESCUE = 5, kENSURE = 6, kEND = 7,
36
- kIF = 8, kUNLESS = 9, kTHEN = 10, kELSIF = 11,
37
- kELSE = 12, kCASE = 13, kWHEN = 14, kWHILE = 15,
38
- kUNTIL = 16, kFOR = 17, kBREAK = 18, kNEXT = 19,
39
- kREDO = 20, kELSIF = 21, kELSE = 22, kCASE = 23,
40
- kWHEN = 24, kWHILE = 25, kUNTIL = 26, kFOR = 27,
41
- kBREAK = 28, kNEXT = 29, kREDO = 30, kRETRY = 31,
42
- kIN = 32, kDO_COND = 33, kDO_BLOCK = 34, kDO_LAMBDA = 35,
43
- kRETURN = 36, kYIELD = 37, kSUPER = 38, kSELF = 39,
44
- kNIL = 40, kTRUE = 41, kFALSE = 42, kAND = 43,
45
- kOR = 44, kNOT = 45, kIF_MOD = 46, kUNLESS_MOD= 47,
46
- kWHILE_MOD = 48, kUNTIL_MOD = 49, kRESCUE_MOD = 50, kALIAS = 51,
47
- kDEFINED = 52, klBEGIN = 53, klEND = 54, k__LINE__ = 55,
48
- k__FILE__ = 56, kDO = 57, kDEFined = 58,
49
- // tokens
50
- tIDENTIFIER = 59, tFID = 60, tGVAR = 61, tIVAR = 62,
51
- tCONSTANT = 63, tCVAR = 64, tLABEL = 65, tINTEGER = 66,
52
- tFLOAT = 67, tSTR_CONTENT= 68, tCHAR = 69, tNTH_REF = 70,
53
- tBACK_REF = 71, tREGEXP_END = 72, tUPLUS = 73, tUMINUS = 74,
54
- tPOW = 75, tCMP = 76, tEQ = 77, tEQQ = 78,
55
- tNEQ = 79, tGEQ = 80, tLEQ = 81, tANDOP = 82,
56
- tOROP = 83, tMATCH = 84, tNMATCH = 85, tDOT2 = 86,
57
- tDOT3 = 87, tAREF = 88, tASET = 89, tLSHFT = 90,
58
- tRSHFT = 91, tCOLON2 = 92, tCOLON3 = 93, tOP_ASGN = 94,
59
- tASSOC = 95, tLPAREN = 96, tLPAREN_ARG = 97, tRPAREN = 98,
60
- tLBRACK = 99, tLBRACE = 100, tLBRACE_ARG = 101, tSTAR = 102,
61
- tAMPER = 103, tLAMBDA = 104, tSYMBEG = 105, tSTRING_BEG= 106,
62
- tXSTRING_BEG= 107, tREGEXP_BEG = 108, tWORDS_BEG = 109, tQWORDS_BEG= 110,
63
- tSTRING_DBEG= 111, tSTRING_DVAR= 112, tSTRING_END = 113, tLAMBEG = 114,
64
- tUMINUS_NUM = 115, tSTRING = 116, tXSTRING_END= 117,
65
-
66
- tPLUS = 118, tMINUS = 119, tNL = 120, tSEMI = 121;
67
-
68
- // special tokens (used for generator)
69
- var tCALL = 150, tMLHS = 151, tOPT_PLUS = 152, tOPT_MINUS = 153,
70
- tOPT_MULT = 154, tOPT_DIV = 155;
71
-
72
- /**
73
- Parse the given ruby code, str, with the given filename. This allows us to
74
- dynamically set the filename, for example, with eval()'d code. This returns
75
- an Instruction sequence, with all of its sub sequences, opcodes etc.
76
- */
77
- var vn_parser = function(filename, str) {
78
-
79
- // current lex state
80
- var lex_state = EXPR_BEG;
81
- // last lexerparser state
82
- var last_state;
83
- // the scanner
84
- var scanner; //= new vn_ruby_string_scanner(str);
85
- // current token
86
- var token = { type: false, value: false };
87
- // last token
88
- var last_token = { type: false, value: false };
89
- //
90
- var sym_tbl = { };
91
- // eval string..
92
- var eval_arr = [];
93
- // valid types of stmt that are valid as the first cmd args (helps us identify if the
94
- // next statemebnt should be appeneded to the current identifer as a cmd arg )
95
- var valid_cmd_args = [tIDENTIFIER, tINTEGER, tCONSTANT, tSTRING_BEG, kDO, '{', tSYMBEG];
96
- // start of command (not stmt), when on new line etc
97
- var cmd_start = false;
98
-
99
- // all contexts
100
- var contexts = [];
101
-
102
- // function push_context(c) {
103
- // contexts.push(c);
104
- // }
105
-
106
-
107
- /**
108
- String parsing
109
- */
110
- var string_parse_stack = [];
111
-
112
- var push_string_parse = function(o) {
113
- string_parse_stack.push(o);
114
- };
115
-
116
- var pop_string_parse = function() {
117
- string_parse_stack.pop();
118
- };
119
-
120
- var current_string_parse = function() {
121
- if (string_parse_stack.length == 0) {
122
- return null;
123
- }
124
- return string_parse_stack[string_parse_stack.length - 1];
125
- };
126
-
127
-
128
- // create object dup
129
- var object_create = function(obj) {
130
- var targ = { };
131
- for (var prop in obj) {
132
- targ[prop] = obj[prop];
133
- }
134
-
135
- return targ;
136
- };
137
-
138
- var original_symbol = {
139
- nud: function () {
140
- return this;
141
- },
142
- led: function (left) {
143
- throw 'led unimplemented';
144
- }
145
- };
146
-
147
- var symbol = function(id, binding_power) {
148
- var sym = sym_tbl[id];
149
- binding_power = binding_power || 0;
150
- if (sym) {
151
- if (binding_power >= sym.lbp) {
152
- sym.lbp = binding_power;
153
- }
154
- }
155
- else {
156
- sym = object_create(original_symbol);
157
- sym.type = sym.value = id;
158
- sym.lbp = binding_power;
159
- sym_tbl[id] = sym;
160
- }
161
- return sym;
162
- };
163
-
164
- var sym_stmt = function (id, bp, block) {
165
- if (!block) {
166
- block = bp;
167
- bp = 0;
168
- }
169
-
170
- var sym = symbol(id);
171
- sym.std = block;
172
- return sym;
173
- };
174
-
175
- var infixr = function (id, bp, led) {
176
- var s = symbol(id, bp);
177
- s.led = led || function (left) {
178
- this.first = left;
179
- this.second = expr(bp - 1);
180
- this.arity = "binary";
181
- return this;
182
- };
183
- return s;
184
- };
185
-
186
- // make a function for us that has a 'usual beahiour' (saves making a function
187
- // over and over) - +/-/*// all do the same thing etc
188
- var infix = function (id, bp, led) {
189
- var s = symbol(id, bp);
190
- s.led = led || function (left) {
191
- this.$lhs = left;
192
- this.$rhs = expr(bp);
193
- this.type = id;
194
- return this;
195
- };
196
- return s;
197
- };
198
-
199
- var prefix = function (id, nud) {
200
- var s = symbol(id);
201
- s.nud = nud || function () {
202
- scope.reserve(this);
203
- this.first = expression(70);
204
- this.arity = "unary";
205
- return this;
206
- };
207
- return s;
208
- };
209
-
210
- var assignment = function (id) {
211
- return infixr(id, 10, function (left) {
212
- if (left.type !== "." && left.type !== "[" && left.type !== tIDENTIFIER && left.type != tIVAR && left.type !== tMLHS && left.type !== tCONSTANT) {
213
- throw 'bad lhs'
214
- }
215
- this.$lhs = left;
216
- this.$rhs = stmt();
217
- this.assignment = true;
218
- // this.type = "assignment";
219
- return this;
220
- });
221
- };
222
-
223
- assignment("=");
224
-
225
- symbol(kDO).nud = function() {
226
- if (token.type == '|') {
227
- var e;
228
- this.$args = [];
229
- // gather block params
230
- next_token();
231
- e = expr();
232
- this.$args.push(e);
233
- while (true) {
234
- if (token.type == "|") {
235
- next_token();
236
- break;
237
- }
238
- else if (token.type == ",") {
239
- next_token();
240
- continue;
241
- }
242
- else {
243
- this.$args.push(expr());
244
- }
245
- // throw "erm.."
246
- }
247
- }
248
- // throw token.value
249
- // next_token();
250
- // throw token.type
251
- this.$stmts = stmts([kEND]);
252
- // read over kEND
253
- next_token();
254
- return this;
255
- };
256
-
257
- // alt block
258
- symbol('{').nud = function() {
259
- // read over {
260
- this.$stmt = stmt();
261
- // read over }
262
- next_token('}');
263
- return this;
264
- };
265
-
266
- // self... simple, just return
267
- symbol(kSELF).nud = function() {
268
- return this;
269
- };
270
-
271
- symbol(kRETURN).nud = function() {
272
- return this;
273
- };
274
-
275
- symbol(kNIL).nud = function() {
276
- return this;
277
- };
278
-
279
- symbol(kSUPER).nud = function() {
280
- return this;
281
- };
282
-
283
- symbol(kTRUE).nud = function() {
284
- return this;
285
- };
286
-
287
- symbol(kFALSE).nud = function() {
288
- return this;
289
- };
290
-
291
- symbol(tSTRING_BEG).nud = function() {
292
- // console.log('in hre..');
293
- // these will be string_contents mixed with actual ruby parse trees
294
- this.$parts = [];
295
- // next_token();
296
- // throw token.value
297
- while (true) {
298
- if (token.type === false) {
299
- throw 'Parsing string error: not expecting EOF before end of string'
300
- }
301
- else {
302
- // console.log(token.value);
303
- if (token.type === tSTRING_END) {
304
- next_token();
305
- break;
306
- }
307
- else {
308
- if (token.type === tSTR_CONTENT) {
309
- this.$parts.push(token)
310
- next_token();
311
- }
312
- else if (token.type === tSTRING_DBEG) {
313
- var d = token;
314
- // skip over dbeg
315
- next_token();
316
- d.$value = stmt();
317
- this.$parts.push(d);
318
- // skip over '}'
319
- next_token();
320
- }
321
- // console.log('found a part');
322
- // this.$parts.push(token);
323
- // next_token();
324
- }
325
-
326
- }
327
- }
328
- return this;
329
- };
330
-
331
- // when we get identifier identifier (treat first like receiver, second like arg1)
332
- symbol(tIDENTIFIER).nud = function() {
333
- // we need to check last_state, as lex_state (current) is overridden when parsing current token
334
- if ((valid_cmd_args.indexOf(token.type) != -1) && (last_state == EXPR_CMDARG)) {
335
- // console.log("about to gather command args..");
336
- gather_command_args(this);
337
- this.type = tCALL;
338
- this.$recv = null;
339
- this.$meth = this.value;
340
- // this.$meth = this;
341
- }
342
- return this;
343
- };
344
-
345
- symbol(tCONSTANT).nud = function() {
346
- return this;
347
- };
348
-
349
- // the 'command' to apply the argumens to
350
- // FIXME: rewrite to asume first arg is not neceserialy a arg, it could be start
351
- // of assocs, or might be start of kDO
352
- var gather_command_args = function(cmd) {
353
- cmd.$call_args = {
354
- args: []
355
- };
356
- // console.log('tIDENTIFIER "' + token.value + '" lex state: ' + lex_state + ' last state: ' + last_state + ' ,last token: ' + last_token.value);
357
- if ((token.type !== kDO) && (token.type !== '{')) {
358
- // dont add if next statement is kDO...
359
- // console.log("getting exopr..");
360
- cmd.$call_args.args.push(expr());
361
- }
362
-
363
- // collect remaining params
364
- if (token.type === ',') {
365
- // read over initial commar
366
- next_token();
367
- while (true) {
368
- s = expr();
369
- // s = expr(80);
370
- // this.$args.push(stmt());
371
- // check if tok is tASSOC.. if so, , then we
372
- // are beginning a hash list, so dont add stmt to $args, but push it to
373
- // the hash arg list instead
374
- // console.log(token.type);
375
- if (token.type === tASSOC) {
376
- // console.log('found tassoc');
377
- // should we check if we already have assoc list? having it more than once per cmd call
378
- // might be an error
379
- var a_keys = [], a_values = [];
380
- cmd.$assocs = { '$keys': a_keys, '$values': a_values };
381
- a_keys.push(s);
382
- // read over tassoc
383
- next_token();
384
- a_values.push(expr());
385
-
386
- while (true) {
387
- if (token.type !== ',') {
388
- // end of assoc list
389
- break;
390
- }
391
- // read over commar
392
- next_token(',');
393
- a_keys.push(expr());
394
- next_token(tASSOC);
395
- a_values.push(expr());
396
- }
397
-
398
- // console.log(this);
399
- // throw 'hash begin!'
400
- }
401
- else {
402
- cmd.$call_args.args.push(s);
403
- }
404
- // CHECK HERE for do_block
405
- // move this outside of loop? once we have do_block, command is over
406
-
407
-
408
- if (token.type !== ',') {
409
- break;
410
- }
411
- // any other case, add it as an arg
412
-
413
- // console.log(token.type);
414
- next_token(',');
415
- // check for 'wrong' token types... a def, class, module etc are NOT valid tokens
416
- if ([kDEF, kCLASS, kMODULE, kIF].indexOf(token.type) !== -1) {
417
- throw 'Command Args: Not expecting token "' + token.type + '". Perhaps a trailing commar?'
418
- }
419
- }
420
- }
421
- if (token.type === kDO) {
422
- // gather do block
423
- cmd.$brace_block = stmt();
424
- }
425
- else if (token.type === '{') {
426
- // gather rlcurly block
427
- cmd.$brace_block = stmt();
428
- }
429
- };
430
-
431
- // kDO opt_block_param compstmt kEND
432
- var gather_do_block = function() {
433
- var result = token;
434
- // read over kDO
435
- next_token();
436
- // throw token.value
437
- result.$stmts = stmts([kEND]);
438
- // read over kEND
439
- next_token();
440
- return result;
441
- }
442
-
443
- symbol(tINTEGER).nud = function() {
444
- return this;
445
- };
446
-
447
- symbol(tSYMBEG).nud = function() {
448
- this.$name = stmt();
449
- return this;
450
- };
451
-
452
- symbol(tIVAR).nud = function() {
453
- return this;
454
- };
455
-
456
- symbol(tCVAR).nud = function() {
457
- return this;
458
- };
459
-
460
- symbol(tGVAR).nud = function() {
461
- return this;
462
- };
463
-
464
- // Catching block definitions in Def statements.
465
- symbol("&").nud = function() {
466
- this.$name = stmt();
467
- return this;
468
- }
469
-
470
-
471
- infix(",", 80, function(left) {
472
- this.type = tMLHS;
473
- // check if already part of a mLHS chain
474
- if (left.type == tMLHS) {
475
- // add to current chain
476
- throw "in here.." + token.value
477
- }
478
- else {
479
- // start new chain
480
- this.$parts = [];
481
- this.$parts.push(left);
482
- this.$parts.push(expr(10));
483
- // dont get next_token. expr() gets it for us.
484
- // next_token();
485
- // this.$parts.push(next_token());
486
- }
487
- // throw token.value
488
- // throw "in here.." + token.value
489
-
490
-
491
- return this;
492
- });
493
-
494
-
495
- /**
496
- Fixme!! this is going to break!!
497
-
498
- Argh! not sure how we are going to do mlghs, mrhs
499
- */
500
- // infix(',', 80, function(left) {
501
- // this.$lhs = left;
502
- // if (token.type === tSYMBEG) {
503
- // // throw 'we need to parse an assoc.'
504
- // next_token();
505
- // next_token();
506
- // next_token();
507
- // next_token();
508
- // }
509
- // else {
510
- // this.$rhs = stmt();
511
- // }
512
- //
513
- // return this;
514
- // });
515
-
516
- // Dot notation
517
- infix(".", 80, function (left) {
518
- // console.log('doing dot!')
519
- this.$recv = left;
520
- this.$meth = token;
521
- this.type = tCALL;
522
- // skip over dot
523
- next_token();
524
- if ((valid_cmd_args.indexOf(token.type) != -1) && (last_state === EXPR_CMDARG)) {
525
- gather_command_args(this);
526
- }
527
- // else {
528
- // if not, check if we just have a block...... no args, just block..
529
- // e.g. my_array.each do ...
530
- // could we just add kDO to the valid_cmd_args array...?
531
- // throw token.value
532
- // }
533
-
534
- return this;
535
- });
536
-
537
- // m - method name
538
- // b - binding power
539
- // t is optinal type (instead of tCALL)
540
- // used for a + a, a - a, a << a etc. (as m)
541
- function meth_call(m, b, t) {
542
- return infix(m, b, function(left) {
543
- this.type = t || tCALL;
544
- this.$recv = left;
545
- this.$meth = this;
546
- this.$call_args = {
547
- args: [stmt()]
548
- }
549
- return this;
550
- });
551
- }
552
-
553
- meth_call(tPLUS, 80, tOPT_PLUS);
554
- meth_call(tMINUS, 80, tOPT_MINUS);
555
- meth_call("*", 80, tOPT_MULT);
556
- meth_call("/", 80, tOPT_DIV);
557
-
558
-
559
- // method calls (with paranthesis)
560
- infix("(", 80, function (left) {
561
- var args = {
562
- args: []
563
- };
564
- // valid left values
565
- if (left.type === '.') {
566
- // already a method call, so just set $args property
567
- left.$call_args = args;
568
- }
569
- else if (left.type === tIDENTIFIER || left.type === tCONSTANT || left.type === tCALL) {
570
- // identifier/constant - turn them into a method call, with args
571
- // as the args (and no receiver!)
572
- // will identifier already be a method call? unless an actual identifier
573
- left.$call_args = args;
574
- }
575
- else {
576
- throw left.value + ' is not a valid receiver'
577
- }
578
-
579
- if (token.type !== ')') {
580
- while (true) {
581
- // console.log("gaething..");
582
- args.args.push(expr());
583
- if (token.type !== ',') {
584
- break;
585
- }
586
- next_token(',');
587
- }
588
- }
589
- next_token(')');
590
-
591
- if (token.type === kDO) {
592
- // gather do block
593
- left.$block = stmt();
594
- }
595
- else if (token.type === '{') {
596
- // gather rlcurly block
597
- left.$block = stmt();
598
- }
599
-
600
- return left;
601
- });
602
-
603
- // array declarations (explicit)
604
- prefix(tLBRACK, function() {
605
- var arr = [];
606
- // throw token.value
607
- if (token.type !== ']') {
608
- while (true) {
609
- arr.push(expr());
610
- if (token.type !== ',') {
611
- break;
612
- }
613
- next_token(',');
614
- }
615
- }
616
- next_token(']');
617
- this.$values = arr;
618
- return this;
619
- });
620
-
621
- // hash literal
622
- prefix(tLBRACE, function () {
623
- this.$keys = [];
624
- this.$values = [];
625
- if (token.type !== '}') {
626
- while (true) {
627
- var t = token;
628
- // check for valid key?
629
- next_token();
630
- // should this be a => ?? probbaly...
631
- next_token();
632
- this.$keys.push(t);
633
- this.$values.push(stmt());
634
- if (token.type !== ',') {
635
- break;
636
- }
637
- next_token(',');
638
- }
639
- }
640
- next_token('}');
641
- return this;
642
- });
643
-
644
- prefix(kCASE, function() {
645
- this.$expr = stmt();
646
- this.$body = [];
647
-
648
- if (token.type == tNL || token.type == tSEMI) next_token();
649
-
650
- while (true) {
651
- if (token.type == kEND) {
652
- next_token();
653
- break;
654
- }
655
- else if (token.type == kWHEN) {
656
- var s, t = token;
657
- t.$args = [];
658
- next_token();
659
- if ([tNL, tSEMI, ","].indexOf(token.type) != -1)
660
- throw "kCASE: not expecting given token type"
661
- while (true) {
662
- s = stmt();
663
- t.$args.push(s);
664
- if (token.type == ",") next_token();
665
- else break;
666
- }
667
- t.$stmts = stmts([kEND, kELSE, kWHEN]);
668
- }
669
- else if (token.type == kELSE) {
670
- var t = token;
671
- next_token();
672
- // throw "jere"
673
- t.$stmts = stmts([kEND]);
674
- // throw "erm"
675
- }
676
- }
677
- return this;
678
- });
679
-
680
- // if statment - expression, not really a statement.
681
- prefix(kIF, function() {
682
- this.$expr = stmt();
683
- this.$tail = [];
684
-
685
- if (token.type == tNL || token.type == tSEMI) {
686
- next_token();
687
- if (token.type == kTHEN) next_token();
688
- }
689
- else if (token.type == kTHEN) {
690
- next_token();
691
- }
692
- else {
693
- throw "kIF: expecting either term or kTHEN"
694
- }
695
-
696
- this.$stmts = stmts([kEND, kELSE, kELSIF]);
697
-
698
- while (true) {
699
- if (token.type == kEND) {
700
- next_token();
701
- break;
702
- }
703
- else if (token.type == kELSIF) {
704
- var t = token;
705
- next_token();
706
- t.$expr = stmt();
707
-
708
- if (token.type == tNL || token.type == tSEMI) {
709
- next_token();
710
- if (token.type == kTHEN) next_token();
711
- }
712
- else if (token.type == kTHEN) {
713
- next_token();
714
- }
715
- else {
716
- throw "kIF: expecting either term or kTHEN"
717
- }
718
-
719
- t.$stmts = stmts([kEND, kELSIF, kELSE]);
720
- this.$tail.push(t);
721
- }
722
- else if (token.type == kELSE) {
723
- var t = token;
724
- next_token();
725
- t.$stmts = stmts([kEND]);
726
- this.$tail.push(t);
727
- }
728
- else {
729
- throw "kIF: unexpected token: " + token.type + ", " + token.value
730
- }
731
- }
732
-
733
- return this;
734
- });
735
-
736
- // method definitions
737
- sym_stmt(kDEF, function () {
738
-
739
- if (token.type === tIDENTIFIER || token.type === tCONSTANT || token.type === kSELF) {
740
- this.$fname = token;
741
- }
742
- else {
743
- throw 'Method Defintion: expected identifier or constant as def name.'
744
- }
745
- // reads over the fname
746
- next_token();
747
-
748
- // check if singleton definition
749
- if (token.type === '.' || token.type === tCOLON2) {
750
- // we have a singleton, so put old $fname as singleton name
751
- this.$sname = this.$fname;
752
- // stype is either '.' or tCOLON2 - might help code generation
753
- this.$stype = token.type;
754
- // now get real fname
755
- next_token();
756
- this.$fname = token;
757
- // read over fname
758
- next_token();
759
- }
760
- else {
761
- // check we havent shot ourself in the foot
762
- if (this.$fname.type === kSELF) {
763
- throw "Cannot use keyword 'self' as method name"
764
- }
765
- }
766
-
767
- // ignore arglist for the moment.
768
- if (token.type === tNL || token.type === tSEMI) {
769
- // we can ignore... nothing to do
770
- }
771
- else {
772
-
773
- this.$arglist = {
774
- arg: [],
775
- rest_arg: [],
776
- opt_arg: [],
777
- opt_block_arg: null
778
- };
779
-
780
- if (token.type === '(') {
781
- // params with paranthesis
782
- this.$paran = true;
783
- next_token();
784
- }
785
- while (true) {
786
- if (token.type === ')') {
787
- // end of params..check if we actually had start paran?
788
- next_token();
789
- break;
790
- }
791
- else {
792
- // for now assume every stmt will be a regular arg. need to check actual types
793
- // later
794
- var s = stmt();
795
- this.$arglist.arg.push(s);
796
- if (token.type == ',') {
797
- // read over commar
798
- next_token();
799
- }
800
- else {
801
-
802
- if (token.type === ')') continue;
803
- else if (token.type == tNL || token.type == tSEMI) break;
804
- else throw "Error: def, unsupported param type " + token.type
805
- }
806
- }
807
- }
808
- }
809
-
810
- // read stmts.
811
- this.$stmts = stmts([kEND]);
812
- // read over kEND
813
- next_token();
814
- return this;
815
- });
816
-
817
- sym_stmt(kCLASS, function() {
818
-
819
- if (token.type === tIDENTIFIER) {
820
- throw 'Class defintion: cannot use tIDENTIFIER as a class name. Expected tCONSTANT'
821
- }
822
- else if(token.type === tCONSTANT) {
823
- this.$kname = token;
824
- }
825
- else {
826
- throw 'Class definition: expected constant as class name'
827
- }
828
- // read over kname
829
- next_token();
830
-
831
- if (token.type == '<') {
832
- next_token();
833
- // for now, only constant is valid superclass. we should allow other things..except new line.
834
- if (token.type == tCONSTANT) {
835
- this.$super = stmt();
836
- next_token();
837
- }
838
- else {
839
- throw "Class error: supername?"
840
- }
841
- }
842
-
843
- this.$stmts = stmts([kEND]);
844
- // read over kEND
845
- next_token();
846
- return this;
847
- });
848
-
849
- sym_stmt(kMODULE, function() {
850
- if (token.type === tIDENTIFIER) {
851
- throw "Module definition: cannot use tIDENTIFIER as a module name. Expected tCONSTANT"
852
- }
853
- else if (token.type === tCONSTANT) {
854
- this.$kname = token;
855
- }
856
- else {
857
- throw "Module definition: Expected tCONSTANT for module name"
858
- }
859
-
860
- // name
861
- next_token();
862
-
863
- this.$stmts = stmts([kEND]);
864
- // kend
865
- next_token();
866
- return this;
867
- });
868
-
869
-
870
-
871
- var stmts = function(t) {
872
- var s;
873
- var r = [];
874
- t = t || [];
875
- while (true) {
876
- if (token.type === false) {
877
- if (t.indexOf(false) === -1) {
878
- break;
879
- }
880
- else {
881
- throw 'stmts: got to EOF before reaching end of statements'
882
- }
883
- }
884
- else if (t.indexOf(token.type) != -1) {
885
- break;
886
- }
887
- else {
888
- if (token.type === tNL || token.type === tSEMI) {
889
- next_token();
890
- }
891
- else {
892
- s = stmt();
893
- r.push(s);
894
- }
895
- }
896
- }
897
- return r;
898
- };
899
-
900
- var stmt = function() {
901
- var c = token;
902
- if (c.std) {
903
- next_token();
904
- return c.std();
905
- }
906
- var e = expr(0);
907
- return e;
908
- };
909
-
910
- var expr = function(right_binding_power) {
911
- var old = token;
912
- next_token();
913
- // console.log(old);
914
- var left = old.nud();
915
- while (right_binding_power < token.lbp) {
916
- old = token;
917
- next_token();
918
- left = old.led(left);
919
- }
920
- return left;
921
- };
922
-
923
-
924
-
925
- var get_next_string_token = function() {
926
- var str_parse = current_string_parse();
927
-
928
- // see if we can read end of string/xstring/regexp markers
929
- if (scanner.scan( new RegExp('^\\' + str_parse.beg))) {
930
- pop_string_parse();
931
- if (str_parse.beg == '"' || str_parse.beg == "'") {
932
- lex_state = EXPR_END;
933
- return [tSTRING_END, scanner.matched];
934
- }
935
- else {
936
- // assume to be xstring
937
- return [tXSTRING_END, scanner.matched]
938
- }
939
- }
940
-
941
- // not end of string, so we must be parsing contents
942
- var str_buffer = [];
943
-
944
- if (scanner.scan(/^#(\$|\@)/)) {
945
- return [tSTRING_DVAR, scanner.matched];
946
- }
947
- else if (scanner.scan(/^#\{/)) {
948
- // we are into ruby code, so stop parsing content (for the moment)
949
- str_parse.content = false;
950
- return [tSTRING_DBEG, scanner.matched];
951
- }
952
- else if (scanner.scan(/^#/)) {
953
- str_buffer.push('#');
954
- }
955
-
956
- // content regexp (what is valid content for strings..)
957
- var reg_exp = (str_parse.beg == '`') ?
958
- // xstring: CAN include new lines
959
- new RegExp('[^\\' + str_parse.beg + '\#\0\\]+|.') :
960
- // normal string: cannot include new lines
961
- new RegExp('[^\\' + str_parse.beg + '\#\0\\\n]+|.');
962
-
963
- scanner.scan(reg_exp);
964
- str_buffer.push(scanner.matched);
965
- return [tSTR_CONTENT, str_buffer.join('')];
966
- };
967
-
968
-
969
- // checks id of current token to make sure it matches, only if id is defined.
970
- var next_token = function(id) {
971
- // last token support
972
- last_token = token;
973
- // capture string stuff
974
- if (current_string_parse() && current_string_parse().content) {
975
- // console.log('geting str token');
976
- var t = get_next_string_token();
977
- // console.log('string token: (' + t[0] + ' : ' + t[1] + ') lex_state: (' + lex_state + ')');
978
- // token = object_create(sym_tblt);
979
- token = { };
980
- token.type = t[0];
981
- token.value = t[1];
982
- return token;
983
- }
984
-
985
- var t = get_next_token();
986
- if (id && (id !== token.type)) {
987
- throw 'Unexpected value "' + token.value + '". Expecting: ' + id
988
- }
989
- // console.log('token: (' + t[0] + ' : ' + t[1] + ') lex_state: (' + lex_state + ')');
990
- // token = { type: t[0], value:t[1] };
991
- // token = {};
992
- token = object_create(sym_tbl[t[0]]);
993
- token.type = t[0];
994
- token.value = t[1];
995
- // console.log(token.value + ', ' + last_token.value);
996
- return token;
997
- };
998
-
999
- // actually get the next token
1000
- var get_next_token = function() {
1001
- var c = '', space_seen = false;
1002
-
1003
- last_state = lex_state;
1004
- cmd_start = false;
1005
-
1006
-
1007
- while (true) {
1008
- // console.log(scanner.working_string);
1009
- // if (scanner.scan(/\ |\t|\r/)) {
1010
- if(scanner.scan(/^(\ |\t|\r)/)) {
1011
- space_seen = true;
1012
- // console.log('found space: "' + scanner.matched + '"');
1013
- // console.log(scanner.working_string);
1014
- continue;
1015
- }
1016
- else if (scanner.scan(/^(\n|#)/)) {
1017
- // console.log('found: ' + scanner.matched);
1018
- c = scanner.matched;
1019
- if (c == '#') {
1020
- scanner.scan(/^(.*\n)/);
1021
- }
1022
- // we can skip any more blank lines..(combine them into one..)
1023
- scanner.scan(/^(\n+)/);
1024
- // console.log('we scanned lots');
1025
- // console.log(scanner.matched);
1026
-
1027
- if (lex_state == EXPR_BEG) {
1028
- continue;
1029
- }
1030
- cmd_start = true;
1031
- lex_state = EXPR_BEG;
1032
- return [tNL, '\n'];
1033
- }
1034
- else if (scanner.scan(/^[+-]/)) {
1035
- var result = scanner.matched == '+' ? tPLUS : tMINUS;
1036
- var sign = (result == tPLUS) ? tUPLUS : tUMINUS;
1037
- // method name
1038
- if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
1039
- lex_state = EXPR_ARG;
1040
- if (scanner.scan(/^@/)) {
1041
- return [sign, result + '@'];
1042
- }
1043
- else {
1044
- return [sign, result];
1045
- }
1046
- }
1047
- // += or -=
1048
- if (scanner.scan(/^\=/)) {
1049
- lex_state = EXPR_BEG;
1050
- return [tOP_ASGN, result];
1051
- }
1052
-
1053
- if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
1054
- lex_state = EXPR_BEG;
1055
- return [sign, result];
1056
- }
1057
-
1058
- lex_state = EXPR_BEG;
1059
- return [result, scanner.matched];
1060
- }
1061
-
1062
-
1063
-
1064
-
1065
- else if (scanner.scan(/^\//)) {
1066
- lex_state = EXPR_BEG;
1067
- return ['/', scanner.matched];
1068
- }
1069
-
1070
- else if (scanner.scan(/^\*\*\=/)) {
1071
- lex_state = EXPR_BEG;
1072
- return [tOP_ASGN, "**"];
1073
- }
1074
- else if (scanner.scan(/^\*\*/)) {
1075
- return [tPOW, "**"];
1076
- }
1077
- else if (scanner.scan(/^\*\=/)) {
1078
- lex_state = EXPR_BEG;
1079
- return [tOP_ASGN, "*"];
1080
- }
1081
- else if (scanner.scan(/^\*/)) {
1082
- var r;
1083
- if (lex_state == EXPR_FNAME) {
1084
- lex_state = EXPR_BEG;
1085
- r = "*";
1086
- }
1087
- else if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
1088
- r = tSTAR;
1089
- }
1090
- else {
1091
- lex_state = EXPR_BEG;
1092
- r = "*"
1093
- }
1094
- return [r, scanner.matched];
1095
- }
1096
-
1097
-
1098
-
1099
-
1100
-
1101
-
1102
- else if (scanner.scan(/^\<\=\>/)) {
1103
- return [tCMP, scanner.matched];
1104
- }
1105
- else if (scanner.scan(/^\<\=/)) {
1106
- return [tLEQ, "<="];
1107
- }
1108
- else if (scanner.scan(/^\<\<\=/)) {
1109
- lex_state = EXPR_BEG;
1110
- return [tOP_ASGN, "<<"];
1111
- }
1112
- else if (scanner.scan(/^\<\</)) {
1113
- if (([EXPR_END, EXPR_DOT, EXPR_ENDARG, EXPR_CLASS].indexOf(lex_state) != -1) && space_seen) {
1114
- return [tLSHFT, "<<"];
1115
- }
1116
- lex_state = EXPR_BEG;
1117
- return [tLSHFT, "<<"];
1118
- }
1119
- else if (scanner.scan(/^\</)) {
1120
- lex_state = EXPR_BEG;
1121
- return ["<", "<"];
1122
- }
1123
-
1124
-
1125
-
1126
-
1127
- else if (scanner.scan(/^\&\&\=/)) {
1128
- lex_state = EXPR_BEG;
1129
- return [tOP_ASGN, "&&"];
1130
- }
1131
- else if (scanner.scan(/^\&\&/)) {
1132
- lex_state = EXPR_BEG;
1133
- return [tANDOP, "&&"];
1134
- }
1135
- else if (scanner.scan(/^\&\=/)) {
1136
- lex_state = EXPR_BEG;
1137
- return [tOP_ASGN, "&"];
1138
- }
1139
- else if (scanner.scan(/^\&/)) {
1140
- var r;
1141
- if (space_seen && !scanner.check(/^\s/)) {
1142
- if (lex_state == EXPR_CMDARG) r = tAMPER;
1143
- else r = "&";
1144
- }
1145
- else if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
1146
- r = tAMPER;
1147
- }
1148
- else {
1149
- r = "&";
1150
- }
1151
- return [r, "&"];
1152
- }
1153
-
1154
-
1155
-
1156
-
1157
- // strings.. in order: double, single, xstring
1158
- else if (scanner.scan(/^\"/)) {
1159
- push_string_parse({ beg: '"', content: true });
1160
- return [tSTRING_BEG, scanner.matched];
1161
- }
1162
- else if (scanner.scan(/^\'/)) {
1163
- push_string_parse({ beg: "'", content: true });
1164
- return [tSTRING_BEG, scanner.matched];
1165
- }
1166
- else if (scanner.scan(/^\`/)) {
1167
- push_string_parse({ beg: "`", content: true });
1168
- return [tXSTRING_BEG, scanner.matched];
1169
- }
1170
-
1171
- // numbers
1172
- else if (scanner.check(/^[0-9]/)) {
1173
- lex_state = EXPR_END;
1174
- if (scanner.scan(/^[\d_]+\.[\d_]+\b/)) {
1175
- return [tFLOAT, scanner.matched];
1176
- }
1177
- else if (scanner.scan(/^[\d_]+\b/)) {
1178
- return [tINTEGER, scanner.matched];
1179
- }
1180
- else if (scanner.scan(/^0(x|X)(\d|[a-f]|[A-F])+/)) {
1181
- return [tINTEGER, scanner.matched];
1182
- }
1183
- else {
1184
- console.log('unexpected number type');
1185
- return [false, false];
1186
- }
1187
- }
1188
-
1189
-
1190
- else if (scanner.scan(/^\|\|\=/)) {
1191
- lex_state = EXPR_BEG;
1192
- return [tOP_ASGN, '||'];
1193
- }
1194
- else if (scanner.scan(/^\|\|/)) {
1195
- lex_state = EXPR_BEG;
1196
- return [tOROP, scanner.matched];
1197
- }
1198
- else if (scanner.scan(/^\|\=/)) {
1199
- lex_state = EXPR_BEG;
1200
- return [tOP_ASGN, '|'];
1201
- }
1202
- else if (scanner.scan(/^\|/)) {
1203
- lex_state = EXPR_BEG;
1204
- return ["|", scanner.matched];
1205
- }
1206
-
1207
- else if (scanner.scan(/^\:/)) {
1208
- // console.log ("HERE " + lex_state);
1209
- if (lex_state === EXPR_END || lex_state === EXPR_ENDARG || scanner.check(/^\s/)) {
1210
- // FIXME: hack for tertiary statements
1211
- if (!scanner.check(/^\w/)) {
1212
- return [':', scanner.matched];
1213
- }
1214
-
1215
- lex_state = EXPR_BEG;
1216
- return [tSYMBEG, scanner.matched];
1217
- }
1218
-
1219
- lex_state = EXPR_FNAME;
1220
- return [tSYMBEG, ':'];
1221
- }
1222
-
1223
- else if (scanner.scan(/^\[/)) {
1224
- result = scanner.matched;
1225
-
1226
- if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) {
1227
- lex_state = EXPR_ARG
1228
- if (scanner.scan(/^\]\=/)) {
1229
- return [tASET, '[]='];
1230
- }
1231
- else if (scanner.scan(/^\]/)) {
1232
- return [tAREF, '[]'];
1233
- }
1234
- else {
1235
- throw "error, unexpecrted '[]' token"
1236
- }
1237
- }
1238
- // space seen allows for method calls with array as first param
1239
- // otherwise it thinks its calling the '[]' method
1240
- else if (lex_state == EXPR_BEG || lex_state == EXPR_MID || space_seen) {
1241
- return [tLBRACK, scanner.matched]
1242
- }
1243
- // hmm?
1244
- return ['[', scanner.matched]
1245
- }
1246
-
1247
- else if (scanner.scan(/^\{/)) {
1248
- var result;
1249
- if ([EXPR_END, EXPR_CMDARG].indexOf(lex_state) !== -1) {
1250
- // primary block
1251
- result = '{';
1252
- }
1253
- else if (lex_state == EXPR_ENDARG) {
1254
- // expr block
1255
- result = tLBRACE_ARG;
1256
- }
1257
- else {
1258
- // hash
1259
- result = tLBRACE;
1260
- }
1261
- return [result, scanner.matched];
1262
- }
1263
-
1264
- // ]
1265
- else if (scanner.scan(/^\]/)) {
1266
- lex_state = EXPR_END;
1267
- return [']', scanner.matched];
1268
- }
1269
-
1270
- else if (scanner.scan(/^\;/)) {
1271
- lex_state = EXPR_BEG;
1272
- return [tSEMI, ';'];
1273
- }
1274
- // #
1275
- else if (scanner.scan(/^\(/)) {
1276
- var result = '(';
1277
- if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
1278
- result = tLPAREN;
1279
- }
1280
- else if (space_seen) {
1281
- if (lex_state == EXPR_CMDARG) {
1282
- result = tLPAREN_ARG;
1283
- }
1284
- else if(lex_state == EXPR_ARG) {
1285
- // dont put space before arys
1286
- result = tLPAREN2;
1287
- }
1288
- }
1289
- lex_state = EXPR_BEG;
1290
- return [result, scanner.matched];
1291
- }
1292
- // )
1293
- else if (scanner.scan(/^\)/)) {
1294
- lex_state = EXPR_END;
1295
- return [')', scanner.matched];
1296
- }
1297
-
1298
- // }
1299
- else if (scanner.scan(/^\}/)) {
1300
- lex_state = EXPR_END;
1301
- // throw 'got to end of string'
1302
- if (current_string_parse()) {
1303
- current_string_parse().content = true
1304
- }
1305
- // check if parsing string...
1306
- return ['}', scanner.matched];
1307
- }
1308
-
1309
- // .
1310
- else if (scanner.scan(/^\./)) {
1311
- // should be EXPR_DOT in ALL cases?
1312
- // if (lex_state == EXPR_FNAME) {
1313
- lex_state = EXPR_DOT;
1314
- // }
1315
- return ['.', scanner.matched];
1316
- }
1317
-
1318
- // ,
1319
- else if (scanner.scan(/^\,/)) {
1320
- lex_state = EXPR_BEG;
1321
- return [',', scanner.matched];
1322
- }
1323
-
1324
- // Class variabled
1325
- else if (scanner.scan(/^\@\@\w*/)) {
1326
- lex_state = EXPR_END;
1327
- return [tCVAR, scanner.matched];
1328
- }
1329
- // Instance variables
1330
- else if (scanner.scan(/^\@\w*/)) {
1331
- lex_state = EXPR_END;
1332
- return [tIVAR, scanner.matched];
1333
- }
1334
-
1335
- else if (scanner.scan(/^\=\>/)) {
1336
- lex_state = EXPR_BEG;
1337
- return [tASSOC, scanner.matched];
1338
- }
1339
-
1340
- else if (scanner.scan(/^\=/)) {
1341
- lex_state = EXPR_BEG;
1342
- return ['=', scanner.matched];
1343
- }
1344
-
1345
- else if (scanner.scan(/^\w+[\?\!]?/)) {
1346
- switch (scanner.matched) {
1347
- case 'def':
1348
- lex_state = EXPR_FNAME;
1349
- return [kDEF, scanner.matched];
1350
- case 'end':
1351
- lex_state = EXPR_END;
1352
- return [kEND, scanner.matched];
1353
- case 'class':
1354
- // catch 'class' being used as a method name. This only works when class is used
1355
- // like object.class .. you cannot just use 'class' to call class method on self
1356
- // without explicitly stating self as the receiver.
1357
- if (lex_state == EXPR_DOT) {
1358
- return [tIDENTIFIER, scanner.matched];
1359
- }
1360
- lex_state = EXPR_CLASS;
1361
- return [kCLASS, scanner.matched];
1362
- case 'module':
1363
- lex_state = EXPR_BEG;
1364
- return [kMODULE, scanner.matched];
1365
- case 'do':
1366
- if (lex_state == EXPR_ENDARG) {
1367
- lex_state = EXPR_BEG;
1368
- return [kDO_BLOCK, scanner.matched];
1369
- }
1370
- return [kDO, scanner.matched];
1371
- case 'if':
1372
- if (lex_state == EXPR_BEG) {
1373
- return [kIF, scanner.matched];
1374
- }
1375
- lex_state = EXPR_BEG;
1376
- return [kIF_MOD, scanner.matched];
1377
- case 'then':
1378
- return [kTHEN, scanner.matched];
1379
- case 'else':
1380
- return [kELSE, scanner.matched];
1381
- case 'elsif':
1382
- return [kELSIF, scanner.matched];
1383
- case 'unless':
1384
- if (lex_state == EXPR_BEG) {
1385
- return [kUNLESS, scanner.matched];
1386
- }
1387
- lex_state = EXPR_BEG;
1388
- return [kUNLESS_MOD, scanner.matched];
1389
- case 'self':
1390
- if (lex_state != EXPR_FNAME) {
1391
- lex_state = EXPR_END;
1392
- }
1393
- return [kSELF, scanner.matched];
1394
- case 'super':
1395
- lex_state = EXPR_ARG;
1396
- return [kSUPER, scanner.matched];
1397
- case 'true':
1398
- lex_state = EXPR_END;
1399
- return [kTRUE, scanner.matched];
1400
- case 'false':
1401
- lex_state = EXPR_END;
1402
- return [kFALSE, scanner.matched];
1403
- case 'nil':
1404
- lex_state = EXPR_END;
1405
- return [kNIL, scanner.matched];
1406
- case 'return':
1407
- lex_state = EXPR_MID;
1408
- return [kRETURN, scanner.matched];
1409
- case 'case':
1410
- lex_state = EXPR_BEG;
1411
- return [kCASE, scanner.matched];
1412
- case 'when':
1413
- lex_state = EXPR_BEG;
1414
- return [kWHEN, scanner.matched];
1415
- case 'yield':
1416
- lex_state = EXPR_ARG;
1417
- return [kYIELD, scanner.matched];
1418
- }
1419
-
1420
- var matched = scanner.matched;
1421
-
1422
- // labels - avoid picking up a mod/class divide name
1423
- if ((scanner.peek(2) != '::') && (scanner.scan(/^\:/))) {
1424
- return [tLABEL, matched + scanner.matched];
1425
- }
1426
-
1427
- if (lex_state == EXPR_FNAME) {
1428
- if (scanner.scan(/^=(?:(?![~>=])|(?==>))/)) {
1429
- lex_state = EXPR_END;
1430
- return [tIDENTIFIER, matched + scanner.matched];
1431
- }
1432
- }
1433
-
1434
- // console.log('current state: ' + lex_state);
1435
-
1436
- if ([EXPR_BEG, EXPR_DOT, EXPR_MID, EXPR_ARG, EXPR_CMDARG].indexOf(lex_state) !== -1) {
1437
- lex_state = EXPR_CMDARG;
1438
- }
1439
- else {
1440
- lex_state = EXPR_END;
1441
- }
1442
-
1443
- return [matched.match(/^[A-Z]/) ? tCONSTANT : tIDENTIFIER, matched];
1444
- }
1445
-
1446
- else {
1447
- // false, false === end of stream
1448
- return [false, false];
1449
- }
1450
- }
1451
- };
1452
-
1453
- var iseq_stack = [], iseq_stack_current = null;
1454
- var iseq_locals_stack = [], iseq_locals_current = null;
1455
- var iseq_jump_stack = [], iseq_jump_current = null;
1456
-
1457
- function iseq_jump_idx() {
1458
- return (iseq_jump_current++).toString();
1459
- }
1460
-
1461
- function iseq_stack_push(s) {
1462
- iseq_jump_current = 0;
1463
- iseq_jump_stack.push(iseq_jump_current);
1464
-
1465
- iseq_locals_stack.push(iseq_locals_current = []);
1466
- iseq_stack.push(s);
1467
- iseq_stack_current = s;
1468
- return s;
1469
- }
1470
-
1471
- function iseq_stack_pop() {
1472
- // console.log(iseq_stack_current[7]);
1473
- // throw "a"
1474
- var f = iseq_stack_current[7].join("");
1475
- console.log(f);
1476
- var func = new Function(f);
1477
- // console.log("here");
1478
- // console.log(iseq_stack_current);
1479
- iseq_stack_current[7] = func;
1480
-
1481
-
1482
- iseq_jump_stack.pop();
1483
- iseq_jump_current = iseq_jump_stack[iseq_jump_stack.length - 1];
1484
-
1485
- iseq_locals_current = iseq_locals_stack[iseq_locals_stack.length - 2];
1486
- iseq_locals_stack.pop();
1487
-
1488
- iseq_stack_current = iseq_stack[iseq_stack.length - 2];
1489
- return iseq_stack.pop();
1490
- }
1491
-
1492
- function write(str) {
1493
- iseq_stack_current[7].push(str);
1494
- }
1495
-
1496
- // function iseq_opcode_push(opcode) {
1497
- // iseq_stack_current[7].push(opcode);
1498
- // return opcode;
1499
- // }
1500
-
1501
- /**
1502
- checks the given name to see if its in the index. If the result is 0 or above,
1503
- it is, and the idx is the index in the locals array. -1 means it is not in the
1504
- array (so not a local)
1505
- */
1506
- function iseq_locals_idx(name) {
1507
- return iseq_locals_current.indexOf(name);
1508
- }
1509
-
1510
- /**
1511
- push locals name. the return value is the new index for the name
1512
- */
1513
- function iseq_locals_push(name) {
1514
- var len = iseq_locals_current.length;
1515
- iseq_locals_current.push(name);
1516
- return len;
1517
- }
1518
-
1519
- function generate_tree(tree) {
1520
- console.log("tree:");
1521
- console.log(tree);
1522
- var top_iseq = iseq_stack_push([0,0,"<compiled>",filename,ISEQ_TYPE_TOP,0,[],[]]);
1523
-
1524
- var i;
1525
- for (i = 0; i < tree.length; i++) {
1526
- generate_stmt(tree[i], { instance: true, full_stmt: true, last_stmt:(tree.length - 1) == i, top_level: true} );
1527
- }
1528
- console.log(iseq_stack_pop());
1529
-
1530
- return top_iseq;
1531
- }
1532
-
1533
- function generate_stmt(stmt, context) {
1534
- switch (stmt.type) {
1535
- case kCLASS:
1536
- generate_class(stmt, context);
1537
- break;
1538
- case kMODULE:
1539
- generate_module(stmt, context);
1540
- break;
1541
- case kDEF:
1542
- generate_def(stmt, context);
1543
- break;
1544
- case tCALL:
1545
- generate_call(stmt, context);
1546
- break;
1547
- case tSYMBEG:
1548
- generate_symbol(stmt, context);
1549
- break;
1550
- case tCONSTANT:
1551
- generate_constant(stmt, context);
1552
- break;
1553
- case tIDENTIFIER:
1554
- generate_identifier(stmt, context);
1555
- break;
1556
- case tINTEGER:
1557
- generate_integer(stmt, context);
1558
- break;
1559
- case tSTRING_BEG:
1560
- generate_string(stmt, context);
1561
- break;
1562
- case kSELF:
1563
- generate_self(stmt, context);
1564
- break;
1565
- case kIF:
1566
- generate_if(stmt, context);
1567
- break;
1568
- case '=':
1569
- generate_assign(stmt, context);
1570
- break;
1571
- case kFALSE:
1572
- generate_false(stmt, context);
1573
- break;
1574
- case kTRUE:
1575
- generate_true(stmt, context);
1576
- break;
1577
- case tLBRACK:
1578
- generate_array(stmt, context);
1579
- break;
1580
- default:
1581
- console.log("unknown generate_stmt type: " + stmt.type + ", " + stmt.value);
1582
- }
1583
- }
1584
-
1585
- function generate_array(stmt, context) {
1586
- write("[");
1587
- if (stmt.$values) {
1588
- var i;
1589
- for (i = 0; i < stmt.$values.length; i++) {
1590
- if (i > 0) write(",");
1591
- generate_stmt(stmt.$values[i], {full_stmt:false, last_stmt:false});
1592
- }
1593
- }
1594
- write("]");
1595
- // iseq_opcode_push([iNEWARRAY, stmt.$values ? stmt.$values.length : 0]);
1596
- }
1597
-
1598
- function generate_assign(stmt, context) {
1599
-
1600
- if (context.last_stmt && context.full_stmt) write("return ");
1601
-
1602
-
1603
- if (stmt.$lhs.type == tIDENTIFIER) {
1604
- var idx;
1605
- // iseq_opcode_push([iSETLOCAL, 0]);
1606
- if ((idx = iseq_locals_idx(stmt.$lhs.value)) == -1) {
1607
- // doesnt exist, so we need a new local
1608
- // iseq_opcode_push([iSETLOCAL, iseq_locals_push(stmt.$lhs.value)]);
1609
- write('vm_setlocal(' + iseq_locals_push(stmt.$lhs.value) + ',');
1610
- generate_stmt(stmt.$rhs, {full_stmt: false, last_stmt: false});
1611
- write(')');
1612
- }
1613
- else {
1614
- // already a local, so just get the index
1615
- // iseq_opcode_push([iSETLOCAL, idx]);
1616
- }
1617
- }
1618
- else {
1619
- throw "unsupported lhs, for now"
1620
- }
1621
-
1622
- if (context.full_stmt) write(";");
1623
- }
1624
-
1625
- function generate_if(stmt, context) {
1626
- // if expression..
1627
- generate_stmt(stmt.$expr, {instance:context.instance, full_stmt:false, last_stmt:false});
1628
- var jmp_label = iseq_jump_idx();
1629
- iseq_opcode_push([iBRANCHUNLESS, jmp_label]);
1630
-
1631
- // stmts
1632
- if (stmt.$stmts) {
1633
- var i, s = stmt.$stmts;
1634
- for (i = 0; i < s.length; i++) {
1635
- generate_stmt(s[i], {instance:context.instance, full_stmt:true, last_stmt:false});
1636
- }
1637
- }
1638
-
1639
- iseq_opcode_push(jmp_label);
1640
-
1641
- // if (context.last_stmt && context.full_stmt) write("return ");
1642
- // write("(function(){");
1643
- //
1644
- // (stmt.type == kIF) ? write("if(RTEST(") : write("if(!RTEST(");
1645
- //
1646
- // // RTEST expression
1647
- // generate_stmt(stmt.$expr, {instance:context.instance, full_stmt:false, last_stmt:false});
1648
- // write(")){\n");
1649
- //
1650
- // if (stmt.$stmts) {
1651
- // var i, s = stmt.$stmts;
1652
- // for (i = 0; i < s.length; i++) {
1653
- // generate_stmt(s[i], {instance:context.instance, full_stmt:true, last_stmt:(s[s.length -1] == s[i] ? true : false)});
1654
- // }
1655
- // }
1656
- //
1657
- // write("}\n");
1658
- //
1659
- // if (stmt.$tail) {
1660
- // var i, t = stmt.$tail;
1661
- // for (i = 0; i < t.length; i++) {
1662
- // if (t[i].type == kELSIF) {
1663
- // write("else if(RTEST(");
1664
- // generate_stmt(t[i].$expr, {instance:context.instance, full_stmt:false, last_stmt:false});
1665
- // write(")){\n");
1666
- // }
1667
- // else {
1668
- // write("else{\n");
1669
- // }
1670
- //
1671
- // if (t[i].$stmts) {
1672
- // var j, k = t[i].$stmts;
1673
- // for (j = 0; j < k.length; j++) {
1674
- // // console.log("doing " + k[j].value);
1675
- // generate_stmt(k[j], {instance:context.instance, full_stmt:true, last_stmt:(k[k.length - 1] == k[i] ? true : false)});
1676
- // }
1677
- // }
1678
- //
1679
- // write("}\n");
1680
- // }
1681
- // }
1682
- //
1683
- // write("})()");
1684
- // if (context.full_stmt) write(";\n");
1685
- }
1686
-
1687
- function generate_false(stmt, context) {
1688
- iseq_opcode_push([iPUTOBJECT, false]);
1689
-
1690
- if (context.last_stmt && context.full_stmt) {
1691
- iseq_opcode_push([iLEAVE]);
1692
- }
1693
- }
1694
-
1695
- function generate_true(stmt, context) {
1696
- iseq_opcode_push([iPUTOBJECT, true]);
1697
-
1698
- if (context.last_stmt && context.full_stmt) {
1699
- iseq_opcode_push([iLEAVE]);
1700
- }
1701
- }
1702
-
1703
-
1704
- function generate_self(stmt, context) {
1705
- if (context.last_stmt && context.full_stmt) write("return ");
1706
- write(current_self());
1707
- if (context.full_stmt) write(";\n");
1708
- }
1709
-
1710
- function generate_string(stmt, context) {
1711
- // iseq_opcode_push([iPUTSTRING, stmt.$parts[0].value]);
1712
-
1713
- // if (context.last_stmt && context.full_stmt) {
1714
- // iseq_opcode_push([iLEAVE]);
1715
- // }
1716
-
1717
- write("'" + stmt.$parts[0].value + "'");
1718
- }
1719
-
1720
- function generate_integer(stmt, context) {
1721
-
1722
- // iseq_opcode_push([iPUTOBJECT, parseInt(stmt.value)]);
1723
- write(parseInt(stmt.value));
1724
-
1725
- if (context.last_stmt && context.full_stmt) {
1726
- iseq_opcode_push([iLEAVE]);
1727
- }
1728
- }
1729
-
1730
- function generate_constant(stmt, context) {
1731
- // iseq_opcode_push([iPUTNIL]);
1732
- // iseq_opcode_push([iGETCONSTANT, stmt.value]);
1733
- write("vm_getconstant(nil,'" + stmt.value + "')");
1734
- }
1735
-
1736
- function generate_identifier(identifier, context) {
1737
- // for now, assumption is that they are all method calls. should check for local or dynamic
1738
-
1739
- // no receiver.
1740
- var idx;
1741
- if ((idx = iseq_locals_idx(identifier.value)) == -1) {
1742
- // not an identifier
1743
- iseq_opcode_push([iPUTNIL]);
1744
- iseq_opcode_push([iSEND, identifier.value, 0, null, 8, null]);
1745
- }
1746
- else {
1747
- // its an identifier
1748
- iseq_opcode_push([iGETLOCAL, idx]);
1749
- }
1750
-
1751
-
1752
- if (context.full_stmt && context.last_stmt) {
1753
- iseq_opcode_push([iLEAVE]);
1754
- }
1755
- else if (context.full_stmt) {
1756
- iseq_opcode_push([iPOP]);
1757
- }
1758
- }
1759
-
1760
- function generate_symbol(sym, context) {
1761
-
1762
- iseq_opcode_push([iPUTOBJECT, ID2SYM(sym.$name.value)]);
1763
-
1764
- if (context.full_stmt && context.last_stmt) {
1765
- iseq_opcode_push([iLEAVE]);
1766
- }
1767
- else if (context.full_stmt) {
1768
- iseq_opcode_push([iPOP]);
1769
- }
1770
- }
1771
-
1772
- function generate_call(call, context) {
1773
-
1774
- write("vm_send(");
1775
-
1776
- // receiver
1777
- if (call.$recv) {
1778
- generate_stmt(call.$recv, {instance:context.instance, full_stmt:false});
1779
- // fix fcall bit..?
1780
- }
1781
- else {
1782
- write("vm_putself()");
1783
- }
1784
-
1785
- // mid
1786
- var mid = call.$meth;
1787
- if (typeof mid === 'object') { mid = mid.value; }
1788
- write(",'" + mid + "',");
1789
-
1790
- // arguments (argv)
1791
- if (call.$call_args && call.$call_args.args) {
1792
- write("[");
1793
- var i = 0, a = call.$call_args.args;
1794
- for (i = 0; i < a.length; i++) {
1795
- if (i > 0) write(",");
1796
- generate_stmt(a[i], {instance:context.instance, full_stmt:false});
1797
- }
1798
- write("],");
1799
- }
1800
- else {
1801
- write("[],");
1802
- }
1803
-
1804
- // block
1805
- write("null");
1806
-
1807
-
1808
- // end
1809
- write(")");
1810
-
1811
- if (context.full_stmt) write(";");
1812
-
1813
-
1814
- // var mid = call.$meth;
1815
- // if (typeof mid === 'object') {
1816
- // mid = mid.value;
1817
- // }
1818
- //
1819
- // var iseq = [iSEND, mid, 0, null, 8, null];
1820
- //
1821
- // // receiver
1822
- // if (call.$recv) {
1823
- // generate_stmt(call.$recv, {instance:context.instance, full_stmt:false});
1824
- // // fix fcall bit
1825
- // iseq[4] = 0;
1826
- // }
1827
- // else {
1828
- // iseq_opcode_push([iPUTNIL]);
1829
- // }
1830
- //
1831
- // // args..
1832
- // if (call.$call_args && call.$call_args.args) {
1833
- // var i, a = call.$call_args.args;
1834
- // for (i = 0; i < a.length; i++) {
1835
- // generate_stmt(a[i], { instance:context.instance, full_stmt:false });
1836
- // }
1837
- // iseq[2] = a.length;
1838
- // }
1839
- //
1840
- // iseq_opcode_push(iseq);
1841
- //
1842
- // if (context.full_stmt && context.last_stmt) {
1843
- // // if last stmt, we want to leave the context (with result of call on stack)
1844
- // iseq_opcode_push([iLEAVE]);
1845
- // }
1846
- // else if (context.full_stmt) {
1847
- // // if not last stmt, but a full stmt, remove result from stack. no-one wants it
1848
- // iseq_opcode_push([iPOP]);
1849
- // }
1850
- //
1851
- // // block
1852
- // if (call.$brace_block) {
1853
- // var b_seq = [0, 0, "block in <compiled>", filename, ISEQ_TYPE_BLOCK, 0, [], []];
1854
- // iseq[3] = b_seq;
1855
- //
1856
- // if (call.$brace_block.$stmts) {
1857
- // // generate stmts
1858
- // iseq_stack_push(b_seq);
1859
- //
1860
- // var i, s = call.$brace_block.$stmts;
1861
- // for (i = 0; i < s.length; i++) {
1862
- // generate_stmt(s[i], {full_stmt:true, last_stmt:false});
1863
- // }
1864
- //
1865
- // iseq_stack_pop();
1866
- // }
1867
- // }
1868
-
1869
-
1870
-
1871
- // iseq_opcode_push([iPUTNIL]);
1872
- // var iseq = [0, 0, definition.$fname.value, filename, ISEQ_TYPE_METHOD, 0, [], []];
1873
- // var opcode = [iDEFINEMETHOD, definition.$fname.value, iseq, 0];
1874
- // iseq_opcode_push(opcode);
1875
- // iseq_stack_push(iseq);
1876
- //
1877
- // if (definition.$stmts) {
1878
- // var i, s = definition.$stmts;
1879
- // for (i = 0; i < s.length; i++) {
1880
- // generate_stmt(s[i], {instance:(definition.$sname ? false : true), full_stmt:true, last_stmt:(s[s.length - 1] == s[i] ? true : false), name:definition.$fname});
1881
- // }
1882
- // }
1883
-
1884
-
1885
-
1886
- // if (context.last_stmt && context.last_stmt) write("return ");
1887
- //
1888
- // if(call.value.match(/^[A-Z]/)) {
1889
- // write(call.value);
1890
- // write("(");
1891
- // }
1892
- // else {
1893
- // // detect block..
1894
- // if (call.$brace_block) {
1895
- // write("rb_block_funcall(");
1896
- // }
1897
- // else {
1898
- // write("rb_funcall(");
1899
- // }
1900
- //
1901
- //
1902
- // if (call.$recv) {
1903
- // generate_stmt(call.$recv, {instance:context.instance, full_stmt:false, last_stmt:context.last_stmt, top_level:context.top_level});
1904
- // }
1905
- // else {
1906
- // write(current_self());
1907
- // }
1908
- //
1909
- // write(",'" + call.$meth.value + "'");
1910
- // }
1911
- //
1912
- // // normal args
1913
- // if (call.$call_args && call.$call_args.args) {
1914
- // var i, a = call.$call_args.args;
1915
- // for (i = 0; i < a.length; i++) {
1916
- // write(",");
1917
- // generate_stmt(a[i], {instance:context.instance, full_stmt:false});
1918
- // }
1919
- // }
1920
- //
1921
- // // assocs
1922
- // if (call.$call_args && call.$call_args.assocs) {
1923
- //
1924
- // }
1925
- //
1926
- // // block
1927
- // if (call.$brace_block) {
1928
- //
1929
- // }
1930
- //
1931
- // // sym block: &:upcase etc
1932
- // if (call.$call_args && call.$call_args.block_arg) {
1933
- // write(",rb_funcall(");
1934
- // generate_stmt(call.$call_args.block_arg.arg, {instance:context.singleton, full_stmt:false, last_stmt:false, top_level:context.top_level});
1935
- // write(",'to_proc')");
1936
- // }
1937
- //
1938
- // write(")");
1939
- // if (context.full_stmt) write(";\n");
1940
- }
1941
-
1942
- function generate_def(definition, context) {
1943
- // assume not singleton for now, so define "on nil"
1944
- iseq_opcode_push([iPUTNIL]);
1945
- var iseq = [0, 0, definition.$fname.value, filename, ISEQ_TYPE_METHOD, 0, [], []];
1946
- var opcode = [iDEFINEMETHOD, definition.$fname.value, iseq, 0];
1947
- iseq_opcode_push(opcode);
1948
- iseq_stack_push(iseq);
1949
-
1950
- if (definition.$stmts) {
1951
- var i, s = definition.$stmts;
1952
- for (i = 0; i < s.length; i++) {
1953
- generate_stmt(s[i], {instance:(definition.$sname ? false : true), full_stmt:true, last_stmt:(s[s.length - 1] == s[i] ? true : false), name:definition.$fname});
1954
- }
1955
- }
1956
-
1957
-
1958
-
1959
- // if (definition.singleton) {
1960
- // write("rb_define_singleton_method(");
1961
- // generate_stmt(definition.singleton, {instance: context.instance, full_stmt:false, last_stmt:false});
1962
- // write(",'" + definition.$fname + "',function(self,_cmd");
1963
- // current_self_push("self");
1964
- // }
1965
- // else if (context.top_level) {
1966
- // write("rb_define_singleton_method(rb_top_self, " + definition.$fname + "',function(self,_cmd");
1967
- // current_self_push("self");
1968
- // }
1969
- // else {
1970
- // write("rb_define_method(" + current_self() + ",'");
1971
- // write(definition.$fname.value);
1972
- // write("',function(self,_cmd");
1973
- // current_self_push("self");
1974
- // }
1975
- //
1976
- // // arglist
1977
- // if (definition.$arglist && definition.$arglist.arg) {
1978
- // var i, a = definition.$arglist.arg;
1979
- // for (i = 0; i < a.length; i++) {
1980
- // write(",");
1981
- // write(a[i].value);
1982
- // // add_to_nametable(a[i].value);
1983
- // }
1984
- // }
1985
- //
1986
- // // block arg support - every method potentialy might have a block.
1987
- // write(",$b");
1988
- //
1989
- // write("){\n");
1990
-
1991
- // block reference goes here (so if we say &block in params, map var block to $b)
1992
- // if definition[:arglist] && definition[:arglist][:opt_block_arg]
1993
- // write "var #{definition[:arglist][:opt_block_arg]} = $b;\n"
1994
- // add_to_nametable definition[:arglist][:opt_block_arg]
1995
- // end
1996
-
1997
- // statements
1998
- // push_string_buffer();
1999
- // push_nametable();
2000
-
2001
- // if (definition.$stmts) {
2002
- // var i, s = definition.$stmts;
2003
- // for (i = 0; i < s.length; i++) {
2004
- // generate_stmt(s[i], {instance:(definition.$sname ? false : true), full_stmt:true, last_stmt:(s[s.length - 1] == s[i] ? true : false), name:definition.$fname});
2005
- // }
2006
- // }
2007
-
2008
- // var body_contents = pop_string_buffer(), name_table = pop_nametable();
2009
- // write each ivar statements..
2010
- // if name_table.length > 0
2011
- // write "var #{name_table.join(",")};\n"
2012
- // end
2013
-
2014
- // write(body_contents);
2015
-
2016
- // current_self_pop();
2017
- // pop_nametable();
2018
- // write("});\n");
2019
-
2020
- iseq_stack_pop();
2021
- }
2022
-
2023
- function generate_class(stmt, context) {
2024
-
2025
- if (context.full_stmt && context.last_stmt) write("return ");
2026
-
2027
- write("vm_defineclass(");
2028
-
2029
- // base
2030
- write("vm_putnil(),");
2031
-
2032
- // superclass
2033
- if (stmt.$super) {
2034
- generate_stmt(stmt.$super, {full_stmt:false, last_stmt:false});
2035
- }
2036
- else {
2037
- write("vm_putnil()");
2038
- }
2039
- write(",");
2040
-
2041
- // class id
2042
- write("'" + stmt.$kname.value + "'");
2043
- write(",");
2044
-
2045
- // iseq
2046
- write("function(){},")
2047
-
2048
- // op_flag
2049
- write(0);
2050
-
2051
- write(")");
2052
-
2053
- if (context.full_stmt) write(";");
2054
-
2055
- // base (for class << Ben; ...; end)
2056
- // iseq_opcode_push([iPUTNIL]);
2057
- // // superclass
2058
- // if (stmt.$super) {
2059
- // // console.log("super..");
2060
- // // console.log(stmt.$super);
2061
- // generate_stmt(stmt.$super, {full_stmt: false, last_stmt:false});
2062
- // }
2063
- // else {
2064
- // iseq_opcode_push([iPUTNIL]);
2065
- // }
2066
- //
2067
- // var iseq = [0, 0, "<class:" + stmt.$kname.value + ">", filename, ISEQ_TYPE_CLASS, 0, [], []];
2068
- // var opcode = [iDEFINECLASS, stmt.$kname.value, iseq, 0];
2069
- // iseq_opcode_push(opcode);
2070
- // iseq_stack_push(iseq);
2071
- //
2072
- // // statements.
2073
- // if (stmt.$stmts) {
2074
- // var i, s = stmt.$stmts;
2075
- // for (i = 0; i < s.length; i++) {
2076
- // generate_stmt(s[i], {instance:false, full_stmt:true, last_stmt:(s[s.length - 1] == s[i] ? true : false), top_level:false});
2077
- // }
2078
- // }
2079
- //
2080
- // iseq_stack_pop();
2081
-
2082
- // write("(function(self) {\n");
2083
- // push_nametable();
2084
- // current_self_push("self");
2085
- //
2086
- // if (stmt.$stmts) {
2087
- // var i, m = stmt.$stmts;
2088
- // for (i = 0; i < m.length; i++) {
2089
- // generate_stmt(m[i], {instance: false, full_stmt: true, last_stmt: (m[m.length -1] == m[i] ? true : false), top_level: false});
2090
- // }
2091
- // }
2092
- //
2093
- // pop_nametable();
2094
- // current_self_pop();
2095
- //
2096
- // write("})(");
2097
- //
2098
- // if (context.top_level) {
2099
- // write("rb_define_class('")
2100
- // write(stmt.$kname.value);
2101
- // write("',");
2102
- // }
2103
- // else {
2104
- // write("rb_define_class_under(" + current_self() + ",'");
2105
- // write(stmt.$kname.value);
2106
- // write("',");
2107
- // }
2108
- //
2109
- // // superclass
2110
- // if (stmt.$super) {
2111
- // write("rb_const_get(self, '" + stmt.$super.value + "'))")
2112
- // }
2113
- // else {
2114
- // write("rb_cObject)");
2115
- // }
2116
- //
2117
- // write(");\n")
2118
- }
2119
-
2120
- function generate_module(mod, context) {
2121
- write("(function(self) {\n");
2122
- push_nametable();
2123
- current_self_push("self");
2124
-
2125
- if (mod.$stmts) {
2126
- var i, m = mod.$stmts;
2127
- for (i = 0; i < m.length; i++) {
2128
- generate_stmt(m[i], {instance: false, full_stmt: false, last_stmt: (m[m.length -1] == m[i] ? true : false), nested: true});
2129
- }
2130
- }
2131
-
2132
- pop_nametable();
2133
- current_self_pop();
2134
-
2135
- write("})(");
2136
-
2137
- if (context.top_level) {
2138
- write("rb_define_module('");
2139
- write(mod.$kname.value);
2140
- write("'));\n");
2141
- }
2142
- else {
2143
- write("rb_define_module_under(" + current_self() + ",'");
2144
- write(mod.$kname.value);
2145
- write("'));\n")
2146
- }
2147
- }
2148
-
2149
- this.parse = function(str) {
2150
- scanner = new vn_ruby_string_scanner(str);
2151
- next_token();
2152
- var s = stmts();
2153
- return generate_tree(s);
2154
- }
2155
-
2156
- this.contexts = function() {
2157
- return contexts;
2158
- }
2159
-
2160
- // the parser - pass is the source to actually parse
2161
- // return function(parse_text) {
2162
- // scanner = new vn_ruby_string_scanner(parse_text);
2163
- // next_token();
2164
- // var s = stmts();
2165
- // generate_tree(s);
2166
- // return s;
2167
- // }
2168
- return this;
2169
- };
2170
-
2171
-
2172
- // String scanner
2173
- var vn_ruby_string_scanner = function(str) {
2174
- // whole string
2175
- this.str = str;
2176
- // current index
2177
- this.at = 0;
2178
- // last matched data
2179
- this.matched = "";
2180
- // working string (basically str substr'd from the 'at' index to the end)
2181
- this.working_string = str;
2182
- };
2183
-
2184
- vn_ruby_string_scanner.prototype.scan = function(reg) {
2185
- // reg = this._fix_regexp_to_match_beg(reg);
2186
- var res = reg.exec(this.working_string);
2187
- if (res == null) {
2188
- return false;
2189
- }
2190
- else if (typeof res == "object") {
2191
- // array.
2192
- this.at += res[0].length;
2193
- this.working_string = this.working_string.substr(res[0].length);
2194
- this.matched = res[0];
2195
- return res;
2196
- }
2197
- else if (typeof res == "string") {
2198
- this.at += res.length;
2199
- this.working_string = this.working_string.substr(res.length);
2200
- return res;
2201
- }
2202
- return false;
2203
- };
2204
-
2205
- vn_ruby_string_scanner.prototype.check = function(reg) {
2206
- // reg = this._fix_regexp_to_match_beg(reg);
2207
- var res = reg.exec(this.working_string);
2208
- return res;
2209
- };
2210
-
2211
- vn_ruby_string_scanner.prototype.matched = function() {
2212
-
2213
- };
2214
-
2215
- vn_ruby_string_scanner.prototype.peek = function(len) {
2216
- return this.working_string.substr(0, len);
2217
- };
2218
-