opal 0.4.4 → 0.5.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.gitmodules +3 -0
- data/.travis.yml +8 -0
- data/CONTRIBUTING.md +46 -2
- data/Gemfile +17 -0
- data/README.md +13 -4
- data/Rakefile +22 -119
- data/bin/opal +11 -2
- data/bin/opal-repl +71 -0
- data/corelib/array.rb +554 -356
- data/corelib/basic_object.rb +22 -18
- data/corelib/boolean.rb +15 -6
- data/corelib/class.rb +12 -6
- data/corelib/comparable.rb +40 -9
- data/corelib/encoding.rb +164 -0
- data/corelib/enumerable.rb +532 -300
- data/corelib/enumerator.rb +31 -6
- data/corelib/error.rb +14 -3
- data/corelib/hash.rb +108 -97
- data/corelib/io.rb +30 -0
- data/corelib/kernel.rb +151 -82
- data/corelib/main.rb +7 -0
- data/corelib/match_data.rb +118 -0
- data/corelib/method.rb +58 -0
- data/corelib/module.rb +145 -77
- data/corelib/native.rb +144 -22
- data/corelib/nil_class.rb +2 -0
- data/corelib/numeric.rb +259 -61
- data/corelib/opal.rb +43 -28
- data/corelib/proc.rb +21 -9
- data/corelib/range.rb +42 -23
- data/corelib/regexp.rb +51 -9
- data/corelib/runtime.js +470 -129
- data/corelib/string.rb +170 -246
- data/corelib/struct.rb +13 -1
- data/corelib/time.rb +414 -43
- data/doc/compiler.md +42 -0
- data/doc/compiler_options.md +5 -0
- data/doc/examples/node_http_server.rb +49 -0
- data/doc/external_libraries.md +9 -0
- data/doc/generated_javascript.md +272 -0
- data/doc/home.md +17 -0
- data/doc/method_missing.md +58 -0
- data/doc/static_applications.md +60 -0
- data/doc/using_ruby_from_javascript.md +18 -0
- data/doc/using_sprockets.md +65 -0
- data/lib/opal.rb +18 -15
- data/lib/opal/builder.rb +26 -9
- data/lib/opal/cli.rb +143 -90
- data/lib/opal/cli_options.rb +19 -13
- data/lib/opal/compiler.rb +307 -0
- data/lib/opal/erb.rb +3 -3
- data/lib/opal/fragment.rb +34 -0
- data/lib/opal/nodes.rb +25 -0
- data/lib/opal/nodes/arglist.rb +56 -0
- data/lib/opal/nodes/array.rb +54 -0
- data/lib/opal/nodes/base.rb +150 -0
- data/lib/opal/nodes/base_scope.rb +11 -0
- data/lib/opal/nodes/call.rb +195 -0
- data/lib/opal/nodes/call_special.rb +153 -0
- data/lib/opal/nodes/case.rb +96 -0
- data/lib/opal/nodes/class.rb +43 -0
- data/lib/opal/nodes/constants.rb +91 -0
- data/lib/opal/nodes/def.rb +157 -0
- data/lib/opal/nodes/defined.rb +113 -0
- data/lib/opal/nodes/definitions.rb +182 -0
- data/lib/opal/nodes/hash.rb +67 -0
- data/lib/opal/nodes/helpers.rb +105 -0
- data/lib/opal/nodes/if.rb +60 -0
- data/lib/opal/nodes/iter.rb +118 -0
- data/lib/opal/nodes/literal.rb +193 -0
- data/lib/opal/nodes/logic.rb +211 -0
- data/lib/opal/nodes/masgn.rb +62 -0
- data/lib/opal/nodes/module.rb +46 -0
- data/lib/opal/nodes/rescue.rb +134 -0
- data/lib/opal/nodes/singleton_class.rb +26 -0
- data/lib/opal/nodes/super.rb +97 -0
- data/lib/opal/nodes/top.rb +63 -0
- data/lib/opal/nodes/variables.rb +155 -0
- data/lib/opal/nodes/while.rb +65 -0
- data/lib/opal/nodes/yield.rb +84 -0
- data/lib/opal/parser.rb +294 -2169
- data/lib/opal/parser/grammar.rb +5326 -0
- data/lib/opal/{grammar.y → parser/grammar.y} +180 -113
- data/lib/opal/parser/keywords.rb +64 -0
- data/lib/opal/{lexer.rb → parser/lexer.rb} +278 -327
- data/lib/opal/{lexer_scope.rb → parser/parser_scope.rb} +2 -5
- data/lib/opal/parser/sexp.rb +63 -0
- data/lib/opal/source_map.rb +6 -5
- data/lib/opal/target_scope.rb +15 -17
- data/lib/opal/version.rb +1 -1
- data/mri_spec/cli_spec.rb +67 -6
- data/opal.gemspec +4 -4
- data/spec/config.ru +2 -1
- data/spec/corelib/enumerable/all_break_spec.rb +5 -0
- data/spec/corelib/enumerable/any_break_spec.rb +5 -0
- data/spec/corelib/enumerable/collect_break_spec.rb +13 -0
- data/spec/corelib/enumerable/count_break_spec.rb +5 -0
- data/spec/corelib/enumerable/detect_break_spec.rb +5 -0
- data/spec/corelib/enumerable/drop_while_break_spec.rb +5 -0
- data/spec/corelib/enumerable/each_slice_break.rb +6 -0
- data/spec/corelib/enumerable/each_with_index_break_spec.rb +5 -0
- data/spec/corelib/enumerable/each_with_object_break_spec.rb +5 -0
- data/spec/corelib/enumerable/find_all_break_spec.rb +5 -0
- data/spec/corelib/enumerable/find_index_break_spec.rb +5 -0
- data/spec/corelib/enumerable/grep_break_spec.rb +5 -0
- data/spec/corelib/enumerable/max_break_spec.rb +5 -0
- data/spec/corelib/enumerable/max_by_break_spec.rb +5 -0
- data/spec/corelib/enumerable/min_break_spec.rb +5 -0
- data/spec/corelib/enumerable/min_by_break_spec.rb +5 -0
- data/spec/corelib/enumerable/none_break_spec.rb +5 -0
- data/spec/corelib/enumerable/one_break_spec.rb +5 -0
- data/spec/corelib/enumerable/reduce_break_spec.rb +5 -0
- data/spec/corelib/enumerable/take_while_break_spec.rb +5 -0
- data/spec/{rubyspec → corelib}/fixtures/class.rb +0 -0
- data/spec/{rubyspec → corelib}/fixtures/class_variables.rb +0 -0
- data/spec/{rubyspec → corelib}/fixtures/constants.rb +0 -0
- data/spec/{rubyspec/core → corelib}/kernel/Array_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/block_given_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/class_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/kernel/define_singleton_method_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/kernel/equal_value_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/extend_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/format_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/freeze_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/kernel/instance_eval_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/instance_variable_defined_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/kernel/instance_variable_get_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/kernel/instance_variable_set_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/kernel/loop_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/match_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/method_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/methods_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/nil_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/p_spec.rb +8 -6
- data/spec/{opal → corelib}/kernel/printf_spec.rb +4 -2
- data/spec/{opal → corelib}/kernel/proc_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/rand_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/respond_to_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/kernel/send_spec.rb +0 -0
- data/spec/{opal → corelib}/kernel/sprintf_spec.rb +0 -0
- data/spec/corelib/kernel/warn_spec.rb +83 -0
- data/spec/{rubyspec → corelib}/language/block_spec.rb +17 -18
- data/spec/{rubyspec → corelib}/language/fixtures/array.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/block.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/break.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/ensure.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/literal_lambda.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/metaclass.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/module.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/next.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/return.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/send.rb +1 -1
- data/spec/{rubyspec → corelib}/language/fixtures/send_1.9.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/super.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/variables.rb +0 -0
- data/spec/{rubyspec → corelib}/language/fixtures/yield.rb +0 -0
- data/spec/{rubyspec → corelib}/language/numbers_spec.rb +0 -2
- data/spec/{rubyspec → corelib}/language/predefined_spec.rb +0 -0
- data/spec/{rubyspec → corelib}/language/proc_spec.rb +0 -2
- data/spec/{rubyspec → corelib}/language/regexp_spec.rb +0 -0
- data/spec/{rubyspec → corelib}/language/send_spec.rb +6 -7
- data/spec/{rubyspec → corelib}/language/string_spec.rb +0 -0
- data/spec/{rubyspec → corelib}/language/symbol_spec.rb +0 -0
- data/spec/{rubyspec → corelib}/language/variables_spec.rb +1 -2
- data/spec/{rubyspec → corelib}/language/versions/array_1.9.rb +0 -0
- data/spec/{rubyspec → corelib}/language/versions/block_1.9.rb +0 -0
- data/spec/{rubyspec → corelib}/language/versions/break_1.9.rb +0 -0
- data/spec/{rubyspec → corelib}/language/versions/case_1.9.rb +0 -0
- data/spec/{rubyspec → corelib}/language/versions/hash_1.9.rb +0 -0
- data/spec/{rubyspec → corelib}/language/versions/literal_lambda_1.9.rb +0 -0
- data/spec/{rubyspec → corelib}/language/versions/not_1.9.rb +0 -0
- data/spec/{rubyspec → corelib}/language/versions/send_1.9.rb +0 -0
- data/spec/{rubyspec → corelib}/language/versions/symbol_1.9.rb +0 -0
- data/spec/{rubyspec → corelib}/language/versions/variables_1.9.rb +1 -1
- data/spec/corelib/module/alias_method_spec.rb +28 -0
- data/spec/{opal → corelib}/module/ancestors_spec.rb +0 -0
- data/spec/{opal → corelib}/module/append_features_spec.rb +0 -0
- data/spec/corelib/module/attr_accessor_spec.rb +26 -0
- data/spec/{rubyspec/core → corelib}/module/const_defined_spec.rb +1 -2
- data/spec/{rubyspec/core → corelib}/module/const_get_spec.rb +1 -2
- data/spec/{rubyspec/core → corelib}/module/const_missing_spec.rb +1 -2
- data/spec/{rubyspec/core → corelib}/module/const_set_spec.rb +1 -2
- data/spec/{opal → corelib}/module/constants_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/module/fixtures/classes.rb +0 -0
- data/spec/{rubyspec/core → corelib}/module/method_defined_spec.rb +0 -1
- data/spec/{opal → corelib}/module/module_function_spec.rb +0 -2
- data/spec/corelib/module/name_spec.rb +52 -0
- data/spec/{rubyspec/core → corelib}/module/public_method_defined_spec.rb +0 -1
- data/spec/{rubyspec/core → corelib}/module/remove_const_spec.rb +0 -1
- data/spec/{rubyspec/core → corelib}/module/undef_method_spec.rb +0 -1
- data/spec/{opal → corelib}/native/alias_native_spec.rb +7 -0
- data/spec/{opal → corelib}/native/each_spec.rb +2 -5
- data/spec/{opal → corelib}/native/element_reference_spec.rb +0 -0
- data/spec/{rubyspec/core/hash/to_native_spec.rb → corelib/native/ext_spec.rb} +0 -0
- data/spec/corelib/native/initialize_spec.rb +17 -0
- data/spec/{opal → corelib}/native/method_missing_spec.rb +0 -0
- data/spec/corelib/native/new_spec.rb +6 -0
- data/spec/{rubyspec/core → corelib}/numeric/abs_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/bit_and_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/bit_or_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/bit_xor_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/ceil_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/chr_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/comparison_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/complement_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/divide_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/downto_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/eql_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/equal_value_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/even_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/exponent_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/floor_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/gt_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/gte_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/integer_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/left_shift_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/lt_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/lte_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/magnitude_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/minus_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/modulo_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/multiply_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/next_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/odd_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/ord_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/plus_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/pred_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/right_shift_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/step_spec.rb +0 -3
- data/spec/{rubyspec/core → corelib}/numeric/succ_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/times_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/to_f_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/to_i_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/to_json_spec.rb +0 -0
- data/spec/corelib/numeric/to_s_spec.rb +26 -0
- data/spec/{rubyspec/core → corelib}/numeric/uminus_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/upto_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/numeric/zero_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/proc/call_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/proc/element_reference_spec.rb +0 -0
- data/spec/{opal → corelib}/proc/proc_tricks_spec.rb +0 -0
- data/spec/corelib/runtime/begin_spec.rb +39 -0
- data/spec/{opal → corelib}/runtime/block_send_spec.rb +0 -0
- data/spec/{opal/language → corelib/runtime}/block_spec.rb +10 -0
- data/spec/corelib/runtime/bridged_classes_spec.rb +64 -0
- data/spec/{opal → corelib/runtime}/constants_spec.rb +0 -0
- data/spec/{opal → corelib}/runtime/eval_spec.rb +0 -0
- data/spec/{opal → corelib}/runtime/main_methods_spec.rb +0 -0
- data/spec/{opal → corelib/runtime}/method_missing_spec.rb +0 -0
- data/spec/corelib/runtime/method_spec.rb +31 -0
- data/spec/corelib/runtime/paren_spec.rb +14 -0
- data/spec/{opal/language → corelib/runtime}/rescue_spec.rb +11 -0
- data/spec/{opal/language → corelib/runtime}/return_spec.rb +0 -0
- data/spec/{opal → corelib}/runtime/send_spec.rb +0 -0
- data/spec/{opal/language → corelib/runtime}/singleton_class_spec.rb +0 -0
- data/spec/{opal/language → corelib/runtime}/super_spec.rb +113 -0
- data/spec/{opal/language → corelib/runtime}/variables_spec.rb +0 -0
- data/spec/{opal → corelib}/source_map_spec.rb +3 -3
- data/spec/{rubyspec/core → corelib}/string/chop_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/chr_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/clone_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/comparison_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/dup_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/element_reference_spec.rb +0 -1
- data/spec/{rubyspec/core → corelib}/string/fixtures/classes.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/format_spec.rb +0 -0
- data/spec/{opal → corelib}/string/freeze_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/gsub_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/lines_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/ljust_spec.rb +0 -1
- data/spec/{rubyspec/core → corelib}/string/lstrip_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/match_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/next_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/ord_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/partition_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/rindex_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/rjust_spec.rb +0 -1
- data/spec/{rubyspec/core → corelib}/string/rstrip_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/scan_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/slice_spec.rb +1 -2
- data/spec/{rubyspec/core → corelib}/string/split_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/strip_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/sub_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/succ_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/sum_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/to_f_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/to_i_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/tr_s_spec.rb +0 -0
- data/spec/{rubyspec/core → corelib}/string/tr_spec.rb +0 -0
- data/spec/filters/bugs/array.rb +236 -4
- data/spec/filters/bugs/basic_object.rb +4 -0
- data/spec/filters/bugs/class.rb +4 -0
- data/spec/filters/bugs/enumerable.rb +58 -0
- data/spec/filters/bugs/enumerator.rb +6 -0
- data/spec/filters/bugs/hash.rb +146 -0
- data/spec/filters/bugs/kernel.rb +10 -0
- data/spec/filters/bugs/language.rb +366 -0
- data/spec/filters/bugs/module.rb +14 -0
- data/spec/filters/bugs/regexp.rb +7 -0
- data/spec/filters/bugs/set.rb +7 -0
- data/spec/filters/bugs/{singleton/instance.rb → singleton.rb} +3 -1
- data/spec/filters/bugs/string.rb +37 -0
- data/spec/filters/bugs/stringscanner.rb +18 -0
- data/spec/filters/bugs/struct.rb +11 -0
- data/spec/filters/bugs/symbol.rb +5 -0
- data/spec/filters/bugs/time.rb +28 -0
- data/spec/filters/bugs/unknown.rb +11 -0
- data/spec/filters/unsupported/array_subclasses.rb +32 -0
- data/spec/filters/unsupported/encoding.rb +14 -0
- data/spec/filters/unsupported/float.rb +4 -0
- data/spec/filters/unsupported/frozen.rb +57 -0
- data/spec/filters/unsupported/hash_compare_by_identity.rb +16 -0
- data/spec/filters/unsupported/immutable_strings.rb +6 -0
- data/spec/filters/unsupported/mutable_strings.rb +49 -0
- data/spec/filters/unsupported/private_methods.rb +26 -0
- data/spec/filters/{mspec → unsupported}/ruby_exe.rb +0 -0
- data/spec/filters/unsupported/string_subclasses.rb +8 -0
- data/spec/filters/unsupported/tainted.rb +46 -0
- data/spec/filters/unsupported/time.rb +21 -0
- data/spec/filters/unsupported/trusted.rb +26 -0
- data/spec/opal/{parser → compiler}/irb_spec.rb +9 -9
- data/spec/{parser → opal/parser}/alias_spec.rb +0 -0
- data/spec/{parser → opal/parser}/and_spec.rb +0 -0
- data/spec/{parser → opal/parser}/array_spec.rb +0 -0
- data/spec/{parser → opal/parser}/attrasgn_spec.rb +0 -0
- data/spec/{parser → opal/parser}/begin_spec.rb +0 -0
- data/spec/{parser → opal/parser}/block_spec.rb +0 -0
- data/spec/{parser → opal/parser}/break_spec.rb +0 -0
- data/spec/{parser → opal/parser}/call_spec.rb +33 -8
- data/spec/{parser → opal/parser}/class_spec.rb +0 -0
- data/spec/{parser → opal/parser}/const_spec.rb +0 -0
- data/spec/{parser → opal/parser}/cvar_spec.rb +0 -0
- data/spec/{parser → opal/parser}/def_spec.rb +17 -17
- data/spec/{parser → opal/parser}/false_spec.rb +0 -0
- data/spec/{parser → opal/parser}/file_spec.rb +0 -0
- data/spec/{parser → opal/parser}/gvar_spec.rb +0 -0
- data/spec/{parser → opal/parser}/hash_spec.rb +0 -0
- data/spec/opal/parser/heredoc_spec.rb +30 -0
- data/spec/{parser → opal/parser}/iasgn_spec.rb +0 -0
- data/spec/{parser → opal/parser}/if_spec.rb +0 -0
- data/spec/{parser → opal/parser}/int_spec.rb +0 -0
- data/spec/opal/parser/iter_spec.rb +59 -0
- data/spec/{parser → opal/parser}/ivar_spec.rb +0 -0
- data/spec/opal/parser/lambda_spec.rb +64 -0
- data/spec/{parser → opal/parser}/lasgn_spec.rb +0 -0
- data/spec/{parser → opal/parser}/line_spec.rb +0 -0
- data/spec/{parser → opal/parser}/lvar_spec.rb +6 -6
- data/spec/{parser → opal/parser}/masgn_spec.rb +0 -0
- data/spec/{parser → opal/parser}/module_spec.rb +0 -0
- data/spec/{parser → opal/parser}/nil_spec.rb +0 -0
- data/spec/{parser → opal/parser}/not_spec.rb +0 -0
- data/spec/{parser → opal/parser}/nth_ref_spec.rb +0 -0
- data/spec/{parser → opal/parser}/op_asgn1_spec.rb +0 -0
- data/spec/{parser → opal/parser}/op_asgn2_spec.rb +0 -0
- data/spec/{parser → opal/parser}/or_spec.rb +0 -0
- data/spec/{parser → opal/parser}/parse_spec.rb +17 -17
- data/spec/{parser → opal/parser}/regexp_spec.rb +0 -0
- data/spec/{parser → opal/parser}/return_spec.rb +0 -0
- data/spec/{parser → opal/parser}/sclass_spec.rb +0 -0
- data/spec/{parser → opal/parser}/self_spec.rb +0 -0
- data/spec/{parser → opal/parser}/str_spec.rb +1 -12
- data/spec/{parser → opal/parser}/string_spec.rb +0 -0
- data/spec/opal/parser/super_spec.rb +20 -0
- data/spec/{parser → opal/parser}/true_spec.rb +0 -0
- data/spec/{parser → opal/parser}/undef_spec.rb +0 -0
- data/spec/{parser → opal/parser}/unless_spec.rb +0 -0
- data/spec/{parser → opal/parser}/while_spec.rb +0 -0
- data/spec/{parser → opal/parser}/xstr_spec.rb +2 -2
- data/spec/{parser → opal/parser}/yield_spec.rb +0 -0
- data/spec/ospec/main.rb.erb +1 -13
- data/spec/ospec/mspec_fixes.rb +87 -0
- data/spec/ospec/runner.rb +188 -0
- data/spec/rubyspecs +351 -0
- data/spec/spec_helper.rb +8 -198
- data/spec/{opal → stdlib}/erb/erb_spec.rb +3 -3
- data/spec/{opal → stdlib}/erb/inline_block.opalerb +0 -0
- data/spec/{opal → stdlib}/erb/quoted.opalerb +0 -0
- data/spec/{opal → stdlib}/erb/simple.opalerb +0 -0
- data/spec/stdlib/json/ext_spec.rb +48 -0
- data/spec/{opal → stdlib}/json/parse_spec.rb +0 -0
- data/spec/stdlib/template/paths_spec.rb +10 -0
- data/stdlib/delegate.rb +29 -0
- data/stdlib/dir.rb +5 -0
- data/stdlib/file.rb +7 -0
- data/stdlib/json.rb +82 -27
- data/stdlib/opal-parser.rb +46 -0
- data/stdlib/opal-source-maps.js.erb +1 -1
- data/stdlib/pathname.rb +31 -0
- data/stdlib/{racc.rb → racc/parser.rb} +0 -0
- data/stdlib/securerandom.rb +12 -0
- data/stdlib/set.rb +89 -0
- data/stdlib/stringio.rb +12 -4
- data/stdlib/strscan.rb +19 -0
- data/stdlib/template.rb +4 -0
- data/stdlib/thread.rb +20 -0
- data/tasks/mspec.rake +147 -0
- metadata +650 -1266
- data/lib/opal/core_ext.rb +0 -5
- data/lib/opal/grammar.rb +0 -5137
- data/lib/opal/grammar_helpers.rb +0 -364
- data/lib/opal/require_parser.rb +0 -77
- data/spec/filters/bugs/alias.rb +0 -6
- data/spec/filters/bugs/ancestors.rb +0 -4
- data/spec/filters/bugs/array/combination.rb +0 -11
- data/spec/filters/bugs/array/count.rb +0 -3
- data/spec/filters/bugs/array/delete_if.rb +0 -3
- data/spec/filters/bugs/array/drop.rb +0 -3
- data/spec/filters/bugs/array/drop_while.rb +0 -5
- data/spec/filters/bugs/array/eql.rb +0 -3
- data/spec/filters/bugs/array/flatten.rb +0 -9
- data/spec/filters/bugs/array/minus.rb +0 -5
- data/spec/filters/bugs/array/multipliy.rb +0 -9
- data/spec/filters/bugs/array/new.rb +0 -3
- data/spec/filters/bugs/array/pop.rb +0 -6
- data/spec/filters/bugs/array/rassoc.rb +0 -4
- data/spec/filters/bugs/array/rindex.rb +0 -6
- data/spec/filters/bugs/array/select.rb +0 -3
- data/spec/filters/bugs/array/shift.rb +0 -7
- data/spec/filters/bugs/array/shuffle.rb +0 -11
- data/spec/filters/bugs/array/slice.rb +0 -7
- data/spec/filters/bugs/array/take.rb +0 -3
- data/spec/filters/bugs/array/to_a.rb +0 -3
- data/spec/filters/bugs/array/try_convert.rb +0 -7
- data/spec/filters/bugs/array/uniq.rb +0 -10
- data/spec/filters/bugs/array/zip.rb +0 -4
- data/spec/filters/bugs/array_delete.rb +0 -4
- data/spec/filters/bugs/array_fetch.rb +0 -3
- data/spec/filters/bugs/array_first.rb +0 -3
- data/spec/filters/bugs/array_flatten.rb +0 -14
- data/spec/filters/bugs/array_intersection.rb +0 -5
- data/spec/filters/bugs/array_join.rb +0 -6
- data/spec/filters/bugs/break.rb +0 -10
- data/spec/filters/bugs/case.rb +0 -4
- data/spec/filters/bugs/coerce_integer.rb +0 -9
- data/spec/filters/bugs/enumerable_sort_by.rb +0 -3
- data/spec/filters/bugs/kernel/instance_variables.rb +0 -3
- data/spec/filters/bugs/kernel/rand.rb +0 -4
- data/spec/filters/bugs/language/array.rb +0 -3
- data/spec/filters/bugs/language/block.rb +0 -6
- data/spec/filters/bugs/language/break.rb +0 -3
- data/spec/filters/bugs/language/class.rb +0 -12
- data/spec/filters/bugs/language/class_variables.rb +0 -12
- data/spec/filters/bugs/language/def.rb +0 -27
- data/spec/filters/bugs/language/defined.rb +0 -3
- data/spec/filters/bugs/language/ensure.rb +0 -4
- data/spec/filters/bugs/language/execution.rb +0 -4
- data/spec/filters/bugs/language/for.rb +0 -18
- data/spec/filters/bugs/language/if.rb +0 -13
- data/spec/filters/bugs/language/loop.rb +0 -4
- data/spec/filters/bugs/language/metaclass.rb +0 -14
- data/spec/filters/bugs/language/module.rb +0 -6
- data/spec/filters/bugs/language/next.rb +0 -3
- data/spec/filters/bugs/language/or.rb +0 -3
- data/spec/filters/bugs/language/order.rb +0 -4
- data/spec/filters/bugs/language/precedence.rb +0 -10
- data/spec/filters/bugs/language/proc.rb +0 -24
- data/spec/filters/bugs/language/redo.rb +0 -5
- data/spec/filters/bugs/language/rescue.rb +0 -9
- data/spec/filters/bugs/language/retry.rb +0 -5
- data/spec/filters/bugs/language/send.rb +0 -10
- data/spec/filters/bugs/language/super.rb +0 -9
- data/spec/filters/bugs/language/until.rb +0 -8
- data/spec/filters/bugs/language/variables.rb +0 -37
- data/spec/filters/bugs/language/while.rb +0 -6
- data/spec/filters/bugs/language/yield.rb +0 -5
- data/spec/filters/bugs/module/class_variables.rb +0 -6
- data/spec/filters/bugs/module/method_defined.rb +0 -6
- data/spec/filters/bugs/public_methods.rb +0 -4
- data/spec/filters/bugs/return.rb +0 -7
- data/spec/filters/bugs/source_map.rb +0 -3
- data/spec/filters/bugs/string/center.rb +0 -4
- data/spec/filters/bugs/string/lines.rb +0 -3
- data/spec/filters/mspec/mocks.rb +0 -3
- data/spec/filters/mspec/should_receive.rb +0 -5
- data/spec/filters/parser/block_args.rb +0 -51
- data/spec/mspec/guards/block_device.rb +0 -0
- data/spec/mspec/guards/endian.rb +0 -0
- data/spec/mspec/helpers/environment.rb +0 -0
- data/spec/mspec/helpers/language_version.rb +0 -0
- data/spec/mspec/helpers/tmp.rb +0 -0
- data/spec/opal/array/element_reference_spec.rb +0 -206
- data/spec/opal/array/equal_value_spec.rb +0 -19
- data/spec/opal/array/fill_spec.rb +0 -26
- data/spec/opal/array/reduce_spec.rb +0 -31
- data/spec/opal/array/to_json_spec.rb +0 -9
- data/spec/opal/basic_object/send_spec.rb +0 -28
- data/spec/opal/boolean/singleton_class_spec.rb +0 -9
- data/spec/opal/boolean/to_json_spec.rb +0 -11
- data/spec/opal/browser/local_storage_spec.rb +0 -55
- data/spec/opal/class/constants_spec.rb +0 -7
- data/spec/opal/class/extend_spec.rb +0 -47
- data/spec/opal/class/instance_methods_spec.rb +0 -13
- data/spec/opal/class/last_value_spec.rb +0 -67
- data/spec/opal/class/proc_methods_spec.rb +0 -23
- data/spec/opal/class/singleton_methods_spec.rb +0 -41
- data/spec/opal/hash/allocate_spec.rb +0 -16
- data/spec/opal/hash/new_spec.rb +0 -10
- data/spec/opal/hash/to_s_spec.rb +0 -9
- data/spec/opal/kernel/to_json_spec.rb +0 -7
- data/spec/opal/module/alias_method_spec.rb +0 -10
- data/spec/opal/module/attr_accessor_spec.rb +0 -8
- data/spec/opal/native/new_spec.rb +0 -19
- data/spec/opal/native/nil_spec.rb +0 -14
- data/spec/opal/nil/to_json_spec.rb +0 -7
- data/spec/opal/numeric/equal_spec.rb +0 -9
- data/spec/opal/runtime2/call_spec.rb +0 -16
- data/spec/opal/runtime2/class_hierarchy_spec.rb +0 -21
- data/spec/opal/runtime2/defined_spec.rb +0 -11
- data/spec/opal/runtime2/super_spec.rb +0 -16
- data/spec/opal/string/to_json_spec.rb +0 -8
- data/spec/parser/iter_spec.rb +0 -59
- data/spec/parser/lambda_spec.rb +0 -64
- data/spec/parser/parser_spec.rb +0 -41
- data/spec/parser/strscan/check_spec.rb +0 -13
- data/spec/parser/strscan/get_byte_spec.rb +0 -29
- data/spec/parser/strscan/scan_spec.rb +0 -33
- data/spec/parser/strscan/skip_spec.rb +0 -40
- data/spec/parser/super_spec.rb +0 -20
- data/spec/rubyspec/core/array/allocate_spec.rb +0 -19
- data/spec/rubyspec/core/array/append_spec.rb +0 -43
- data/spec/rubyspec/core/array/array_spec.rb +0 -7
- data/spec/rubyspec/core/array/assoc_spec.rb +0 -40
- data/spec/rubyspec/core/array/at_spec.rb +0 -56
- data/spec/rubyspec/core/array/choice_spec.rb +0 -20
- data/spec/rubyspec/core/array/clear_spec.rb +0 -61
- data/spec/rubyspec/core/array/clone_spec.rb +0 -15
- data/spec/rubyspec/core/array/collect_spec.rb +0 -53
- data/spec/rubyspec/core/array/combination_spec.rb +0 -55
- data/spec/rubyspec/core/array/compact_spec.rb +0 -111
- data/spec/rubyspec/core/array/comparison_spec.rb +0 -16
- data/spec/rubyspec/core/array/concat_spec.rb +0 -19
- data/spec/rubyspec/core/array/constructor_spec.rb +0 -24
- data/spec/rubyspec/core/array/count_spec.rb +0 -17
- data/spec/rubyspec/core/array/delete_at_spec.rb +0 -71
- data/spec/rubyspec/core/array/delete_if_spec.rb +0 -71
- data/spec/rubyspec/core/array/delete_spec.rb +0 -104
- data/spec/rubyspec/core/array/drop_spec.rb +0 -29
- data/spec/rubyspec/core/array/drop_while_spec.rb +0 -17
- data/spec/rubyspec/core/array/dup_spec.rb +0 -15
- data/spec/rubyspec/core/array/each_index_spec.rb +0 -40
- data/spec/rubyspec/core/array/each_spec.rb +0 -30
- data/spec/rubyspec/core/array/empty_spec.rb +0 -10
- data/spec/rubyspec/core/array/eql_spec.rb +0 -14
- data/spec/rubyspec/core/array/fetch_spec.rb +0 -52
- data/spec/rubyspec/core/array/find_index_spec.rb +0 -8
- data/spec/rubyspec/core/array/first_spec.rb +0 -89
- data/spec/rubyspec/core/array/fixtures/classes.rb +0 -538
- data/spec/rubyspec/core/array/flatten_spec.rb +0 -232
- data/spec/rubyspec/core/array/frozen_spec.rb +0 -32
- data/spec/rubyspec/core/array/include_spec.rb +0 -33
- data/spec/rubyspec/core/array/index_spec.rb +0 -6
- data/spec/rubyspec/core/array/insert_spec.rb +0 -90
- data/spec/rubyspec/core/array/inspect_spec.rb +0 -7
- data/spec/rubyspec/core/array/intersection_spec.rb +0 -78
- data/spec/rubyspec/core/array/join_spec.rb +0 -34
- data/spec/rubyspec/core/array/keep_if_spec.rb +0 -12
- data/spec/rubyspec/core/array/last_spec.rb +0 -88
- data/spec/rubyspec/core/array/length_spec.rb +0 -7
- data/spec/rubyspec/core/array/map_spec.rb +0 -11
- data/spec/rubyspec/core/array/max_spec.rb +0 -32
- data/spec/rubyspec/core/array/min_spec.rb +0 -32
- data/spec/rubyspec/core/array/minus_spec.rb +0 -89
- data/spec/rubyspec/core/array/multiply_spec.rb +0 -143
- data/spec/rubyspec/core/array/new_spec.rb +0 -137
- data/spec/rubyspec/core/array/ntimes_spec.rb +0 -26
- data/spec/rubyspec/core/array/plus_spec.rb +0 -64
- data/spec/rubyspec/core/array/pop_spec.rb +0 -196
- data/spec/rubyspec/core/array/push_spec.rb +0 -44
- data/spec/rubyspec/core/array/rassoc_spec.rb +0 -38
- data/spec/rubyspec/core/array/reject_spec.rb +0 -134
- data/spec/rubyspec/core/array/replace_spec.rb +0 -7
- data/spec/rubyspec/core/array/reverse_each_spec.rb +0 -37
- data/spec/rubyspec/core/array/reverse_spec.rb +0 -58
- data/spec/rubyspec/core/array/rindex_spec.rb +0 -71
- data/spec/rubyspec/core/array/select_spec.rb +0 -36
- data/spec/rubyspec/core/array/shared/collect.rb +0 -7
- data/spec/rubyspec/core/array/shared/enumeratorize.rb +0 -12
- data/spec/rubyspec/core/array/shared/eql.rb +0 -95
- data/spec/rubyspec/core/array/shared/index.rb +0 -37
- data/spec/rubyspec/core/array/shared/inspect.rb +0 -3
- data/spec/rubyspec/core/array/shared/join.rb +0 -7
- data/spec/rubyspec/core/array/shared/keep_if.rb +0 -3
- data/spec/rubyspec/core/array/shared/length.rb +0 -3
- data/spec/rubyspec/core/array/shared/replace.rb +0 -3
- data/spec/rubyspec/core/array/shared/slice.rb +0 -3
- data/spec/rubyspec/core/array/shift_spec.rb +0 -160
- data/spec/rubyspec/core/array/shuffle_spec.rb +0 -87
- data/spec/rubyspec/core/array/size_spec.rb +0 -7
- data/spec/rubyspec/core/array/slice_spec.rb +0 -166
- data/spec/rubyspec/core/array/sort_spec.rb +0 -271
- data/spec/rubyspec/core/array/take_spec.rb +0 -29
- data/spec/rubyspec/core/array/take_while_spec.rb +0 -17
- data/spec/rubyspec/core/array/to_a_spec.rb +0 -24
- data/spec/rubyspec/core/array/to_ary_spec.rb +0 -20
- data/spec/rubyspec/core/array/try_convert_spec.rb +0 -52
- data/spec/rubyspec/core/array/uniq_spec.rb +0 -167
- data/spec/rubyspec/core/array/unshift_spec.rb +0 -64
- data/spec/rubyspec/core/array/zip_spec.rb +0 -55
- data/spec/rubyspec/core/class/fixtures/classes.rb +0 -9
- data/spec/rubyspec/core/class/new_spec.rb +0 -113
- data/spec/rubyspec/core/enumerable/all_spec.rb +0 -130
- data/spec/rubyspec/core/enumerable/any_spec.rb +0 -150
- data/spec/rubyspec/core/enumerable/collect_spec.rb +0 -39
- data/spec/rubyspec/core/enumerable/count_spec.rb +0 -45
- data/spec/rubyspec/core/enumerable/detect_spec.rb +0 -48
- data/spec/rubyspec/core/enumerable/drop_spec.rb +0 -20
- data/spec/rubyspec/core/enumerable/drop_while_spec.rb +0 -18
- data/spec/rubyspec/core/enumerable/each_slice_spec.rb +0 -25
- data/spec/rubyspec/core/enumerable/each_with_index_spec.rb +0 -14
- data/spec/rubyspec/core/enumerable/each_with_object_spec.rb +0 -20
- data/spec/rubyspec/core/enumerable/entries_spec.rb +0 -9
- data/spec/rubyspec/core/enumerable/find_all_spec.rb +0 -16
- data/spec/rubyspec/core/enumerable/find_index_spec.rb +0 -44
- data/spec/rubyspec/core/enumerable/find_spec.rb +0 -56
- data/spec/rubyspec/core/enumerable/first_spec.rb +0 -43
- data/spec/rubyspec/core/enumerable/fixtures/classes.rb +0 -240
- data/spec/rubyspec/core/enumerable/grep_spec.rb +0 -24
- data/spec/rubyspec/core/enumerable/group_by_spec.rb +0 -16
- data/spec/rubyspec/core/enumerable/none_spec.rb +0 -68
- data/spec/rubyspec/core/enumerable/select_spec.rb +0 -16
- data/spec/rubyspec/core/enumerable/sort_by_spec.rb +0 -31
- data/spec/rubyspec/core/enumerable/take_spec.rb +0 -43
- data/spec/rubyspec/core/enumerable/to_a_spec.rb +0 -9
- data/spec/rubyspec/core/enumerator/each_spec.rb +0 -11
- data/spec/rubyspec/core/enumerator/new_spec.rb +0 -17
- data/spec/rubyspec/core/enumerator/next_spec.rb +0 -25
- data/spec/rubyspec/core/enumerator/rewind_spec.rb +0 -28
- data/spec/rubyspec/core/false/and_spec.rb +0 -11
- data/spec/rubyspec/core/false/inspect_spec.rb +0 -7
- data/spec/rubyspec/core/false/or_spec.rb +0 -11
- data/spec/rubyspec/core/false/to_s_spec.rb +0 -7
- data/spec/rubyspec/core/false/xor_spec.rb +0 -11
- data/spec/rubyspec/core/hash/allocate_spec.rb +0 -13
- data/spec/rubyspec/core/hash/assoc_spec.rb +0 -25
- data/spec/rubyspec/core/hash/clear_spec.rb +0 -19
- data/spec/rubyspec/core/hash/clone_spec.rb +0 -10
- data/spec/rubyspec/core/hash/constructor_spec.rb +0 -13
- data/spec/rubyspec/core/hash/default_proc_spec.rb +0 -20
- data/spec/rubyspec/core/hash/default_spec.rb +0 -17
- data/spec/rubyspec/core/hash/delete_if_spec.rb +0 -13
- data/spec/rubyspec/core/hash/delete_spec.rb +0 -11
- data/spec/rubyspec/core/hash/dup_spec.rb +0 -10
- data/spec/rubyspec/core/hash/each_key_spec.rb +0 -15
- data/spec/rubyspec/core/hash/each_pair_spec.rb +0 -30
- data/spec/rubyspec/core/hash/each_spec.rb +0 -36
- data/spec/rubyspec/core/hash/each_value_spec.rb +0 -15
- data/spec/rubyspec/core/hash/element_reference_spec.rb +0 -41
- data/spec/rubyspec/core/hash/element_set_spec.rb +0 -7
- data/spec/rubyspec/core/hash/empty_spec.rb +0 -10
- data/spec/rubyspec/core/hash/fetch_spec.rb +0 -24
- data/spec/rubyspec/core/hash/flatten_spec.rb +0 -46
- data/spec/rubyspec/core/hash/has_key_spec.rb +0 -24
- data/spec/rubyspec/core/hash/has_value_spec.rb +0 -12
- data/spec/rubyspec/core/hash/include_spec.rb +0 -24
- data/spec/rubyspec/core/hash/index_spec.rb +0 -13
- data/spec/rubyspec/core/hash/indexes_spec.rb +0 -9
- data/spec/rubyspec/core/hash/indices_spec.rb +0 -9
- data/spec/rubyspec/core/hash/invert_spec.rb +0 -12
- data/spec/rubyspec/core/hash/keep_if_spec.rb +0 -18
- data/spec/rubyspec/core/hash/key_spec.rb +0 -24
- data/spec/rubyspec/core/hash/keys_spec.rb +0 -10
- data/spec/rubyspec/core/hash/length_spec.rb +0 -10
- data/spec/rubyspec/core/hash/member_spec.rb +0 -24
- data/spec/rubyspec/core/hash/merge_spec.rb +0 -37
- data/spec/rubyspec/core/hash/new_spec.rb +0 -19
- data/spec/rubyspec/core/hash/rassoc_spec.rb +0 -34
- data/spec/rubyspec/core/hash/reject_spec.rb +0 -18
- data/spec/rubyspec/core/hash/replace_spec.rb +0 -7
- data/spec/rubyspec/core/hash/select_spec.rb +0 -52
- data/spec/rubyspec/core/hash/shift_spec.rb +0 -19
- data/spec/rubyspec/core/hash/size_spec.rb +0 -10
- data/spec/rubyspec/core/hash/to_a_spec.rb +0 -13
- data/spec/rubyspec/core/hash/to_json_spec.rb +0 -11
- data/spec/rubyspec/core/hash/update_spec.rb +0 -17
- data/spec/rubyspec/core/hash/value_spec.rb +0 -12
- data/spec/rubyspec/core/hash/values_at_spec.rb +0 -9
- data/spec/rubyspec/core/hash/values_spec.rb +0 -7
- data/spec/rubyspec/core/kernel/eql_spec.rb +0 -15
- data/spec/rubyspec/core/kernel/equal_spec.rb +0 -12
- data/spec/rubyspec/core/kernel/tap_spec.rb +0 -10
- data/spec/rubyspec/core/kernel/to_s_spec.rb +0 -5
- data/spec/rubyspec/core/matchdata/to_a_spec.rb +0 -5
- data/spec/rubyspec/core/nil/and_spec.rb +0 -11
- data/spec/rubyspec/core/nil/dup_spec.rb +0 -7
- data/spec/rubyspec/core/nil/inspect_spec.rb +0 -7
- data/spec/rubyspec/core/nil/nil_spec.rb +0 -7
- data/spec/rubyspec/core/nil/or_spec.rb +0 -11
- data/spec/rubyspec/core/nil/to_a_spec.rb +0 -7
- data/spec/rubyspec/core/nil/to_f_spec.rb +0 -11
- data/spec/rubyspec/core/nil/to_h_spec.rb +0 -10
- data/spec/rubyspec/core/nil/to_i_spec.rb +0 -11
- data/spec/rubyspec/core/nil/to_s_spec.rb +0 -7
- data/spec/rubyspec/core/nil/xor_spec.rb +0 -11
- data/spec/rubyspec/core/numeric/to_s_spec.rb +0 -8
- data/spec/rubyspec/core/range/begin_spec.rb +0 -9
- data/spec/rubyspec/core/range/case_compare_spec.rb +0 -15
- data/spec/rubyspec/core/range/end_spec.rb +0 -9
- data/spec/rubyspec/core/regexp/match_spec.rb +0 -95
- data/spec/rubyspec/core/string/capitalize_spec.rb +0 -10
- data/spec/rubyspec/core/string/casecmp_spec.rb +0 -16
- data/spec/rubyspec/core/string/center_spec.rb +0 -49
- data/spec/rubyspec/core/string/chomp_spec.rb +0 -48
- data/spec/rubyspec/core/string/downcase_spec.rb +0 -6
- data/spec/rubyspec/core/string/empty_spec.rb +0 -7
- data/spec/rubyspec/core/string/end_with_spec.rb +0 -16
- data/spec/rubyspec/core/string/include_spec.rb +0 -6
- data/spec/rubyspec/core/string/index_spec.rb +0 -405
- data/spec/rubyspec/core/string/intern_spec.rb +0 -9
- data/spec/rubyspec/core/string/length_spec.rb +0 -9
- data/spec/rubyspec/core/string/reverse_spec.rb +0 -7
- data/spec/rubyspec/core/string/size_spec.rb +0 -9
- data/spec/rubyspec/core/string/start_with_spec.rb +0 -12
- data/spec/rubyspec/core/string/swapcase_spec.rb +0 -13
- data/spec/rubyspec/core/string/to_a_spec.rb +0 -9
- data/spec/rubyspec/core/string/to_s_spec.rb +0 -6
- data/spec/rubyspec/core/string/to_str_spec.rb +0 -6
- data/spec/rubyspec/core/string/to_sym_spec.rb +0 -9
- data/spec/rubyspec/core/string/upcase_spec.rb +0 -6
- data/spec/rubyspec/core/struct/fixtures/classes.rb +0 -26
- data/spec/rubyspec/core/struct/initialize_spec.rb +0 -11
- data/spec/rubyspec/core/struct/new_spec.rb +0 -24
- data/spec/rubyspec/core/symbol/to_proc_spec.rb +0 -12
- data/spec/rubyspec/core/time/at_spec.rb +0 -7
- data/spec/rubyspec/core/time/day_spec.rb +0 -5
- data/spec/rubyspec/core/time/friday_spec.rb +0 -9
- data/spec/rubyspec/core/time/hour_spec.rb +0 -5
- data/spec/rubyspec/core/time/min_spec.rb +0 -5
- data/spec/rubyspec/core/time/monday_spec.rb +0 -9
- data/spec/rubyspec/core/time/month_spec.rb +0 -5
- data/spec/rubyspec/core/time/now_spec.rb +0 -5
- data/spec/rubyspec/core/time/saturday_spec.rb +0 -9
- data/spec/rubyspec/core/true/and_spec.rb +0 -11
- data/spec/rubyspec/core/true/inspect_spec.rb +0 -7
- data/spec/rubyspec/core/true/or_spec.rb +0 -11
- data/spec/rubyspec/core/true/to_s_spec.rb +0 -7
- data/spec/rubyspec/core/true/xor_spec.rb +0 -11
- data/spec/rubyspec/language/alias_spec.rb +0 -160
- data/spec/rubyspec/language/and_spec.rb +0 -66
- data/spec/rubyspec/language/array_spec.rb +0 -117
- data/spec/rubyspec/language/break_spec.rb +0 -332
- data/spec/rubyspec/language/case_spec.rb +0 -310
- data/spec/rubyspec/language/class_spec.rb +0 -190
- data/spec/rubyspec/language/class_variable_spec.rb +0 -56
- data/spec/rubyspec/language/def_spec.rb +0 -551
- data/spec/rubyspec/language/defined_spec.rb +0 -107
- data/spec/rubyspec/language/ensure_spec.rb +0 -104
- data/spec/rubyspec/language/execution_spec.rb +0 -15
- data/spec/rubyspec/language/for_spec.rb +0 -192
- data/spec/rubyspec/language/hash_spec.rb +0 -65
- data/spec/rubyspec/language/if_spec.rb +0 -356
- data/spec/rubyspec/language/literal_lambda_spec.rb +0 -1
- data/spec/rubyspec/language/loop_spec.rb +0 -67
- data/spec/rubyspec/language/metaclass_spec.rb +0 -159
- data/spec/rubyspec/language/module_spec.rb +0 -56
- data/spec/rubyspec/language/next_spec.rb +0 -469
- data/spec/rubyspec/language/not_spec.rb +0 -55
- data/spec/rubyspec/language/or_spec.rb +0 -90
- data/spec/rubyspec/language/order_spec.rb +0 -77
- data/spec/rubyspec/language/precedence_spec.rb +0 -483
- data/spec/rubyspec/language/redo_spec.rb +0 -65
- data/spec/rubyspec/language/rescue_spec.rb +0 -121
- data/spec/rubyspec/language/retry_spec.rb +0 -56
- data/spec/rubyspec/language/return_spec.rb +0 -281
- data/spec/rubyspec/language/singleton_class_spec.rb +0 -32
- data/spec/rubyspec/language/super_spec.rb +0 -284
- data/spec/rubyspec/language/undef_spec.rb +0 -16
- data/spec/rubyspec/language/unless_spec.rb +0 -45
- data/spec/rubyspec/language/until_spec.rb +0 -234
- data/spec/rubyspec/language/while_spec.rb +0 -238
- data/spec/rubyspec/language/yield_spec.rb +0 -128
- data/spec/rubyspec/library/date/new_spec.rb +0 -10
- data/spec/rubyspec/library/date/to_s_spec.rb +0 -7
- data/spec/rubyspec/library/date/today_spec.rb +0 -7
- data/spec/rubyspec/library/erb/util/html_escape_spec.rb +0 -10
- data/spec/rubyspec/library/observer/add_observer_spec.rb +0 -31
- data/spec/rubyspec/library/observer/count_observers_spec.rb +0 -33
- data/spec/rubyspec/library/observer/delete_observer_spec.rb +0 -19
- data/spec/rubyspec/library/observer/delete_observers_spec.rb +0 -19
- data/spec/rubyspec/library/observer/fixtures/classes.rb +0 -25
- data/spec/rubyspec/library/observer/notify_observers_spec.rb +0 -31
- data/spec/rubyspec/library/rbconfig/config_spec.rb +0 -47
- data/spec/rubyspec/library/singleton/clone_spec.rb +0 -8
- data/spec/rubyspec/library/singleton/dup_spec.rb +0 -8
- data/spec/rubyspec/library/singleton/fixtures/classes.rb +0 -18
- data/spec/rubyspec/library/singleton/instance_spec.rb +0 -30
- data/spec/rubyspec/library/stringscanner/element_reference_spec.rb +0 -29
- data/spec/rubyspec/library/stringscanner/pos_spec.rb +0 -20
- data/spec/rubyspec/spec_helper.rb +0 -96
- data/stdlib/fileutils.rb +0 -0
- data/stdlib/iconv.rb +0 -0
- data/stdlib/opal-browser/local_storage.rb +0 -27
- data/stdlib/opal-browser/script_loader.rb +0 -35
- data/stdlib/opal-parser.js.erb +0 -13
- data/stdlib/yaml.rb +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'opal/nodes/base'
|
|
2
|
+
|
|
3
|
+
module Opal
|
|
4
|
+
module Nodes
|
|
5
|
+
class WhileNode < Base
|
|
6
|
+
handle :while
|
|
7
|
+
|
|
8
|
+
children :test, :body
|
|
9
|
+
|
|
10
|
+
def compile
|
|
11
|
+
with_temp do |redo_var|
|
|
12
|
+
test_code = js_truthy(test)
|
|
13
|
+
|
|
14
|
+
compiler.in_while do
|
|
15
|
+
while_loop[:closure] = true if wrap_in_closure?
|
|
16
|
+
while_loop[:redo_var] = redo_var
|
|
17
|
+
|
|
18
|
+
body_code = stmt(body)
|
|
19
|
+
|
|
20
|
+
if uses_redo?
|
|
21
|
+
push "#{redo_var} = false; #{while_open}#{redo_var} || "
|
|
22
|
+
push test_code
|
|
23
|
+
push while_close
|
|
24
|
+
else
|
|
25
|
+
push while_open, test_code, while_close
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
push "#{redo_var} = false;" if uses_redo?
|
|
29
|
+
line body_code, "}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
wrap '(function() {', '; return nil; })()' if wrap_in_closure?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def while_open
|
|
37
|
+
"while ("
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def while_close
|
|
41
|
+
") {"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def uses_redo?
|
|
45
|
+
while_loop[:use_redo]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def wrap_in_closure?
|
|
49
|
+
expr? or recv?
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class UntilNode < WhileNode
|
|
54
|
+
handle :until
|
|
55
|
+
|
|
56
|
+
def while_open
|
|
57
|
+
"while (!("
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def while_close
|
|
61
|
+
")) {"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'opal/nodes/base'
|
|
2
|
+
|
|
3
|
+
module Opal
|
|
4
|
+
module Nodes
|
|
5
|
+
class BaseYieldNode < Base
|
|
6
|
+
def compile_call(children, level)
|
|
7
|
+
scope.uses_block!
|
|
8
|
+
|
|
9
|
+
if yields_single_arg?(children)
|
|
10
|
+
push expr(children.first)
|
|
11
|
+
wrap "$opal.$yield1(#{block_name}, ", ')'
|
|
12
|
+
else
|
|
13
|
+
push expr(s(:arglist, *children))
|
|
14
|
+
|
|
15
|
+
if uses_splat?(children)
|
|
16
|
+
wrap "$opal.$yieldX(#{block_name}, ", ')'
|
|
17
|
+
else
|
|
18
|
+
wrap "$opal.$yieldX(#{block_name}, [", '])'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def block_name
|
|
24
|
+
scope.block_name || '$yield'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def yields_single_arg?(children)
|
|
28
|
+
!uses_splat?(children) and children.size == 1
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def uses_splat?(children)
|
|
32
|
+
children.any? { |child| child.type == :splat }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class YieldNode < BaseYieldNode
|
|
37
|
+
handle :yield
|
|
38
|
+
|
|
39
|
+
def compile
|
|
40
|
+
compile_call(children, @level)
|
|
41
|
+
|
|
42
|
+
if stmt?
|
|
43
|
+
wrap 'if (', ' === $breaker) return $breaker.$v'
|
|
44
|
+
else
|
|
45
|
+
with_temp do |tmp|
|
|
46
|
+
wrap "(((#{tmp} = ", ") === $breaker) ? $breaker.$v : #{tmp})"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# special opal yield assign, for `a = yield(arg1, arg2)` to assign
|
|
54
|
+
# to a temp value to make yield expr into stmt.
|
|
55
|
+
#
|
|
56
|
+
# level will always be stmt as its the reason for this to exist
|
|
57
|
+
#
|
|
58
|
+
# s(:yasgn, :a, s(:yield, arg1, arg2))
|
|
59
|
+
class YasgnNode < BaseYieldNode
|
|
60
|
+
handle :yasgn
|
|
61
|
+
|
|
62
|
+
children :var_name, :yield_args
|
|
63
|
+
|
|
64
|
+
def compile
|
|
65
|
+
compile_call(s(*yield_args[1..-1]), :stmt)
|
|
66
|
+
wrap "if ((#{var_name} = ", ") === $breaker) return $breaker.$v"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Created by `#returns()` for when a yield statement should return
|
|
71
|
+
# it's value (its last in a block etc).
|
|
72
|
+
class ReturnableYieldNode < BaseYieldNode
|
|
73
|
+
handle :returnable_yield
|
|
74
|
+
|
|
75
|
+
def compile
|
|
76
|
+
compile_call children, @level
|
|
77
|
+
|
|
78
|
+
with_temp do |tmp|
|
|
79
|
+
wrap "return #{tmp} = ", ", #{tmp} === $breaker ? #{tmp} : #{tmp}"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
data/lib/opal/parser.rb
CHANGED
|
@@ -1,2298 +1,423 @@
|
|
|
1
|
-
require 'opal/
|
|
2
|
-
require 'opal/
|
|
3
|
-
require 'opal/
|
|
4
|
-
require 'opal/
|
|
1
|
+
require 'opal/parser/sexp'
|
|
2
|
+
require 'opal/parser/lexer'
|
|
3
|
+
require 'opal/parser/grammar'
|
|
4
|
+
require 'opal/parser/parser_scope'
|
|
5
5
|
|
|
6
6
|
module Opal
|
|
7
|
-
class Parser
|
|
7
|
+
class Parser < Racc::Parser
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
# to the destination. It also keeps hold of the original sexp from which
|
|
11
|
-
# it was generated. Using this sexp, when writing fragments in order, a
|
|
12
|
-
# mapping can be created of the original location => target location,
|
|
13
|
-
# aka, source-maps!
|
|
14
|
-
class Fragment
|
|
15
|
-
# String of javascript this fragment holds
|
|
16
|
-
attr_reader :code
|
|
9
|
+
attr_reader :lexer, :file, :scope
|
|
17
10
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# In debug mode we may wish to include the original line as a comment
|
|
24
|
-
def to_code
|
|
25
|
-
if @sexp
|
|
26
|
-
"/*:#{@sexp.line}*/#{@code}"
|
|
27
|
-
else
|
|
28
|
-
@code
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# inspect the contents of this fragment, f("fooo")
|
|
33
|
-
def inspect
|
|
34
|
-
"f(#{@code.inspect})"
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def line
|
|
38
|
-
@sexp.line if @sexp
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Generated code gets indented with two spaces on each scope
|
|
43
|
-
INDENT = ' '
|
|
44
|
-
|
|
45
|
-
# Expressions are handled at diffferent levels. Some sexps
|
|
46
|
-
# need to know the js expression they are generating into.
|
|
47
|
-
LEVEL = [:stmt, :stmt_closure, :list, :expr, :recv]
|
|
48
|
-
|
|
49
|
-
# All compare method nodes - used to optimize performance of
|
|
50
|
-
# math comparisons
|
|
51
|
-
COMPARE = %w[< > <= >=]
|
|
52
|
-
|
|
53
|
-
# Reserved javascript keywords - we cannot create variables with the
|
|
54
|
-
# same name
|
|
55
|
-
RESERVED = %w(
|
|
56
|
-
break case catch continue debugger default delete do else finally for
|
|
57
|
-
function if in instanceof new return switch this throw try typeof var let
|
|
58
|
-
void while with class enum export extends import super true false native
|
|
59
|
-
const static
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
# Statements which should not have ';' added to them.
|
|
63
|
-
STATEMENTS = [:xstr, :dxstr]
|
|
64
|
-
|
|
65
|
-
# Final generated javascript for this parser
|
|
66
|
-
attr_reader :result
|
|
67
|
-
|
|
68
|
-
# generated fragments as an array
|
|
69
|
-
attr_reader :fragments
|
|
70
|
-
|
|
71
|
-
# Parse some ruby code to a string.
|
|
72
|
-
#
|
|
73
|
-
# Opal::Parser.new.parse("1 + 2")
|
|
74
|
-
# # => "(function() {....})()"
|
|
75
|
-
def parse(source, options = {})
|
|
76
|
-
@sexp = Grammar.new.parse(source, options[:file])
|
|
77
|
-
@line = 1
|
|
78
|
-
@indent = ''
|
|
79
|
-
@unique = 0
|
|
80
|
-
|
|
81
|
-
@helpers = {
|
|
82
|
-
:breaker => true,
|
|
83
|
-
:slice => true
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
# options
|
|
87
|
-
@file = options[:file] || '(file)'
|
|
88
|
-
@source_file = options[:source_file] || @file
|
|
89
|
-
@method_missing = (options[:method_missing] != false)
|
|
90
|
-
@arity_check = options[:arity_check]
|
|
91
|
-
@const_missing = (options[:const_missing] != false)
|
|
92
|
-
@irb_vars = (options[:irb] == true)
|
|
93
|
-
|
|
94
|
-
@method_calls = {}
|
|
95
|
-
|
|
96
|
-
@fragments = self.top(@sexp).flatten
|
|
97
|
-
|
|
98
|
-
@fragments.unshift f(version_comment)
|
|
99
|
-
|
|
100
|
-
@result = @fragments.map(&:code).join('')
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# Always at top of generated file to show current opal version
|
|
104
|
-
def version_comment
|
|
105
|
-
"/* Generated by Opal #{Opal::VERSION} */\n"
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def source_map
|
|
109
|
-
Opal::SourceMap.new(@fragments, '(file)')
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def extract_parser_options(content)
|
|
113
|
-
result = {}
|
|
114
|
-
|
|
115
|
-
if /^#\ opal\:(.*)/ =~ content
|
|
116
|
-
$~[1].split(',').map(&:strip).each do |opt|
|
|
117
|
-
next if opt == ""
|
|
118
|
-
opt = opt.gsub('-', '_')
|
|
119
|
-
|
|
120
|
-
if opt =~ /no_/
|
|
121
|
-
result[opt.sub(/no_/, '').to_sym] = false
|
|
122
|
-
else
|
|
123
|
-
result[opt.to_sym] = true
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
result
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
# This is called when a parsing/processing error occurs. This
|
|
132
|
-
# method simply appends the filename and curent line number onto
|
|
133
|
-
# the message and raises it.
|
|
134
|
-
#
|
|
135
|
-
# parser.error "bad variable name"
|
|
136
|
-
# # => raise "bad variable name :foo.rb:26"
|
|
137
|
-
#
|
|
138
|
-
# @param [String] msg error message to raise
|
|
139
|
-
def error(msg)
|
|
140
|
-
raise SyntaxError, "#{msg} :#{@file}:#{@line}"
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# This is called when a parsing/processing warning occurs. This
|
|
144
|
-
# method simply appends the filename and curent line number onto
|
|
145
|
-
# the message and issues a warning.
|
|
146
|
-
#
|
|
147
|
-
# @param [String] msg warning message to raise
|
|
148
|
-
def warning(msg)
|
|
149
|
-
warn "#{msg} :#{@file}:#{@line}"
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
# Instances of `Scope` can use this to determine the current
|
|
153
|
-
# scope indent. The indent is used to keep generated code easily
|
|
154
|
-
# readable.
|
|
155
|
-
#
|
|
156
|
-
# @return [String]
|
|
157
|
-
def parser_indent
|
|
158
|
-
@indent
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Create a new sexp using the given parts. Even though this just
|
|
162
|
-
# returns an array, it must be used incase the internal structure
|
|
163
|
-
# of sexps does change.
|
|
164
|
-
#
|
|
165
|
-
# s(:str, "hello there")
|
|
166
|
-
# # => [:str, "hello there"]
|
|
167
|
-
#
|
|
168
|
-
# @result [Array]
|
|
169
|
-
def s(*parts)
|
|
170
|
-
sexp = Array.new(parts)
|
|
171
|
-
sexp.line = @line
|
|
172
|
-
sexp
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
# @param [String] code the string of code
|
|
176
|
-
# @return [Fragment]
|
|
177
|
-
def f(code, sexp = nil)
|
|
178
|
-
Fragment.new(code, sexp)
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
alias_method :fragment, :f
|
|
182
|
-
|
|
183
|
-
# Converts a ruby method name into its javascript equivalent for
|
|
184
|
-
# a method/function call. All ruby method names get prefixed with
|
|
185
|
-
# a '$', and if the name is a valid javascript identifier, it will
|
|
186
|
-
# have a '.' prefix (for dot-calling), otherwise it will be
|
|
187
|
-
# wrapped in brackets to use reference notation calling.
|
|
188
|
-
#
|
|
189
|
-
# mid_to_jsid('foo') # => ".$foo"
|
|
190
|
-
# mid_to_jsid('class') # => ".$class"
|
|
191
|
-
# mid_to_jsid('==') # => "['$==']"
|
|
192
|
-
# mid_to_jsid('name=') # => "['$name=']"
|
|
193
|
-
#
|
|
194
|
-
# @param [String] mid ruby method id
|
|
195
|
-
# @return [String]
|
|
196
|
-
def mid_to_jsid(mid)
|
|
197
|
-
if /\=|\+|\-|\*|\/|\!|\?|\<|\>|\&|\||\^|\%|\~|\[/ =~ mid.to_s
|
|
198
|
-
"['$#{mid}']"
|
|
199
|
-
else
|
|
200
|
-
'.$' + mid
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
# Converts a ruby lvar/arg name to a js identifier. Not all ruby names
|
|
205
|
-
# are valid in javascript. A $ suffix is added to non-valid names.
|
|
206
|
-
def lvar_to_js(var)
|
|
207
|
-
var = "#{var}$" if RESERVED.include? var.to_s
|
|
208
|
-
var.to_sym
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
# Used to generate a unique id name per file. These are used
|
|
212
|
-
# mainly to name method bodies for methods that use blocks.
|
|
213
|
-
#
|
|
214
|
-
# @return [String]
|
|
215
|
-
def unique_temp
|
|
216
|
-
"TMP_#{@unique += 1}"
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
# Generate the code for the top level sexp, i.e. the root sexp
|
|
220
|
-
# for a file. This is used directly by `#parse`. It pushes a
|
|
221
|
-
# ":top" scope onto the stack and handles the passed in sexp.
|
|
222
|
-
# The result is a string of javascript representing the sexp.
|
|
223
|
-
#
|
|
224
|
-
# @param [Array] sexp the sexp to process
|
|
225
|
-
# @return [String]
|
|
226
|
-
def top(sexp, options = {})
|
|
227
|
-
code, vars = nil, nil
|
|
228
|
-
|
|
229
|
-
# empty file = nil as our top sexp
|
|
230
|
-
sexp = s(:nil) unless sexp
|
|
231
|
-
|
|
232
|
-
in_scope(:top) do
|
|
233
|
-
indent {
|
|
234
|
-
scope = s(:scope, sexp)
|
|
235
|
-
scope.line = sexp.line
|
|
236
|
-
|
|
237
|
-
code = process(scope, :stmt)
|
|
238
|
-
code = [code] unless code.is_a? Array
|
|
239
|
-
code.unshift f(@indent, sexp)
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
@scope.add_temp "self = $opal.top"
|
|
243
|
-
@scope.add_temp "$scope = $opal"
|
|
244
|
-
@scope.add_temp "nil = $opal.nil"
|
|
245
|
-
@scope.add_temp "def = $opal.Object._proto" if @scope.defines_defn
|
|
246
|
-
@helpers.keys.each { |h| @scope.add_temp "$#{h} = $opal.#{h}" }
|
|
247
|
-
|
|
248
|
-
vars = [f(INDENT, sexp), @scope.to_vars, f("\n", sexp)]
|
|
249
|
-
|
|
250
|
-
if @irb_vars
|
|
251
|
-
code.unshift f("if (!$opal.irb_vars) { $opal.irb_vars = {}; }\n", sexp)
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
if @method_missing
|
|
256
|
-
stubs = f("\n#{INDENT}$opal.add_stubs([" + @method_calls.keys.map { |k| "'$#{k}'" }.join(", ") + "]);\n", sexp)
|
|
257
|
-
else
|
|
258
|
-
stubs = []
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
[f("(function($opal) {\n", sexp), vars, stubs, code, f("\n})(Opal);\n", sexp)]
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
# Every time the parser enters a new scope, this is called with
|
|
265
|
-
# the scope type as an argument. Valid types are `:top` for the
|
|
266
|
-
# top level/file scope; `:class`, `:module` and `:sclass` for the
|
|
267
|
-
# obvious ruby classes/modules; `:def` and `:iter` for methods
|
|
268
|
-
# and blocks respectively.
|
|
269
|
-
#
|
|
270
|
-
# This method just pushes a new instance of `Opal::Scope` onto the
|
|
271
|
-
# stack, sets the new scope as the `@scope` variable, and yields
|
|
272
|
-
# the given block. Once the block returns, the old scope is put
|
|
273
|
-
# back on top of the stack.
|
|
274
|
-
#
|
|
275
|
-
# in_scope(:class) do
|
|
276
|
-
# # generate class body in here
|
|
277
|
-
# body = "..."
|
|
278
|
-
# end
|
|
279
|
-
#
|
|
280
|
-
# # use body result..
|
|
281
|
-
#
|
|
282
|
-
# @param [Symbol] type the type of scope
|
|
283
|
-
# @return [nil]
|
|
284
|
-
def in_scope(type)
|
|
285
|
-
return unless block_given?
|
|
286
|
-
|
|
287
|
-
parent = @scope
|
|
288
|
-
@scope = TargetScope.new(type, self).tap { |s| s.parent = parent }
|
|
289
|
-
yield @scope
|
|
290
|
-
|
|
291
|
-
@scope = parent
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
# To keep code blocks nicely indented, this will yield a block after
|
|
295
|
-
# adding an extra layer of indent, and then returning the resulting
|
|
296
|
-
# code after reverting the indent.
|
|
297
|
-
#
|
|
298
|
-
# indented_code = indent do
|
|
299
|
-
# "foo"
|
|
300
|
-
# end
|
|
301
|
-
#
|
|
302
|
-
# @result [String]
|
|
303
|
-
def indent(&block)
|
|
304
|
-
indent = @indent
|
|
305
|
-
@indent += INDENT
|
|
306
|
-
@space = "\n#@indent"
|
|
307
|
-
res = yield
|
|
308
|
-
@indent = indent
|
|
309
|
-
@space = "\n#@indent"
|
|
310
|
-
res
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
# Temporary varibales will be needed from time to time in the
|
|
314
|
-
# generated code, and this method will assign (or reuse) on
|
|
315
|
-
# while the block is yielding, and queue it back up once it is
|
|
316
|
-
# finished. Variables are queued once finished with to save the
|
|
317
|
-
# numbers of variables needed at runtime.
|
|
318
|
-
#
|
|
319
|
-
# with_temp do |tmp|
|
|
320
|
-
# "tmp = 'value';"
|
|
321
|
-
# end
|
|
322
|
-
#
|
|
323
|
-
# @return [String] generated code withing block
|
|
324
|
-
def with_temp(&block)
|
|
325
|
-
tmp = @scope.new_temp
|
|
326
|
-
res = yield tmp
|
|
327
|
-
@scope.queue_temp tmp
|
|
328
|
-
res
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
# Used when we enter a while statement. This pushes onto the current
|
|
332
|
-
# scope's while stack so we know how to handle break, next etc.
|
|
333
|
-
#
|
|
334
|
-
# Usage:
|
|
335
|
-
#
|
|
336
|
-
# in_while do
|
|
337
|
-
# # generate while body here.
|
|
338
|
-
# end
|
|
339
|
-
def in_while
|
|
340
|
-
return unless block_given?
|
|
341
|
-
@while_loop = @scope.push_while
|
|
342
|
-
result = yield
|
|
343
|
-
@scope.pop_while
|
|
344
|
-
|
|
345
|
-
result
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
def in_case
|
|
349
|
-
return unless block_given?
|
|
350
|
-
old = @case_stmt
|
|
351
|
-
@case_stmt = {}
|
|
352
|
-
yield
|
|
353
|
-
@case_stmt = old
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
# Returns true if the parser is curently handling a while sexp,
|
|
357
|
-
# false otherwise.
|
|
358
|
-
#
|
|
359
|
-
# @return [Boolean]
|
|
360
|
-
def in_while?
|
|
361
|
-
@scope.in_while?
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
# Processes a given sexp. This will send a method to the receiver
|
|
365
|
-
# of the format "process_<sexp_name>". Any sexp handler should
|
|
366
|
-
# return a string of content.
|
|
367
|
-
#
|
|
368
|
-
# For example, calling `process` with `s(:sym, 42)` will call the
|
|
369
|
-
# method `#process_lit`. If a method with that name cannot be
|
|
370
|
-
# found, then an error is raised.
|
|
371
|
-
#
|
|
372
|
-
# process(s(:int, 42), :stmt)
|
|
373
|
-
# # => "42"
|
|
374
|
-
#
|
|
375
|
-
# @param [Array] sexp the sexp to process
|
|
376
|
-
# @param [Symbol] level the level to process (see `LEVEL`)
|
|
377
|
-
# @return [String]
|
|
378
|
-
def process(sexp, level = :expr)
|
|
379
|
-
type = sexp.shift
|
|
380
|
-
meth = "process_#{type}"
|
|
381
|
-
raise "Unsupported sexp: #{type}" unless respond_to? meth
|
|
382
|
-
|
|
383
|
-
@line = sexp.line
|
|
384
|
-
|
|
385
|
-
__send__(meth, sexp, level)
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
# The last sexps in method bodies, for example, need to be returned
|
|
389
|
-
# in the compiled javascript. Due to syntax differences between
|
|
390
|
-
# javascript any ruby, some sexps need to be handled specially. For
|
|
391
|
-
# example, `if` statemented cannot be returned in javascript, so
|
|
392
|
-
# instead the "truthy" and "falsy" parts of the if statement both
|
|
393
|
-
# need to be returned instead.
|
|
394
|
-
#
|
|
395
|
-
# Sexps that need to be returned are passed to this method, and the
|
|
396
|
-
# alterned/new sexps are returned and should be used instead. Most
|
|
397
|
-
# sexps can just be added into a s(:return) sexp, so that is the
|
|
398
|
-
# default action if no special case is required.
|
|
399
|
-
#
|
|
400
|
-
# sexp = s(:str, "hey")
|
|
401
|
-
# parser.returns(sexp)
|
|
402
|
-
# # => s(:js_return, s(:str, "hey"))
|
|
403
|
-
#
|
|
404
|
-
# `s(:js_return)` is just a special sexp used to return the result
|
|
405
|
-
# of processing its arguments.
|
|
406
|
-
#
|
|
407
|
-
# @param [Array] sexp the sexp to alter
|
|
408
|
-
# @return [Array] altered sexp
|
|
409
|
-
def returns(sexp)
|
|
410
|
-
return returns s(:nil) unless sexp
|
|
411
|
-
|
|
412
|
-
case sexp.first
|
|
413
|
-
when :break, :next
|
|
414
|
-
sexp
|
|
415
|
-
when :yield
|
|
416
|
-
sexp[0] = :returnable_yield
|
|
417
|
-
sexp
|
|
418
|
-
when :scope
|
|
419
|
-
sexp[1] = returns sexp[1]
|
|
420
|
-
sexp
|
|
421
|
-
when :block
|
|
422
|
-
if sexp.length > 1
|
|
423
|
-
sexp[-1] = returns sexp[-1]
|
|
424
|
-
else
|
|
425
|
-
sexp << returns(s(:nil))
|
|
426
|
-
end
|
|
427
|
-
sexp
|
|
428
|
-
when :when
|
|
429
|
-
sexp[2] = returns(sexp[2])
|
|
430
|
-
sexp
|
|
431
|
-
when :rescue
|
|
432
|
-
sexp[1] = returns sexp[1]
|
|
433
|
-
|
|
434
|
-
if sexp[2] and sexp[2][0] == :resbody and sexp[2][2]
|
|
435
|
-
sexp[2][2] = returns sexp[2][2]
|
|
436
|
-
end
|
|
437
|
-
sexp
|
|
438
|
-
when :ensure
|
|
439
|
-
sexp[1] = returns sexp[1]
|
|
440
|
-
sexp
|
|
441
|
-
when :while
|
|
442
|
-
# sexp[2] = returns(sexp[2])
|
|
443
|
-
sexp
|
|
444
|
-
when :return
|
|
445
|
-
sexp
|
|
446
|
-
when :xstr
|
|
447
|
-
sexp[1] = "return #{sexp[1]};" unless /return|;/ =~ sexp[1]
|
|
448
|
-
sexp
|
|
449
|
-
when :dxstr
|
|
450
|
-
sexp[1] = "return #{sexp[1]}" unless /return|;|\n/ =~ sexp[1]
|
|
451
|
-
sexp
|
|
452
|
-
when :if
|
|
453
|
-
sexp[2] = returns(sexp[2] || s(:nil))
|
|
454
|
-
sexp[3] = returns(sexp[3] || s(:nil))
|
|
455
|
-
sexp
|
|
456
|
-
else
|
|
457
|
-
s(:js_return, sexp).tap { |s|
|
|
458
|
-
s.line = sexp.line
|
|
459
|
-
}
|
|
460
|
-
end
|
|
461
|
-
end
|
|
462
|
-
|
|
463
|
-
# Returns true if the given sexp is an expression. All expressions
|
|
464
|
-
# will get ';' appended to their result, except for the statement
|
|
465
|
-
# sexps. See `STATEMENTS` for a list of sexp names that are
|
|
466
|
-
# statements.
|
|
467
|
-
#
|
|
468
|
-
# @param [Array] sexp the sexp to check
|
|
469
|
-
# @return [Boolean]
|
|
470
|
-
def expression?(sexp)
|
|
471
|
-
!STATEMENTS.include?(sexp.first)
|
|
472
|
-
end
|
|
473
|
-
|
|
474
|
-
# More than one expression in a row will be grouped by the grammar
|
|
475
|
-
# into a block sexp. A block sexp just holds any number of other
|
|
476
|
-
# sexps.
|
|
477
|
-
#
|
|
478
|
-
# s(:block, s(:str, "hey"), s(:int, 42))
|
|
479
|
-
#
|
|
480
|
-
# A block can actually be empty. As opal requires real values to
|
|
481
|
-
# be returned (to appease javascript values), a nil sexp
|
|
482
|
-
# s(:nil) will be generated if the block is empty.
|
|
483
|
-
#
|
|
484
|
-
# @return [String]
|
|
485
|
-
def process_block(sexp, level)
|
|
486
|
-
return process s(:nil) if sexp.empty?
|
|
487
|
-
|
|
488
|
-
result = []
|
|
489
|
-
join = (@scope.class_scope? ? "\n\n#@indent" : "\n#@indent")
|
|
490
|
-
|
|
491
|
-
sexp.each do |stmt|
|
|
492
|
-
result << f(join, sexp) unless result.empty?
|
|
493
|
-
|
|
494
|
-
# find any inline yield statements
|
|
495
|
-
if yasgn = find_inline_yield(stmt)
|
|
496
|
-
result << process(yasgn, level) << f(";", yasgn)
|
|
497
|
-
end
|
|
498
|
-
|
|
499
|
-
expr = expression?(stmt) and LEVEL.index(level) < LEVEL.index(:list)
|
|
500
|
-
|
|
501
|
-
result << process(stmt, level)
|
|
502
|
-
result << f(";", stmt) if expr
|
|
503
|
-
end
|
|
504
|
-
|
|
505
|
-
result
|
|
506
|
-
end
|
|
507
|
-
|
|
508
|
-
# When a block sexp gets generated, any inline yields (i.e. yield
|
|
509
|
-
# statements that are not direct members of the block) need to be
|
|
510
|
-
# generated as a top level member. This is because if a yield
|
|
511
|
-
# is returned by a break statement, then the method must return.
|
|
512
|
-
#
|
|
513
|
-
# As inline expressions in javascript cannot return, the block
|
|
514
|
-
# must be rewritten.
|
|
515
|
-
#
|
|
516
|
-
# For example, a yield inside an array:
|
|
517
|
-
#
|
|
518
|
-
# [1, 2, 3, yield(4)]
|
|
519
|
-
#
|
|
520
|
-
# Must be rewitten into:
|
|
521
|
-
#
|
|
522
|
-
# tmp = yield 4
|
|
523
|
-
# [1, 2, 3, tmp]
|
|
524
|
-
#
|
|
525
|
-
# This rewriting happens on sexps directly.
|
|
526
|
-
#
|
|
527
|
-
# @param [Sexp] stmt sexps to (maybe) rewrite
|
|
528
|
-
# @return [Sexp]
|
|
529
|
-
def find_inline_yield(stmt)
|
|
530
|
-
found = nil
|
|
531
|
-
case stmt.first
|
|
532
|
-
when :js_return
|
|
533
|
-
if found = find_inline_yield(stmt[1])
|
|
534
|
-
found = found[2]
|
|
535
|
-
end
|
|
536
|
-
when :array
|
|
537
|
-
stmt[1..-1].each_with_index do |el, idx|
|
|
538
|
-
if el.first == :yield
|
|
539
|
-
found = el
|
|
540
|
-
stmt[idx+1] = s(:js_tmp, '$yielded')
|
|
541
|
-
end
|
|
542
|
-
end
|
|
543
|
-
when :call
|
|
544
|
-
arglist = stmt[3]
|
|
545
|
-
arglist[1..-1].each_with_index do |el, idx|
|
|
546
|
-
if el.first == :yield
|
|
547
|
-
found = el
|
|
548
|
-
arglist[idx+1] = s(:js_tmp, '$yielded')
|
|
549
|
-
end
|
|
550
|
-
end
|
|
551
|
-
end
|
|
552
|
-
|
|
553
|
-
if found
|
|
554
|
-
@scope.add_temp '$yielded' unless @scope.has_temp? '$yielded'
|
|
555
|
-
s(:yasgn, '$yielded', found)
|
|
556
|
-
end
|
|
557
|
-
end
|
|
558
|
-
|
|
559
|
-
def process_scope(sexp, level)
|
|
560
|
-
stmt = sexp[0] || s(:nil)
|
|
561
|
-
stmt = returns stmt unless @scope.class_scope?
|
|
562
|
-
|
|
563
|
-
process stmt, :stmt
|
|
564
|
-
end
|
|
565
|
-
|
|
566
|
-
# s(:js_return, sexp)
|
|
567
|
-
def process_js_return(sexp, level)
|
|
568
|
-
[f("return ", sexp), process(sexp[0])]
|
|
569
|
-
end
|
|
570
|
-
|
|
571
|
-
# s(:js_tmp, str)
|
|
572
|
-
def process_js_tmp(sexp, level)
|
|
573
|
-
f(sexp[0].to_s, sexp)
|
|
574
|
-
end
|
|
575
|
-
|
|
576
|
-
def js_block_given(sexp, level)
|
|
577
|
-
@scope.uses_block!
|
|
578
|
-
if @scope.block_name
|
|
579
|
-
f("(#{@scope.block_name} !== nil)", sexp)
|
|
580
|
-
elsif scope = @scope.find_parent_def and scope.block_name
|
|
581
|
-
f("(#{scope.block_name} !== nil)", sexp)
|
|
582
|
-
else
|
|
583
|
-
f("false", sexp)
|
|
584
|
-
end
|
|
585
|
-
end
|
|
586
|
-
|
|
587
|
-
def handle_block_given(sexp, reverse = false)
|
|
588
|
-
@scope.uses_block!
|
|
589
|
-
name = @scope.block_name
|
|
590
|
-
|
|
591
|
-
f((reverse ? "#{ name } === nil" : "#{ name } !== nil"), sexp)
|
|
592
|
-
end
|
|
593
|
-
|
|
594
|
-
def process_sym(sexp, level)
|
|
595
|
-
f(sexp[0].to_s.inspect, sexp)
|
|
596
|
-
end
|
|
597
|
-
|
|
598
|
-
# Process integers. Wrap in parens if a receiver of method call
|
|
599
|
-
def process_int(sexp, level)
|
|
600
|
-
f((level == :recv ? "(#{sexp[0]})" : sexp[0].to_s), sexp)
|
|
601
|
-
end
|
|
602
|
-
|
|
603
|
-
# Floats generated just like integers
|
|
604
|
-
alias_method :process_float, :process_int
|
|
605
|
-
|
|
606
|
-
# Regexp literals. Convert to empty js regexp if empty (not compatible)
|
|
607
|
-
def process_regexp(sexp, level)
|
|
608
|
-
val = sexp[0]
|
|
609
|
-
f((val == // ? /^/.inspect : val.inspect), sexp)
|
|
610
|
-
end
|
|
611
|
-
|
|
612
|
-
# Dynamic regexps with interpolation
|
|
613
|
-
# s(:dregx, parts...) => new Regexp("...")
|
|
614
|
-
def process_dregx(sexp, level)
|
|
615
|
-
result = []
|
|
616
|
-
|
|
617
|
-
sexp.each do |part|
|
|
618
|
-
result << f(" + ", sexp) unless result.empty?
|
|
619
|
-
|
|
620
|
-
if String === part
|
|
621
|
-
result << f(part.inspect, sexp)
|
|
622
|
-
elsif part[0] == :str
|
|
623
|
-
result << process(part)
|
|
624
|
-
else
|
|
625
|
-
result << process(part[1])
|
|
626
|
-
end
|
|
627
|
-
end
|
|
628
|
-
|
|
629
|
-
[f("(new RegExp(", sexp), result, f("))", sexp)]
|
|
630
|
-
end
|
|
631
|
-
|
|
632
|
-
# Exclusive range, uses opal __range helper.
|
|
633
|
-
# s(:dot3, start, end) => __range(start, end, false)
|
|
634
|
-
def process_dot2(sexp, level)
|
|
635
|
-
@helpers[:range] = true
|
|
636
|
-
|
|
637
|
-
[f("$range(", sexp), process(sexp[0]), f(", ", sexp), process(sexp[1]), f(", false)", sexp)]
|
|
638
|
-
end
|
|
639
|
-
|
|
640
|
-
# Inclusive range, uses __range helper
|
|
641
|
-
# s(:dot3, start, end) => __range(start, end, true)
|
|
642
|
-
def process_dot3(sexp, level)
|
|
643
|
-
@helpers[:range] = true
|
|
644
|
-
|
|
645
|
-
[f("$range(", sexp), process(sexp[0]), f(", ", sexp), process(sexp[1]), f(", true)", sexp)]
|
|
646
|
-
end
|
|
647
|
-
|
|
648
|
-
# Simple strings, no interpolation.
|
|
649
|
-
# s(:str, "string") => "string"
|
|
650
|
-
def process_str(sexp, level)
|
|
651
|
-
f sexp[0].inspect, sexp
|
|
652
|
-
end
|
|
653
|
-
|
|
654
|
-
# defined?(x) => various
|
|
655
|
-
def process_defined(sexp, level)
|
|
656
|
-
part = sexp[0]
|
|
657
|
-
case part[0]
|
|
658
|
-
when :self
|
|
659
|
-
f("'self'", sexp)
|
|
660
|
-
when :nil
|
|
661
|
-
f("'nil'", sexp)
|
|
662
|
-
when :true
|
|
663
|
-
f("'true'", sexp)
|
|
664
|
-
when :false
|
|
665
|
-
f("'false'", sexp)
|
|
666
|
-
when :call
|
|
667
|
-
mid = mid_to_jsid part[2].to_s
|
|
668
|
-
recv = part[1] ? process(part[1]) : f(current_self, sexp)
|
|
669
|
-
[f("(", sexp), recv, f("#{mid} ? 'method' : nil)", sexp)]
|
|
670
|
-
when :xstr, :dxstr
|
|
671
|
-
[f("(typeof(", sexp), process(part), f(") !== 'undefined')", sexp)]
|
|
672
|
-
when :const
|
|
673
|
-
f("($scope.#{part[1].to_s} != null)", sexp)
|
|
674
|
-
when :cvar
|
|
675
|
-
f("($opal.cvars[#{part[1].to_s.inspect}] != null ? 'class-variable' : nil)", sexp)
|
|
676
|
-
when :colon2
|
|
677
|
-
f("false", sexp)
|
|
678
|
-
when :colon3
|
|
679
|
-
f("($opal.Object._scope.#{sexp[0][1]} == null ? nil : 'constant')", sexp)
|
|
680
|
-
when :ivar
|
|
681
|
-
ivar_name = part[1].to_s[1..-1]
|
|
682
|
-
with_temp do |t|
|
|
683
|
-
f("((#{t} = #{current_self}[#{ivar_name.inspect}], #{t} != null && #{t} !== nil) ? 'instance-variable' : nil)", sexp)
|
|
684
|
-
end
|
|
685
|
-
when :lvar
|
|
686
|
-
f("local-variable", sexp)
|
|
687
|
-
else
|
|
688
|
-
raise "bad defined? part: #{part[0]}"
|
|
689
|
-
end
|
|
690
|
-
end
|
|
691
|
-
|
|
692
|
-
# not keyword or '!' operand
|
|
693
|
-
# s(:not, value) => (tmp = value, (tmp === nil || tmp === false))
|
|
694
|
-
def process_not(sexp, level)
|
|
695
|
-
with_temp do |tmp|
|
|
696
|
-
expr = sexp[0]
|
|
697
|
-
[f("(#{tmp} = ", sexp), process(expr), f(", (#{tmp} === nil || #{tmp} === false))", sexp)]
|
|
698
|
-
end
|
|
699
|
-
end
|
|
700
|
-
|
|
701
|
-
# A block pass '&foo' syntax
|
|
702
|
-
# s(:block_pass, value) => value.$to_proc()
|
|
703
|
-
def process_block_pass(exp, level)
|
|
704
|
-
process s(:call, exp[0], :to_proc, s(:arglist))
|
|
705
|
-
end
|
|
706
|
-
|
|
707
|
-
# A block/iter with embeded call. Compiles into function
|
|
708
|
-
# s(:iter, call, block_args [, body) => (function() { ... })
|
|
709
|
-
def process_iter(sexp, level)
|
|
710
|
-
call, args, body = sexp
|
|
711
|
-
|
|
712
|
-
body ||= s(:nil)
|
|
713
|
-
body = returns body
|
|
714
|
-
code = []
|
|
715
|
-
params = nil
|
|
716
|
-
scope_name = nil
|
|
717
|
-
identity = nil
|
|
718
|
-
to_vars = nil
|
|
719
|
-
|
|
720
|
-
args = nil if Fixnum === args # argh
|
|
721
|
-
args ||= s(:masgn, s(:array))
|
|
722
|
-
args = args.first == :lasgn ? s(:array, args) : args[1]
|
|
723
|
-
|
|
724
|
-
# opt args are last, if present, and are a [:block]
|
|
725
|
-
if args.last.is_a?(Array) and args.last[0] == :block
|
|
726
|
-
opt_args = args.pop
|
|
727
|
-
opt_args.shift
|
|
728
|
-
end
|
|
729
|
-
|
|
730
|
-
if args.last.is_a?(Array) and args.last[0] == :block_pass
|
|
731
|
-
block_arg = args.pop
|
|
732
|
-
block_arg = block_arg[1][1].to_sym
|
|
733
|
-
end
|
|
734
|
-
|
|
735
|
-
if args.last.is_a?(Array) and args.last[0] == :splat
|
|
736
|
-
splat = args.last[1][1]
|
|
737
|
-
args.pop
|
|
738
|
-
len = args.length
|
|
739
|
-
end
|
|
740
|
-
|
|
741
|
-
indent do
|
|
742
|
-
in_scope(:iter) do
|
|
743
|
-
identity = @scope.identify!
|
|
744
|
-
@scope.add_temp "#{current_self} = #{identity}._s || this"
|
|
745
|
-
|
|
746
|
-
args[1..-1].each do |arg|
|
|
747
|
-
arg = arg[1]
|
|
748
|
-
arg = "#{arg}$" if RESERVED.include? arg.to_s
|
|
749
|
-
|
|
750
|
-
if opt_args and current_opt = opt_args.find { |s| s[1] == arg.to_sym }
|
|
751
|
-
code << [f("if (#{arg} == null) #{arg} = ", sexp), process(current_opt[2]), f(";\n", sexp)]
|
|
752
|
-
else
|
|
753
|
-
code << f("if (#{arg} == null) #{arg} = nil;\n", sexp)
|
|
754
|
-
end
|
|
755
|
-
end
|
|
756
|
-
|
|
757
|
-
params = js_block_args(args[1..-1])
|
|
758
|
-
|
|
759
|
-
if splat
|
|
760
|
-
@scope.add_arg splat
|
|
761
|
-
params << splat
|
|
762
|
-
code << f("#{splat} = $slice.call(arguments, #{len - 1});", sexp)
|
|
763
|
-
end
|
|
764
|
-
|
|
765
|
-
if block_arg
|
|
766
|
-
@scope.block_name = block_arg
|
|
767
|
-
@scope.add_temp block_arg
|
|
768
|
-
scope_name = @scope.identify!
|
|
769
|
-
|
|
770
|
-
blk = []
|
|
771
|
-
blk << f("\n#@indent#{block_arg} = #{scope_name}._p || nil, #{scope_name}.p = null;\n#@indent", sexp)
|
|
772
|
-
|
|
773
|
-
code.unshift blk
|
|
774
|
-
end
|
|
775
|
-
|
|
776
|
-
code << f("\n#@indent", sexp)
|
|
777
|
-
code << process(body, :stmt)
|
|
778
|
-
|
|
779
|
-
if @scope.defines_defn
|
|
780
|
-
@scope.add_temp "def = ((#{current_self}._isClass) ? #{current_self}._proto : #{current_self})"
|
|
781
|
-
end
|
|
782
|
-
|
|
783
|
-
to_vars = [f("\n#@indent", sexp), @scope.to_vars, f("\n#@indent", sexp)]
|
|
784
|
-
end
|
|
785
|
-
end
|
|
786
|
-
|
|
787
|
-
itercode = [f("function(#{params.join ', '}) {\n", sexp), to_vars, code, f("\n#@indent}", sexp)]
|
|
788
|
-
|
|
789
|
-
itercode.unshift f("(#{identity} = ", sexp)
|
|
790
|
-
itercode << f(", #{identity}._s = #{current_self}, #{identity})", sexp)
|
|
791
|
-
|
|
792
|
-
call << itercode
|
|
793
|
-
process call, level
|
|
794
|
-
end
|
|
795
|
-
|
|
796
|
-
# Maps block args into array of jsid. Adds $ suffix to invalid js
|
|
797
|
-
# identifiers.
|
|
798
|
-
#
|
|
799
|
-
# s(:args, parts...) => ["a", "b", "break$"]
|
|
800
|
-
def js_block_args(sexp)
|
|
801
|
-
sexp.map do |arg|
|
|
802
|
-
@scope.add_arg lvar_to_js(arg[1])
|
|
803
|
-
end
|
|
804
|
-
end
|
|
805
|
-
|
|
806
|
-
##
|
|
807
|
-
# recv.mid = rhs
|
|
808
|
-
#
|
|
809
|
-
# s(recv, :mid=, s(:arglist, rhs))
|
|
810
|
-
def process_attrasgn(exp, level)
|
|
811
|
-
recv, mid, arglist = exp
|
|
812
|
-
process s(:call, recv, mid, arglist), level
|
|
813
|
-
end
|
|
814
|
-
|
|
815
|
-
# s(:call, recv, :mid, s(:arglist))
|
|
816
|
-
# s(:call, nil, :mid, s(:arglist))
|
|
817
|
-
def process_call(sexp, level)
|
|
818
|
-
recv, meth, arglist, iter = sexp
|
|
819
|
-
mid = mid_to_jsid meth.to_s
|
|
820
|
-
|
|
821
|
-
@method_calls[meth.to_sym] = true
|
|
822
|
-
|
|
823
|
-
# we are trying to access a lvar in irb mode
|
|
824
|
-
if @irb_vars and @scope.top? and arglist == s(:arglist) and recv == nil
|
|
825
|
-
return with_temp { |t|
|
|
826
|
-
lvar = meth.intern
|
|
827
|
-
lvar = "#{lvar}$" if RESERVED.include? lvar
|
|
828
|
-
call = s(:call, s(:self), meth.intern, s(:arglist))
|
|
829
|
-
[f("((#{t} = $opal.irb_vars.#{lvar}) == null ? ", sexp), process(call), f(" : #{t})", sexp)]
|
|
830
|
-
}
|
|
831
|
-
end
|
|
832
|
-
|
|
833
|
-
case meth
|
|
834
|
-
when :block_given?
|
|
835
|
-
return js_block_given(sexp, level)
|
|
836
|
-
end
|
|
837
|
-
|
|
838
|
-
splat = arglist[1..-1].any? { |a| a.first == :splat }
|
|
839
|
-
|
|
840
|
-
if Array === arglist.last and arglist.last.first == :block_pass
|
|
841
|
-
block = process(arglist.pop)
|
|
842
|
-
elsif iter
|
|
843
|
-
block = iter
|
|
844
|
-
end
|
|
845
|
-
|
|
846
|
-
recv ||= s(:self)
|
|
847
|
-
|
|
848
|
-
if block
|
|
849
|
-
tmpfunc = @scope.new_temp
|
|
850
|
-
end
|
|
851
|
-
|
|
852
|
-
tmprecv = @scope.new_temp if splat || tmpfunc
|
|
853
|
-
args = ""
|
|
854
|
-
|
|
855
|
-
recv_code = process recv, :recv
|
|
856
|
-
|
|
857
|
-
call_recv = s(:js_tmp, tmprecv || recv_code)
|
|
858
|
-
arglist.insert 1, call_recv if tmpfunc and !splat
|
|
859
|
-
args = process arglist
|
|
860
|
-
|
|
861
|
-
dispatch = if tmprecv
|
|
862
|
-
[f("(#{tmprecv} = "), recv_code, f(")#{mid}")]
|
|
863
|
-
else
|
|
864
|
-
[recv_code, f(mid)]
|
|
865
|
-
end
|
|
866
|
-
|
|
867
|
-
if tmpfunc
|
|
868
|
-
dispatch.unshift f("(#{tmpfunc} = ")
|
|
869
|
-
dispatch << f(", #{tmpfunc}._p = ")
|
|
870
|
-
dispatch << block
|
|
871
|
-
dispatch << f(", #{tmpfunc})")
|
|
872
|
-
end
|
|
873
|
-
|
|
874
|
-
result = if splat
|
|
875
|
-
[dispatch, f(".apply("), (tmprecv ? f(tmprecv) : recv_code),
|
|
876
|
-
f(", "), args, f(")")]
|
|
877
|
-
elsif tmpfunc
|
|
878
|
-
[dispatch, f(".call("), args, f(")")]
|
|
879
|
-
else
|
|
880
|
-
[dispatch, f("("), args, f(")")]
|
|
881
|
-
end
|
|
882
|
-
|
|
883
|
-
@scope.queue_temp tmpfunc if tmpfunc
|
|
884
|
-
result
|
|
885
|
-
end
|
|
886
|
-
|
|
887
|
-
# s(:arglist, [arg [, arg ..]])
|
|
888
|
-
def process_arglist(sexp, level)
|
|
889
|
-
code, work = [], []
|
|
890
|
-
|
|
891
|
-
sexp.each do |current|
|
|
892
|
-
splat = current.first == :splat
|
|
893
|
-
arg = process current
|
|
894
|
-
|
|
895
|
-
if splat
|
|
896
|
-
if work.empty?
|
|
897
|
-
if code.empty?
|
|
898
|
-
code << f("[].concat(", sexp)
|
|
899
|
-
code << arg
|
|
900
|
-
code << f(")")
|
|
901
|
-
else
|
|
902
|
-
code += ".concat(#{arg})"
|
|
903
|
-
end
|
|
904
|
-
else
|
|
905
|
-
if code.empty?
|
|
906
|
-
code << [f("["), work, f("]")]
|
|
907
|
-
else
|
|
908
|
-
code << [f(".concat(["), work, f("])")]
|
|
909
|
-
end
|
|
910
|
-
|
|
911
|
-
code << [f(".concat("), arg, f(")")]
|
|
912
|
-
end
|
|
913
|
-
|
|
914
|
-
work = []
|
|
915
|
-
else
|
|
916
|
-
work << f(", ") unless work.empty?
|
|
917
|
-
work << arg
|
|
918
|
-
end
|
|
919
|
-
end
|
|
920
|
-
|
|
921
|
-
unless work.empty?
|
|
922
|
-
join = work
|
|
923
|
-
|
|
924
|
-
if code.empty?
|
|
925
|
-
code = join
|
|
926
|
-
else
|
|
927
|
-
code << f(".concat(") << join << f(")")
|
|
928
|
-
end
|
|
929
|
-
end
|
|
930
|
-
|
|
931
|
-
code
|
|
932
|
-
end
|
|
933
|
-
|
|
934
|
-
# s(:splat, sexp)
|
|
935
|
-
def process_splat(sexp, level)
|
|
936
|
-
if sexp.first == [:nil]
|
|
937
|
-
[f("[]")]
|
|
938
|
-
elsif sexp.first.first == :sym
|
|
939
|
-
[f("["), process(sexp[0]), f("]")]
|
|
940
|
-
else
|
|
941
|
-
process sexp.first, :recv
|
|
942
|
-
end
|
|
943
|
-
end
|
|
944
|
-
|
|
945
|
-
# s(:class, cid, super, body)
|
|
946
|
-
def process_class(sexp, level)
|
|
947
|
-
cid, sup, body = sexp
|
|
948
|
-
|
|
949
|
-
body[1] = s(:nil) unless body[1]
|
|
950
|
-
|
|
951
|
-
code = []
|
|
952
|
-
@helpers[:klass] = true
|
|
953
|
-
|
|
954
|
-
if Symbol === cid or String === cid
|
|
955
|
-
base = process s(:self)
|
|
956
|
-
name = cid.to_s
|
|
957
|
-
elsif cid[0] == :colon2
|
|
958
|
-
base = process(cid[1])
|
|
959
|
-
name = cid[2].to_s
|
|
960
|
-
elsif cid[0] == :colon3
|
|
961
|
-
base = process(s(:js_tmp, '$opal.Object'))
|
|
962
|
-
name = cid[1].to_s
|
|
963
|
-
else
|
|
964
|
-
raise "Bad receiver in class"
|
|
965
|
-
end
|
|
966
|
-
|
|
967
|
-
sup = sup ? process(sup) : process(s(:js_tmp, 'null'))
|
|
968
|
-
|
|
969
|
-
indent do
|
|
970
|
-
in_scope(:class) do
|
|
971
|
-
@scope.name = name
|
|
972
|
-
@scope.add_temp "#{ @scope.proto } = #{name}._proto", "$scope = #{name}._scope"
|
|
973
|
-
|
|
974
|
-
if Array === body.last
|
|
975
|
-
# A single statement will need a block
|
|
976
|
-
needs_block = body.last.first != :block
|
|
977
|
-
body.last.first == :block
|
|
978
|
-
last_body_statement = needs_block ? body.last : body.last.last
|
|
979
|
-
|
|
980
|
-
if last_body_statement and Array === last_body_statement
|
|
981
|
-
if [:defn, :defs].include? last_body_statement.first
|
|
982
|
-
body[-1] = s(:block, body[-1]) if needs_block
|
|
983
|
-
body.last << s(:nil)
|
|
984
|
-
end
|
|
985
|
-
end
|
|
986
|
-
end
|
|
987
|
-
|
|
988
|
-
body = process(returns(body), :stmt)
|
|
989
|
-
code << f("\n")
|
|
990
|
-
code << @scope.to_donate_methods
|
|
991
|
-
|
|
992
|
-
code << f(@indent)
|
|
993
|
-
code << @scope.to_vars
|
|
994
|
-
code << f("\n\n#@indent")
|
|
995
|
-
code << body
|
|
996
|
-
end
|
|
997
|
-
end
|
|
998
|
-
|
|
999
|
-
spacer = "\n#{@indent}#{INDENT}"
|
|
1000
|
-
cls = "function #{name}() {};"
|
|
1001
|
-
boot = "#{name} = $klass($base, $super, #{name.inspect}, #{name});"
|
|
1002
|
-
|
|
1003
|
-
[f("(function($base, $super){#{spacer}#{cls}#{spacer}#{boot}\n", sexp),
|
|
1004
|
-
code, f("\n#@indent})", sexp), f("(", sexp), base, f(", ", sexp), sup, f(")", sexp)]
|
|
1005
|
-
end
|
|
1006
|
-
|
|
1007
|
-
# Singleton class syntax. Runs body in context of singleton_class.
|
|
1008
|
-
# s(:sclass, recv, body) => (function() { ... }).call(recv.$singleton_class())
|
|
1009
|
-
def process_sclass(sexp, level)
|
|
1010
|
-
recv, body, code = sexp[0], sexp[1], []
|
|
1011
|
-
|
|
1012
|
-
in_scope(:sclass) do
|
|
1013
|
-
@scope.add_temp "$scope = #{current_self}._scope"
|
|
1014
|
-
@scope.add_temp "def = #{current_self}._proto"
|
|
1015
|
-
|
|
1016
|
-
code << @scope.to_vars << process(body, :stmt)
|
|
1017
|
-
end
|
|
1018
|
-
|
|
1019
|
-
[f("(function(){"), code, f("}).call("), process(recv, :recv), f(".$singleton_class())")]
|
|
1020
|
-
end
|
|
1021
|
-
|
|
1022
|
-
# s(:module, cid, body)
|
|
1023
|
-
def process_module(sexp, level)
|
|
1024
|
-
cid, body = sexp
|
|
1025
|
-
code = []
|
|
1026
|
-
@helpers[:module] = true
|
|
1027
|
-
|
|
1028
|
-
if Symbol === cid or String === cid
|
|
1029
|
-
base = process(s(:self))
|
|
1030
|
-
name = cid.to_s
|
|
1031
|
-
elsif cid[0] == :colon2
|
|
1032
|
-
base = process(cid[1])
|
|
1033
|
-
name = cid[2].to_s
|
|
1034
|
-
elsif cid[0] == :colon3
|
|
1035
|
-
base = f('$opal.Object', sexp)
|
|
1036
|
-
name = cid[1].to_s
|
|
1037
|
-
else
|
|
1038
|
-
raise "Bad receiver in class"
|
|
1039
|
-
end
|
|
1040
|
-
|
|
1041
|
-
indent do
|
|
1042
|
-
in_scope(:module) do
|
|
1043
|
-
@scope.name = name
|
|
1044
|
-
@scope.add_temp "#{ @scope.proto } = #{name}._proto", "$scope = #{name}._scope"
|
|
1045
|
-
body = process body, :stmt
|
|
1046
|
-
|
|
1047
|
-
code << f(@indent)
|
|
1048
|
-
code << @scope.to_vars
|
|
1049
|
-
code << f("\n\n#@indent")
|
|
1050
|
-
code << body
|
|
1051
|
-
code << f("\n#@ident")
|
|
1052
|
-
code << @scope.to_donate_methods
|
|
1053
|
-
end
|
|
1054
|
-
end
|
|
1055
|
-
|
|
1056
|
-
spacer = "\n#{@indent}#{INDENT}"
|
|
1057
|
-
cls = "function #{name}() {};"
|
|
1058
|
-
boot = "#{name} = $module($base, #{name.inspect}, #{name});"
|
|
1059
|
-
|
|
1060
|
-
code.unshift f("(function($base){#{spacer}#{cls}#{spacer}#{boot}\n", sexp)
|
|
1061
|
-
code << f("\n#@indent})(")
|
|
1062
|
-
code << base
|
|
1063
|
-
code << f(")")
|
|
1064
|
-
|
|
1065
|
-
code
|
|
1066
|
-
end
|
|
1067
|
-
|
|
1068
|
-
# undef :foo
|
|
1069
|
-
# => delete MyClass.prototype.$foo
|
|
1070
|
-
# FIXME: we should be setting method to a stub method here
|
|
1071
|
-
def process_undef(sexp, level)
|
|
1072
|
-
f("delete #{ @scope.proto }#{ mid_to_jsid sexp[0][1].to_s }", sexp)
|
|
1073
|
-
end
|
|
1074
|
-
|
|
1075
|
-
# s(:defn, mid, s(:args), s(:scope))
|
|
1076
|
-
def process_defn(sexp, level)
|
|
1077
|
-
mid, args, stmts = sexp
|
|
1078
|
-
|
|
1079
|
-
js_def nil, mid, args, stmts, sexp.line, sexp.end_line, sexp
|
|
1080
|
-
end
|
|
1081
|
-
|
|
1082
|
-
# s(:defs, recv, mid, s(:args), s(:scope))
|
|
1083
|
-
def process_defs(sexp, level)
|
|
1084
|
-
recv, mid, args, stmts = sexp
|
|
1085
|
-
|
|
1086
|
-
js_def recv, mid, args, stmts, sexp.line, sexp.end_line, sexp
|
|
1087
|
-
end
|
|
1088
|
-
|
|
1089
|
-
def js_def(recvr, mid, args, stmts, line, end_line, sexp)
|
|
1090
|
-
jsid = mid_to_jsid mid.to_s
|
|
1091
|
-
|
|
1092
|
-
if recvr
|
|
1093
|
-
@scope.defines_defs = true
|
|
1094
|
-
smethod = true if @scope.class_scope? && recvr.first == :self
|
|
1095
|
-
recv = process(recvr)
|
|
1096
|
-
else
|
|
1097
|
-
@scope.defines_defn = true
|
|
1098
|
-
recv = current_self
|
|
1099
|
-
end
|
|
1100
|
-
|
|
1101
|
-
code = []
|
|
1102
|
-
params = nil
|
|
1103
|
-
scope_name = nil
|
|
1104
|
-
uses_super = nil
|
|
1105
|
-
uses_splat = nil
|
|
1106
|
-
|
|
1107
|
-
# opt args if last arg is sexp
|
|
1108
|
-
opt = args.pop if Array === args.last
|
|
1109
|
-
|
|
1110
|
-
argc = args.length - 1
|
|
1111
|
-
|
|
1112
|
-
# block name &block
|
|
1113
|
-
if args.last.to_s.start_with? '&'
|
|
1114
|
-
block_name = args.pop.to_s[1..-1].to_sym
|
|
1115
|
-
argc -= 1
|
|
1116
|
-
end
|
|
1117
|
-
|
|
1118
|
-
# splat args *splat
|
|
1119
|
-
if args.last.to_s.start_with? '*'
|
|
1120
|
-
uses_splat = true
|
|
1121
|
-
if args.last == :*
|
|
1122
|
-
argc -= 1
|
|
1123
|
-
else
|
|
1124
|
-
splat = args[-1].to_s[1..-1].to_sym
|
|
1125
|
-
args[-1] = splat
|
|
1126
|
-
argc -= 1
|
|
1127
|
-
end
|
|
1128
|
-
end
|
|
1129
|
-
|
|
1130
|
-
if @arity_check
|
|
1131
|
-
arity_code = arity_check(args, opt, uses_splat, block_name, mid) + "\n#{INDENT}"
|
|
1132
|
-
end
|
|
1133
|
-
|
|
1134
|
-
indent do
|
|
1135
|
-
in_scope(:def) do
|
|
1136
|
-
@scope.mid = mid
|
|
1137
|
-
@scope.defs = true if recvr
|
|
1138
|
-
|
|
1139
|
-
if block_name
|
|
1140
|
-
@scope.uses_block!
|
|
1141
|
-
@scope.add_arg block_name
|
|
1142
|
-
end
|
|
1143
|
-
|
|
1144
|
-
yielder = block_name || '$yield'
|
|
1145
|
-
@scope.block_name = yielder
|
|
1146
|
-
|
|
1147
|
-
params = process args
|
|
1148
|
-
stmt_code = [f("\n#@indent"), process(stmts, :stmt)]
|
|
1149
|
-
|
|
1150
|
-
opt[1..-1].each do |o|
|
|
1151
|
-
next if o[2][2] == :undefined
|
|
1152
|
-
code << f("if (#{o[1]} == null) {\n#{@indent + INDENT}", o)
|
|
1153
|
-
code << process(o)
|
|
1154
|
-
code << f("\n#{@indent}}", o)
|
|
1155
|
-
end if opt
|
|
1156
|
-
|
|
1157
|
-
code << f("#{splat} = $slice.call(arguments, #{argc});", sexp) if splat
|
|
1158
|
-
|
|
1159
|
-
scope_name = @scope.identity
|
|
1160
|
-
|
|
1161
|
-
if @scope.uses_block?
|
|
1162
|
-
@scope.add_temp "$iter = #{scope_name}._p"
|
|
1163
|
-
@scope.add_temp "#{yielder} = $iter || nil"
|
|
1164
|
-
|
|
1165
|
-
code.unshift f("#{scope_name}._p = null;", sexp)
|
|
1166
|
-
end
|
|
1167
|
-
|
|
1168
|
-
code.push(*stmt_code)
|
|
1169
|
-
|
|
1170
|
-
uses_super = @scope.uses_super
|
|
1171
|
-
|
|
1172
|
-
code = [f("#{arity_code}#@indent", sexp), @scope.to_vars, code]
|
|
1173
|
-
|
|
1174
|
-
if @scope.uses_zuper
|
|
1175
|
-
code.unshift f("var $zuper = $slice.call(arguments, 0);", sexp)
|
|
1176
|
-
end
|
|
1177
|
-
|
|
1178
|
-
if @scope.catch_return
|
|
1179
|
-
code.unshift f("try {\n", sexp)
|
|
1180
|
-
code.push f("\n} catch($returner) { if ($returner === $opal.returner) { return $returner.$v; } throw $returner; }", sexp)
|
|
1181
|
-
end
|
|
1182
|
-
end
|
|
1183
|
-
end
|
|
1184
|
-
|
|
1185
|
-
result = [f("#{"#{scope_name} = " if scope_name}function(", sexp)]
|
|
1186
|
-
result.push(*params)
|
|
1187
|
-
result << f(") {\n", sexp)
|
|
1188
|
-
result.push(*code)
|
|
1189
|
-
result << f("\n#@indent}", sexp)
|
|
1190
|
-
|
|
1191
|
-
if recvr
|
|
1192
|
-
if smethod
|
|
1193
|
-
[f("#{@scope.name}.constructor.prototype['$#{mid}'] = ", sexp), result]
|
|
1194
|
-
else
|
|
1195
|
-
[recv, f("#{jsid} = ", sexp), result]
|
|
1196
|
-
end
|
|
1197
|
-
elsif @scope.class? and @scope.name == 'Object'
|
|
1198
|
-
[f("#{current_self}._defn('$#{mid}', ", sexp), result, f(")", sexp)]
|
|
1199
|
-
elsif @scope.class_scope?
|
|
1200
|
-
@scope.methods << "$#{mid}"
|
|
1201
|
-
if uses_super
|
|
1202
|
-
@scope.add_temp uses_super
|
|
1203
|
-
uses_super = "#{uses_super} = #{@scope.proto}#{jsid};\n#@indent"
|
|
1204
|
-
end
|
|
1205
|
-
|
|
1206
|
-
[f("#{uses_super}#{@scope.proto}#{jsid} = ", sexp), result]
|
|
1207
|
-
else # :top, :iter
|
|
1208
|
-
[f("def#{jsid} = ", sexp), result]
|
|
1209
|
-
end
|
|
1210
|
-
end
|
|
1211
|
-
|
|
1212
|
-
##
|
|
1213
|
-
# Returns code used in debug mode to check arity of method call
|
|
1214
|
-
def arity_check(args, opt, splat, block_name, mid)
|
|
1215
|
-
meth = mid.to_s.inspect
|
|
1216
|
-
|
|
1217
|
-
arity = args.size - 1
|
|
1218
|
-
arity -= (opt.size - 1) if opt
|
|
1219
|
-
arity -= 1 if splat
|
|
1220
|
-
arity = -arity - 1 if opt or splat
|
|
1221
|
-
|
|
1222
|
-
# $arity will point to our received arguments count
|
|
1223
|
-
aritycode = "var $arity = arguments.length;"
|
|
1224
|
-
|
|
1225
|
-
if arity < 0 # splat or opt args
|
|
1226
|
-
aritycode + "if ($arity < #{-(arity + 1)}) { $opal.ac($arity, #{arity}, this, #{meth}); }"
|
|
1227
|
-
else
|
|
1228
|
-
aritycode + "if ($arity !== #{arity}) { $opal.ac($arity, #{arity}, this, #{meth}); }"
|
|
1229
|
-
end
|
|
1230
|
-
end
|
|
1231
|
-
|
|
1232
|
-
def process_args(exp, level)
|
|
1233
|
-
args = []
|
|
1234
|
-
|
|
1235
|
-
exp.each do |a|
|
|
1236
|
-
a = a.to_sym
|
|
1237
|
-
next if a.to_s == '*'
|
|
1238
|
-
a = lvar_to_js a
|
|
1239
|
-
@scope.add_arg a
|
|
1240
|
-
args << a
|
|
1241
|
-
end
|
|
1242
|
-
|
|
1243
|
-
f(args.join(', '), exp)
|
|
1244
|
-
end
|
|
1245
|
-
|
|
1246
|
-
# s(:self) # => this
|
|
1247
|
-
def process_self(sexp, level)
|
|
1248
|
-
f(current_self, sexp)
|
|
1249
|
-
end
|
|
1250
|
-
|
|
1251
|
-
# Returns the current value for 'self'. This will be native
|
|
1252
|
-
# 'this' for methods and blocks, and the class name for class
|
|
1253
|
-
# and module bodies.
|
|
1254
|
-
# s(:self) => self or this or class name
|
|
1255
|
-
def current_self
|
|
1256
|
-
if @scope.class_scope?
|
|
1257
|
-
@scope.name
|
|
1258
|
-
elsif @scope.top? or @scope.iter?
|
|
1259
|
-
'self'
|
|
1260
|
-
else # defn, defs
|
|
1261
|
-
'this'
|
|
1262
|
-
end
|
|
1263
|
-
end
|
|
1264
|
-
|
|
1265
|
-
# true literal
|
|
1266
|
-
# s(:true) => true
|
|
1267
|
-
def process_true(sexp, level)
|
|
1268
|
-
f "true", sexp
|
|
1269
|
-
end
|
|
1270
|
-
|
|
1271
|
-
# false literal
|
|
1272
|
-
# s(:false) => false
|
|
1273
|
-
def process_false(sexp, level)
|
|
1274
|
-
f "false", sexp
|
|
1275
|
-
end
|
|
1276
|
-
|
|
1277
|
-
# nil literal
|
|
1278
|
-
# s(:nil) => nil
|
|
1279
|
-
def process_nil(sexp, level)
|
|
1280
|
-
f "nil", sexp
|
|
1281
|
-
end
|
|
1282
|
-
|
|
1283
|
-
# s(:array [, sexp [, sexp]]) => [...]
|
|
1284
|
-
def process_array(sexp, level)
|
|
1285
|
-
return [f("[]", sexp)] if sexp.empty?
|
|
1286
|
-
|
|
1287
|
-
code, work = [], []
|
|
1288
|
-
|
|
1289
|
-
sexp.each do |current|
|
|
1290
|
-
splat = current.first == :splat
|
|
1291
|
-
part = process current
|
|
1292
|
-
|
|
1293
|
-
if splat
|
|
1294
|
-
if work.empty?
|
|
1295
|
-
if code.empty?
|
|
1296
|
-
code << f("[].concat(", sexp) << part << f(")", sexp)
|
|
1297
|
-
else
|
|
1298
|
-
code << f(".concat(", sexp) << part << f(")", sexp)
|
|
1299
|
-
end
|
|
1300
|
-
else
|
|
1301
|
-
if code.empty?
|
|
1302
|
-
code << f("[", sexp) << work << f("]", sexp)
|
|
1303
|
-
else
|
|
1304
|
-
code << f(".concat([", sexp) << work << f("])", sexp)
|
|
1305
|
-
end
|
|
1306
|
-
|
|
1307
|
-
code << f(".concat(", sexp) << part << f(")", sexp)
|
|
1308
|
-
end
|
|
1309
|
-
work = []
|
|
1310
|
-
else
|
|
1311
|
-
work << f(", ", current) unless work.empty?
|
|
1312
|
-
work << part
|
|
1313
|
-
end
|
|
1314
|
-
end
|
|
1315
|
-
|
|
1316
|
-
unless work.empty?
|
|
1317
|
-
join = [f("[", sexp), work, f("]", sexp)]
|
|
1318
|
-
|
|
1319
|
-
if code.empty?
|
|
1320
|
-
code = join
|
|
1321
|
-
else
|
|
1322
|
-
code.push([f(".concat(", sexp), join, f(")", sexp)])
|
|
1323
|
-
end
|
|
1324
|
-
end
|
|
11
|
+
def parse(source, file = '(string)')
|
|
12
|
+
@lexer = Lexer.new(source, file)
|
|
13
|
+
@file = file
|
|
14
|
+
@scopes = []
|
|
1325
15
|
|
|
1326
|
-
|
|
16
|
+
self.parse_to_sexp
|
|
1327
17
|
end
|
|
1328
18
|
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
sexp.each_with_index do |obj, idx|
|
|
1335
|
-
if idx.even?
|
|
1336
|
-
keys << obj
|
|
1337
|
-
else
|
|
1338
|
-
vals << obj
|
|
1339
|
-
end
|
|
1340
|
-
end
|
|
1341
|
-
|
|
1342
|
-
if keys.all? { |k| [:sym, :str].include? k[0] }
|
|
1343
|
-
hash_obj = {}
|
|
1344
|
-
hash_keys = []
|
|
1345
|
-
keys.size.times do |i|
|
|
1346
|
-
k = keys[i][1].to_s.inspect
|
|
1347
|
-
hash_keys << k unless hash_obj.include? k
|
|
1348
|
-
hash_obj[k] = process(vals[i])
|
|
1349
|
-
end
|
|
1350
|
-
|
|
1351
|
-
result = []
|
|
1352
|
-
@helpers[:hash2] = true
|
|
1353
|
-
|
|
1354
|
-
hash_keys.each do |k|
|
|
1355
|
-
result << f(", ", sexp) unless result.empty?
|
|
1356
|
-
result << f("#{k}: ", sexp)
|
|
1357
|
-
result << hash_obj[k]
|
|
1358
|
-
end
|
|
1359
|
-
|
|
1360
|
-
[f("$hash2([#{hash_keys.join ', '}], {", sexp), result, f("})", sexp)]
|
|
1361
|
-
else
|
|
1362
|
-
@helpers[:hash] = true
|
|
1363
|
-
result = []
|
|
1364
|
-
|
|
1365
|
-
sexp.each do |p|
|
|
1366
|
-
result << f(", ", p) unless result.empty?
|
|
1367
|
-
result << process(p)
|
|
1368
|
-
end
|
|
19
|
+
def parse_to_sexp
|
|
20
|
+
push_scope
|
|
21
|
+
result = do_parse
|
|
22
|
+
pop_scope
|
|
1369
23
|
|
|
1370
|
-
|
|
1371
|
-
end
|
|
24
|
+
result
|
|
1372
25
|
end
|
|
1373
26
|
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
expr, stmt = sexp
|
|
1377
|
-
redo_var = @scope.new_temp
|
|
1378
|
-
code = []
|
|
1379
|
-
|
|
1380
|
-
stmt_level = if level == :expr or level == :recv
|
|
1381
|
-
:stmt_closure
|
|
1382
|
-
else
|
|
1383
|
-
:stmt
|
|
1384
|
-
end
|
|
1385
|
-
|
|
1386
|
-
code << js_truthy(expr) << f("){", sexp)
|
|
1387
|
-
pre = "while ("
|
|
1388
|
-
|
|
1389
|
-
in_while do
|
|
1390
|
-
@while_loop[:closure] = true if stmt_level == :stmt_closure
|
|
1391
|
-
@while_loop[:redo_var] = redo_var
|
|
1392
|
-
body = process(stmt, :stmt)
|
|
1393
|
-
|
|
1394
|
-
if @while_loop[:use_redo]
|
|
1395
|
-
pre = "#{redo_var}=false;" + pre + "#{redo_var} || "
|
|
1396
|
-
code << f("#{redo_var}=false;", sexp)
|
|
1397
|
-
end
|
|
1398
|
-
|
|
1399
|
-
code << body
|
|
1400
|
-
end
|
|
1401
|
-
|
|
1402
|
-
code << f("}", sexp)
|
|
1403
|
-
code.unshift f(pre, sexp)
|
|
1404
|
-
@scope.queue_temp redo_var
|
|
1405
|
-
|
|
1406
|
-
if stmt_level == :stmt_closure
|
|
1407
|
-
code.unshift f("(function() {", sexp)
|
|
1408
|
-
code.push f("; return nil; }).call(#{current_self})", sexp)
|
|
1409
|
-
end
|
|
1410
|
-
|
|
1411
|
-
code
|
|
27
|
+
def next_token
|
|
28
|
+
@lexer.next_token
|
|
1412
29
|
end
|
|
1413
30
|
|
|
1414
|
-
def
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
:stmt_closure
|
|
1419
|
-
else
|
|
1420
|
-
:stmt
|
|
1421
|
-
end
|
|
1422
|
-
|
|
1423
|
-
code = []
|
|
1424
|
-
pre = "while (!("
|
|
1425
|
-
code << js_truthy(expr) << f(")) {", exp)
|
|
1426
|
-
|
|
1427
|
-
in_while do
|
|
1428
|
-
@while_loop[:closure] = true if stmt_level == :stmt_closure
|
|
1429
|
-
@while_loop[:redo_var] = redo_var
|
|
1430
|
-
body = process(stmt, :stmt)
|
|
1431
|
-
|
|
1432
|
-
if @while_loop[:use_redo]
|
|
1433
|
-
pre = "#{redo_var}=false;" + pre + "#{redo_var} || "
|
|
1434
|
-
code << f("#{redo_var}=false;", exp)
|
|
1435
|
-
end
|
|
1436
|
-
|
|
1437
|
-
code << body
|
|
1438
|
-
end
|
|
1439
|
-
|
|
1440
|
-
code << f("}", exp)
|
|
1441
|
-
code.unshift f(pre, exp)
|
|
1442
|
-
@scope.queue_temp redo_var
|
|
1443
|
-
|
|
1444
|
-
if stmt_level == :stmt_closure
|
|
1445
|
-
code.unshift f("(function() {", exp)
|
|
1446
|
-
code << f("; return nil; }).call(#{current_self})", exp)
|
|
1447
|
-
end
|
|
1448
|
-
|
|
1449
|
-
code
|
|
31
|
+
def s(*parts)
|
|
32
|
+
sexp = Sexp.new(parts)
|
|
33
|
+
sexp.line = @lexer.line
|
|
34
|
+
sexp
|
|
1450
35
|
end
|
|
1451
36
|
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
if [:class, :module].include? @scope.type
|
|
1460
|
-
@scope.methods << "$#{exp[0][1].to_s}"
|
|
1461
|
-
f("%s%s = %s%s" % [@scope.proto, new, @scope.proto, old], exp)
|
|
1462
|
-
else
|
|
1463
|
-
current = current_self
|
|
1464
|
-
f("%s._proto%s = %s._proto%s" % [current, new, current, old], exp)
|
|
1465
|
-
end
|
|
37
|
+
def push_scope(type = nil)
|
|
38
|
+
top = @scopes.last
|
|
39
|
+
scope = ParserScope.new type
|
|
40
|
+
scope.parent = top
|
|
41
|
+
@scopes << scope
|
|
42
|
+
@scope = scope
|
|
1466
43
|
end
|
|
1467
44
|
|
|
1468
|
-
def
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
len = 0
|
|
1472
|
-
code = []
|
|
1473
|
-
|
|
1474
|
-
if rhs[0] == :array
|
|
1475
|
-
len = rhs.length - 1 # we are guaranteed an array of this length
|
|
1476
|
-
code << f("#{tmp} = ", sexp) << process(rhs)
|
|
1477
|
-
elsif rhs[0] == :to_ary
|
|
1478
|
-
code << f("((#{tmp} = ", sexp) << process(rhs[1])
|
|
1479
|
-
code << f(")._isArray ? #{tmp} : (#{tmp} = [#{tmp}]))", sexp)
|
|
1480
|
-
elsif rhs[0] == :splat
|
|
1481
|
-
code << f("(#{tmp} = ", sexp) << process(rhs[1])
|
|
1482
|
-
code << f(")['$to_a'] ? (#{tmp} = #{tmp}['$to_a']()) : (#{tmp})._isArray ? #{tmp} : (#{tmp} = [#{tmp}])", sexp)
|
|
1483
|
-
else
|
|
1484
|
-
raise "Unsupported mlhs type"
|
|
1485
|
-
end
|
|
1486
|
-
|
|
1487
|
-
lhs[1..-1].each_with_index do |l, idx|
|
|
1488
|
-
code << f(", ", sexp) unless code.empty?
|
|
1489
|
-
|
|
1490
|
-
if l.first == :splat
|
|
1491
|
-
if s = l[1]
|
|
1492
|
-
s << s(:js_tmp, "$slice.call(#{tmp}, #{idx})")
|
|
1493
|
-
code << process(s)
|
|
1494
|
-
end
|
|
1495
|
-
else
|
|
1496
|
-
if idx >= len
|
|
1497
|
-
assign = s(:js_tmp, "(#{tmp}[#{idx}] == null ? nil : #{tmp}[#{idx}])")
|
|
1498
|
-
else
|
|
1499
|
-
assign = s(:js_tmp, "#{tmp}[#{idx}]")
|
|
1500
|
-
end
|
|
1501
|
-
|
|
1502
|
-
if l[0] == :lasgn or l[0] == :iasgn or l[0] == :lvar
|
|
1503
|
-
l << assign
|
|
1504
|
-
elsif l[0] == :call
|
|
1505
|
-
l[2] = "#{l[2]}=".to_sym
|
|
1506
|
-
l.last << assign
|
|
1507
|
-
elsif l[0] == :attrasgn
|
|
1508
|
-
l.last << assign
|
|
1509
|
-
else
|
|
1510
|
-
raise "bad lhs for masgn: #{l.inspect}"
|
|
1511
|
-
end
|
|
1512
|
-
|
|
1513
|
-
code << process(l)
|
|
1514
|
-
end
|
|
1515
|
-
end
|
|
1516
|
-
|
|
1517
|
-
@scope.queue_temp tmp
|
|
1518
|
-
code
|
|
45
|
+
def pop_scope
|
|
46
|
+
@scopes.pop
|
|
47
|
+
@scope = @scopes.last
|
|
1519
48
|
end
|
|
1520
49
|
|
|
1521
|
-
def
|
|
1522
|
-
|
|
50
|
+
def on_error(t, val, vstack)
|
|
51
|
+
raise "parse error on value #{val.inspect} (#{token_to_str(t) || '?'}) :#{@file}:#{lexer.line}"
|
|
1523
52
|
end
|
|
1524
53
|
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
lvar = "#{lvar}$".to_sym if RESERVED.include? lvar.to_s
|
|
1530
|
-
|
|
1531
|
-
if @irb_vars and @scope.top?
|
|
1532
|
-
[f("$opal.irb_vars.#{lvar} = ", sexp), process(rhs)]
|
|
1533
|
-
else
|
|
1534
|
-
@scope.add_local lvar
|
|
1535
|
-
rhs = process(rhs)
|
|
1536
|
-
result = [f(lvar, sexp), f(" = ", sexp), rhs]
|
|
1537
|
-
|
|
1538
|
-
if level == :recv
|
|
1539
|
-
result.unshift f("(", sexp)
|
|
1540
|
-
result.push f(")", sexp)
|
|
1541
|
-
end
|
|
1542
|
-
|
|
1543
|
-
result
|
|
1544
|
-
end
|
|
54
|
+
def new_block(stmt = nil)
|
|
55
|
+
s = s(:block)
|
|
56
|
+
s << stmt if stmt
|
|
57
|
+
s
|
|
1545
58
|
end
|
|
1546
59
|
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
if @irb_vars and @scope.top?
|
|
1553
|
-
with_temp { |t| f("((#{t} = $opal.irb_vars.#{lvar}) == null ? nil : #{t})", sexp) }
|
|
60
|
+
def new_compstmt(block)
|
|
61
|
+
if block.size == 1
|
|
62
|
+
nil
|
|
63
|
+
elsif block.size == 2
|
|
64
|
+
block[1]
|
|
1554
65
|
else
|
|
1555
|
-
|
|
66
|
+
block.line = block[1].line
|
|
67
|
+
block
|
|
1556
68
|
end
|
|
1557
69
|
end
|
|
1558
70
|
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
ivar = ivar.to_s[1..-1]
|
|
1563
|
-
lhs = RESERVED.include?(ivar) ? "#{current_self}['#{ivar}']" : "#{current_self}.#{ivar}"
|
|
1564
|
-
[f(lhs, exp), f(" = ", exp), process(rhs)]
|
|
1565
|
-
end
|
|
1566
|
-
|
|
1567
|
-
# s(:ivar, :ivar)
|
|
1568
|
-
def process_ivar(exp, level)
|
|
1569
|
-
ivar = exp[0].to_s[1..-1]
|
|
1570
|
-
part = RESERVED.include?(ivar) ? "['#{ivar}']" : ".#{ivar}"
|
|
1571
|
-
@scope.add_ivar part
|
|
1572
|
-
f("#{current_self}#{part}", exp)
|
|
1573
|
-
end
|
|
1574
|
-
|
|
1575
|
-
# s(:gvar, gvar)
|
|
1576
|
-
def process_gvar(sexp, level)
|
|
1577
|
-
gvar = sexp[0].to_s[1..-1]
|
|
1578
|
-
@helpers['gvars'] = true
|
|
1579
|
-
f("$gvars[#{gvar.inspect}]", sexp)
|
|
1580
|
-
end
|
|
71
|
+
def new_body(compstmt, res, els, ens)
|
|
72
|
+
s = compstmt || s(:block)
|
|
73
|
+
s.line = compstmt.line if compstmt
|
|
1581
74
|
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
75
|
+
if res
|
|
76
|
+
s = s(:rescue, s)
|
|
77
|
+
res.each { |r| s << r }
|
|
78
|
+
s << els if els
|
|
79
|
+
end
|
|
1585
80
|
|
|
1586
|
-
|
|
1587
|
-
def process_gasgn(sexp, level)
|
|
1588
|
-
gvar = sexp[0].to_s[1..-1]
|
|
1589
|
-
rhs = sexp[1]
|
|
1590
|
-
@helpers['gvars'] = true
|
|
1591
|
-
[f("$gvars[#{gvar.to_s.inspect}] = ", sexp), process(rhs)]
|
|
81
|
+
ens ? s(:ensure, s, ens) : s
|
|
1592
82
|
end
|
|
1593
83
|
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
end
|
|
84
|
+
def new_def(line, recv, name, args, body)
|
|
85
|
+
body = s(:block, body) if body.type != :block
|
|
86
|
+
scope = s(:scope, body)
|
|
87
|
+
body << s(:nil) if body.size == 1
|
|
88
|
+
scope.line = body.line
|
|
89
|
+
args.line = line
|
|
90
|
+
s = s(:def, recv, name.to_sym, args, scope)
|
|
91
|
+
s.line = line
|
|
92
|
+
s.end_line = @lexer.line
|
|
93
|
+
s
|
|
1605
94
|
end
|
|
1606
95
|
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
96
|
+
def new_class(path, sup, body)
|
|
97
|
+
scope = s(:scope)
|
|
98
|
+
scope << body unless body.size == 1
|
|
99
|
+
scope.line = body.line
|
|
100
|
+
s = s(:class, path, sup, scope)
|
|
101
|
+
s
|
|
1611
102
|
end
|
|
1612
103
|
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
104
|
+
def new_sclass(expr, body)
|
|
105
|
+
scope = s(:scope)
|
|
106
|
+
scope << body #unless body.size == 1
|
|
107
|
+
scope.line = body.line
|
|
108
|
+
s = s(:sclass, expr, scope)
|
|
109
|
+
s
|
|
1618
110
|
end
|
|
1619
111
|
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
[f("$opal.$return(", sexp), val, f(")", sexp)]
|
|
1627
|
-
|
|
1628
|
-
elsif level == :expr and @scope.def?
|
|
1629
|
-
@scope.catch_return = true
|
|
1630
|
-
[f("$opal.$return(", sexp), val, f(")", sexp)]
|
|
1631
|
-
|
|
1632
|
-
elsif level == :stmt
|
|
1633
|
-
[f("return ", sexp), val]
|
|
1634
|
-
|
|
1635
|
-
else
|
|
1636
|
-
raise SyntaxError, "void value expression: cannot return as an expression"
|
|
1637
|
-
end
|
|
112
|
+
def new_module(path, body)
|
|
113
|
+
scope = s(:scope)
|
|
114
|
+
scope << body unless body.size == 1
|
|
115
|
+
scope.line = body.line
|
|
116
|
+
s = s(:module, path, scope)
|
|
117
|
+
s
|
|
1638
118
|
end
|
|
1639
119
|
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
result = f(code, sexp)
|
|
1646
|
-
|
|
1647
|
-
level == :recv ? [f("(", sexp), result, f(")", sexp)] : result
|
|
120
|
+
def new_iter(args, body)
|
|
121
|
+
s = s(:iter, args)
|
|
122
|
+
s << body if body
|
|
123
|
+
s.end_line = @lexer.line
|
|
124
|
+
s
|
|
1648
125
|
end
|
|
1649
126
|
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
sexp.each do |p|
|
|
1656
|
-
if String === p
|
|
1657
|
-
result << f(p.to_s, sexp)
|
|
1658
|
-
needs_sc = true if level == :stmt and !p.to_s.include?(';')
|
|
1659
|
-
elsif p.first == :evstr
|
|
1660
|
-
result.push(*process(p.last, :stmt))
|
|
1661
|
-
elsif p.first == :str
|
|
1662
|
-
result << f(p.last.to_s, p)
|
|
1663
|
-
needs_sc = true if level == :stmt and !p.last.to_s.include?(';')
|
|
1664
|
-
else
|
|
1665
|
-
raise "Bad dxstr part"
|
|
1666
|
-
end
|
|
1667
|
-
end
|
|
1668
|
-
|
|
1669
|
-
result << f(";", sexp) if needs_sc
|
|
1670
|
-
|
|
1671
|
-
if level == :recv
|
|
1672
|
-
[f("(", sexp), result, f(")", sexp)]
|
|
1673
|
-
else
|
|
1674
|
-
result
|
|
1675
|
-
end
|
|
127
|
+
def new_if(expr, stmt, tail)
|
|
128
|
+
s = s(:if, expr, stmt, tail)
|
|
129
|
+
s.line = expr.line
|
|
130
|
+
s.end_line = @lexer.line
|
|
131
|
+
s
|
|
1676
132
|
end
|
|
1677
133
|
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
result = []
|
|
134
|
+
def new_args(norm, opt, rest, block)
|
|
135
|
+
res = s(:args)
|
|
1681
136
|
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
elsif p.first == :evstr
|
|
1687
|
-
result << f("(", p)
|
|
1688
|
-
result << process(p.last)
|
|
1689
|
-
result << f(")", p)
|
|
1690
|
-
elsif p.first == :str
|
|
1691
|
-
result << f(p.last.inspect, p)
|
|
1692
|
-
else
|
|
1693
|
-
raise "Bad dstr part"
|
|
137
|
+
if norm
|
|
138
|
+
norm.each do |arg|
|
|
139
|
+
scope.add_local arg
|
|
140
|
+
res << arg
|
|
1694
141
|
end
|
|
1695
142
|
end
|
|
1696
143
|
|
|
1697
|
-
if
|
|
1698
|
-
[
|
|
1699
|
-
|
|
1700
|
-
result
|
|
1701
|
-
end
|
|
1702
|
-
end
|
|
1703
|
-
|
|
1704
|
-
def process_dsym(sexp, level)
|
|
1705
|
-
result = []
|
|
1706
|
-
|
|
1707
|
-
sexp.each do |p|
|
|
1708
|
-
result << f(" + ", sexp) unless result.empty?
|
|
1709
|
-
|
|
1710
|
-
if String === p
|
|
1711
|
-
result << f(p.inspect, sexp)
|
|
1712
|
-
elsif p.first == :evstr
|
|
1713
|
-
result << process(s(:call, p.last, :to_s, s(:arglist)))
|
|
1714
|
-
elsif p.first == :str
|
|
1715
|
-
result << f(p.last.inspect, sexp)
|
|
1716
|
-
else
|
|
1717
|
-
raise "Bad dsym part"
|
|
144
|
+
if opt
|
|
145
|
+
opt[1..-1].each do |_opt|
|
|
146
|
+
res << _opt[1]
|
|
1718
147
|
end
|
|
1719
148
|
end
|
|
1720
149
|
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
def process_if(sexp, level)
|
|
1726
|
-
test, truthy, falsy = sexp
|
|
1727
|
-
returnable = (level == :expr or level == :recv)
|
|
1728
|
-
|
|
1729
|
-
if returnable
|
|
1730
|
-
truthy = returns(truthy || s(:nil))
|
|
1731
|
-
falsy = returns(falsy || s(:nil))
|
|
1732
|
-
end
|
|
1733
|
-
|
|
1734
|
-
# optimize unless (we don't want else unless we need to)
|
|
1735
|
-
if falsy and !truthy
|
|
1736
|
-
truthy = falsy
|
|
1737
|
-
falsy = nil
|
|
1738
|
-
check = js_falsy test
|
|
1739
|
-
else
|
|
1740
|
-
check = js_truthy test
|
|
150
|
+
if rest
|
|
151
|
+
res << rest
|
|
152
|
+
rest_str = rest.to_s[1..-1]
|
|
153
|
+
scope.add_local rest_str.to_sym unless rest_str.empty?
|
|
1741
154
|
end
|
|
1742
155
|
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
outdent = @indent
|
|
1748
|
-
indent { result.push(f("\n#{outdent}} else {\n#@indent", sexp), process(falsy, :stmt)) } if falsy
|
|
1749
|
-
|
|
1750
|
-
result << f("\n#@indent}", sexp)
|
|
1751
|
-
|
|
1752
|
-
if returnable
|
|
1753
|
-
result.unshift f("(function() { ", sexp)
|
|
1754
|
-
result.push f("; return nil; }).call(#{current_self})", sexp)
|
|
156
|
+
if block
|
|
157
|
+
res << block
|
|
158
|
+
scope.add_local block.to_s[1..-1].to_sym
|
|
1755
159
|
end
|
|
1756
160
|
|
|
1757
|
-
|
|
1758
|
-
end
|
|
161
|
+
res << opt if opt
|
|
1759
162
|
|
|
1760
|
-
|
|
1761
|
-
if sexp.first == :call
|
|
1762
|
-
mid = sexp[2]
|
|
1763
|
-
if mid == :block_given?
|
|
1764
|
-
return process sexp
|
|
1765
|
-
elsif COMPARE.include? mid.to_s
|
|
1766
|
-
return process sexp
|
|
1767
|
-
elsif mid == :"=="
|
|
1768
|
-
return process sexp
|
|
1769
|
-
end
|
|
1770
|
-
elsif [:lvar, :self].include? sexp.first
|
|
1771
|
-
[process(sexp.dup), f(" !== false && ", sexp), process(sexp.dup), f(" !== nil", sexp)]
|
|
1772
|
-
end
|
|
163
|
+
res
|
|
1773
164
|
end
|
|
1774
165
|
|
|
1775
|
-
def
|
|
1776
|
-
|
|
1777
|
-
return optimized
|
|
1778
|
-
end
|
|
166
|
+
def new_block_args(norm, opt, rest, block)
|
|
167
|
+
res = s(:array)
|
|
1779
168
|
|
|
1780
|
-
|
|
1781
|
-
|
|
169
|
+
if norm
|
|
170
|
+
norm.each do |arg|
|
|
171
|
+
if arg.is_a? Symbol
|
|
172
|
+
scope.add_local arg
|
|
173
|
+
res << s(:lasgn, arg)
|
|
174
|
+
else
|
|
175
|
+
res << arg
|
|
176
|
+
end
|
|
177
|
+
end
|
|
1782
178
|
end
|
|
1783
|
-
end
|
|
1784
179
|
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
if mid == :block_given?
|
|
1789
|
-
return handle_block_given(sexp, true)
|
|
180
|
+
if opt
|
|
181
|
+
opt[1..-1].each do |_opt|
|
|
182
|
+
res << s(:lasgn, _opt[1])
|
|
1790
183
|
end
|
|
1791
184
|
end
|
|
1792
185
|
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
result << f(") === false || #{tmp} === nil", sexp)
|
|
1798
|
-
result
|
|
186
|
+
if rest
|
|
187
|
+
r = rest.to_s[1..-1].to_sym
|
|
188
|
+
res << s(:splat, s(:lasgn, r))
|
|
189
|
+
scope.add_local r
|
|
1799
190
|
end
|
|
1800
|
-
end
|
|
1801
|
-
|
|
1802
|
-
# s(:and, lhs, rhs)
|
|
1803
|
-
def process_and(sexp, level)
|
|
1804
|
-
lhs, rhs = sexp
|
|
1805
|
-
t = nil
|
|
1806
|
-
tmp = @scope.new_temp
|
|
1807
191
|
|
|
1808
|
-
if
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
result << f(" : #{tmp})", sexp)
|
|
1813
|
-
@scope.queue_temp tmp
|
|
1814
|
-
|
|
1815
|
-
return result
|
|
192
|
+
if block
|
|
193
|
+
b = block.to_s[1..-1].to_sym
|
|
194
|
+
res << s(:block_pass, s(:lasgn, b))
|
|
195
|
+
scope.add_local b
|
|
1816
196
|
end
|
|
1817
197
|
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
[f("(#{tmp} = ", sexp), process(lhs), f(", #{tmp} !== false && #{tmp} !== nil ? ", sexp), process(rhs), f(" : #{tmp})", sexp)]
|
|
1821
|
-
|
|
1822
|
-
end
|
|
1823
|
-
|
|
1824
|
-
# s(:or, lhs, rhs)
|
|
1825
|
-
def process_or(sexp, level)
|
|
1826
|
-
lhs, rhs = sexp
|
|
198
|
+
res << opt if opt
|
|
1827
199
|
|
|
1828
|
-
|
|
1829
|
-
lhs = process lhs
|
|
1830
|
-
rhs = process rhs
|
|
1831
|
-
[f("(((#{tmp} = ", sexp), lhs, f(") !== false && #{tmp} !== nil) ? #{tmp} : ", sexp), rhs, f(")", sexp)]
|
|
1832
|
-
end
|
|
1833
|
-
end
|
|
200
|
+
args = res.size == 2 && norm ? res[1] : s(:masgn, res)
|
|
1834
201
|
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
call = handle_yield_call sexp, level
|
|
1838
|
-
|
|
1839
|
-
if level == :stmt
|
|
1840
|
-
[f("if (", sexp), call, f(" === $breaker) return $breaker.$v")]
|
|
202
|
+
if args.type == :array
|
|
203
|
+
s(:masgn, args)
|
|
1841
204
|
else
|
|
1842
|
-
|
|
1843
|
-
[f("(((#{tmp} = ", sexp), call, f(") === $breaker) ? $breaker.$v : #{tmp})", sexp)]
|
|
1844
|
-
end
|
|
1845
|
-
end
|
|
1846
|
-
end
|
|
1847
|
-
|
|
1848
|
-
# special opal yield assign, for `a = yield(arg1, arg2)` to assign
|
|
1849
|
-
# to a temp value to make yield expr into stmt.
|
|
1850
|
-
#
|
|
1851
|
-
# level will always be stmt as its the reason for this to exist
|
|
1852
|
-
#
|
|
1853
|
-
# s(:yasgn, :a, s(:yield, arg1, arg2))
|
|
1854
|
-
def process_yasgn(sexp, level)
|
|
1855
|
-
call = handle_yield_call s(*sexp[1][1..-1]), :stmt
|
|
1856
|
-
|
|
1857
|
-
[f("if ((#{sexp[0]} = ", sexp), call, f(") === $breaker) return $breaker.$v", sexp)]
|
|
1858
|
-
end
|
|
1859
|
-
|
|
1860
|
-
# Created by `#returns()` for when a yield statement should return
|
|
1861
|
-
# it's value (its last in a block etc).
|
|
1862
|
-
def process_returnable_yield(sexp, level)
|
|
1863
|
-
call = handle_yield_call sexp, level
|
|
1864
|
-
|
|
1865
|
-
with_temp do |tmp|
|
|
1866
|
-
[f("return #{tmp} = ", sexp), call,
|
|
1867
|
-
f(", #{tmp} === $breaker ? #{tmp} : #{tmp}")]
|
|
205
|
+
args
|
|
1868
206
|
end
|
|
1869
207
|
end
|
|
1870
208
|
|
|
1871
|
-
def
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
209
|
+
def new_call(recv, meth, args = nil)
|
|
210
|
+
call = s(:call, recv, meth)
|
|
211
|
+
args = s(:arglist) unless args
|
|
212
|
+
args.type = :arglist if args.type == :array
|
|
213
|
+
call << args
|
|
1875
214
|
|
|
1876
|
-
if
|
|
1877
|
-
|
|
215
|
+
if recv
|
|
216
|
+
call.line = recv.line
|
|
217
|
+
elsif args[1]
|
|
218
|
+
call.line = args[1].line
|
|
1878
219
|
end
|
|
1879
220
|
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
if splat
|
|
1884
|
-
[f("$opal.$yieldX(#{y}, ", sexp), args, f(")")]
|
|
221
|
+
# fix arglist spilling over into next line if no args
|
|
222
|
+
if args.length == 1
|
|
223
|
+
args.line = call.line
|
|
1885
224
|
else
|
|
1886
|
-
|
|
225
|
+
args.line = args[1].line
|
|
1887
226
|
end
|
|
1888
|
-
end
|
|
1889
227
|
|
|
1890
|
-
|
|
1891
|
-
val = sexp.empty? ? f('nil', sexp) : process(sexp[0])
|
|
1892
|
-
if in_while?
|
|
1893
|
-
@while_loop[:closure] ? [f("return ", sexp), val, f("", sexp)] : f("break;", sexp)
|
|
1894
|
-
elsif @scope.iter?
|
|
1895
|
-
error "break must be used as a statement" unless level == :stmt
|
|
1896
|
-
[f("return ($breaker.$v = ", sexp), val, f(", $breaker)", sexp)]
|
|
1897
|
-
else
|
|
1898
|
-
error "void value expression: cannot use break outside of iter/while"
|
|
1899
|
-
end
|
|
228
|
+
call
|
|
1900
229
|
end
|
|
1901
230
|
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
# are we inside a statement_closure
|
|
1907
|
-
returnable = level != :stmt
|
|
1908
|
-
done_else = false
|
|
1909
|
-
|
|
1910
|
-
in_case do
|
|
1911
|
-
if cond = exp[0]
|
|
1912
|
-
@case_stmt[:cond] = true
|
|
1913
|
-
@scope.add_local "$case"
|
|
1914
|
-
expr = process cond
|
|
1915
|
-
pre << f("$case = ", exp) << expr << f(";", exp)
|
|
1916
|
-
end
|
|
1917
|
-
|
|
1918
|
-
exp[1..-1].each do |wen|
|
|
1919
|
-
if wen and wen.first == :when
|
|
1920
|
-
returns(wen) if returnable
|
|
1921
|
-
wen = process(wen, :stmt)
|
|
1922
|
-
code << f("else ", exp) unless code.empty?
|
|
1923
|
-
code << wen
|
|
1924
|
-
elsif wen # s(:else)
|
|
1925
|
-
done_else = true
|
|
1926
|
-
wen = returns(wen) if returnable
|
|
1927
|
-
code << f("else {", exp) << process(wen, :stmt) << f("}", exp)
|
|
1928
|
-
end
|
|
1929
|
-
end
|
|
1930
|
-
end
|
|
1931
|
-
|
|
1932
|
-
code << f("else { return nil }", exp) if returnable and !done_else
|
|
1933
|
-
|
|
1934
|
-
code.unshift pre
|
|
1935
|
-
|
|
1936
|
-
if returnable
|
|
1937
|
-
code.unshift f("(function() { ", exp)
|
|
1938
|
-
code << f(" }).call(#{current_self})", exp)
|
|
1939
|
-
end
|
|
1940
|
-
|
|
1941
|
-
code
|
|
231
|
+
def add_block_pass(arglist, block)
|
|
232
|
+
arglist << block if block
|
|
233
|
+
arglist
|
|
1942
234
|
end
|
|
1943
235
|
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
test << f(" || ") unless test.empty?
|
|
1956
|
-
|
|
1957
|
-
if a.first == :splat # when inside another when means a splat of values
|
|
1958
|
-
call = f("$splt[i]['$===']($case)", a)
|
|
1959
|
-
|
|
1960
|
-
splt = [f("(function($splt) { for(var i = 0; i < $splt.length; i++) {", exp)]
|
|
1961
|
-
splt << f("if (") << call << f(") { return true; }", exp)
|
|
1962
|
-
splt << f("} return false; }).call(#{current_self}, ", exp)
|
|
1963
|
-
splt << process(a[1]) << f(")")
|
|
236
|
+
def new_op_asgn(op, lhs, rhs)
|
|
237
|
+
case op
|
|
238
|
+
when :"||"
|
|
239
|
+
result = s(:op_asgn_or, new_gettable(lhs))
|
|
240
|
+
result << (lhs << rhs)
|
|
241
|
+
when :"&&"
|
|
242
|
+
result = s(:op_asgn_and, new_gettable(lhs))
|
|
243
|
+
result << (lhs << rhs)
|
|
244
|
+
else
|
|
245
|
+
result = lhs
|
|
246
|
+
result << new_call(new_gettable(lhs), op, s(:arglist, rhs))
|
|
1964
247
|
|
|
1965
|
-
test << splt
|
|
1966
|
-
else
|
|
1967
|
-
if @case_stmt[:cond]
|
|
1968
|
-
call = s(:call, a, :===, s(:arglist, s(:js_tmp, "$case")))
|
|
1969
|
-
test << process(call)
|
|
1970
|
-
else
|
|
1971
|
-
test << js_truthy(a)
|
|
1972
|
-
end
|
|
1973
|
-
end
|
|
1974
248
|
end
|
|
1975
249
|
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
# lhs =~ rhs
|
|
1980
|
-
#
|
|
1981
|
-
# s(:match3, lhs, rhs) # => s(:call, lhs, :=~, s(:arglist, rhs))
|
|
1982
|
-
def process_match3(sexp, level)
|
|
1983
|
-
process s(:call, sexp[0], :=~, s(:arglist, sexp[1])), level
|
|
250
|
+
result.line = lhs.line
|
|
251
|
+
result
|
|
1984
252
|
end
|
|
1985
253
|
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
254
|
+
def new_assign(lhs, rhs)
|
|
255
|
+
case lhs.type
|
|
256
|
+
when :iasgn, :cdecl, :lasgn, :gasgn, :cvdecl, :nth_ref
|
|
257
|
+
lhs << rhs
|
|
258
|
+
lhs
|
|
259
|
+
when :call, :attrasgn
|
|
260
|
+
lhs.last << rhs
|
|
261
|
+
lhs
|
|
262
|
+
when :colon2
|
|
263
|
+
lhs << rhs
|
|
264
|
+
lhs.type = :casgn
|
|
265
|
+
lhs
|
|
266
|
+
when :colon3
|
|
267
|
+
lhs << rhs
|
|
268
|
+
lhs.type = :casgn3
|
|
269
|
+
lhs
|
|
270
|
+
else
|
|
271
|
+
raise "Bad lhs for new_assign: #{lhs.type}"
|
|
1992
272
|
end
|
|
1993
273
|
end
|
|
1994
274
|
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
#
|
|
2009
|
-
# s(:colon2, base, :NAME)
|
|
2010
|
-
def process_colon2(sexp, level)
|
|
2011
|
-
base, cname = sexp
|
|
2012
|
-
result = []
|
|
2013
|
-
|
|
2014
|
-
if @const_missing
|
|
2015
|
-
with_temp do |t|
|
|
2016
|
-
base = process base
|
|
2017
|
-
|
|
2018
|
-
result << f("((#{t} = (", sexp) << base << f(")._scope).", sexp)
|
|
2019
|
-
result << f("#{cname} == null ? #{t}.cm('#{cname}') : #{t}.#{cname})", sexp)
|
|
2020
|
-
end
|
|
275
|
+
def new_assignable(ref)
|
|
276
|
+
case ref.type
|
|
277
|
+
when :ivar
|
|
278
|
+
ref.type = :iasgn
|
|
279
|
+
when :const
|
|
280
|
+
ref.type = :cdecl
|
|
281
|
+
when :identifier
|
|
282
|
+
scope.add_local ref[1] unless scope.has_local? ref[1]
|
|
283
|
+
ref.type = :lasgn
|
|
284
|
+
when :gvar
|
|
285
|
+
ref.type = :gasgn
|
|
286
|
+
when :cvar
|
|
287
|
+
ref.type = :cvdecl
|
|
2021
288
|
else
|
|
2022
|
-
|
|
289
|
+
raise "Bad new_assignable type: #{ref.type}"
|
|
2023
290
|
end
|
|
2024
291
|
|
|
2025
|
-
|
|
2026
|
-
end
|
|
2027
|
-
|
|
2028
|
-
# s(:colon3, :CONST_NAME) # => $opal.Object._scope.CONST_NAME
|
|
2029
|
-
def process_colon3(exp, level)
|
|
2030
|
-
with_temp do |t|
|
|
2031
|
-
f("((#{t} = $opal.Object._scope.#{exp[0]}) == null ? $opal.cm('#{exp[0]}') : #{t})", exp)
|
|
2032
|
-
end
|
|
292
|
+
ref
|
|
2033
293
|
end
|
|
2034
294
|
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
295
|
+
def new_gettable(ref)
|
|
296
|
+
res = case ref.type
|
|
297
|
+
when :lasgn
|
|
298
|
+
s(:lvar, ref[1])
|
|
299
|
+
when :iasgn
|
|
300
|
+
s(:ivar, ref[1])
|
|
301
|
+
when :gasgn
|
|
302
|
+
s(:gvar, ref[1])
|
|
303
|
+
when :cvdecl
|
|
304
|
+
s(:cvar, ref[1])
|
|
305
|
+
else
|
|
306
|
+
raise "Bad new_gettable ref: #{ref.type}"
|
|
307
|
+
end
|
|
2047
308
|
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
# s(:zsuper)
|
|
2051
|
-
def process_zsuper(exp, level)
|
|
2052
|
-
if @scope.def?
|
|
2053
|
-
@scope.uses_zuper = true
|
|
2054
|
-
js_super f("$zuper", exp), true, exp
|
|
2055
|
-
else
|
|
2056
|
-
js_super f("$slice.call(arguments)", exp), true, exp
|
|
2057
|
-
end
|
|
309
|
+
res.line = ref.line
|
|
310
|
+
res
|
|
2058
311
|
end
|
|
2059
312
|
|
|
2060
|
-
def
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
elsif @scope.type == :def
|
|
2080
|
-
@scope.uses_block!
|
|
2081
|
-
@scope.identify!
|
|
2082
|
-
cls_name = @scope.parent.name || "#{current_self}._klass._proto"
|
|
2083
|
-
jsid = mid_to_jsid @scope.mid.to_s
|
|
2084
|
-
|
|
2085
|
-
if pass_block
|
|
2086
|
-
@scope.uses_block!
|
|
2087
|
-
iter = "$iter"
|
|
2088
|
-
else
|
|
2089
|
-
iter = "null"
|
|
2090
|
-
end
|
|
2091
|
-
|
|
2092
|
-
if @scope.defs
|
|
2093
|
-
[f("$opal.dispatch_super(this, #{@scope.mid.to_s.inspect},", sexp), args, f(", #{iter}, #{cls_name})", sexp)]
|
|
313
|
+
def new_var_ref(ref)
|
|
314
|
+
case ref.type
|
|
315
|
+
when :self, :nil, :true, :false, :line, :file
|
|
316
|
+
ref
|
|
317
|
+
when :const
|
|
318
|
+
ref
|
|
319
|
+
when :ivar, :gvar, :cvar
|
|
320
|
+
ref
|
|
321
|
+
when :int
|
|
322
|
+
# this is when we passed __LINE__ which is converted into :int
|
|
323
|
+
ref
|
|
324
|
+
when :str
|
|
325
|
+
# returns for __FILE__ as it is converted into str
|
|
326
|
+
ref
|
|
327
|
+
when :identifier
|
|
328
|
+
if scope.has_local? ref[1]
|
|
329
|
+
s(:lvar, ref[1])
|
|
2094
330
|
else
|
|
2095
|
-
|
|
331
|
+
s(:call, nil, ref[1], s(:arglist))
|
|
2096
332
|
end
|
|
2097
|
-
|
|
2098
|
-
elsif @scope.type == :iter
|
|
2099
|
-
chain, defn, mid = @scope.get_super_chain
|
|
2100
|
-
trys = chain.map { |c| "#{c}._sup" }.join ' || '
|
|
2101
|
-
[f("(#{trys} || #{current_self}._klass._super._proto[#{mid}]).apply(#{current_self}, ", sexp), args, f(")", sexp)]
|
|
2102
333
|
else
|
|
2103
|
-
raise "
|
|
334
|
+
raise "Bad var_ref type: #{ref.type}"
|
|
2104
335
|
end
|
|
2105
336
|
end
|
|
2106
337
|
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
# s(:op_asgn_or, s(:lvar, :a), s(:lasgn, :a, rhs))
|
|
2110
|
-
def process_op_asgn_or(exp, level)
|
|
2111
|
-
process s(:or, exp[0], exp[1])
|
|
2112
|
-
end
|
|
2113
|
-
|
|
2114
|
-
# a &&= rhs
|
|
2115
|
-
#
|
|
2116
|
-
# s(:op_asgn_and, s(:lvar, :a), s(:lasgn, :a, rhs))
|
|
2117
|
-
def process_op_asgn_and(sexp, level)
|
|
2118
|
-
process s(:and, sexp[0], sexp[1])
|
|
2119
|
-
end
|
|
2120
|
-
|
|
2121
|
-
# lhs[args] ||= rhs
|
|
2122
|
-
#
|
|
2123
|
-
# s(:op_asgn1, lhs, args, :||, rhs)
|
|
2124
|
-
def process_op_asgn1(sexp, level)
|
|
2125
|
-
lhs, arglist, op, rhs = sexp
|
|
2126
|
-
|
|
2127
|
-
with_temp do |a| # args
|
|
2128
|
-
with_temp do |r| # recv
|
|
2129
|
-
args = process arglist[1]
|
|
2130
|
-
recv = process lhs
|
|
2131
|
-
|
|
2132
|
-
aref = s(:call, s(:js_tmp, r), :[], s(:arglist, s(:js_tmp, a)))
|
|
2133
|
-
aset = s(:call, s(:js_tmp, r), :[]=, s(:arglist, s(:js_tmp, a), rhs))
|
|
2134
|
-
orop = s(:or, aref, aset)
|
|
338
|
+
def new_super(args)
|
|
339
|
+
args = (args || s(:arglist))
|
|
2135
340
|
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
result << recv << f(", ", sexp) << process(orop)
|
|
2139
|
-
result << f(")", sexp)
|
|
2140
|
-
result
|
|
2141
|
-
end
|
|
341
|
+
if args.type == :array
|
|
342
|
+
args.type = :arglist
|
|
2142
343
|
end
|
|
2143
|
-
end
|
|
2144
|
-
|
|
2145
|
-
# lhs.b += rhs
|
|
2146
|
-
#
|
|
2147
|
-
# s(:op_asgn2, lhs, :b=, :+, rhs)
|
|
2148
|
-
def process_op_asgn2(sexp, level)
|
|
2149
|
-
lhs = process sexp[0]
|
|
2150
|
-
mid = sexp[1].to_s[0..-2]
|
|
2151
|
-
op = sexp[2]
|
|
2152
|
-
rhs = sexp[3]
|
|
2153
|
-
|
|
2154
|
-
if op.to_s == "||"
|
|
2155
|
-
with_temp do |temp|
|
|
2156
|
-
getr = s(:call, s(:js_tmp, temp), mid, s(:arglist))
|
|
2157
|
-
asgn = s(:call, s(:js_tmp, temp), "#{mid}=", s(:arglist, rhs))
|
|
2158
|
-
orop = s(:or, getr, asgn)
|
|
2159
344
|
|
|
2160
|
-
|
|
2161
|
-
end
|
|
2162
|
-
elsif op.to_s == '&&'
|
|
2163
|
-
with_temp do |temp|
|
|
2164
|
-
getr = s(:call, s(:js_tmp, temp), mid, s(:arglist))
|
|
2165
|
-
asgn = s(:call, s(:js_tmp, temp), "#{mid}=", s(:arglist, rhs))
|
|
2166
|
-
andop = s(:and, getr, asgn)
|
|
2167
|
-
|
|
2168
|
-
[f("(#{temp} = ", sexp), lhs, f(", ", sexp), process(andop), f(")", sexp)]
|
|
2169
|
-
end
|
|
2170
|
-
else
|
|
2171
|
-
with_temp do |temp|
|
|
2172
|
-
getr = s(:call, s(:js_tmp, temp), mid, s(:arglist))
|
|
2173
|
-
oper = s(:call, getr, op, s(:arglist, rhs))
|
|
2174
|
-
asgn = s(:call, s(:js_tmp, temp), "#{mid}=", s(:arglist, oper))
|
|
2175
|
-
|
|
2176
|
-
[f("(#{temp} = ", sexp), lhs, f(", ", sexp), process(asgn), f(")", sexp)]
|
|
2177
|
-
end
|
|
2178
|
-
end
|
|
345
|
+
s(:super, args)
|
|
2179
346
|
end
|
|
2180
347
|
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
if level == :recv || level == :expr
|
|
2185
|
-
retn = true
|
|
2186
|
-
begn = returns begn
|
|
2187
|
-
end
|
|
2188
|
-
|
|
2189
|
-
result = []
|
|
2190
|
-
body = process begn, level
|
|
2191
|
-
ensr = exp[1] || s(:nil)
|
|
2192
|
-
ensr = process ensr, level
|
|
2193
|
-
|
|
2194
|
-
body = [f("try {\n", exp), body, f("}", exp)]
|
|
2195
|
-
|
|
2196
|
-
result << body << f("#{@space}finally {#@space", exp) << ensr << f("}", exp)
|
|
2197
|
-
|
|
2198
|
-
if retn
|
|
2199
|
-
[f("(function() { ", exp), result, f("; }).call(#{current_self})", exp)]
|
|
2200
|
-
else
|
|
2201
|
-
result
|
|
2202
|
-
end
|
|
348
|
+
def new_yield(args)
|
|
349
|
+
args = (args || s(:arglist))[1..-1]
|
|
350
|
+
s(:yield, *args)
|
|
2203
351
|
end
|
|
2204
352
|
|
|
2205
|
-
def
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
exp[1..-1].each do |a|
|
|
2212
|
-
handled_else = true unless a.first == :resbody
|
|
2213
|
-
part = indent { process a, level }
|
|
2214
|
-
|
|
2215
|
-
unless parts.empty?
|
|
2216
|
-
parts << f("else ", exp)
|
|
2217
|
-
end
|
|
2218
|
-
|
|
2219
|
-
parts << part
|
|
2220
|
-
end
|
|
2221
|
-
# if no rescue statement captures our error, we should rethrow
|
|
2222
|
-
parts << indent { f("else { throw $err; }", exp) } unless handled_else
|
|
2223
|
-
|
|
2224
|
-
code = []
|
|
2225
|
-
code << f("try {#@space#{INDENT}", exp)
|
|
2226
|
-
code << body
|
|
2227
|
-
code << f("#@space} catch ($err) {#@space", exp)
|
|
2228
|
-
code << parts
|
|
2229
|
-
code << f("#@space}", exp)
|
|
2230
|
-
|
|
2231
|
-
if level == :expr
|
|
2232
|
-
code.unshift f("(function() { ", exp)
|
|
2233
|
-
code << f(" }).call(#{current_self})", exp)
|
|
353
|
+
def new_xstr(str)
|
|
354
|
+
return s(:xstr, '') unless str
|
|
355
|
+
case str.type
|
|
356
|
+
when :str then str.type = :xstr
|
|
357
|
+
when :dstr then str.type = :dxstr
|
|
358
|
+
when :evstr then str = s(:dxstr, '', str)
|
|
2234
359
|
end
|
|
2235
360
|
|
|
2236
|
-
|
|
361
|
+
str
|
|
2237
362
|
end
|
|
2238
363
|
|
|
2239
|
-
def
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
err = []
|
|
2248
|
-
types.each do |t|
|
|
2249
|
-
err << f(", ", exp) unless err.empty?
|
|
2250
|
-
call = s(:call, t, :===, s(:arglist, s(:js_tmp, "$err")))
|
|
2251
|
-
a = process call
|
|
2252
|
-
err << a
|
|
2253
|
-
end
|
|
2254
|
-
err << f("true", exp) if err.empty?
|
|
2255
|
-
|
|
2256
|
-
if Array === args.last and [:lasgn, :iasgn].include? args.last.first
|
|
2257
|
-
val = args.last
|
|
2258
|
-
val[2] = s(:js_tmp, "$err")
|
|
2259
|
-
val = [process(val) , f(";", exp)]
|
|
364
|
+
def new_dsym(str)
|
|
365
|
+
return s(:nil) unless str
|
|
366
|
+
case str.type
|
|
367
|
+
when :str
|
|
368
|
+
str.type = :sym
|
|
369
|
+
str[1] = str[1].to_sym
|
|
370
|
+
when :dstr
|
|
371
|
+
str.type = :dsym
|
|
2260
372
|
end
|
|
2261
373
|
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
[f("if (", exp), err, f("){#@space", exp), val, body, f("}", exp)]
|
|
2265
|
-
end
|
|
2266
|
-
|
|
2267
|
-
# FIXME: Hack.. grammar should remove top level begin.
|
|
2268
|
-
def process_begin(exp, level)
|
|
2269
|
-
process exp[0], level
|
|
374
|
+
str
|
|
2270
375
|
end
|
|
2271
376
|
|
|
2272
|
-
def
|
|
2273
|
-
|
|
2274
|
-
|
|
377
|
+
def new_str(str)
|
|
378
|
+
# cover empty strings
|
|
379
|
+
return s(:str, "") unless str
|
|
380
|
+
# catch s(:str, "", other_str)
|
|
381
|
+
if str.size == 3 and str[1] == "" and str.type == :str
|
|
382
|
+
return str[2]
|
|
383
|
+
# catch s(:str, "content", more_content)
|
|
384
|
+
elsif str.type == :str && str.size > 3
|
|
385
|
+
str.type = :dstr
|
|
386
|
+
str
|
|
387
|
+
# top level evstr should be a dstr
|
|
388
|
+
elsif str.type == :evstr
|
|
389
|
+
s(:dstr, "", str)
|
|
2275
390
|
else
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
result << (exp.empty? ? f('nil', exp) : process(exp[0]))
|
|
2280
|
-
result << f(";", exp)
|
|
391
|
+
str
|
|
392
|
+
end
|
|
393
|
+
end
|
|
2281
394
|
|
|
2282
|
-
|
|
395
|
+
def new_regexp(reg, ending)
|
|
396
|
+
return s(:regexp, //) unless reg
|
|
397
|
+
case reg.type
|
|
398
|
+
when :str
|
|
399
|
+
s(:regexp, Regexp.new(reg[1], ending))
|
|
400
|
+
when :evstr
|
|
401
|
+
s(:dregx, "", reg)
|
|
402
|
+
when :dstr
|
|
403
|
+
reg.type = :dregx
|
|
404
|
+
reg
|
|
2283
405
|
end
|
|
2284
406
|
end
|
|
2285
407
|
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
if
|
|
2291
|
-
|
|
2292
|
-
|
|
408
|
+
def str_append(str, str2)
|
|
409
|
+
return str2 unless str
|
|
410
|
+
return str unless str2
|
|
411
|
+
|
|
412
|
+
if str.type == :evstr
|
|
413
|
+
str = s(:dstr, "", str)
|
|
414
|
+
elsif str.type == :str
|
|
415
|
+
str = s(:dstr, str[1])
|
|
2293
416
|
else
|
|
2294
|
-
|
|
417
|
+
#puts str.type
|
|
2295
418
|
end
|
|
419
|
+
str << str2
|
|
420
|
+
str
|
|
2296
421
|
end
|
|
2297
422
|
end
|
|
2298
423
|
end
|