opal 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -10
- data/LICENSE +75 -0
- data/README.md +55 -3
- data/Rakefile +62 -139
- data/bin/opal +7 -10
- data/gems/core/README.md +5 -0
- data/gems/core/Rakefile +7 -0
- data/gems/core/core.gemspec +13 -0
- data/gems/core/lib/core.rb +33 -0
- data/gems/core/lib/core/array.rb +1470 -0
- data/gems/core/lib/core/basic_object.rb +15 -0
- data/gems/core/lib/core/class.rb +31 -0
- data/gems/core/lib/core/dir.rb +26 -0
- data/gems/core/lib/core/error.rb +43 -0
- data/gems/core/lib/core/false_class.rb +21 -0
- data/gems/core/lib/core/file.rb +54 -0
- data/gems/core/lib/core/hash.rb +725 -0
- data/gems/core/lib/core/kernel.rb +240 -0
- data/gems/core/lib/core/module.rb +98 -0
- data/gems/core/lib/core/nil_class.rb +41 -0
- data/gems/core/lib/core/numeric.rb +370 -0
- data/gems/core/lib/core/proc.rb +11 -0
- data/gems/core/lib/core/range.rb +17 -0
- data/gems/core/lib/core/regexp.rb +18 -0
- data/gems/core/lib/core/string.rb +328 -0
- data/gems/core/lib/core/symbol.rb +15 -0
- data/gems/core/lib/core/top_self.rb +8 -0
- data/gems/core/lib/core/true_class.rb +20 -0
- data/gems/core/lib/core/vm.rb +16 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/append_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/assoc_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/at_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/clear_spec.rb +1 -1
- data/{opals/opal/opal → gems/core}/spec/core/array/collect_bang_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/collect_spec.rb +0 -0
- data/gems/core/spec/core/array/compact_spec.rb +41 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/concat_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/constructor_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/each_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/element_reference_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/first_spec.rb +1 -1
- data/{opals/opal/opal → gems/core}/spec/core/array/include_spec.rb +0 -0
- data/gems/core/spec/core/array/join_spec.rb +6 -0
- data/gems/core/spec/core/array/last_spec.rb +51 -0
- data/gems/core/spec/core/array/length_spec.rb +6 -0
- data/{opals/opal/opal → gems/core}/spec/core/array/map_spec.rb +2 -0
- data/gems/core/spec/core/array/reverse_spec.rb +6 -0
- data/{opals/opal/opal → gems/core}/spec/core/builtin_constants/builtin_constants_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/false/and_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/false/inspect_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/false/or_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/false/to_s_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/false/xor_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/file/join_spec.rb +1 -1
- data/gems/core/spec/core/hash/assoc_spec.rb +32 -0
- data/{opals/opal/opal → gems/core}/spec/core/kernel/instance_eval_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/kernel/loop_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/kernel/raise_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/module/attr_accessor_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/number/lt_spec.rb +0 -0
- data/gems/core/spec/core/string/sub_spec.rb +24 -0
- data/{opals/opal/opal → gems/core}/spec/core/true/and_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/true/inspect_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/true/or_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/true/to_s_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/core/true/xor_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/language/and_spec.rb +2 -3
- data/{opals/opal/opal → gems/core}/spec/language/array_spec.rb +21 -5
- data/gems/core/spec/language/block_spec.rb +38 -0
- data/{opals/opal/opal → gems/core}/spec/language/break_spec.rb +0 -0
- data/gems/core/spec/language/case_spec.rb +103 -0
- data/{opals/opal/opal → gems/core}/spec/language/def_spec.rb +11 -1
- data/{opals/opal/opal → gems/core}/spec/language/eigenclass_spec.rb +0 -0
- data/gems/core/spec/language/file_spec.rb +13 -0
- data/gems/core/spec/language/fixtures/block.rb +21 -0
- data/gems/core/spec/language/fixtures/super.rb +293 -0
- data/{opals/opal/opal → gems/core}/spec/language/hash_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/language/if_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/language/loop_spec.rb +0 -0
- data/gems/core/spec/language/metaclass_spec.rb +21 -0
- data/{opals/opal/opal → gems/core}/spec/language/method_spec.rb +60 -0
- data/{opals/opal/opal → gems/core}/spec/language/next_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/language/or_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/language/redo_spec.rb +0 -0
- data/gems/core/spec/language/regexp_spec.rb +26 -0
- data/{opals/opal/opal → gems/core}/spec/language/rescue_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/language/return_spec.rb +0 -0
- data/{opals/opal/opal → gems/core}/spec/language/string_spec.rb +0 -0
- data/gems/core/spec/language/super_spec.rb +32 -0
- data/{opals/opal/opal → gems/core}/spec/language/until_spec.rb +47 -47
- data/gems/core/spec/language/variables_spec.rb +155 -0
- data/{opals/opal/opal → gems/core}/spec/language/while_spec.rb +47 -47
- data/{opals/opal/opal → gems/core}/spec/spec_helper.rb +1 -1
- data/gems/core_fs/README.md +19 -0
- data/gems/dev/Rakefile +5 -0
- data/gems/dev/lib/dev.js +99 -0
- data/gems/dev/lib/dev/generator.js +1264 -0
- data/gems/dev/lib/dev/parser.js +979 -0
- data/gems/dev/lib/dev/ruby_parser.js +1088 -0
- data/gems/dev/lib/dev/ruby_parser.y +1267 -0
- data/gems/dev/lib/dev/string_scanner.js +38 -0
- data/gems/dev/tools/racc2js/README.md +39 -0
- data/gems/dev/tools/racc2js/math_parser.js +222 -0
- data/gems/dev/tools/racc2js/math_parser.rb +133 -0
- data/gems/dev/tools/racc2js/math_parser.y +28 -0
- data/gems/dev/tools/racc2js/parser.js +218 -0
- data/gems/dev/tools/racc2js/racc2js.rb +153 -0
- data/gems/json/README.md +4 -0
- data/gems/json/json.gemspec +14 -0
- data/gems/json/lib/json.rb +64 -0
- data/gems/json/lib/json/ext.rb +51 -0
- data/{opals/opal/browser/lib/browser/json_parse.js → gems/json/lib/json/json2.js} +197 -37
- data/gems/ospec/README.md +0 -0
- data/gems/ospec/lib/ospec.rb +6 -0
- data/gems/ospec/lib/ospec/autorun.rb +3 -0
- data/gems/ospec/lib/ospec/dsl.rb +15 -0
- data/gems/ospec/lib/ospec/example.rb +11 -0
- data/gems/ospec/lib/ospec/example/before_and_after_hooks.rb +56 -0
- data/gems/ospec/lib/ospec/example/errors.rb +17 -0
- data/gems/ospec/lib/ospec/example/example_group.rb +12 -0
- data/gems/ospec/lib/ospec/example/example_group_factory.rb +21 -0
- data/gems/ospec/lib/ospec/example/example_group_hierarchy.rb +20 -0
- data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/example/example_group_methods.rb +26 -68
- data/gems/ospec/lib/ospec/example/example_group_proxy.rb +14 -0
- data/gems/ospec/lib/ospec/example/example_methods.rb +46 -0
- data/gems/ospec/lib/ospec/example/example_proxy.rb +18 -0
- data/gems/ospec/lib/ospec/expectations.rb +19 -0
- data/gems/ospec/lib/ospec/expectations/errors.rb +8 -0
- data/gems/ospec/lib/ospec/expectations/fail_with.rb +8 -0
- data/gems/ospec/lib/ospec/expectations/handler.rb +27 -0
- data/gems/ospec/lib/ospec/matchers.rb +24 -0
- data/{opals/opal/Rakefile → gems/ospec/lib/ospec/matchers/be.rb} +0 -0
- data/gems/ospec/lib/ospec/matchers/generated_descriptions.rb +20 -0
- data/gems/ospec/lib/ospec/matchers/operator_matcher.rb +52 -0
- data/gems/ospec/lib/ospec/runner.rb +40 -0
- data/gems/ospec/lib/ospec/runner/example_group_runner.rb +44 -0
- data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/formatter/html_formatter.rb +31 -40
- data/gems/ospec/lib/ospec/runner/formatter/terminal_formatter.rb +48 -0
- data/gems/ospec/lib/ospec/runner/options.rb +36 -0
- data/{opals/opal/spec/lib/spec → gems/ospec/lib/ospec}/runner/reporter.rb +23 -55
- data/gems/ospec/ospec.gemspec +0 -0
- data/gems/rquery/README.md +9 -0
- data/gems/rquery/lib/rquery.rb +10 -0
- data/gems/rquery/lib/rquery/ajax.rb +4 -0
- data/gems/rquery/lib/rquery/css.rb +96 -0
- data/gems/rquery/lib/rquery/document.rb +25 -0
- data/gems/rquery/lib/rquery/element.rb +292 -0
- data/gems/rquery/lib/rquery/event.rb +108 -0
- data/gems/rquery/lib/rquery/jquery.js +8177 -0
- data/gems/rquery/lib/rquery/request.rb +138 -0
- data/gems/rquery/lib/rquery/response.rb +49 -0
- data/gems/rquery/rquery.gemspec +16 -0
- data/lib/opal.js +1597 -0
- data/lib/opal.rb +6 -69
- data/lib/opal/builder.rb +115 -0
- data/lib/opal/bundle.rb +131 -0
- data/lib/opal/command.rb +11 -0
- data/lib/opal/context.rb +69 -0
- data/lib/opal/context/console.rb +12 -0
- data/lib/opal/context/file_system.rb +19 -0
- data/lib/opal/context/loader.rb +117 -0
- data/lib/opal/gem.rb +153 -0
- data/lib/opal/ruby/nodes.rb +1302 -0
- data/lib/opal/ruby/parser.rb +780 -0
- data/lib/opal/ruby/ruby_parser.rb +5170 -0
- data/lib/opal/ruby/ruby_parser.y +1298 -0
- data/opal.gemspec +11 -256
- metadata +179 -240
- data/.gitmodules +0 -6
- data/Opalfile +0 -384
- data/VERSION +0 -1
- data/demos/apps/browser_demo/index.html +0 -11
- data/demos/apps/browser_demo/lib/browser_demo.rb +0 -31
- data/demos/apps/simple_opal/Opalfile +0 -13
- data/demos/apps/simple_opal/index.html +0 -11
- data/demos/apps/simple_opal/lib/app_controller.rb +0 -62
- data/demos/apps/simple_opal/lib/main_window.rb +0 -146
- data/demos/browser/request/index.html +0 -52
- data/demos/browser/request/request.rb +0 -48
- data/gen/browser/__PROJECT_NAME__/Rakefile +0 -12
- data/gen/browser/__PROJECT_NAME__/index.html +0 -11
- data/gen/browser/__PROJECT_NAME__/javascripts/opal.debug.js +0 -4687
- data/gen/browser/__PROJECT_NAME__/javascripts/opal.min.js +0 -175
- data/gen/browser/__PROJECT_NAME__/lib/__PROJECT_NAME__.rb +0 -1
- data/lib/opal/builders/base.rb +0 -50
- data/lib/opal/builders/css.rb +0 -46
- data/lib/opal/builders/javascript.rb +0 -44
- data/lib/opal/builders/opal.rb +0 -79
- data/lib/opal/builders/ruby.rb +0 -50
- data/lib/opal/builders/ruby/generate.rb +0 -1851
- data/lib/opal/builders/ruby/nodes.rb +0 -210
- data/lib/opal/builders/ruby/ruby.rb +0 -916
- data/lib/opal/builders/ruby/ruby_parser.rb +0 -6008
- data/lib/opal/builders/ruby/ruby_parser.rb.y +0 -1451
- data/lib/opal/models/build_item.rb +0 -104
- data/lib/opal/models/hash_struct.rb +0 -40
- data/lib/opal/models/project.rb +0 -252
- data/lib/opal/models/struct_accessors.rb +0 -58
- data/lib/opal/models/target.rb +0 -176
- data/lib/opal/opal/build.rb +0 -169
- data/lib/opal/opal/env/console.rb +0 -66
- data/lib/opal/opal/env/fs.rb +0 -98
- data/lib/opal/opal/env/object.rb +0 -48
- data/lib/opal/opal/environment.rb +0 -139
- data/lib/opal/opal/gen.rb +0 -62
- data/lib/opal/opal/opal.rb +0 -75
- data/lib/opal/opal/repl.rb +0 -38
- data/lib/opal/opalfile/dsl.rb +0 -62
- data/lib/opal/opalfile/opalfile.rb +0 -133
- data/lib/opal/opalfile/task.rb +0 -96
- data/lib/opal/opalfile/task_manager.rb +0 -63
- data/lib/opal/opalfile/task_scope.rb +0 -52
- data/lib/opal/rack/app_server.rb +0 -119
- data/lib/opal/rake/opal_task.rb +0 -34
- data/opals/opal/README.md +0 -37
- data/opals/opal/browser/Opalfile +0 -11
- data/opals/opal/browser/README.md +0 -146
- data/opals/opal/browser/SIZZLE_LICESNSE.txt +0 -148
- data/opals/opal/browser/lib/browser.rb +0 -118
- data/opals/opal/browser/lib/browser/builder.rb +0 -41
- data/opals/opal/browser/lib/browser/canvas_context.rb +0 -115
- data/opals/opal/browser/lib/browser/dimensions.rb +0 -50
- data/opals/opal/browser/lib/browser/document.rb +0 -146
- data/opals/opal/browser/lib/browser/element.rb +0 -487
- data/opals/opal/browser/lib/browser/element/attributes.rb +0 -88
- data/opals/opal/browser/lib/browser/element/css.rb +0 -290
- data/opals/opal/browser/lib/browser/element/form.rb +0 -146
- data/opals/opal/browser/lib/browser/event/dom_events.rb +0 -81
- data/opals/opal/browser/lib/browser/event/event.rb +0 -177
- data/opals/opal/browser/lib/browser/event/trigger_events.rb +0 -53
- data/opals/opal/browser/lib/browser/geometry.rb +0 -97
- data/opals/opal/browser/lib/browser/json.rb +0 -32
- data/opals/opal/browser/lib/browser/request/request.rb +0 -201
- data/opals/opal/browser/lib/browser/sizzle.js +0 -1068
- data/opals/opal/browser/lib/browser/string.rb +0 -42
- data/opals/opal/browser/lib/browser/touch.rb +0 -37
- data/opals/opal/browser/lib/browser/vml_context.js +0 -33
- data/opals/opal/browser/lib/browser/window.rb +0 -36
- data/opals/opal/browser/spec/browser/browser_detection_spec.rb +0 -7
- data/opals/opal/browser/spec/document/aref_spec.rb +0 -110
- data/opals/opal/browser/spec/document/ready_spec.rb +0 -16
- data/opals/opal/browser/spec/element/body_spec.rb +0 -11
- data/opals/opal/browser/spec/element/clear_spec.rb +0 -26
- data/opals/opal/browser/spec/element/empty_spec.rb +0 -29
- data/opals/opal/browser/spec/element/has_class_spec.rb +0 -40
- data/opals/opal/browser/spec/element/hidden_spec.rb +0 -23
- data/opals/opal/browser/spec/element/hide_spec.rb +0 -31
- data/opals/opal/browser/spec/element/remove_spec.rb +0 -25
- data/opals/opal/browser/spec/element/show_spec.rb +0 -31
- data/opals/opal/browser/spec/element/style_spec.rb +0 -69
- data/opals/opal/browser/spec/element/toggle_spec.rb +0 -31
- data/opals/opal/browser/spec/element/visible_spec.rb +0 -23
- data/opals/opal/browser/spec/spec_helper.rb +0 -1
- data/opals/opal/opal/Opalfile +0 -14
- data/opals/opal/opal/spec/core/array/compact_spec.rb +0 -15
- data/opals/opal/opal/spec/fixtures/super.rb +0 -70
- data/opals/opal/opal/spec/language/____temp_remove_this.rb +0 -12
- data/opals/opal/opal/spec/language/block_spec.rb +0 -18
- data/opals/opal/opal/spec/language/case_spec.rb +0 -103
- data/opals/opal/opal/spec/language/metaclass_spec.rb +0 -21
- data/opals/opal/opal/spec/language/super_spec.rb +0 -26
- data/opals/opal/runtime/Opalfile +0 -78
- data/opals/opal/runtime/README.md +0 -12
- data/opals/opal/runtime/docs/debugging.md +0 -51
- data/opals/opal/runtime/lib/array.rb +0 -1516
- data/opals/opal/runtime/lib/basic_object.rb +0 -49
- data/opals/opal/runtime/lib/class.rb +0 -54
- data/opals/opal/runtime/lib/dir.rb +0 -36
- data/opals/opal/runtime/lib/error.rb +0 -49
- data/opals/opal/runtime/lib/false_class.rb +0 -52
- data/opals/opal/runtime/lib/file.rb +0 -79
- data/opals/opal/runtime/lib/hash.rb +0 -791
- data/opals/opal/runtime/lib/io.rb +0 -39
- data/opals/opal/runtime/lib/kernel.rb +0 -288
- data/opals/opal/runtime/lib/match_data.rb +0 -36
- data/opals/opal/runtime/lib/module.rb +0 -109
- data/opals/opal/runtime/lib/nil_class.rb +0 -69
- data/opals/opal/runtime/lib/number.rb +0 -398
- data/opals/opal/runtime/lib/proc.rb +0 -77
- data/opals/opal/runtime/lib/range.rb +0 -63
- data/opals/opal/runtime/lib/regexp.rb +0 -111
- data/opals/opal/runtime/lib/ruby.rb +0 -30
- data/opals/opal/runtime/lib/string.rb +0 -328
- data/opals/opal/runtime/lib/symbol.rb +0 -40
- data/opals/opal/runtime/lib/top_self.rb +0 -33
- data/opals/opal/runtime/lib/true_class.rb +0 -45
- data/opals/opal/runtime/runtime/browser.js +0 -287
- data/opals/opal/runtime/runtime/debug.js +0 -180
- data/opals/opal/runtime/runtime/opal.js +0 -1008
- data/opals/opal/runtime/runtime/post_opal.js +0 -1
- data/opals/opal/runtime/runtime/pre_opal.js +0 -2
- data/opals/opal/runtime/runtime/server_side.js +0 -50
- data/opals/opal/spec/LICENSE.txt +0 -26
- data/opals/opal/spec/Opalfile +0 -5
- data/opals/opal/spec/bin/spec.rb +0 -43
- data/opals/opal/spec/lib/spec.rb +0 -33
- data/opals/opal/spec/lib/spec/dsl.rb +0 -41
- data/opals/opal/spec/lib/spec/example.rb +0 -35
- data/opals/opal/spec/lib/spec/example/before_and_after_hooks.rb +0 -81
- data/opals/opal/spec/lib/spec/example/errors.rb +0 -42
- data/opals/opal/spec/lib/spec/example/example_group.rb +0 -37
- data/opals/opal/spec/lib/spec/example/example_group_factory.rb +0 -43
- data/opals/opal/spec/lib/spec/example/example_group_hierarchy.rb +0 -45
- data/opals/opal/spec/lib/spec/example/example_group_proxy.rb +0 -41
- data/opals/opal/spec/lib/spec/example/example_methods.rb +0 -73
- data/opals/opal/spec/lib/spec/example/example_proxy.rb +0 -48
- data/opals/opal/spec/lib/spec/expectations.rb +0 -46
- data/opals/opal/spec/lib/spec/expectations/errors.rb +0 -35
- data/opals/opal/spec/lib/spec/expectations/fail_with.rb +0 -37
- data/opals/opal/spec/lib/spec/expectations/handler.rb +0 -48
- data/opals/opal/spec/lib/spec/matchers.rb +0 -50
- data/opals/opal/spec/lib/spec/matchers/be.rb +0 -26
- data/opals/opal/spec/lib/spec/matchers/generated_descriptions.rb +0 -47
- data/opals/opal/spec/lib/spec/matchers/operator_matcher.rb +0 -66
- data/opals/opal/spec/lib/spec/runner.rb +0 -48
- data/opals/opal/spec/lib/spec/runner/example_group_runner.rb +0 -71
- data/opals/opal/spec/lib/spec/runner/formatter/terminal_formatter.rb +0 -82
- data/opals/opal/spec/lib/spec/runner/options.rb +0 -63
- data/opals/opal/spec/resources/index.html +0 -25
- data/opals/opal/spec/resources/spec.css +0 -132
- data/spec/cherry_kit/iseq_spec.rb +0 -38
- data/spec/spec_helper.rb +0 -16
- data/spec/vienna_spec.rb +0 -7
- data/yard/index.html +0 -43
- data/yard/style.css +0 -765
|
@@ -1,1851 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# generate.rb
|
|
3
|
-
# vienna
|
|
4
|
-
#
|
|
5
|
-
# Created by Adam Beynon.
|
|
6
|
-
# Copyright 2009 Adam Beynon.
|
|
7
|
-
#
|
|
8
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
10
|
-
# in the Software without restriction, including without limitation the rights
|
|
11
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
13
|
-
# furnished to do so, subject to the following conditions:
|
|
14
|
-
#
|
|
15
|
-
# The above copyright notice and this permission notice shall be included in
|
|
16
|
-
# all copies or substantial portions of the Software.
|
|
17
|
-
#
|
|
18
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
24
|
-
# THE SOFTWARE.
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
require File.join(File.dirname(__FILE__), 'ruby_parser.rb')
|
|
28
|
-
|
|
29
|
-
module Vienna
|
|
30
|
-
|
|
31
|
-
class RubyParser < ::Racc::Parser
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# ISEQ types
|
|
35
|
-
ISEQ_TYPE_TOP = 1
|
|
36
|
-
ISEQ_TYPE_METHOD = 2
|
|
37
|
-
ISEQ_TYPE_BLOCK = 3
|
|
38
|
-
ISEQ_TYPE_CLASS = 4
|
|
39
|
-
ISEQ_TYPE_RESCUE = 5
|
|
40
|
-
ISEQ_TYPE_ENSURE = 6
|
|
41
|
-
ISEQ_TYPE_EVAL = 7
|
|
42
|
-
ISEQ_TYPE_MAIN = 8
|
|
43
|
-
# opt args etc use this
|
|
44
|
-
ISEQ_TYPE_TEMP = 9
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# Generate any type of statement with the given options
|
|
49
|
-
#
|
|
50
|
-
def generate_stmt stmt, context
|
|
51
|
-
return if stmt.is_a?(Array)
|
|
52
|
-
# puts stmt
|
|
53
|
-
case stmt.node
|
|
54
|
-
when :klass
|
|
55
|
-
generate_class stmt, context
|
|
56
|
-
when :module
|
|
57
|
-
generate_module stmt, context
|
|
58
|
-
when :class_shift
|
|
59
|
-
generate_class_shift stmt, context
|
|
60
|
-
when :def
|
|
61
|
-
generate_def stmt, context
|
|
62
|
-
when :numeric
|
|
63
|
-
generate_numeric stmt, context
|
|
64
|
-
when :call
|
|
65
|
-
generate_call stmt, context
|
|
66
|
-
when :super
|
|
67
|
-
generate_super stmt, context
|
|
68
|
-
when :identifier
|
|
69
|
-
generate_identifier stmt, context
|
|
70
|
-
when :ivar
|
|
71
|
-
generate_ivar stmt, context
|
|
72
|
-
when :cvar
|
|
73
|
-
generate_cvar stmt, context
|
|
74
|
-
when :constant
|
|
75
|
-
generate_constant stmt, context
|
|
76
|
-
when :symbol
|
|
77
|
-
generate_symbol stmt, context
|
|
78
|
-
when :self
|
|
79
|
-
generate_self stmt, context
|
|
80
|
-
when :true
|
|
81
|
-
generate_true stmt, context
|
|
82
|
-
when :false
|
|
83
|
-
generate_false stmt, context
|
|
84
|
-
when :nil
|
|
85
|
-
generate_nil stmt, context
|
|
86
|
-
when :if
|
|
87
|
-
generate_if stmt, context
|
|
88
|
-
when :unless
|
|
89
|
-
generate_if stmt, context
|
|
90
|
-
# when :if_mod
|
|
91
|
-
# generate_if_mod stmt, context
|
|
92
|
-
# when :unless_mod
|
|
93
|
-
# generate_if_mod stmt, context
|
|
94
|
-
when :string
|
|
95
|
-
generate_string stmt, context
|
|
96
|
-
when :xstring
|
|
97
|
-
generate_xstring stmt, context
|
|
98
|
-
when :array
|
|
99
|
-
generate_array stmt, context
|
|
100
|
-
when :assign
|
|
101
|
-
generate_assign stmt, context
|
|
102
|
-
when :assoc_list
|
|
103
|
-
generate_assoc_list stmt, context
|
|
104
|
-
when :op_asgn
|
|
105
|
-
generate_op_asgn stmt, context
|
|
106
|
-
when :lparen
|
|
107
|
-
generate_lparen stmt, context
|
|
108
|
-
when :return
|
|
109
|
-
generate_return stmt, context
|
|
110
|
-
when :break
|
|
111
|
-
generate_break stmt, context
|
|
112
|
-
when :colon2
|
|
113
|
-
generate_colon2 stmt, context
|
|
114
|
-
when :colon3
|
|
115
|
-
generate_colon3 stmt, context
|
|
116
|
-
when :case
|
|
117
|
-
generate_case stmt, context
|
|
118
|
-
when :yield
|
|
119
|
-
generate_yield stmt, context
|
|
120
|
-
when :orop
|
|
121
|
-
generate_orop stmt, context
|
|
122
|
-
when :andop
|
|
123
|
-
generate_andop stmt, context
|
|
124
|
-
when :not
|
|
125
|
-
generate_not stmt, context
|
|
126
|
-
when :tertiary
|
|
127
|
-
generate_tertiary stmt, context
|
|
128
|
-
when :dot2
|
|
129
|
-
generate_dot2 stmt, context
|
|
130
|
-
when :dot3
|
|
131
|
-
generate_dot3 stmt, context
|
|
132
|
-
when :__FILE__
|
|
133
|
-
generate__FILE__ stmt, context
|
|
134
|
-
when :__LINE__
|
|
135
|
-
generate__LINE__ stmt, context
|
|
136
|
-
when :opt_plus
|
|
137
|
-
generate_opt_plus stmt, context
|
|
138
|
-
when :opt_minus
|
|
139
|
-
generate_opt_minus stmt, context
|
|
140
|
-
when :opt_mult
|
|
141
|
-
generate_opt_mult stmt, context
|
|
142
|
-
when :opt_div
|
|
143
|
-
generate_opt_div stmt, context
|
|
144
|
-
when :opt_mod
|
|
145
|
-
generate_opt_mod stmt, context
|
|
146
|
-
when :block_given
|
|
147
|
-
generate_block_given stmt, context
|
|
148
|
-
when :regexp
|
|
149
|
-
generate_regexp stmt, context
|
|
150
|
-
when :alias
|
|
151
|
-
generate_alias stmt, context
|
|
152
|
-
when :begin
|
|
153
|
-
generate_begin stmt, context
|
|
154
|
-
when :aset_op_asgn
|
|
155
|
-
generate_aset_op_asgn stmt, context
|
|
156
|
-
when :gvar
|
|
157
|
-
generate_gvar stmt, context
|
|
158
|
-
when :while
|
|
159
|
-
generate_while stmt, context
|
|
160
|
-
when :until
|
|
161
|
-
generate_while stmt, context
|
|
162
|
-
when :lambda
|
|
163
|
-
generate_lambda stmt, context
|
|
164
|
-
when :words
|
|
165
|
-
generate_words stmt, context
|
|
166
|
-
when :next
|
|
167
|
-
generate_next stmt, context
|
|
168
|
-
when :redo
|
|
169
|
-
generate_redo stmt, context
|
|
170
|
-
else
|
|
171
|
-
write "\n[Unknown type for generate_stmt: #{stmt.inspect}]\n"
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
class Iseq
|
|
176
|
-
|
|
177
|
-
attr_accessor :type, :local_current
|
|
178
|
-
|
|
179
|
-
def initialize(type)
|
|
180
|
-
@type = type
|
|
181
|
-
# names => minimized names
|
|
182
|
-
@locals = { }
|
|
183
|
-
# arg name => minimized arg names
|
|
184
|
-
@args = { }
|
|
185
|
-
# arg types/names - these are all ordered
|
|
186
|
-
@norm_arg_names = []
|
|
187
|
-
@opt_arg_names = []
|
|
188
|
-
@rest_arg_name = nil
|
|
189
|
-
@post_arg_names = []
|
|
190
|
-
@block_arg_name = nil
|
|
191
|
-
|
|
192
|
-
@parent_iseq = nil
|
|
193
|
-
|
|
194
|
-
@opt_arg_str = {}
|
|
195
|
-
|
|
196
|
-
@local_current = "a"
|
|
197
|
-
|
|
198
|
-
@code = []
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
@should_handle_return = false
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
def method_id=(method_id)
|
|
205
|
-
@method_id = method_id
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
def method_id
|
|
209
|
-
if @method_id
|
|
210
|
-
@method_id
|
|
211
|
-
elsif @parent_iseq
|
|
212
|
-
@parent_iseq.method_id
|
|
213
|
-
else
|
|
214
|
-
nil
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
def new_temp_variable
|
|
219
|
-
id = "$#{@local_current}"
|
|
220
|
-
@local_current = @local_current.next
|
|
221
|
-
@locals[id] = id
|
|
222
|
-
id
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
# push "normal" arg name
|
|
226
|
-
def push_arg_name(name)
|
|
227
|
-
# id = @local_current
|
|
228
|
-
# @local_current = @local_current.next
|
|
229
|
-
# @args[name] = "_#{id}"
|
|
230
|
-
# @norm_arg_names.push name
|
|
231
|
-
# "_#{id}"
|
|
232
|
-
@args[name] = name
|
|
233
|
-
@norm_arg_names.push name
|
|
234
|
-
name
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
# push optional arg name, with the node for its default value
|
|
238
|
-
#
|
|
239
|
-
# ['a', ""] <- for example
|
|
240
|
-
def push_opt_arg(name, str)
|
|
241
|
-
# name = arg[0]
|
|
242
|
-
@args[name] = name
|
|
243
|
-
@opt_arg_names.push name
|
|
244
|
-
@opt_arg_str[name] = str
|
|
245
|
-
name
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
# push rest arg name
|
|
249
|
-
def push_rest_arg_name(name)
|
|
250
|
-
# id = @local_current
|
|
251
|
-
# @local_current = @local_current.next
|
|
252
|
-
@args[name] = name
|
|
253
|
-
@rest_arg_name = name
|
|
254
|
-
name
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
# post (notmal args at end) names
|
|
258
|
-
def push_post_arg_name(name)
|
|
259
|
-
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
# block.. not actually added to function
|
|
263
|
-
def push_block_arg_name(name)
|
|
264
|
-
@block_arg_name = name
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def block_arg_name
|
|
268
|
-
@block_arg_name ||= '__block__'
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
def push_local_name(name)
|
|
272
|
-
# id = @local_current
|
|
273
|
-
# @local_current = @local_current.next
|
|
274
|
-
# @locals[name] = "_#{id}"
|
|
275
|
-
# "_#{id}"
|
|
276
|
-
@locals[name] = name
|
|
277
|
-
name
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
def lookup_local(name)
|
|
281
|
-
return nil if name == nil
|
|
282
|
-
if @locals.has_key?(name)
|
|
283
|
-
@locals[name]
|
|
284
|
-
elsif @args.has_key?(name)
|
|
285
|
-
@args[name]
|
|
286
|
-
elsif @block_arg_name == name
|
|
287
|
-
"__block__"
|
|
288
|
-
elsif @type == RubyParser::ISEQ_TYPE_BLOCK
|
|
289
|
-
@parent_iseq.lookup_local(name)
|
|
290
|
-
else
|
|
291
|
-
nil
|
|
292
|
-
end
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
def parent_iseq=(other)
|
|
296
|
-
@parent_iseq = other
|
|
297
|
-
|
|
298
|
-
if @type == RubyParser::ISEQ_TYPE_BLOCK
|
|
299
|
-
# @local_current = other.local_current
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
def tell_method_to_handle_return
|
|
304
|
-
if @type == RubyParser::ISEQ_TYPE_METHOD
|
|
305
|
-
@should_handle_return = true
|
|
306
|
-
elsif @parent_iseq
|
|
307
|
-
@parent_iseq.tell_method_to_handle_return
|
|
308
|
-
else
|
|
309
|
-
# should we throw error? return isnt in right place..?
|
|
310
|
-
end
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
def parent_iseq
|
|
314
|
-
@parent_iseq
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
def finalize
|
|
318
|
-
if @type == RubyParser::ISEQ_TYPE_BLOCK
|
|
319
|
-
# @parent_iseq.local_current = @local_current
|
|
320
|
-
end
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
def write(str)
|
|
324
|
-
@code << str
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
# r is array to append strings for outputting
|
|
328
|
-
def deal_with_method_args(r)
|
|
329
|
-
r << "function("
|
|
330
|
-
|
|
331
|
-
norm = @norm_arg_names.length
|
|
332
|
-
opt = @opt_arg_names.length
|
|
333
|
-
post = @post_arg_names.length
|
|
334
|
-
rest = @rest_arg_name
|
|
335
|
-
|
|
336
|
-
# Case 1: no args at all (block is dealt with seperately) - def a()
|
|
337
|
-
if norm == 0 && opt == 0 && post == 0 && rest.nil?
|
|
338
|
-
r << "){"
|
|
339
|
-
|
|
340
|
-
if RubyParser::ISEQ_TYPE_METHOD === @type || RubyParser::ISEQ_TYPE_BLOCK === @type
|
|
341
|
-
# r << "var self = this;"
|
|
342
|
-
end
|
|
343
|
-
# block..
|
|
344
|
-
if @block_arg_name != nil
|
|
345
|
-
r << "if (arguments.length > 0 && arguments[0].info & this.TP) {"
|
|
346
|
-
r << " var __block__ = arguments[0];"
|
|
347
|
-
r << "}"
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
# Case 2: just splat args - def a(*args)
|
|
351
|
-
elsif norm == 0 && opt == 0 && post == 0 && rest
|
|
352
|
-
r << "#{@args[@rest_arg_name]}"
|
|
353
|
-
r << "){"
|
|
354
|
-
if RubyParser::ISEQ_TYPE_METHOD === @type || RubyParser::ISEQ_TYPE_BLOCK === @type
|
|
355
|
-
# r << "var self = this;"
|
|
356
|
-
end
|
|
357
|
-
# block..
|
|
358
|
-
if @block_arg_name
|
|
359
|
-
r << %Q|
|
|
360
|
-
if (arguments.length > 0 && arguments[0].info & this.TP) {
|
|
361
|
-
var __block__ = arguments[arguments.length - 1];
|
|
362
|
-
#{@args[@rest_arg_name]} = Array.prototype.slice.call(arguments, arguments.length -1);
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
#{@args[@rest_arg_name]} = Array.prototype.slice.call(arguments);
|
|
366
|
-
}|
|
|
367
|
-
else
|
|
368
|
-
r << %{#{@args[@rest_arg_name]}=Array.prototype.slice.call(arguments);}
|
|
369
|
-
end
|
|
370
|
-
|
|
371
|
-
# Case: one norm arg, rest splat args - def a(name, *args)
|
|
372
|
-
elsif norm == 1 && opt == 0 && post == 0 && rest
|
|
373
|
-
r << "#{@args[@norm_arg_names.first]}"
|
|
374
|
-
r << ",#{@args[@rest_arg_name]}"
|
|
375
|
-
r << "){"
|
|
376
|
-
if RubyParser::ISEQ_TYPE_METHOD === @type || RubyParser::ISEQ_TYPE_BLOCK === @type
|
|
377
|
-
# r << "var self = this;"
|
|
378
|
-
end
|
|
379
|
-
r << "#{@args[@norm_arg_names.first]}=arguments[0];"
|
|
380
|
-
r << %{#{@args[@rest_arg_name]}=Array.prototype.slice.call(arguments,1);}
|
|
381
|
-
|
|
382
|
-
# Case 3: just normal args (any number) - def a(l,m,n,o,p)
|
|
383
|
-
elsif norm > 0 && opt == 0 && post == 0 && rest.nil?
|
|
384
|
-
@norm_arg_names.each do |a|
|
|
385
|
-
r << "," unless a == @norm_arg_names.first
|
|
386
|
-
r << "#{@args[a]}"
|
|
387
|
-
end
|
|
388
|
-
r << "){"
|
|
389
|
-
if RubyParser::ISEQ_TYPE_METHOD === @type || RubyParser::ISEQ_TYPE_BLOCK === @type
|
|
390
|
-
# r << "var self = this;"
|
|
391
|
-
end
|
|
392
|
-
# block..
|
|
393
|
-
if @block_arg_name
|
|
394
|
-
length = @norm_arg_names.length
|
|
395
|
-
r << %Q|var __block__ =
|
|
396
|
-
(arguments[#{length}] && arguments[#{length}].info & this.TP)
|
|
397
|
-
? arguments[#{length}] : this.n;|
|
|
398
|
-
end
|
|
399
|
-
|
|
400
|
-
# Case: optional args, nothing else; def (a=1); end
|
|
401
|
-
elsif norm == 0 && opt > 0 && post == 0 && rest.nil?
|
|
402
|
-
@opt_arg_names.each do |arg|
|
|
403
|
-
r << arg
|
|
404
|
-
r << ", " unless @opt_arg_names.last == arg
|
|
405
|
-
end
|
|
406
|
-
r << "){"
|
|
407
|
-
@opt_arg_names.each do |arg|
|
|
408
|
-
r << "if (#{arg} == undefined) {"
|
|
409
|
-
r << " #{arg} = #{@opt_arg_str[arg]};"
|
|
410
|
-
r << "}"
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
if @block_arg_name
|
|
414
|
-
length = @opt_arg_names.length
|
|
415
|
-
r << %Q|var __block__ =
|
|
416
|
-
(arguments[#{length}] && arguments[#{length}].info & this.TP)
|
|
417
|
-
? arguments[#{length}] : this.n;|
|
|
418
|
-
end
|
|
419
|
-
|
|
420
|
-
# Case: some normal args, some optional, nothing else
|
|
421
|
-
elsif norm > 0 && opt > 0 && post == 0 && rest.nil?
|
|
422
|
-
@norm_arg_names.each do |a|
|
|
423
|
-
r << ', ' unless a == @norm_arg_names.first
|
|
424
|
-
r << @args[a]
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
@opt_arg_names.each do |arg|
|
|
428
|
-
r << ", "
|
|
429
|
-
r << arg
|
|
430
|
-
# write ", " unless
|
|
431
|
-
end
|
|
432
|
-
r << "){"
|
|
433
|
-
@opt_arg_names.each do |arg|
|
|
434
|
-
r << "if (#{arg} == undefined) {"
|
|
435
|
-
r << " #{arg} = #{@opt_arg_str[arg]};"
|
|
436
|
-
r << "}"
|
|
437
|
-
end
|
|
438
|
-
|
|
439
|
-
end
|
|
440
|
-
end
|
|
441
|
-
|
|
442
|
-
def to_s
|
|
443
|
-
r = ""
|
|
444
|
-
|
|
445
|
-
case @type
|
|
446
|
-
when RubyParser::ISEQ_TYPE_TOP
|
|
447
|
-
r << "(function(__FILE__){"
|
|
448
|
-
# locals
|
|
449
|
-
if @locals.length > 0
|
|
450
|
-
r << "var #{@locals.each_value.to_a.join(" = this.n,")} = this.n;"
|
|
451
|
-
end
|
|
452
|
-
r << @code.join("")
|
|
453
|
-
r << "})"
|
|
454
|
-
|
|
455
|
-
when RubyParser::ISEQ_TYPE_CLASS
|
|
456
|
-
r << "function(){"
|
|
457
|
-
|
|
458
|
-
# locals
|
|
459
|
-
if @locals.length > 0
|
|
460
|
-
r << "var #{@locals.each_value.to_a.join(" = this.n,")} = this.n;"
|
|
461
|
-
end
|
|
462
|
-
# code
|
|
463
|
-
r << @code.join("")
|
|
464
|
-
|
|
465
|
-
r << "}"
|
|
466
|
-
|
|
467
|
-
when RubyParser::ISEQ_TYPE_METHOD
|
|
468
|
-
|
|
469
|
-
deal_with_method_args(r)
|
|
470
|
-
|
|
471
|
-
# block arg name
|
|
472
|
-
if @block_arg_name != nil
|
|
473
|
-
# r << "var _ = opal_block; opal_block = nil;"
|
|
474
|
-
end
|
|
475
|
-
|
|
476
|
-
# see below
|
|
477
|
-
if @should_handle_return
|
|
478
|
-
r << "try {"
|
|
479
|
-
end
|
|
480
|
-
|
|
481
|
-
# locals
|
|
482
|
-
if @locals.length > 0
|
|
483
|
-
r << "var #{@locals.each_value.to_a.join(" = this.n,")} = this.n;"
|
|
484
|
-
end
|
|
485
|
-
# code
|
|
486
|
-
r << @code.join("")
|
|
487
|
-
|
|
488
|
-
# if we are a method, we might need to handle a block returning. In
|
|
489
|
-
# that case we will get it here in our method, and we simply need to
|
|
490
|
-
# return the return value...happy days. (rethrow error if its not what
|
|
491
|
-
# we need)
|
|
492
|
-
if @should_handle_return
|
|
493
|
-
r << "} catch(e) {"
|
|
494
|
-
r << "if (e.__keyword__ == 'return') {"
|
|
495
|
-
r << " return e.opal_value;"
|
|
496
|
-
r << "}"
|
|
497
|
-
r << "throw e;"
|
|
498
|
-
r << "}"
|
|
499
|
-
|
|
500
|
-
end
|
|
501
|
-
|
|
502
|
-
# always return nil as worst case scenario (should never get here?)
|
|
503
|
-
# r << "return #{NIL};"
|
|
504
|
-
r << "}"
|
|
505
|
-
|
|
506
|
-
when RubyParser::ISEQ_TYPE_BLOCK
|
|
507
|
-
r << "this.P("
|
|
508
|
-
deal_with_method_args(r)
|
|
509
|
-
|
|
510
|
-
# r << "if (arguments.callee.opal_self) {"
|
|
511
|
-
# r << " var __old_self__ = self;"
|
|
512
|
-
# r << " self = this;"
|
|
513
|
-
# r << "}"
|
|
514
|
-
|
|
515
|
-
# r << "var res = (function() {"
|
|
516
|
-
|
|
517
|
-
# locals
|
|
518
|
-
if @locals.length > 0
|
|
519
|
-
r << "var #{@locals.each_value.to_a.join(" = this.n,")} = this.n;"
|
|
520
|
-
end
|
|
521
|
-
# WTF? this should take "var $=$$;" but we get errors...huh!?!?
|
|
522
|
-
# r << "if($$!=nil){var$=$$;}"
|
|
523
|
-
# this seems to be the easiest way to do it, but its hela ugly
|
|
524
|
-
# r << "with({$:($$==nil?$:$$),_:(__==nil?_:__)}){"
|
|
525
|
-
r << @code.join("")
|
|
526
|
-
|
|
527
|
-
# r << "})();"
|
|
528
|
-
|
|
529
|
-
# r << "if (arguments.callee.opal_self) {"
|
|
530
|
-
# r << " self = __old_self__;"
|
|
531
|
-
# r << "}"
|
|
532
|
-
|
|
533
|
-
# r << "return res;"
|
|
534
|
-
|
|
535
|
-
r << "})"
|
|
536
|
-
|
|
537
|
-
when RubyParser::ISEQ_TYPE_TEMP
|
|
538
|
-
r << @code.join("")
|
|
539
|
-
end
|
|
540
|
-
r
|
|
541
|
-
end
|
|
542
|
-
|
|
543
|
-
end
|
|
544
|
-
|
|
545
|
-
# An optional argument iseq used for generating just the code for an optioan
|
|
546
|
-
# argument. This code is stored, then later used as/if needed. Basically,
|
|
547
|
-
# has a write method that self contains the code.
|
|
548
|
-
#
|
|
549
|
-
class OptionalArgumentIseq
|
|
550
|
-
|
|
551
|
-
end
|
|
552
|
-
|
|
553
|
-
def write(str)
|
|
554
|
-
@iseq_current.write str
|
|
555
|
-
end
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
# Convert ruby style id to js property id - everything is prepended a '$'
|
|
559
|
-
# This method is used also for generating call method strings. For this
|
|
560
|
-
# reason, the method looks at the method name for any non a-z characters
|
|
561
|
-
# which will mean that we cannot use a safe js name. For example, setter
|
|
562
|
-
# methods need to be wrapped =>
|
|
563
|
-
#
|
|
564
|
-
# self.something = 10
|
|
565
|
-
# # => self['$something='](10).
|
|
566
|
-
#
|
|
567
|
-
# We no longer just replace '=' with '$e' etc as this slows down the runtime
|
|
568
|
-
# when looking through methods, and using __send__() etc.
|
|
569
|
-
#
|
|
570
|
-
def mid_to_jsid(mid)
|
|
571
|
-
# everything needs to be prepended with '$'
|
|
572
|
-
mid = "$#{mid}"
|
|
573
|
-
|
|
574
|
-
if /[\!\=\?\+\-\*\/\^\&\%\@\|\[\]\<\>\~]/.match mid
|
|
575
|
-
# special characters, so we must wrap in []
|
|
576
|
-
"['#{mid}']"
|
|
577
|
-
else
|
|
578
|
-
# no special characters, so we can just return .mid
|
|
579
|
-
".#{mid}"
|
|
580
|
-
end
|
|
581
|
-
# "$#{mid}".
|
|
582
|
-
# gsub(/\!/, "$b").
|
|
583
|
-
# gsub(/\=/, "$e").
|
|
584
|
-
# gsub(/\?/, "$q").
|
|
585
|
-
# gsub(/\+/, "$p").
|
|
586
|
-
# gsub(/\-/, "$m").
|
|
587
|
-
# gsub(/\|/, '$r').
|
|
588
|
-
# gsub(/\&/, "$a").
|
|
589
|
-
# gsub(/\</, "$l").
|
|
590
|
-
# gsub(/\>/, "$g").
|
|
591
|
-
# gsub(/\[/, "$z").
|
|
592
|
-
# gsub(/\]/, "$x").
|
|
593
|
-
# gsub(/\//, "$d").
|
|
594
|
-
# gsub(/\*/, "$t").
|
|
595
|
-
# gsub(/\@/, "$a").
|
|
596
|
-
# gsub(/\^/, "$o")
|
|
597
|
-
end
|
|
598
|
-
|
|
599
|
-
def generate_tree(tree)
|
|
600
|
-
top_iseq = iseq_stack_push(ISEQ_TYPE_TOP)
|
|
601
|
-
tree.each do |stmt|
|
|
602
|
-
generate_stmt stmt, :full_stmt => true, :last_stmt => tree.last == stmt
|
|
603
|
-
end
|
|
604
|
-
iseq_stack_pop
|
|
605
|
-
end
|
|
606
|
-
|
|
607
|
-
def iseq_stack_push type
|
|
608
|
-
@iseq_current = Iseq.new type
|
|
609
|
-
@iseq_stack << @iseq_current
|
|
610
|
-
@iseq_current
|
|
611
|
-
end
|
|
612
|
-
|
|
613
|
-
def iseq_stack_pop
|
|
614
|
-
iseq = @iseq_stack.last
|
|
615
|
-
@iseq_stack.pop
|
|
616
|
-
@iseq_current = @iseq_stack.last
|
|
617
|
-
# finalize (var locals etc)
|
|
618
|
-
iseq.finalize
|
|
619
|
-
iseq.to_s
|
|
620
|
-
end
|
|
621
|
-
|
|
622
|
-
def generate_class(cls, context)
|
|
623
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
624
|
-
|
|
625
|
-
current_iseq = @iseq_current
|
|
626
|
-
class_iseq = iseq_stack_push(ISEQ_TYPE_CLASS)
|
|
627
|
-
class_iseq.parent_iseq = current_iseq
|
|
628
|
-
|
|
629
|
-
# do each bodystmt
|
|
630
|
-
cls.bodystmt[:compstmt].each do |b|
|
|
631
|
-
generate_stmt b, :full_stmt => true, :last_stmt => b == cls.bodystmt[:compstmt].last
|
|
632
|
-
end
|
|
633
|
-
|
|
634
|
-
write "return nil;" if cls.bodystmt.length == 0
|
|
635
|
-
|
|
636
|
-
iseq_stack_pop
|
|
637
|
-
|
|
638
|
-
write "#{SELF}.define_class("
|
|
639
|
-
# superclass
|
|
640
|
-
if cls.super_klass
|
|
641
|
-
generate_stmt cls.super_klass[:expr], :full_stmt => false
|
|
642
|
-
else
|
|
643
|
-
write "#{NIL}"
|
|
644
|
-
end
|
|
645
|
-
write %{,"#{cls.klass_name}",#{class_iseq},0)}
|
|
646
|
-
|
|
647
|
-
write ";\n" if context[:full_stmt]
|
|
648
|
-
end
|
|
649
|
-
|
|
650
|
-
def generate_module(cls, context)
|
|
651
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
652
|
-
|
|
653
|
-
current_iseq = @iseq_current
|
|
654
|
-
class_iseq = iseq_stack_push(ISEQ_TYPE_CLASS)
|
|
655
|
-
class_iseq.parent_iseq = current_iseq
|
|
656
|
-
|
|
657
|
-
# do each bodystmt
|
|
658
|
-
cls.bodystmt[:compstmt].each do |b|
|
|
659
|
-
generate_stmt b, :full_stmt => true, :last_stmt => b == cls.bodystmt[:compstmt].last
|
|
660
|
-
end
|
|
661
|
-
|
|
662
|
-
write "return nil;" if cls.bodystmt.length == 0
|
|
663
|
-
|
|
664
|
-
iseq_stack_pop
|
|
665
|
-
|
|
666
|
-
write "#{SELF}.define_class(#{NIL},'#{cls.klass_name}',#{class_iseq},2)"
|
|
667
|
-
|
|
668
|
-
# write "vm$e($,"
|
|
669
|
-
# superclass - always nil for module
|
|
670
|
-
# write "nil"
|
|
671
|
-
# write %{,"#{cls.klass_name}",#{class_iseq},2)}
|
|
672
|
-
|
|
673
|
-
write ";\n" if context[:full_stmt]
|
|
674
|
-
end
|
|
675
|
-
|
|
676
|
-
def generate_class_shift(cls, context)
|
|
677
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
678
|
-
|
|
679
|
-
current_iseq = @iseq_current
|
|
680
|
-
class_iseq = iseq_stack_push(ISEQ_TYPE_CLASS)
|
|
681
|
-
class_iseq.parent_iseq = current_iseq
|
|
682
|
-
|
|
683
|
-
# each bodystmt
|
|
684
|
-
cls[:bodystmt][:compstmt].each do |b|
|
|
685
|
-
generate_stmt b, :full_stmt => true, :last_stmt => b == cls[:bodystmt][:compstmt].last
|
|
686
|
-
end
|
|
687
|
-
|
|
688
|
-
write "return nil" if cls[:bodystmt][:compstmt].length == 0
|
|
689
|
-
|
|
690
|
-
iseq_stack_pop
|
|
691
|
-
|
|
692
|
-
write "#{SELF}.define_class(#{NIL},"
|
|
693
|
-
|
|
694
|
-
generate_stmt cls[:expr], :full_stmt => false
|
|
695
|
-
write ",#{class_iseq},1)"
|
|
696
|
-
|
|
697
|
-
write ";\n" if context[:full_stmt]
|
|
698
|
-
end
|
|
699
|
-
|
|
700
|
-
def generate_def(stmt, context)
|
|
701
|
-
# if stmt[:bodystmt][:opt_rescue]
|
|
702
|
-
# puts "a"
|
|
703
|
-
# end
|
|
704
|
-
# if stmt[:fname] == "execute"
|
|
705
|
-
# pp stmt[:bodystmt]
|
|
706
|
-
# end
|
|
707
|
-
# if stmt[:bodystmt].vn_opt_rescue
|
|
708
|
-
# puts stmt[:bodystmt].vn_opt_rescue
|
|
709
|
-
# end
|
|
710
|
-
# puts stmt
|
|
711
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
712
|
-
|
|
713
|
-
is_singleton = stmt[:singleton] ? 'true' : 'false'
|
|
714
|
-
|
|
715
|
-
current_iseq = @iseq_current
|
|
716
|
-
def_iseq = iseq_stack_push(ISEQ_TYPE_METHOD)
|
|
717
|
-
def_iseq.parent_iseq = current_iseq
|
|
718
|
-
def_iseq.method_id = stmt[:fname]
|
|
719
|
-
|
|
720
|
-
# normal args
|
|
721
|
-
if stmt[:arglist].arg
|
|
722
|
-
stmt[:arglist].arg.each do |arg|
|
|
723
|
-
@iseq_current.push_arg_name arg[:value]
|
|
724
|
-
end
|
|
725
|
-
end
|
|
726
|
-
|
|
727
|
-
# opt args
|
|
728
|
-
if stmt[:arglist].opt
|
|
729
|
-
stmt[:arglist].opt.each do |opt|
|
|
730
|
-
opt_current_iseq = @iseq_current
|
|
731
|
-
opt_iseq = iseq_stack_push(ISEQ_TYPE_TEMP)
|
|
732
|
-
generate_stmt opt[1], {}
|
|
733
|
-
iseq_stack_pop
|
|
734
|
-
# puts "need to generate op: #{opt}"
|
|
735
|
-
@iseq_current.push_opt_arg opt[0], opt_iseq.to_s
|
|
736
|
-
end
|
|
737
|
-
# puts "opt args:"
|
|
738
|
-
# puts stmt[:arglist].opt
|
|
739
|
-
# puts "---------"
|
|
740
|
-
end
|
|
741
|
-
|
|
742
|
-
# rest args
|
|
743
|
-
if stmt[:arglist].rest
|
|
744
|
-
@iseq_current.push_rest_arg_name stmt[:arglist].rest
|
|
745
|
-
end
|
|
746
|
-
|
|
747
|
-
# block name..
|
|
748
|
-
if stmt[:arglist].block
|
|
749
|
-
@iseq_current.push_block_arg_name(stmt[:arglist].block)
|
|
750
|
-
end
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
# body statements
|
|
754
|
-
if stmt[:bodystmt][:compstmt].length > 0
|
|
755
|
-
stmt[:bodystmt][:compstmt].each do |s|
|
|
756
|
-
generate_stmt s, :full_stmt => true, :last_stmt => stmt[:bodystmt][:compstmt].last == s
|
|
757
|
-
end
|
|
758
|
-
else
|
|
759
|
-
# no bodystmts, return nil be default
|
|
760
|
-
write "return #{NIL};"
|
|
761
|
-
end
|
|
762
|
-
iseq_stack_pop
|
|
763
|
-
|
|
764
|
-
# define method
|
|
765
|
-
|
|
766
|
-
# base.. singleton or self
|
|
767
|
-
if stmt[:singleton]
|
|
768
|
-
generate_stmt stmt[:singleton], :full_stmt => false, :last_stmt => false
|
|
769
|
-
write ".dm("
|
|
770
|
-
else
|
|
771
|
-
write "#{SELF}.dm("
|
|
772
|
-
end
|
|
773
|
-
|
|
774
|
-
# FIXME: only write line in debug mode!
|
|
775
|
-
write %{"#{stmt[:fname]}",#{def_iseq},#{is_singleton}, #{stmt[:line_number]})}
|
|
776
|
-
write ";\n" if context[:full_stmt]
|
|
777
|
-
end
|
|
778
|
-
|
|
779
|
-
def generate_identifier(stmt, context)
|
|
780
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
781
|
-
local = @iseq_current.lookup_local(stmt[:name])
|
|
782
|
-
if local
|
|
783
|
-
write local
|
|
784
|
-
else
|
|
785
|
-
# write %{vm$a($,"#{stmt[:name]}",[],nil,8)}
|
|
786
|
-
write "#{SELF}#{mid_to_jsid(stmt[:name])}()"
|
|
787
|
-
end
|
|
788
|
-
|
|
789
|
-
write ";\n" if context[:full_stmt]
|
|
790
|
-
end
|
|
791
|
-
|
|
792
|
-
def generate_call(call, context)
|
|
793
|
-
used_param = false
|
|
794
|
-
|
|
795
|
-
if context[:full_stmt] and context[:last_stmt]
|
|
796
|
-
# go all the way back to original recv
|
|
797
|
-
original_recv = call
|
|
798
|
-
|
|
799
|
-
while original_recv[:recv]
|
|
800
|
-
original_recv = original_recv[:recv]
|
|
801
|
-
end
|
|
802
|
-
|
|
803
|
-
# should we "donate" the return statement (need to for case, if, unless)
|
|
804
|
-
|
|
805
|
-
if [:case, :if, :unless].include? original_recv.node
|
|
806
|
-
original_recv[:donate_recv] = true
|
|
807
|
-
else
|
|
808
|
-
write "return "
|
|
809
|
-
end
|
|
810
|
-
end
|
|
811
|
-
|
|
812
|
-
# write "vm$a("
|
|
813
|
-
# receiver
|
|
814
|
-
if call[:recv]
|
|
815
|
-
call_bit = 0
|
|
816
|
-
generate_stmt call[:recv], :recv => true
|
|
817
|
-
else
|
|
818
|
-
call_bit = 8
|
|
819
|
-
# self as recv
|
|
820
|
-
write "#{SELF}"
|
|
821
|
-
end
|
|
822
|
-
|
|
823
|
-
# method id
|
|
824
|
-
write %{#{mid_to_jsid(call[:meth])}(}
|
|
825
|
-
|
|
826
|
-
# normal args - need to check for splats
|
|
827
|
-
is_splat = false
|
|
828
|
-
unless call[:call_args].nil? or call[:call_args][:args].nil?
|
|
829
|
-
call[:call_args][:args].each do |arg|
|
|
830
|
-
is_splat = true if arg.node == :splat
|
|
831
|
-
end
|
|
832
|
-
end
|
|
833
|
-
|
|
834
|
-
if is_splat
|
|
835
|
-
write "(function(){"
|
|
836
|
-
write "var a=[],b=nil;"
|
|
837
|
-
call[:call_args][:args].each do |arg|
|
|
838
|
-
# puts arg
|
|
839
|
-
if arg.node == :splat
|
|
840
|
-
write "b = "
|
|
841
|
-
generate_stmt arg[:val], :full_stmt => false
|
|
842
|
-
write ";"
|
|
843
|
-
write "for(var i = 0; i < b.length; i++){"
|
|
844
|
-
write "a.push(b[i]);"
|
|
845
|
-
write "};"
|
|
846
|
-
else
|
|
847
|
-
write "a.push("
|
|
848
|
-
generate_stmt arg, :full_stmt => false
|
|
849
|
-
write ");"
|
|
850
|
-
end
|
|
851
|
-
end
|
|
852
|
-
write "return a;})()"
|
|
853
|
-
else
|
|
854
|
-
# write "["
|
|
855
|
-
unless call[:call_args].nil? or call[:call_args][:args].nil?
|
|
856
|
-
call[:call_args][:args].each do |arg|
|
|
857
|
-
used_param = true
|
|
858
|
-
write "," unless call[:call_args][:args].first == arg
|
|
859
|
-
generate_stmt arg, :full_stmt => false
|
|
860
|
-
end
|
|
861
|
-
end
|
|
862
|
-
|
|
863
|
-
# assocs
|
|
864
|
-
if call[:call_args] and call[:call_args][:assocs]
|
|
865
|
-
used_param = true
|
|
866
|
-
write "," unless call[:call_args].nil? or call[:call_args][:args].nil?
|
|
867
|
-
write "vnH("
|
|
868
|
-
call[:call_args][:assocs].each do |assoc|
|
|
869
|
-
write "," unless call[:call_args][:assocs].first == assoc
|
|
870
|
-
generate_stmt assoc[:key], :full_stmt => false, :last_stmt => false
|
|
871
|
-
write ","
|
|
872
|
-
generate_stmt assoc[:value], :full_stmt => false, :last_stmt => false
|
|
873
|
-
end
|
|
874
|
-
write ")"
|
|
875
|
-
end
|
|
876
|
-
|
|
877
|
-
# write "]"
|
|
878
|
-
end
|
|
879
|
-
# write ","
|
|
880
|
-
|
|
881
|
-
# block
|
|
882
|
-
if call[:brace_block]
|
|
883
|
-
write "," if used_param
|
|
884
|
-
current_iseq = @iseq_current
|
|
885
|
-
block_iseq = iseq_stack_push(ISEQ_TYPE_BLOCK)
|
|
886
|
-
block_iseq.parent_iseq = current_iseq
|
|
887
|
-
|
|
888
|
-
# block arg names
|
|
889
|
-
if call[:brace_block][:params]
|
|
890
|
-
call[:brace_block][:params].each do |p|
|
|
891
|
-
# puts p
|
|
892
|
-
block_iseq.push_arg_name(p[:value]) unless p.is_a?(String)
|
|
893
|
-
end
|
|
894
|
-
end
|
|
895
|
-
|
|
896
|
-
# block stmts
|
|
897
|
-
if call[:brace_block][:stmt]
|
|
898
|
-
call[:brace_block][:stmt].each do |a|
|
|
899
|
-
generate_stmt a, :full_stmt => true, :last_stmt => call[:brace_block][:stmt].last == a
|
|
900
|
-
end
|
|
901
|
-
end
|
|
902
|
-
|
|
903
|
-
iseq_stack_pop
|
|
904
|
-
|
|
905
|
-
write block_iseq.to_s
|
|
906
|
-
# map(&:name)
|
|
907
|
-
elsif call[:call_args][:block_arg]
|
|
908
|
-
if used_param
|
|
909
|
-
write ","
|
|
910
|
-
else
|
|
911
|
-
used_param = true
|
|
912
|
-
end
|
|
913
|
-
generate_stmt call[:call_args][:block_arg][:arg], :full_stmt => false
|
|
914
|
-
write "==#{SELF}.n ? #{SELF}.n : "
|
|
915
|
-
|
|
916
|
-
generate_stmt call[:call_args][:block_arg][:arg], :full_stmt => false
|
|
917
|
-
write %{.$to_proc()}
|
|
918
|
-
else
|
|
919
|
-
# write "nil"
|
|
920
|
-
end
|
|
921
|
-
# write ","
|
|
922
|
-
|
|
923
|
-
# op flag
|
|
924
|
-
# write "#{call_bit})"
|
|
925
|
-
|
|
926
|
-
write ")"
|
|
927
|
-
|
|
928
|
-
write ";\n" if context[:full_stmt]
|
|
929
|
-
end
|
|
930
|
-
|
|
931
|
-
def generate_string(str, context)
|
|
932
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
933
|
-
|
|
934
|
-
if str[:value].length == 0
|
|
935
|
-
write %{""}
|
|
936
|
-
elsif str[:value].length == 1
|
|
937
|
-
if str[:value][0].node == :string_content
|
|
938
|
-
write %{"#{str[:value][0][:value].gsub(/\"/, '\"')}"}
|
|
939
|
-
else
|
|
940
|
-
generate_stmt str[:value][0][:value][0], {}
|
|
941
|
-
write ".$to_s()"
|
|
942
|
-
end
|
|
943
|
-
else
|
|
944
|
-
write "["
|
|
945
|
-
str[:value].each do |s|
|
|
946
|
-
write "," unless str[:value].first == s
|
|
947
|
-
if s.node == :string_content
|
|
948
|
-
write %{"#{s[:value].gsub(/\"/, '\"')}"}
|
|
949
|
-
else
|
|
950
|
-
# write %{vm$a(}
|
|
951
|
-
generate_stmt s[:value][0], :full_stmt => false
|
|
952
|
-
write ".$to_s()"
|
|
953
|
-
# write %{,"to_s",[],nil,8)}
|
|
954
|
-
end
|
|
955
|
-
end
|
|
956
|
-
write "].join('')"
|
|
957
|
-
end
|
|
958
|
-
|
|
959
|
-
write ";\n" if context[:full_stmt]
|
|
960
|
-
end
|
|
961
|
-
|
|
962
|
-
def generate_xstring(str, context)
|
|
963
|
-
# write "return " if context[:last_stmt] and context[:full_stmt]
|
|
964
|
-
|
|
965
|
-
if str[:value].length == 0
|
|
966
|
-
write %{}
|
|
967
|
-
elsif str[:value].length == 1
|
|
968
|
-
write str[:value][0][:value]
|
|
969
|
-
else
|
|
970
|
-
str[:value].each do |s|
|
|
971
|
-
if s.node == :string_content
|
|
972
|
-
write s[:value]
|
|
973
|
-
else
|
|
974
|
-
generate_stmt s[:value][0], :full_stmt => false
|
|
975
|
-
end
|
|
976
|
-
end
|
|
977
|
-
end
|
|
978
|
-
|
|
979
|
-
# write ";\n" if context[:full_stmt]
|
|
980
|
-
end
|
|
981
|
-
|
|
982
|
-
def generate_constant(cnst, context)
|
|
983
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
984
|
-
write "#{SELF}.const_get('#{cnst[:name]}')"
|
|
985
|
-
# write %{vm$b($,"#{cnst[:name]}")}
|
|
986
|
-
write ";\n" if context[:full_stmt]
|
|
987
|
-
end
|
|
988
|
-
|
|
989
|
-
def generate_assign(stmt, context)
|
|
990
|
-
should_return = context[:last_stmt] and context[:full_stmt]
|
|
991
|
-
param_seen = false
|
|
992
|
-
# LHS is a local identifier
|
|
993
|
-
if stmt[:lhs].node == :identifier
|
|
994
|
-
local = @iseq_current.lookup_local stmt[:lhs][:name]
|
|
995
|
-
unless local
|
|
996
|
-
local = @iseq_current.push_local_name(stmt[:lhs][:name])
|
|
997
|
-
end
|
|
998
|
-
|
|
999
|
-
if stmt[:rhs].node == :if || stmt[:rhs].node == :unless
|
|
1000
|
-
if_local_name = generate_stmt stmt[:rhs], {}
|
|
1001
|
-
write "return " if should_return
|
|
1002
|
-
write %{#{local}=#{if_local_name}}
|
|
1003
|
-
else
|
|
1004
|
-
write "return " if should_return
|
|
1005
|
-
write %{#{local}=}
|
|
1006
|
-
generate_stmt stmt[:rhs], {}
|
|
1007
|
-
end
|
|
1008
|
-
elsif stmt[:lhs].node == :ivar
|
|
1009
|
-
write "return " if should_return
|
|
1010
|
-
write %{#{SELF}.is("#{stmt[:lhs][:name]}",}
|
|
1011
|
-
generate_stmt stmt[:rhs], :full_stmt => false, :last_stmt => false
|
|
1012
|
-
write %{)}
|
|
1013
|
-
elsif stmt[:lhs].node == :constant
|
|
1014
|
-
write %{#{SELF}.const_set("#{stmt[:lhs][:name]}",}
|
|
1015
|
-
generate_stmt stmt[:rhs], :full_stmt => false, :last_stmt => false
|
|
1016
|
-
write %{)}
|
|
1017
|
-
elsif stmt[:lhs].node == :call
|
|
1018
|
-
write "return " if should_return
|
|
1019
|
-
# puts stmt
|
|
1020
|
-
# write %{vm$a(}
|
|
1021
|
-
# recv
|
|
1022
|
-
generate_stmt stmt[:lhs][:recv], :full_stmt => false
|
|
1023
|
-
# id
|
|
1024
|
-
write %{#{mid_to_jsid(stmt[:lhs][:meth] +'=')}(}
|
|
1025
|
-
# args
|
|
1026
|
-
if stmt[:lhs][:args] and stmt[:lhs][:args][:args]
|
|
1027
|
-
stmt[:lhs][:args][:args].each do |arg|
|
|
1028
|
-
param_seen = true
|
|
1029
|
-
write "," unless stmt[:lhs][:args][:args].first == arg
|
|
1030
|
-
generate_stmt arg, :full_stmt => false
|
|
1031
|
-
# write ","
|
|
1032
|
-
end
|
|
1033
|
-
end
|
|
1034
|
-
write "," if param_seen
|
|
1035
|
-
generate_stmt stmt[:rhs], :full_stmt => false
|
|
1036
|
-
write ")"
|
|
1037
|
-
|
|
1038
|
-
else
|
|
1039
|
-
puts stmt
|
|
1040
|
-
abort "bad lhs type"
|
|
1041
|
-
end
|
|
1042
|
-
write ";\n" if context[:full_stmt]
|
|
1043
|
-
end
|
|
1044
|
-
|
|
1045
|
-
# how we replace "self/this"
|
|
1046
|
-
SELF = "this"
|
|
1047
|
-
# how we replace nil
|
|
1048
|
-
NIL = "#{SELF}.n"
|
|
1049
|
-
|
|
1050
|
-
def generate_self(stmt, context)
|
|
1051
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1052
|
-
write "#{SELF}"
|
|
1053
|
-
write ";\n" if context[:full_stmt]
|
|
1054
|
-
end
|
|
1055
|
-
|
|
1056
|
-
def generate_symbol(sym, context)
|
|
1057
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1058
|
-
write %{#{SELF}.Y("#{sym[:name]}")}
|
|
1059
|
-
write ";\n" if context[:full_stmt]
|
|
1060
|
-
end
|
|
1061
|
-
|
|
1062
|
-
def generate_numeric(num, context)
|
|
1063
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1064
|
-
write "(" if context[:recv]
|
|
1065
|
-
write "#{num[:value]}"
|
|
1066
|
-
write ")" if context[:recv]
|
|
1067
|
-
write ";\n" if context[:full_stmt]
|
|
1068
|
-
end
|
|
1069
|
-
|
|
1070
|
-
def generate_ivar stmt, context
|
|
1071
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1072
|
-
# write "vm_ivarget($, '#{stmt[:name]}')"
|
|
1073
|
-
write "#{SELF}.ig('#{stmt[:name]}')"
|
|
1074
|
-
write ";\n" if context[:full_stmt]
|
|
1075
|
-
end
|
|
1076
|
-
|
|
1077
|
-
def generate_gvar(stmt, context)
|
|
1078
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1079
|
-
write "rb_gvar_get('#{stmt[:name]}')"
|
|
1080
|
-
write ";\n" if context[:full_stmt]
|
|
1081
|
-
end
|
|
1082
|
-
|
|
1083
|
-
def generate_yield stmt, context
|
|
1084
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1085
|
-
|
|
1086
|
-
# block_name = @iseq_current.block_arg_name
|
|
1087
|
-
block_name = '__block__'
|
|
1088
|
-
|
|
1089
|
-
# for now, normal args or a single *splat
|
|
1090
|
-
if stmt[:call_args] and stmt[:call_args][:args][0].node == :splat
|
|
1091
|
-
write "#{SELF}.rbYield(#{block_name},[])"
|
|
1092
|
-
else
|
|
1093
|
-
write "#{SELF}.rbYield(#{block_name},["
|
|
1094
|
-
|
|
1095
|
-
if stmt[:call_args] and stmt[:call_args][:args]
|
|
1096
|
-
stmt[:call_args][:args].each do |a|
|
|
1097
|
-
write "," unless stmt[:call_args][:args].first == a
|
|
1098
|
-
generate_stmt a, :full_stmt => false, :last_stmt => false
|
|
1099
|
-
end
|
|
1100
|
-
end
|
|
1101
|
-
write "])"
|
|
1102
|
-
end
|
|
1103
|
-
|
|
1104
|
-
write ";\n" if context[:full_stmt]
|
|
1105
|
-
end
|
|
1106
|
-
|
|
1107
|
-
def generate_block_given stmt, context
|
|
1108
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1109
|
-
write "((!__block__ || !__block__.r) ? #{SELF}.f : #{SELF}.t)"
|
|
1110
|
-
write ";\n" if context[:full_stmt]
|
|
1111
|
-
end
|
|
1112
|
-
|
|
1113
|
-
# def generate_if_mod(stmt, context)
|
|
1114
|
-
# # write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1115
|
-
#
|
|
1116
|
-
# # write "(function(){"
|
|
1117
|
-
#
|
|
1118
|
-
# # if/unless mod
|
|
1119
|
-
# if stmt.node == :if_mod
|
|
1120
|
-
# write "if("
|
|
1121
|
-
# else
|
|
1122
|
-
# write "if(!"
|
|
1123
|
-
# end
|
|
1124
|
-
#
|
|
1125
|
-
# generate_stmt stmt[:expr], :full_stmt => false, :last_stmt => false
|
|
1126
|
-
# write ".r){"
|
|
1127
|
-
# generate_stmt stmt[:stmt], :full_stmt => true, :last_stmt => false
|
|
1128
|
-
# write "}"
|
|
1129
|
-
# # return nil as safety value
|
|
1130
|
-
# # write "return #{NIL};})()"
|
|
1131
|
-
# write ";\n" if context[:full_stmt]
|
|
1132
|
-
# end
|
|
1133
|
-
|
|
1134
|
-
def generate_array(ary, context)
|
|
1135
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1136
|
-
write "["
|
|
1137
|
-
if ary[:args]
|
|
1138
|
-
ary[:args].each do |a|
|
|
1139
|
-
write "," unless ary[:args].first == a
|
|
1140
|
-
generate_stmt a, :full_stmt => false, :last_stmt => false
|
|
1141
|
-
end
|
|
1142
|
-
end
|
|
1143
|
-
write "]"
|
|
1144
|
-
write ";\n" if context[:full_stmt]
|
|
1145
|
-
end
|
|
1146
|
-
|
|
1147
|
-
def generate_opt_plus(stmt, context)
|
|
1148
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1149
|
-
# write %{vm_optplus(}
|
|
1150
|
-
generate_stmt stmt[:recv], :recv => true
|
|
1151
|
-
write "#{mid_to_jsid('+')}("
|
|
1152
|
-
generate_stmt stmt[:call_args][:args][0], :full_stmt => false
|
|
1153
|
-
write ")"
|
|
1154
|
-
write ";\n" if context[:full_stmt]
|
|
1155
|
-
end
|
|
1156
|
-
|
|
1157
|
-
def generate_opt_minus(stmt, context)
|
|
1158
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1159
|
-
generate_stmt stmt[:recv], :last_stmt => false, :full_stmt => false
|
|
1160
|
-
write "#{mid_to_jsid('-')}("
|
|
1161
|
-
generate_stmt stmt[:call_args][:args][0], :full_stmt => false
|
|
1162
|
-
write ")"
|
|
1163
|
-
write ";\n" if context[:full_stmt]
|
|
1164
|
-
end
|
|
1165
|
-
|
|
1166
|
-
def generate_opt_mult(stmt, context)
|
|
1167
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1168
|
-
generate_stmt stmt[:recv], :last_stmt => false, :full_stmt => false
|
|
1169
|
-
write "#{mid_to_jsid('*')}("
|
|
1170
|
-
generate_stmt stmt[:call_args][:args][0], :full_stmt => false
|
|
1171
|
-
write ")"
|
|
1172
|
-
write ";\n" if context[:full_stmt]
|
|
1173
|
-
end
|
|
1174
|
-
|
|
1175
|
-
def generate_opt_div(stmt, context)
|
|
1176
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1177
|
-
generate_stmt stmt[:recv], :last_stmt => false, :full_stmt => false
|
|
1178
|
-
write "#{mid_to_jsid('/')}("
|
|
1179
|
-
generate_stmt stmt[:call_args][:args][0], :full_stmt => false
|
|
1180
|
-
write ")"
|
|
1181
|
-
write ";\n" if context[:full_stmt]
|
|
1182
|
-
end
|
|
1183
|
-
|
|
1184
|
-
def generate_nil(stmt, context)
|
|
1185
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1186
|
-
write NIL
|
|
1187
|
-
write ";\n" if context[:full_stmt]
|
|
1188
|
-
end
|
|
1189
|
-
|
|
1190
|
-
def generate_true(stmt, context)
|
|
1191
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1192
|
-
write "#{SELF}.t"
|
|
1193
|
-
write ";\n" if context[:full_stmt]
|
|
1194
|
-
end
|
|
1195
|
-
|
|
1196
|
-
def generate_false(stmt, context)
|
|
1197
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1198
|
-
write "#{SELF}.f"
|
|
1199
|
-
write ";\n" if context[:full_stmt]
|
|
1200
|
-
end
|
|
1201
|
-
|
|
1202
|
-
def generate_regexp(stmt, context)
|
|
1203
|
-
# puts stmt
|
|
1204
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1205
|
-
write "/"
|
|
1206
|
-
stmt[:value].each do |part|
|
|
1207
|
-
write part[:value]
|
|
1208
|
-
end
|
|
1209
|
-
write "/"
|
|
1210
|
-
# write %{/#{stmt[:value][0][:value]}/}
|
|
1211
|
-
write ";\n" if context[:full_stmt]
|
|
1212
|
-
end
|
|
1213
|
-
|
|
1214
|
-
def generate_dot2(stmt, context)
|
|
1215
|
-
# return #{self}.R(#{start}, #{ending}, #{exclusive}.r);
|
|
1216
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1217
|
-
write "#{SELF}.R("
|
|
1218
|
-
generate_stmt stmt[:start], :full_stmt => false
|
|
1219
|
-
write ","
|
|
1220
|
-
generate_stmt stmt[:ending], :full_stmt => false
|
|
1221
|
-
write ",true)"
|
|
1222
|
-
write ";\n" if context[:full_stmt]
|
|
1223
|
-
end
|
|
1224
|
-
|
|
1225
|
-
def generate_dot3(stmt, context)
|
|
1226
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1227
|
-
write "#{SELF}.R("
|
|
1228
|
-
generate_stmt stmt[:start], :full_stmt => false
|
|
1229
|
-
write ","
|
|
1230
|
-
generate_stmt stmt[:ending], :full_stmt => false
|
|
1231
|
-
write ",false)"
|
|
1232
|
-
write ";\n" if context[:full_stmt]
|
|
1233
|
-
end
|
|
1234
|
-
|
|
1235
|
-
def generate_alias(stmt, context)
|
|
1236
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1237
|
-
write "vm_alias($,"
|
|
1238
|
-
generate_stmt stmt[:lhs], :full_stmt => false
|
|
1239
|
-
write ","
|
|
1240
|
-
generate_stmt stmt[:rhs], :full_stmt => false
|
|
1241
|
-
write ")"
|
|
1242
|
-
write ";\n" if context[:full_stmt]
|
|
1243
|
-
end
|
|
1244
|
-
|
|
1245
|
-
def generate__FILE__ stmt, context
|
|
1246
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1247
|
-
write %{__FILE__}
|
|
1248
|
-
write ";\n" if context[:full_stmt]
|
|
1249
|
-
end
|
|
1250
|
-
|
|
1251
|
-
def generate__LINE__ stmt, context
|
|
1252
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1253
|
-
write %{0}
|
|
1254
|
-
write ";\n" if context[:full_stmt]
|
|
1255
|
-
end
|
|
1256
|
-
# primay::CONST
|
|
1257
|
-
def generate_colon2 stmt, context
|
|
1258
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1259
|
-
# write %{vm$b(}
|
|
1260
|
-
generate_stmt stmt[:lhs], :full_stmt => false
|
|
1261
|
-
write %{.const_get("#{stmt[:rhs]}")}
|
|
1262
|
-
write ";\n" if context[:full_stmt]
|
|
1263
|
-
end
|
|
1264
|
-
|
|
1265
|
-
def generate_colon3 stmt, context
|
|
1266
|
-
|
|
1267
|
-
end
|
|
1268
|
-
|
|
1269
|
-
def generate_if(stmt, context)
|
|
1270
|
-
|
|
1271
|
-
# if we are not a full stmt, then we must return the last stmt's value.
|
|
1272
|
-
# Each last stmt will save its value into this var name so it can be used
|
|
1273
|
-
# again outside. nil is default and implies we dont need to do this. This
|
|
1274
|
-
# method (generate_if) returns the temp variable name so the caller can
|
|
1275
|
-
# decide what to do with it
|
|
1276
|
-
return_value_name = nil
|
|
1277
|
-
|
|
1278
|
-
# whether or not the last stmt for each stmt should be returned. This is
|
|
1279
|
-
# only ever true when we are the last stmt, AND we are a full stmt
|
|
1280
|
-
should_return_last = (context[:last_stmt] && context[:full_stmt] ? true : false)
|
|
1281
|
-
|
|
1282
|
-
# keep track of if we did an else statement.. if we havent, then we might
|
|
1283
|
-
# need to add one as a default response.. just return nil..
|
|
1284
|
-
done_else_statement = false
|
|
1285
|
-
|
|
1286
|
-
unless context[:full_stmt]
|
|
1287
|
-
return_value_name = @iseq_current.new_temp_variable
|
|
1288
|
-
end
|
|
1289
|
-
|
|
1290
|
-
# if/unless clause
|
|
1291
|
-
if stmt.node == :if
|
|
1292
|
-
write "if("
|
|
1293
|
-
else # must be unless
|
|
1294
|
-
write "if(!"
|
|
1295
|
-
end
|
|
1296
|
-
|
|
1297
|
-
generate_stmt stmt[:expr], :recv => true
|
|
1298
|
-
write ".r){"
|
|
1299
|
-
stmt[:stmt].each do |s|
|
|
1300
|
-
is_last_stmt = false
|
|
1301
|
-
if stmt[:stmt].last == s
|
|
1302
|
-
if should_return_last
|
|
1303
|
-
is_last_stmt = true
|
|
1304
|
-
elsif return_value_name
|
|
1305
|
-
write "#{return_value_name} = "
|
|
1306
|
-
end
|
|
1307
|
-
end
|
|
1308
|
-
# alays return last stmt. we output inside a function context to capture
|
|
1309
|
-
# the return value so that this will not return from the function itself
|
|
1310
|
-
generate_stmt s, :full_stmt => true, :last_stmt => is_last_stmt
|
|
1311
|
-
end
|
|
1312
|
-
write "}"
|
|
1313
|
-
|
|
1314
|
-
# now onto the tail (elsif, else etc)
|
|
1315
|
-
if stmt[:tail]
|
|
1316
|
-
stmt[:tail].each do |t|
|
|
1317
|
-
if t.node == :elsif
|
|
1318
|
-
write "else if("
|
|
1319
|
-
generate_stmt t[:expr], :recv => true
|
|
1320
|
-
write ".r){"
|
|
1321
|
-
t[:stmt].each do |s|
|
|
1322
|
-
is_last_stmt = false
|
|
1323
|
-
if t[:stmt].last == s
|
|
1324
|
-
if should_return_last
|
|
1325
|
-
is_last_stmt = true
|
|
1326
|
-
# write "return "
|
|
1327
|
-
elsif return_value_name
|
|
1328
|
-
write "#{return_value_name} = "
|
|
1329
|
-
end
|
|
1330
|
-
end
|
|
1331
|
-
generate_stmt s, :full_stmt => true, :last_stmt => is_last_stmt
|
|
1332
|
-
end
|
|
1333
|
-
write "}"
|
|
1334
|
-
else # else node
|
|
1335
|
-
done_else_statement = true
|
|
1336
|
-
write "else{"
|
|
1337
|
-
t[:stmt].each do |s|
|
|
1338
|
-
is_last_stmt = false
|
|
1339
|
-
if t[:stmt].last == s
|
|
1340
|
-
if should_return_last
|
|
1341
|
-
is_last_stmt = true
|
|
1342
|
-
elsif return_value_name
|
|
1343
|
-
write "#{return_value_name} = "
|
|
1344
|
-
end
|
|
1345
|
-
end
|
|
1346
|
-
generate_stmt s, :full_stmt => true, :last_stmt => is_last_stmt
|
|
1347
|
-
end
|
|
1348
|
-
write "}"
|
|
1349
|
-
end
|
|
1350
|
-
end
|
|
1351
|
-
end
|
|
1352
|
-
|
|
1353
|
-
# did we encounter an else statement? make sure..
|
|
1354
|
-
unless done_else_statement
|
|
1355
|
-
write "else{"
|
|
1356
|
-
if should_return_last
|
|
1357
|
-
write "return "
|
|
1358
|
-
end
|
|
1359
|
-
write "#{NIL};"
|
|
1360
|
-
write "}"
|
|
1361
|
-
end
|
|
1362
|
-
|
|
1363
|
-
# so it can be used..
|
|
1364
|
-
return_value_name
|
|
1365
|
-
end
|
|
1366
|
-
|
|
1367
|
-
def generate_op_asgn(stmt, context)
|
|
1368
|
-
# resulting stmt
|
|
1369
|
-
result = nil
|
|
1370
|
-
# if || or &&, then treat differently... everything else is simply a call
|
|
1371
|
-
# node :call, :recv => val[1], :meth => '-@', :call_args => { :args => []}
|
|
1372
|
-
|
|
1373
|
-
if stmt[:lhs].node == :identifier
|
|
1374
|
-
# adam += 20
|
|
1375
|
-
# => adam = adam + 20
|
|
1376
|
-
name = stmt[:lhs][:name]
|
|
1377
|
-
recv = node(:identifier, :name => name)
|
|
1378
|
-
lhs = node(:identifier, :name => name)
|
|
1379
|
-
|
|
1380
|
-
elsif stmt[:lhs].node == :ivar
|
|
1381
|
-
|
|
1382
|
-
name = stmt[:lhs][:name]
|
|
1383
|
-
recv = node(:ivar, :name => name)
|
|
1384
|
-
lhs = node(:ivar, :name => name)
|
|
1385
|
-
|
|
1386
|
-
elsif stmt[:lhs].node == :call
|
|
1387
|
-
|
|
1388
|
-
recv = stmt[:lhs]
|
|
1389
|
-
lhs = stmt[:lhs]
|
|
1390
|
-
|
|
1391
|
-
end
|
|
1392
|
-
|
|
1393
|
-
if stmt[:op] == '||'
|
|
1394
|
-
rhs = node(:assign, :lhs => lhs, :rhs => stmt[:rhs])
|
|
1395
|
-
result = node(:orop, :lhs => lhs, :rhs => rhs)
|
|
1396
|
-
else
|
|
1397
|
-
# should be generic
|
|
1398
|
-
rhs = node(:call, :recv => recv, :meth => stmt[:op], :call_args => { :args => [stmt[:rhs]]})
|
|
1399
|
-
# rhs = node(:call, :recv => node(:identifier, :name => name), :meth => stmt[:op], :call_args => { :args => [stmt[:rhs]]})
|
|
1400
|
-
result = node(:assign, :lhs => lhs, :rhs => rhs)
|
|
1401
|
-
end
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
generate_stmt result, context
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
# end new
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
# puts result
|
|
1413
|
-
# generate_stmt result, {}
|
|
1414
|
-
|
|
1415
|
-
# if stmt[:lhs].node == :ivarpa
|
|
1416
|
-
|
|
1417
|
-
# puts stmt
|
|
1418
|
-
# write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1419
|
-
|
|
1420
|
-
# if stmt[:lhs].node == :ivar
|
|
1421
|
-
# if stmt[:op] == "||"
|
|
1422
|
-
# rhs = node(:assign, :lhs => stmt[:lhs], :rhs => stmt[:rhs])
|
|
1423
|
-
# generate_stmt(node(:orop, :lhs => stmt[:lhs], :rhs => rhs), {})
|
|
1424
|
-
# # write "(function(){var a;"
|
|
1425
|
-
# # write "if(!RTEST(a = vm_ivarget($,'#{stmt[:lhs][:name]}'))){"
|
|
1426
|
-
# # write "return vm_ivarset($,'#{stmt[:lhs][:name]}',"
|
|
1427
|
-
# # generate_stmt stmt[:rhs], :full_stmt => false
|
|
1428
|
-
# # write ");}"
|
|
1429
|
-
# # write "return a;"
|
|
1430
|
-
# # write "})()"
|
|
1431
|
-
# elsif stmt[:op] == "+"
|
|
1432
|
-
# write "vm_ivarset($,'#{stmt[:lhs][:name]}',vm_optplus("
|
|
1433
|
-
# write "vm_ivarget($,'#{stmt[:lhs][:name]}'),"
|
|
1434
|
-
# generate_stmt stmt[:rhs], :full_stmt => false
|
|
1435
|
-
# write "))"
|
|
1436
|
-
# elsif stmt[:op] == "-"
|
|
1437
|
-
# write "vm_ivarset($,'#{stmt[:lhs][:name]}',vm_optminus("
|
|
1438
|
-
# write "vm_ivarget($,'#{stmt[:lhs][:name]}'),"
|
|
1439
|
-
# generate_stmt stmt[:rhs], :full_stmt => false
|
|
1440
|
-
# write "))"
|
|
1441
|
-
# elsif stmt[:op] == "*"
|
|
1442
|
-
# write "vm_ivarset($,'#{stmt[:lhs][:name]}',vm_optmult("
|
|
1443
|
-
# write "vm_ivarget($,'#{stmt[:lhs][:name]}'),"
|
|
1444
|
-
# generate_stmt stmt[:rhs], :full_stmt => false
|
|
1445
|
-
# write "))"
|
|
1446
|
-
# elsif stmt[:op] == "/"
|
|
1447
|
-
# write "vm_ivarset($,'#{stmt[:lhs][:name]}',vm_optdiv("
|
|
1448
|
-
# write "vm_ivarget($,'#{stmt[:lhs][:name]}'),"
|
|
1449
|
-
# generate_stmt stmt[:rhs], :full_stmt => false
|
|
1450
|
-
# write "))"
|
|
1451
|
-
# else
|
|
1452
|
-
# abort "bas op type for op_asgn"
|
|
1453
|
-
# end
|
|
1454
|
-
# else
|
|
1455
|
-
# abort "bad LHS for op_asgn"
|
|
1456
|
-
# end
|
|
1457
|
-
|
|
1458
|
-
# write ";\n" if context[:full_stmt]
|
|
1459
|
-
end
|
|
1460
|
-
|
|
1461
|
-
# yuck!
|
|
1462
|
-
def generate_case stmt, context
|
|
1463
|
-
# if stmt[:donate_recv]
|
|
1464
|
-
# write "DONATABLE RECV"
|
|
1465
|
-
# end
|
|
1466
|
-
|
|
1467
|
-
# first get our case value (if method call, we dont want to call it for
|
|
1468
|
-
# every comparison, so store it ina temp variable for later use)
|
|
1469
|
-
case_var_name = @iseq_current.new_temp_variable
|
|
1470
|
-
|
|
1471
|
-
# if we are not a full stmt, then we might need to store return value
|
|
1472
|
-
case_result = context[:full_stmt] ? nil : @iseq_current.new_temp_variable
|
|
1473
|
-
|
|
1474
|
-
# if we simply return the last stmt..
|
|
1475
|
-
is_last = context[:last_stmt] && context[:full_stmt]
|
|
1476
|
-
|
|
1477
|
-
# make sure we do the else part
|
|
1478
|
-
done_else = false
|
|
1479
|
-
|
|
1480
|
-
write "#{case_var_name} = "
|
|
1481
|
-
|
|
1482
|
-
if stmt[:expr]
|
|
1483
|
-
generate_stmt stmt[:expr], :full_stmt => false, :last_stmt => false
|
|
1484
|
-
write ";"
|
|
1485
|
-
else
|
|
1486
|
-
write "#{SELF}.t;"
|
|
1487
|
-
end
|
|
1488
|
-
|
|
1489
|
-
# write "(function($c){"
|
|
1490
|
-
stmt[:body].each do |c|
|
|
1491
|
-
if c.node == :when
|
|
1492
|
-
# clauses
|
|
1493
|
-
if stmt[:body].first == c
|
|
1494
|
-
write "if"
|
|
1495
|
-
else
|
|
1496
|
-
write "else if"
|
|
1497
|
-
end
|
|
1498
|
-
write "("
|
|
1499
|
-
c[:args].each do |a|
|
|
1500
|
-
write " || " unless c[:args].first == a
|
|
1501
|
-
|
|
1502
|
-
generate_stmt a, :recv => true
|
|
1503
|
-
# ruby truthiness test to make sure result is truthy
|
|
1504
|
-
write "#{mid_to_jsid('===')}(#{case_var_name}).r"
|
|
1505
|
-
# write ",'===',[$c],nil,0)"
|
|
1506
|
-
end
|
|
1507
|
-
write") {"
|
|
1508
|
-
c[:stmt].each do |s|
|
|
1509
|
-
# assign to variable? (for non full stmts)
|
|
1510
|
-
if c[:stmt].last == s && case_result
|
|
1511
|
-
write "#{case_result} = "
|
|
1512
|
-
end
|
|
1513
|
-
|
|
1514
|
-
generate_stmt s, :full_stmt => true, :last_stmt => is_last && c[:stmt].last == s
|
|
1515
|
-
end
|
|
1516
|
-
write "}"
|
|
1517
|
-
else # it is an else, so anything else goes
|
|
1518
|
-
done_else = true
|
|
1519
|
-
|
|
1520
|
-
write "else {"
|
|
1521
|
-
c[:stmt].each do |s|
|
|
1522
|
-
if c[:stmt].last == s && case_result
|
|
1523
|
-
write "#{case_result} = "
|
|
1524
|
-
end
|
|
1525
|
-
generate_stmt s, :full_stmt => true, :last_stmt => is_last && c[:stmt].last == s
|
|
1526
|
-
end
|
|
1527
|
-
write "}"
|
|
1528
|
-
end
|
|
1529
|
-
end
|
|
1530
|
-
|
|
1531
|
-
unless done_else
|
|
1532
|
-
write "else {"
|
|
1533
|
-
|
|
1534
|
-
if case_result
|
|
1535
|
-
write "#{case_result} = "
|
|
1536
|
-
else
|
|
1537
|
-
write "return " if is_last
|
|
1538
|
-
end
|
|
1539
|
-
|
|
1540
|
-
write NIL
|
|
1541
|
-
write ";"
|
|
1542
|
-
write "}"
|
|
1543
|
-
end
|
|
1544
|
-
|
|
1545
|
-
# do we need to return for a call stmt later on?
|
|
1546
|
-
write "return " if stmt[:donate_recv]
|
|
1547
|
-
|
|
1548
|
-
# if we need to return our result...
|
|
1549
|
-
if case_result
|
|
1550
|
-
write case_result
|
|
1551
|
-
end
|
|
1552
|
-
end
|
|
1553
|
-
|
|
1554
|
-
def generate_orop(stmt, context)
|
|
1555
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1556
|
-
write "#{SELF}.o("
|
|
1557
|
-
generate_stmt stmt[:lhs], :full_stmt => false
|
|
1558
|
-
# write ".o("
|
|
1559
|
-
write ",function(){"
|
|
1560
|
-
generate_stmt stmt[:rhs], :full_stmt => true, :last_stmt => true
|
|
1561
|
-
write "})"
|
|
1562
|
-
|
|
1563
|
-
write ";\n" if context[:full_stmt]
|
|
1564
|
-
end
|
|
1565
|
-
|
|
1566
|
-
def generate_andop(stmt, context)
|
|
1567
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1568
|
-
write "#{SELF}.a("
|
|
1569
|
-
generate_stmt stmt[:lhs], :full_stmt => false
|
|
1570
|
-
# write ".o("
|
|
1571
|
-
write ",function(){"
|
|
1572
|
-
generate_stmt stmt[:rhs], :full_stmt => true, :last_stmt => true
|
|
1573
|
-
write "})"
|
|
1574
|
-
|
|
1575
|
-
write ";\n" if context[:full_stmt]
|
|
1576
|
-
end
|
|
1577
|
-
|
|
1578
|
-
def generate_assoc_list stmt, context
|
|
1579
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1580
|
-
write "vnH("
|
|
1581
|
-
stmt[:list].each do |assoc|
|
|
1582
|
-
write "," unless stmt[:list].first == assoc
|
|
1583
|
-
generate_stmt assoc[:key], :full_stmt => false, :last_stmt => false
|
|
1584
|
-
write ","
|
|
1585
|
-
generate_stmt assoc[:value], :full_stmt => false, :last_stmt => false
|
|
1586
|
-
end
|
|
1587
|
-
write ")"
|
|
1588
|
-
write ";\n" if context[:full_stmt]
|
|
1589
|
-
end
|
|
1590
|
-
|
|
1591
|
-
def generate_begin(stmt, context)
|
|
1592
|
-
if stmt[:stmt][:opt_rescue]
|
|
1593
|
-
write "try{"
|
|
1594
|
-
stmt[:stmt][:compstmt].each do |s|
|
|
1595
|
-
generate_stmt s, :full_stmt => true, :last_stmt => (context[:last_stmt] && stmt[:stmt][:compstmt].last == s)
|
|
1596
|
-
end
|
|
1597
|
-
# puts stmt[:stmt][:opt_rescue]
|
|
1598
|
-
write "}"
|
|
1599
|
-
write "catch(e) {"
|
|
1600
|
-
if stmt[:stmt][:opt_rescue][:var]
|
|
1601
|
-
local = @iseq_current.lookup_local(stmt[:stmt][:opt_rescue][:var][:name])
|
|
1602
|
-
unless local
|
|
1603
|
-
local = @iseq_current.push_local_name(stmt[:stmt][:opt_rescue][:var][:name])
|
|
1604
|
-
end
|
|
1605
|
-
# write "#{local} = e;"
|
|
1606
|
-
# make sure we are using a opal error
|
|
1607
|
-
write %Q|
|
|
1608
|
-
if (e.mid2jsid) {
|
|
1609
|
-
#{local} = e;
|
|
1610
|
-
} else {
|
|
1611
|
-
#{local} = #{SELF}.rbNativeError(e);
|
|
1612
|
-
}
|
|
1613
|
-
|
|
|
1614
|
-
# write "console.log('catch');console.log(e.klass);"
|
|
1615
|
-
if stmt[:stmt][:opt_rescue][:stmt]
|
|
1616
|
-
stmt[:stmt][:opt_rescue][:stmt].each do |s|
|
|
1617
|
-
generate_stmt s, :full_stmt => true
|
|
1618
|
-
end
|
|
1619
|
-
end
|
|
1620
|
-
end
|
|
1621
|
-
write "}"
|
|
1622
|
-
else
|
|
1623
|
-
stmt[:stmt][:compstmt].each do |stmt|
|
|
1624
|
-
generate_stmt stmt, :full_stmt => true, :last_stmt => false
|
|
1625
|
-
end
|
|
1626
|
-
end
|
|
1627
|
-
end
|
|
1628
|
-
|
|
1629
|
-
def generate_return(stmt, context)
|
|
1630
|
-
|
|
1631
|
-
if @iseq_current.type == RubyParser::ISEQ_TYPE_BLOCK
|
|
1632
|
-
# if we are inside a block, we must rbReturn (i.e. throw an error to
|
|
1633
|
-
# return to escape blocks etc, see opal.js). Also, we must tell the
|
|
1634
|
-
# nearset method from iseq_current that it contains a block/proc so
|
|
1635
|
-
# it can provide a simple try/catch statement to try and catch it if it
|
|
1636
|
-
# returns.
|
|
1637
|
-
|
|
1638
|
-
@iseq_current.tell_method_to_handle_return
|
|
1639
|
-
|
|
1640
|
-
write "#{SELF}.rbReturn("
|
|
1641
|
-
# puts stmt
|
|
1642
|
-
if stmt[:call_args] and stmt[:call_args][:args]
|
|
1643
|
-
if stmt[:call_args][:args].length == 1
|
|
1644
|
-
generate_stmt stmt[:call_args][:args].first, :full_stmt => false
|
|
1645
|
-
else
|
|
1646
|
-
abort "generate_return multiple args not yet done"
|
|
1647
|
-
end
|
|
1648
|
-
else
|
|
1649
|
-
write "#{NIL}"
|
|
1650
|
-
end
|
|
1651
|
-
|
|
1652
|
-
write ");\n" if context[:full_stmt]
|
|
1653
|
-
else
|
|
1654
|
-
# assume we are in a method... if so, carry on as normal
|
|
1655
|
-
write "return "
|
|
1656
|
-
# puts stmt
|
|
1657
|
-
if stmt[:call_args] and stmt[:call_args][:args]
|
|
1658
|
-
if stmt[:call_args][:args].length == 1
|
|
1659
|
-
generate_stmt stmt[:call_args][:args].first, :full_stmt => false
|
|
1660
|
-
else
|
|
1661
|
-
abort "generate_return multiple args not yet done"
|
|
1662
|
-
end
|
|
1663
|
-
else
|
|
1664
|
-
write "#{NIL}"
|
|
1665
|
-
end
|
|
1666
|
-
|
|
1667
|
-
write ";\n" if context[:full_stmt]
|
|
1668
|
-
end
|
|
1669
|
-
end
|
|
1670
|
-
|
|
1671
|
-
def generate_lparen(stmt, context)
|
|
1672
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1673
|
-
write "("
|
|
1674
|
-
if stmt[:stmt] and stmt[:stmt][0]
|
|
1675
|
-
generate_stmt stmt[:stmt][0], :full_stmt => false
|
|
1676
|
-
else
|
|
1677
|
-
write "#{NIL}"
|
|
1678
|
-
end
|
|
1679
|
-
write ")"
|
|
1680
|
-
write ";\n" if context[:full_stmt]
|
|
1681
|
-
end
|
|
1682
|
-
|
|
1683
|
-
def generate_aset_op_asgn(stmt, context)
|
|
1684
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1685
|
-
if stmt[:recv].node == :identifier
|
|
1686
|
-
abort "unsupported. currently"
|
|
1687
|
-
else
|
|
1688
|
-
abort "bad recv node for aset_op_asgn (#{stmt[:recv]})"
|
|
1689
|
-
end
|
|
1690
|
-
write ";\n" if context[:full_stmt]
|
|
1691
|
-
end
|
|
1692
|
-
|
|
1693
|
-
def generate_not(stmt, context)
|
|
1694
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1695
|
-
generate_stmt stmt[:expr], :full_stmt => false
|
|
1696
|
-
write "#{mid_to_jsid('!')}()"
|
|
1697
|
-
write ";\n" if context[:full_stmt]
|
|
1698
|
-
end
|
|
1699
|
-
|
|
1700
|
-
def generate_super(stmt, context)
|
|
1701
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1702
|
-
write %{#{SELF}.opal_super(arguments.callee, }
|
|
1703
|
-
|
|
1704
|
-
# args, depends on is super has parens etc, simple for now: parens
|
|
1705
|
-
if stmt[:call_args] and stmt[:call_args][:args]
|
|
1706
|
-
write "["
|
|
1707
|
-
stmt[:call_args][:args].each do |arg|
|
|
1708
|
-
write "," unless arg == stmt[:call_args][:args].first
|
|
1709
|
-
generate_stmt arg, :full_stmt => false
|
|
1710
|
-
end
|
|
1711
|
-
write "]"
|
|
1712
|
-
|
|
1713
|
-
elsif stmt[:inherit]
|
|
1714
|
-
write "Array.prototype.slice.call(arguments)"
|
|
1715
|
-
else
|
|
1716
|
-
write "[]"
|
|
1717
|
-
end
|
|
1718
|
-
|
|
1719
|
-
write ")"
|
|
1720
|
-
write ";\n" if context[:full_stmt]
|
|
1721
|
-
end
|
|
1722
|
-
|
|
1723
|
-
def generate_break(stmt, context)
|
|
1724
|
-
write "#{SELF}.rbBreak("
|
|
1725
|
-
if stmt[:call_args] and stmt[:call_args][:args]
|
|
1726
|
-
stmt[:call_args][:args].each do |arg|
|
|
1727
|
-
write "," unless stmt[:call_args][:args].first == arg
|
|
1728
|
-
generate_stmt arg, :full_stmt => false
|
|
1729
|
-
end
|
|
1730
|
-
end
|
|
1731
|
-
write ");"
|
|
1732
|
-
end
|
|
1733
|
-
|
|
1734
|
-
def generate_next(stmt, context)
|
|
1735
|
-
write "#{SELF}.rbNext("
|
|
1736
|
-
if stmt[:call_args] and stmt[:call_args][:args]
|
|
1737
|
-
stmt[:call_args][:args].each do |arg|
|
|
1738
|
-
write "," unless stmt[:call_args][:args].first == arg
|
|
1739
|
-
generate_stmt arg, :full_stmt => false
|
|
1740
|
-
end
|
|
1741
|
-
end
|
|
1742
|
-
write ")"
|
|
1743
|
-
|
|
1744
|
-
write ";" if context[:full_stmt]
|
|
1745
|
-
end
|
|
1746
|
-
|
|
1747
|
-
def generate_tertiary(stmt, context)
|
|
1748
|
-
write "return " if context[:full_stmt] and context[:last_stmt]
|
|
1749
|
-
write "("
|
|
1750
|
-
generate_stmt stmt[:expr], :full_stmt => false
|
|
1751
|
-
write ").r ? "
|
|
1752
|
-
generate_stmt stmt[:true], :full_stmt => false
|
|
1753
|
-
write " : "
|
|
1754
|
-
generate_stmt stmt[:false], :full_stmt => false
|
|
1755
|
-
write ";\n" if context[:full_stmt]
|
|
1756
|
-
end
|
|
1757
|
-
|
|
1758
|
-
def generate_while(stmt, context)
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
write "#{SELF}.rbWhile(function(){"
|
|
1763
|
-
if stmt.node == :while
|
|
1764
|
-
write "return ("
|
|
1765
|
-
else
|
|
1766
|
-
# until..
|
|
1767
|
-
write "return (!("
|
|
1768
|
-
end
|
|
1769
|
-
|
|
1770
|
-
generate_stmt stmt[:expr], {}
|
|
1771
|
-
|
|
1772
|
-
if stmt.node == :while
|
|
1773
|
-
write ".r);"
|
|
1774
|
-
else
|
|
1775
|
-
# until..
|
|
1776
|
-
write ".r));"
|
|
1777
|
-
end
|
|
1778
|
-
|
|
1779
|
-
# generate_stmt stmt[:expr], {}
|
|
1780
|
-
|
|
1781
|
-
write "}, function() {"
|
|
1782
|
-
|
|
1783
|
-
stmt[:stmt].each do |stmt|
|
|
1784
|
-
generate_stmt stmt, :full_stmt => true
|
|
1785
|
-
end
|
|
1786
|
-
|
|
1787
|
-
# write "}"
|
|
1788
|
-
|
|
1789
|
-
write "})"
|
|
1790
|
-
|
|
1791
|
-
write ";\n" if context[:full_stmt]
|
|
1792
|
-
end
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
def generate_lambda(stmt, context)
|
|
1798
|
-
write "return " if context[:last_stmt] && context[:full_stmt]
|
|
1799
|
-
|
|
1800
|
-
write "#{SELF}.L(function() {"
|
|
1801
|
-
|
|
1802
|
-
stmt[:body].each do |stmt|
|
|
1803
|
-
generate_stmt stmt, :full_stmt => true
|
|
1804
|
-
end
|
|
1805
|
-
|
|
1806
|
-
write "})"
|
|
1807
|
-
|
|
1808
|
-
write ";\n" if context[:full_stmt]
|
|
1809
|
-
end
|
|
1810
|
-
|
|
1811
|
-
def generate_words(stmt, context)
|
|
1812
|
-
write "return " if context[:last_stmt] and context[:full_stmt]
|
|
1813
|
-
|
|
1814
|
-
done_first = false
|
|
1815
|
-
|
|
1816
|
-
write "["
|
|
1817
|
-
stmt[:list].first.each do |list|
|
|
1818
|
-
if list.node == :string_content
|
|
1819
|
-
str = list[:value]
|
|
1820
|
-
str = str.strip! || str
|
|
1821
|
-
str.split(' ').each do |part|
|
|
1822
|
-
if done_first
|
|
1823
|
-
write ", '#{part}'"
|
|
1824
|
-
else
|
|
1825
|
-
done_first = true
|
|
1826
|
-
write "'#{part}'"
|
|
1827
|
-
end
|
|
1828
|
-
end
|
|
1829
|
-
else
|
|
1830
|
-
if done_first
|
|
1831
|
-
write ", "
|
|
1832
|
-
else
|
|
1833
|
-
done_first = true
|
|
1834
|
-
end
|
|
1835
|
-
# puts list
|
|
1836
|
-
generate_stmt list[:value].first, {}
|
|
1837
|
-
write '.$to_s()'
|
|
1838
|
-
end
|
|
1839
|
-
end
|
|
1840
|
-
|
|
1841
|
-
write "]"
|
|
1842
|
-
write ";\n" if context[:full_stmt]
|
|
1843
|
-
end
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
def generate_redo(stmt, context)
|
|
1847
|
-
write "#{SELF}.rbRedo()"
|
|
1848
|
-
write ";" if context[:full_stmt]
|
|
1849
|
-
end
|
|
1850
|
-
end
|
|
1851
|
-
end
|