rubyduino 0.1.1
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/.gitmodules +3 -0
- data/CHANGELOG.md +9 -0
- data/LICENSE.txt +21 -0
- data/README.md +72 -0
- data/Rakefile +12 -0
- data/bin/rubyduino +186 -0
- data/examples/hello.rb +9 -0
- data/lib/rubyduino/arduino_entry.c +9 -0
- data/lib/rubyduino/sp_runtime.h +159 -0
- data/lib/rubyduino/spinel.rb +8 -0
- data/lib/rubyduino/spinel_arduino_codegen.rb +129 -0
- data/lib/rubyduino/version.rb +5 -0
- data/lib/rubyduino.rb +9 -0
- data/sig/rubyduino.rbs +4 -0
- data/vendor/spinel/AUTHORS +1 -0
- data/vendor/spinel/LICENSE +19 -0
- data/vendor/spinel/Makefile +406 -0
- data/vendor/spinel/POLY-AS-SET.md +217 -0
- data/vendor/spinel/README.md +409 -0
- data/vendor/spinel/benchmark/bm_ackermann.rb +12 -0
- data/vendor/spinel/benchmark/bm_ao_render.rb +323 -0
- data/vendor/spinel/benchmark/bm_attr_accessor.rb +41 -0
- data/vendor/spinel/benchmark/bm_bigint_fib.rb +10 -0
- data/vendor/spinel/benchmark/bm_binary_trees.rb +53 -0
- data/vendor/spinel/benchmark/bm_csv_process.rb +58 -0
- data/vendor/spinel/benchmark/bm_fannkuch.rb +88 -0
- data/vendor/spinel/benchmark/bm_fasta.rb +87 -0
- data/vendor/spinel/benchmark/bm_fib.rb +9 -0
- data/vendor/spinel/benchmark/bm_gcbench.rb +73 -0
- data/vendor/spinel/benchmark/bm_getivar.rb +34 -0
- data/vendor/spinel/benchmark/bm_getivar_module.rb +34 -0
- data/vendor/spinel/benchmark/bm_huffman.rb +141 -0
- data/vendor/spinel/benchmark/bm_inline.rb +68 -0
- data/vendor/spinel/benchmark/bm_io_wordcount.rb +57 -0
- data/vendor/spinel/benchmark/bm_json_parse.rb +157 -0
- data/vendor/spinel/benchmark/bm_keyword_args.rb +23 -0
- data/vendor/spinel/benchmark/bm_life.rb +70 -0
- data/vendor/spinel/benchmark/bm_linked_list.rb +75 -0
- data/vendor/spinel/benchmark/bm_loops_times.rb +16 -0
- data/vendor/spinel/benchmark/bm_mandel_term.rb +34 -0
- data/vendor/spinel/benchmark/bm_matmul.rb +42 -0
- data/vendor/spinel/benchmark/bm_nbody.rb +115 -0
- data/vendor/spinel/benchmark/bm_nested_loop.rb +29 -0
- data/vendor/spinel/benchmark/bm_nqueens.rb +46 -0
- data/vendor/spinel/benchmark/bm_object_new.rb +21 -0
- data/vendor/spinel/benchmark/bm_object_new_init.rb +21 -0
- data/vendor/spinel/benchmark/bm_object_new_no_escape.rb +28 -0
- data/vendor/spinel/benchmark/bm_partial_sums.rb +38 -0
- data/vendor/spinel/benchmark/bm_pidigits.rb +31 -0
- data/vendor/spinel/benchmark/bm_rbtree.rb +100 -0
- data/vendor/spinel/benchmark/bm_ruby_xor.rb +28 -0
- data/vendor/spinel/benchmark/bm_send_bmethod.rb +31 -0
- data/vendor/spinel/benchmark/bm_send_cfunc_block.rb +18 -0
- data/vendor/spinel/benchmark/bm_send_rubyfunc_block.rb +23 -0
- data/vendor/spinel/benchmark/bm_setivar.rb +33 -0
- data/vendor/spinel/benchmark/bm_setivar_object.rb +33 -0
- data/vendor/spinel/benchmark/bm_setivar_young.rb +37 -0
- data/vendor/spinel/benchmark/bm_sieve.rb +23 -0
- data/vendor/spinel/benchmark/bm_so_lists.rb +47 -0
- data/vendor/spinel/benchmark/bm_so_mandelbrot.rb +65 -0
- data/vendor/spinel/benchmark/bm_spectral_norm.rb +71 -0
- data/vendor/spinel/benchmark/bm_splay.rb +128 -0
- data/vendor/spinel/benchmark/bm_str_concat.rb +15 -0
- data/vendor/spinel/benchmark/bm_structaref.rb +25 -0
- data/vendor/spinel/benchmark/bm_structaset.rb +24 -0
- data/vendor/spinel/benchmark/bm_sudoku.rb +217 -0
- data/vendor/spinel/benchmark/bm_tak.rb +10 -0
- data/vendor/spinel/benchmark/bm_tarai.rb +10 -0
- data/vendor/spinel/benchmark/bm_template.rb +50 -0
- data/vendor/spinel/benchmark/bm_throw.rb +25 -0
- data/vendor/spinel/benchmark/bm_wordfreq.rb +43 -0
- data/vendor/spinel/docs/FFI.md +198 -0
- data/vendor/spinel/examples/ffi/libm/README.md +24 -0
- data/vendor/spinel/examples/ffi/libm/libm.rb +17 -0
- data/vendor/spinel/examples/ffi/sqlite/README.md +73 -0
- data/vendor/spinel/examples/ffi/sqlite/blog.rb +185 -0
- data/vendor/spinel/examples/ffi/sqlite/sqlite3_lib.rb +46 -0
- data/vendor/spinel/lib/erb.rb +19 -0
- data/vendor/spinel/lib/forwardable.rb +8 -0
- data/vendor/spinel/lib/mruby_shim.h +118 -0
- data/vendor/spinel/lib/optparse.rb +123 -0
- data/vendor/spinel/lib/regexp/re_compile.c +979 -0
- data/vendor/spinel/lib/regexp/re_exec.c +665 -0
- data/vendor/spinel/lib/regexp/re_internal.h +146 -0
- data/vendor/spinel/lib/regexp/re_utf8.c +76 -0
- data/vendor/spinel/lib/set.rb +12 -0
- data/vendor/spinel/lib/sp_bigint.c +5400 -0
- data/vendor/spinel/lib/sp_bigint.h +117 -0
- data/vendor/spinel/lib/sp_runtime.h +1361 -0
- data/vendor/spinel/lib/stringio.c +286 -0
- data/vendor/spinel/lib/stringio.rb +5 -0
- data/vendor/spinel/lib/strscan.c +170 -0
- data/vendor/spinel/lib/strscan.rb +55 -0
- data/vendor/spinel/spinel +191 -0
- data/vendor/spinel/spinel.bat +158 -0
- data/vendor/spinel/spinel_codegen.rb +39906 -0
- data/vendor/spinel/spinel_parse +0 -0
- data/vendor/spinel/spinel_parse.c +1586 -0
- data/vendor/spinel/test/alias_global.rb +16 -0
- data/vendor/spinel/test/alias_global.rb.expected +3 -0
- data/vendor/spinel/test/alias_method.rb +28 -0
- data/vendor/spinel/test/alias_method.rb.expected +5 -0
- data/vendor/spinel/test/and_node_poly_operand.rb +24 -0
- data/vendor/spinel/test/anon_block_forward.rb +47 -0
- data/vendor/spinel/test/anon_block_forward.rb.expected +4 -0
- data/vendor/spinel/test/array_3d_nested.rb +48 -0
- data/vendor/spinel/test/array_clear_typed.rb +40 -0
- data/vendor/spinel/test/array_clear_typed.rb.expected +7 -0
- data/vendor/spinel/test/array_concat.rb +18 -0
- data/vendor/spinel/test/array_concat.rb.expected +2 -0
- data/vendor/spinel/test/array_each_with_object.rb +17 -0
- data/vendor/spinel/test/array_each_with_object.rb.expected +2 -0
- data/vendor/spinel/test/array_fill_poly.rb +17 -0
- data/vendor/spinel/test/array_flat_map.rb +16 -0
- data/vendor/spinel/test/array_flat_map.rb.expected +2 -0
- data/vendor/spinel/test/array_keyed_hash_int_array_eql.rb +29 -0
- data/vendor/spinel/test/array_keyed_hash_int_array_eql.rb.expected +6 -0
- data/vendor/spinel/test/array_method_name_clash.rb +15 -0
- data/vendor/spinel/test/array_method_name_clash.rb.expected +1 -0
- data/vendor/spinel/test/array_new_block_typed_container.rb +37 -0
- data/vendor/spinel/test/array_new_block_typed_container.rb.expected +7 -0
- data/vendor/spinel/test/array_new_empty_inner_deferred.rb +47 -0
- data/vendor/spinel/test/array_new_empty_inner_deferred.rb.expected +8 -0
- data/vendor/spinel/test/array_partition_gc.rb +20 -0
- data/vendor/spinel/test/array_partition_gc.rb.expected +3 -0
- data/vendor/spinel/test/array_plus.rb +18 -0
- data/vendor/spinel/test/array_plus.rb.expected +2 -0
- data/vendor/spinel/test/array_rotate_bang.rb +54 -0
- data/vendor/spinel/test/array_rotate_bang.rb.expected +34 -0
- data/vendor/spinel/test/array_shuffle_ptr.rb +11 -0
- data/vendor/spinel/test/array_shuffle_ptr.rb.expected +1 -0
- data/vendor/spinel/test/array_slice_bang.rb +81 -0
- data/vendor/spinel/test/array_slice_bang.rb.expected +40 -0
- data/vendor/spinel/test/attr.rb +77 -0
- data/vendor/spinel/test/attr.rb.expected +9 -0
- data/vendor/spinel/test/attr_writer_poly_box.rb +24 -0
- data/vendor/spinel/test/attr_writer_poly_no_double_eval.rb +29 -0
- data/vendor/spinel/test/attr_writer_poly_no_double_eval.rb.expected +3 -0
- data/vendor/spinel/test/attr_writer_returns_rhs.rb +23 -0
- data/vendor/spinel/test/auto_unbox_keeps_int_slot.rb +38 -0
- data/vendor/spinel/test/auto_unbox_keeps_int_slot.rb.expected +3 -0
- data/vendor/spinel/test/auto_unbox_poly_to_int_local.rb +36 -0
- data/vendor/spinel/test/auto_unbox_poly_to_int_local.rb.expected +2 -0
- data/vendor/spinel/test/back_ref.rb +21 -0
- data/vendor/spinel/test/back_ref.rb.expected +6 -0
- data/vendor/spinel/test/bare_return_in_cls_method.rb +46 -0
- data/vendor/spinel/test/bare_return_in_cls_method.rb.expected +2 -0
- data/vendor/spinel/test/bare_return_in_initialize.rb +55 -0
- data/vendor/spinel/test/bare_return_in_initialize.rb.expected +4 -0
- data/vendor/spinel/test/bare_return_in_poly_method.rb +26 -0
- data/vendor/spinel/test/bare_return_in_poly_method.rb.expected +2 -0
- data/vendor/spinel/test/bigint_div_by_zero.rb +43 -0
- data/vendor/spinel/test/bigint_div_by_zero.rb.expected +3 -0
- data/vendor/spinel/test/block2.rb +31 -0
- data/vendor/spinel/test/block2.rb.expected +4 -0
- data/vendor/spinel/test/block_forward_block_arg.rb +60 -0
- data/vendor/spinel/test/block_forward_block_arg.rb.expected +4 -0
- data/vendor/spinel/test/block_forward_recv_typed.rb +82 -0
- data/vendor/spinel/test/block_forward_recv_typed.rb.expected +11 -0
- data/vendor/spinel/test/block_forward_self_call.rb +61 -0
- data/vendor/spinel/test/block_forward_self_call.rb.expected +6 -0
- data/vendor/spinel/test/block_given_block_param.rb +46 -0
- data/vendor/spinel/test/block_given_block_param.rb.expected +3 -0
- data/vendor/spinel/test/block_param_shadow.rb +246 -0
- data/vendor/spinel/test/block_param_shadow.rb.expected +71 -0
- data/vendor/spinel/test/bm_instance_eval.rb +209 -0
- data/vendor/spinel/test/bm_instance_eval.rb.expected +27 -0
- data/vendor/spinel/test/bound_method_array.rb +22 -0
- data/vendor/spinel/test/bound_method_array.rb.expected +4 -0
- data/vendor/spinel/test/bound_method_basic.rb +27 -0
- data/vendor/spinel/test/bound_method_basic.rb.expected +2 -0
- data/vendor/spinel/test/bound_method_gc.rb +30 -0
- data/vendor/spinel/test/bound_method_gc.rb.expected +1 -0
- data/vendor/spinel/test/bound_method_obj_recv.rb +41 -0
- data/vendor/spinel/test/bound_method_obj_recv.rb.expected +4 -0
- data/vendor/spinel/test/bound_method_single_eval.rb +37 -0
- data/vendor/spinel/test/bound_method_single_eval.rb.expected +4 -0
- data/vendor/spinel/test/box_pointer_to_poly.rb +27 -0
- data/vendor/spinel/test/box_pointer_to_poly.rb.expected +1 -0
- data/vendor/spinel/test/box_unbox_local_assign_cond.rb +22 -0
- data/vendor/spinel/test/box_unbox_local_assign_cond.rb.expected +2 -0
- data/vendor/spinel/test/bundle_array_a.rb +400 -0
- data/vendor/spinel/test/bundle_array_a.rb.expected +117 -0
- data/vendor/spinel/test/bundle_array_b.rb +369 -0
- data/vendor/spinel/test/bundle_array_b.rb.expected +136 -0
- data/vendor/spinel/test/bundle_array_c.rb +146 -0
- data/vendor/spinel/test/bundle_array_c.rb.expected +51 -0
- data/vendor/spinel/test/bundle_array_d.rb +181 -0
- data/vendor/spinel/test/bundle_array_d.rb.expected +66 -0
- data/vendor/spinel/test/bundle_hash.rb +328 -0
- data/vendor/spinel/test/bundle_hash.rb.expected +104 -0
- data/vendor/spinel/test/bundle_int_array.rb +125 -0
- data/vendor/spinel/test/bundle_int_array.rb.expected +24 -0
- data/vendor/spinel/test/bundle_integer.rb +248 -0
- data/vendor/spinel/test/bundle_integer.rb.expected +113 -0
- data/vendor/spinel/test/bundle_io_sys.rb +223 -0
- data/vendor/spinel/test/bundle_io_sys.rb.expected +62 -0
- data/vendor/spinel/test/bundle_misc_a.rb +462 -0
- data/vendor/spinel/test/bundle_misc_a.rb.expected +208 -0
- data/vendor/spinel/test/bundle_misc_b.rb +401 -0
- data/vendor/spinel/test/bundle_misc_b.rb.expected +120 -0
- data/vendor/spinel/test/bundle_poly.rb +145 -0
- data/vendor/spinel/test/bundle_poly.rb.expected +66 -0
- data/vendor/spinel/test/bundle_string_a.rb +278 -0
- data/vendor/spinel/test/bundle_string_a.rb.expected +93 -0
- data/vendor/spinel/test/bundle_string_b.rb +226 -0
- data/vendor/spinel/test/bundle_string_b.rb.expected +83 -0
- data/vendor/spinel/test/bundle_sym.rb +302 -0
- data/vendor/spinel/test/bundle_sym.rb.expected +117 -0
- data/vendor/spinel/test/call_and_write.rb +28 -0
- data/vendor/spinel/test/call_and_write.rb.expected +3 -0
- data/vendor/spinel/test/call_arg_int_to_obj_cast.rb +55 -0
- data/vendor/spinel/test/call_arg_int_to_obj_cast.rb.expected +1 -0
- data/vendor/spinel/test/call_op_write.rb +51 -0
- data/vendor/spinel/test/call_op_write.rb.expected +11 -0
- data/vendor/spinel/test/call_or_write.rb +35 -0
- data/vendor/spinel/test/call_or_write.rb.expected +3 -0
- data/vendor/spinel/test/case.rb +43 -0
- data/vendor/spinel/test/case.rb.expected +10 -0
- data/vendor/spinel/test/case_string_when_sym_no_match.rb +59 -0
- data/vendor/spinel/test/case_string_when_sym_no_match.rb.expected +7 -0
- data/vendor/spinel/test/case_when_class.rb +70 -0
- data/vendor/spinel/test/case_when_class.rb.expected +5 -0
- data/vendor/spinel/test/chained_attr_setter.rb +55 -0
- data/vendor/spinel/test/chained_ivar_op_assign_emits_inner_write.rb +28 -0
- data/vendor/spinel/test/chained_ivar_op_assign_emits_inner_write.rb.expected +3 -0
- data/vendor/spinel/test/chained_ivar_write_call_rhs.rb +30 -0
- data/vendor/spinel/test/chained_ivar_write_call_rhs.rb.expected +2 -0
- data/vendor/spinel/test/chained_ivar_write_split.rb +26 -0
- data/vendor/spinel/test/chained_ivar_write_split.rb.expected +3 -0
- data/vendor/spinel/test/chained_ivar_write_subclass.rb +26 -0
- data/vendor/spinel/test/chained_ivar_write_subclass.rb.expected +2 -0
- data/vendor/spinel/test/chained_or_assign_collection_array_nested.rb +32 -0
- data/vendor/spinel/test/chained_or_assign_collection_array_nested.rb.expected +3 -0
- data/vendor/spinel/test/chained_or_assign_collection_element.rb +29 -0
- data/vendor/spinel/test/chained_or_assign_collection_element.rb.expected +2 -0
- data/vendor/spinel/test/chained_or_assign_collection_poly_array.rb +25 -0
- data/vendor/spinel/test/chained_or_assign_collection_poly_array.rb.expected +3 -0
- data/vendor/spinel/test/chained_or_assign_collection_str_keys.rb +24 -0
- data/vendor/spinel/test/chained_or_assign_collection_str_keys.rb.expected +3 -0
- data/vendor/spinel/test/class_constant_path_read.rb +26 -0
- data/vendor/spinel/test/class_constant_path_read.rb.expected +4 -0
- data/vendor/spinel/test/class_constant_sym_array.rb +19 -0
- data/vendor/spinel/test/class_constant_sym_array.rb.expected +4 -0
- data/vendor/spinel/test/class_def_order.rb +66 -0
- data/vendor/spinel/test/class_def_order.rb.expected +4 -0
- data/vendor/spinel/test/class_method_open_class_call.rb +31 -0
- data/vendor/spinel/test/class_method_open_class_call.rb.expected +3 -0
- data/vendor/spinel/test/class_var_read.rb +113 -0
- data/vendor/spinel/test/class_var_read.rb.expected +8 -0
- data/vendor/spinel/test/class_var_write.rb +19 -0
- data/vendor/spinel/test/class_var_write.rb.expected +1 -0
- data/vendor/spinel/test/cls_ivar_type_parent_defer.rb +32 -0
- data/vendor/spinel/test/cls_method_object.rb +31 -0
- data/vendor/spinel/test/cls_method_object.rb.expected +2 -0
- data/vendor/spinel/test/codegen_class_in_module_with_explicit_parent.rb +15 -0
- data/vendor/spinel/test/codegen_class_in_module_with_explicit_parent.rb.expected +1 -0
- data/vendor/spinel/test/codegen_const_lookup_in_toplevel_method.rb +13 -0
- data/vendor/spinel/test/codegen_const_lookup_in_toplevel_method.rb.expected +1 -0
- data/vendor/spinel/test/comparable.rb +21 -0
- data/vendor/spinel/test/comparable.rb.expected +5 -0
- data/vendor/spinel/test/const_init_block_param_scan.rb +13 -0
- data/vendor/spinel/test/const_init_block_param_scan.rb.expected +2 -0
- data/vendor/spinel/test/constant_path.rb +102 -0
- data/vendor/spinel/test/constant_path.rb.expected +21 -0
- data/vendor/spinel/test/constants.rb +44 -0
- data/vendor/spinel/test/constants.rb.expected +13 -0
- data/vendor/spinel/test/control.rb +23 -0
- data/vendor/spinel/test/control.rb.expected +7 -0
- data/vendor/spinel/test/default_args.rb +108 -0
- data/vendor/spinel/test/default_args.rb.expected +13 -0
- data/vendor/spinel/test/default_argv_narrows_from_string_call_site.rb +32 -0
- data/vendor/spinel/test/default_argv_narrows_from_string_call_site.rb.expected +1 -0
- data/vendor/spinel/test/each_poly_recv_block_auto_splat.rb +43 -0
- data/vendor/spinel/test/each_poly_recv_block_auto_splat.rb.expected +2 -0
- data/vendor/spinel/test/each_with_object_seed_shadow.rb +14 -0
- data/vendor/spinel/test/each_with_object_seed_shadow.rb.expected +4 -0
- data/vendor/spinel/test/elsif_isa_chain.rb +56 -0
- data/vendor/spinel/test/elsif_isa_chain.rb.expected +6 -0
- data/vendor/spinel/test/embedded_var.rb +17 -0
- data/vendor/spinel/test/embedded_var.rb.expected +2 -0
- data/vendor/spinel/test/empty_array_param.rb +94 -0
- data/vendor/spinel/test/empty_array_param.rb.expected +18 -0
- data/vendor/spinel/test/empty_hash_ivar_string_value.rb +51 -0
- data/vendor/spinel/test/empty_hash_ivar_string_value.rb.expected +4 -0
- data/vendor/spinel/test/endless_method.rb +61 -0
- data/vendor/spinel/test/endless_method.rb.expected +11 -0
- data/vendor/spinel/test/endless_method_rescue.rb +33 -0
- data/vendor/spinel/test/endless_method_rescue.rb.expected +10 -0
- data/vendor/spinel/test/ensure_raise_overrides_body_raise.rb +19 -0
- data/vendor/spinel/test/ensure_raise_overrides_body_raise.rb.expected +1 -0
- data/vendor/spinel/test/ensure_runs_on_raise.rb +32 -0
- data/vendor/spinel/test/ensure_runs_on_raise.rb.expected +3 -0
- data/vendor/spinel/test/ensure_runs_on_raise_nested.rb +38 -0
- data/vendor/spinel/test/ensure_runs_on_raise_nested.rb.expected +4 -0
- data/vendor/spinel/test/ensure_runs_on_return.rb +61 -0
- data/vendor/spinel/test/ensure_runs_on_return.rb.expected +6 -0
- data/vendor/spinel/test/ensure_runs_on_return_from_rescue.rb +26 -0
- data/vendor/spinel/test/ensure_runs_on_return_from_rescue.rb.expected +2 -0
- data/vendor/spinel/test/ensure_runs_on_return_nested.rb +37 -0
- data/vendor/spinel/test/ensure_runs_on_return_nested.rb.expected +3 -0
- data/vendor/spinel/test/enumerable.rb +19 -0
- data/vendor/spinel/test/enumerable.rb.expected +2 -0
- data/vendor/spinel/test/env_string_inference.rb +37 -0
- data/vendor/spinel/test/env_string_inference.rb.expected +6 -0
- data/vendor/spinel/test/exception_object_methods.rb +99 -0
- data/vendor/spinel/test/exception_object_methods.rb.expected +15 -0
- data/vendor/spinel/test/exceptions.rb +34 -0
- data/vendor/spinel/test/exceptions.rb.expected +4 -0
- data/vendor/spinel/test/features.rb +32 -0
- data/vendor/spinel/test/features.rb.expected +9 -0
- data/vendor/spinel/test/ffi_buffer_reader.rb +23 -0
- data/vendor/spinel/test/ffi_buffer_reader.rb.expected +5 -0
- data/vendor/spinel/test/ffi_const.rb +12 -0
- data/vendor/spinel/test/ffi_const.rb.expected +5 -0
- data/vendor/spinel/test/ffi_libc_libm_basic.rb +16 -0
- data/vendor/spinel/test/ffi_libc_libm_basic.rb.expected +5 -0
- data/vendor/spinel/test/ffi_ptr_nil.rb +27 -0
- data/vendor/spinel/test/ffi_ptr_nil.rb.expected +2 -0
- data/vendor/spinel/test/ffi_void_return.rb +14 -0
- data/vendor/spinel/test/ffi_void_return.rb.expected +2 -0
- data/vendor/spinel/test/fiber_ivar_persists_across_yield.rb +22 -0
- data/vendor/spinel/test/fiber_ivar_persists_across_yield.rb.expected +3 -0
- data/vendor/spinel/test/fiber_yield_across_method_call.rb +28 -0
- data/vendor/spinel/test/fiber_yield_across_method_call.rb.expected +3 -0
- data/vendor/spinel/test/file_basename_gc.rb +59 -0
- data/vendor/spinel/test/file_basename_gc.rb.expected +2 -0
- data/vendor/spinel/test/forward_call_class_method_inherited_init.rb +36 -0
- data/vendor/spinel/test/forward_call_class_method_inherited_init.rb.expected +1 -0
- data/vendor/spinel/test/forward_call_class_method_inherited_init_int_array.rb +32 -0
- data/vendor/spinel/test/forward_call_class_method_inherited_init_int_array.rb.expected +1 -0
- data/vendor/spinel/test/forward_call_class_method_inherited_init_obj.rb +41 -0
- data/vendor/spinel/test/forward_call_class_method_inherited_init_obj.rb.expected +1 -0
- data/vendor/spinel/test/forward_call_class_method_int_array.rb +26 -0
- data/vendor/spinel/test/forward_call_class_method_int_array.rb.expected +1 -0
- data/vendor/spinel/test/forward_call_class_method_nested.rb +35 -0
- data/vendor/spinel/test/forward_call_class_method_nested.rb.expected +1 -0
- data/vendor/spinel/test/forward_call_class_method_obj.rb +36 -0
- data/vendor/spinel/test/forward_call_class_method_obj.rb.expected +1 -0
- data/vendor/spinel/test/forward_call_param_type_inference.rb +23 -0
- data/vendor/spinel/test/forward_call_param_type_inference.rb.expected +1 -0
- data/vendor/spinel/test/forward_call_param_type_int_array.rb +34 -0
- data/vendor/spinel/test/forward_call_param_type_int_array.rb.expected +1 -0
- data/vendor/spinel/test/forward_call_param_type_obj.rb +38 -0
- data/vendor/spinel/test/forward_call_param_type_obj.rb.expected +1 -0
- data/vendor/spinel/test/gc_root_ptr_array_literal.rb +63 -0
- data/vendor/spinel/test/gc_root_ptr_array_literal.rb.expected +1 -0
- data/vendor/spinel/test/gc_save_double_in_new.rb +13 -0
- data/vendor/spinel/test/gc_save_double_in_new.rb.expected +1 -0
- data/vendor/spinel/test/gc_scan_skip_inherited_ivar.rb +54 -0
- data/vendor/spinel/test/gc_scan_skip_inherited_ivar.rb.expected +2 -0
- data/vendor/spinel/test/global_var.rb +53 -0
- data/vendor/spinel/test/global_var.rb.expected +12 -0
- data/vendor/spinel/test/gvar.rb +22 -0
- data/vendor/spinel/test/gvar.rb.expected +4 -0
- data/vendor/spinel/test/hash_dig.rb +92 -0
- data/vendor/spinel/test/hash_dig.rb.expected +37 -0
- data/vendor/spinel/test/hash_keys_each_shadow.rb +40 -0
- data/vendor/spinel/test/hash_keys_each_shadow.rb.expected +9 -0
- data/vendor/spinel/test/hash_shorthand.rb +37 -0
- data/vendor/spinel/test/hash_shorthand.rb.expected +6 -0
- data/vendor/spinel/test/hash_shorthand_str.rb +48 -0
- data/vendor/spinel/test/hash_shorthand_str.rb.expected +19 -0
- data/vendor/spinel/test/heterogeneous_dispatch_int_return_narrow.rb +46 -0
- data/vendor/spinel/test/heterogeneous_dispatch_int_return_narrow.rb.expected +2 -0
- data/vendor/spinel/test/if_static_false_skips_dead_branch_compile.rb +50 -0
- data/vendor/spinel/test/if_static_false_skips_dead_branch_compile.rb.expected +3 -0
- data/vendor/spinel/test/implicit_self_param_poly.rb +17 -0
- data/vendor/spinel/test/implicit_self_param_poly.rb.expected +1 -0
- data/vendor/spinel/test/index_write.rb +106 -0
- data/vendor/spinel/test/index_write.rb.expected +30 -0
- data/vendor/spinel/test/inference_method_set.rb +35 -0
- data/vendor/spinel/test/inference_method_set.rb.expected +2 -0
- data/vendor/spinel/test/inherit.rb +52 -0
- data/vendor/spinel/test/inherit.rb.expected +7 -0
- data/vendor/spinel/test/inherited_method_param_widen.rb +49 -0
- data/vendor/spinel/test/inherited_method_param_widen.rb.expected +1 -0
- data/vendor/spinel/test/init_locals.rb +43 -0
- data/vendor/spinel/test/init_locals.rb.expected +3 -0
- data/vendor/spinel/test/initialize_param_poly_call_sites.rb +20 -0
- data/vendor/spinel/test/initialize_param_poly_call_sites.rb.expected +2 -0
- data/vendor/spinel/test/initialize_param_through_call.rb +15 -0
- data/vendor/spinel/test/initialize_param_through_call.rb.expected +1 -0
- data/vendor/spinel/test/initialize_void_wrapper_gc_save.rb +40 -0
- data/vendor/spinel/test/initialize_void_wrapper_gc_save.rb.expected +1 -0
- data/vendor/spinel/test/inspect.rb +86 -0
- data/vendor/spinel/test/inspect.rb.expected +52 -0
- data/vendor/spinel/test/instance_eval_trampoline.rb +88 -0
- data/vendor/spinel/test/instance_eval_trampoline.rb.expected +5 -0
- data/vendor/spinel/test/int_bracket_skip_sym_idx.rb +40 -0
- data/vendor/spinel/test/int_bracket_skip_sym_idx.rb.expected +5 -0
- data/vendor/spinel/test/int_keyed_hash_lookup_as_array.rb +19 -0
- data/vendor/spinel/test/int_keyed_hash_lookup_as_array.rb.expected +2 -0
- data/vendor/spinel/test/intarray_slice_assign_from_intarray_ptr_array_first.rb +25 -0
- data/vendor/spinel/test/intarray_slice_assign_from_intarray_ptr_array_first.rb.expected +1 -0
- data/vendor/spinel/test/integer_div.rb +21 -0
- data/vendor/spinel/test/integer_div.rb.expected +10 -0
- data/vendor/spinel/test/integer_div_by_zero.rb +80 -0
- data/vendor/spinel/test/integer_div_by_zero.rb.expected +10 -0
- data/vendor/spinel/test/interp_method_widening.rb +39 -0
- data/vendor/spinel/test/interp_method_widening.rb.expected +4 -0
- data/vendor/spinel/test/interp_symbol.rb +18 -0
- data/vendor/spinel/test/interp_symbol.rb.expected +3 -0
- data/vendor/spinel/test/introspect.rb +35 -0
- data/vendor/spinel/test/introspect.rb.expected +11 -0
- data/vendor/spinel/test/issue176_empty_hash_default.rb +34 -0
- data/vendor/spinel/test/issue176_empty_hash_default.rb.expected +3 -0
- data/vendor/spinel/test/issue203_string_new.rb +27 -0
- data/vendor/spinel/test/issue203_string_new.rb.expected +4 -0
- data/vendor/spinel/test/issue204_user_find_fetch.rb +25 -0
- data/vendor/spinel/test/issue204_user_find_fetch.rb.expected +5 -0
- data/vendor/spinel/test/issue207_factory_pattern.rb +35 -0
- data/vendor/spinel/test/issue207_factory_pattern.rb.expected +1 -0
- data/vendor/spinel/test/issue207_full_repro.rb +52 -0
- data/vendor/spinel/test/issue207_full_repro.rb.expected +1 -0
- data/vendor/spinel/test/issue208_inherited_class_method.rb +24 -0
- data/vendor/spinel/test/issue208_inherited_class_method.rb.expected +4 -0
- data/vendor/spinel/test/issue219_aref_chain.rb +36 -0
- data/vendor/spinel/test/issue219_aref_chain.rb.expected +5 -0
- data/vendor/spinel/test/issue224_bare_new_inherited.rb +66 -0
- data/vendor/spinel/test/issue224_bare_new_inherited.rb.expected +4 -0
- data/vendor/spinel/test/issue229_uncalled_cls_method.rb +76 -0
- data/vendor/spinel/test/issue229_uncalled_cls_method.rb.expected +3 -0
- data/vendor/spinel/test/issue235_chain_tail_widening.rb +48 -0
- data/vendor/spinel/test/issue235_chain_tail_widening.rb.expected +5 -0
- data/vendor/spinel/test/issue236_chain_empty_literal.rb +84 -0
- data/vendor/spinel/test/issue236_chain_empty_literal.rb.expected +7 -0
- data/vendor/spinel/test/issue239_cls_method_default_args.rb +41 -0
- data/vendor/spinel/test/issue239_cls_method_default_args.rb.expected +5 -0
- data/vendor/spinel/test/issue_266_def_length_inference.rb +63 -0
- data/vendor/spinel/test/issue_266_def_length_inference.rb.expected +1 -0
- data/vendor/spinel/test/ivar_and_write_basic.rb +34 -0
- data/vendor/spinel/test/ivar_and_write_basic.rb.expected +5 -0
- data/vendor/spinel/test/ivar_c_keyword.rb +14 -0
- data/vendor/spinel/test/ivar_c_keyword.rb.expected +1 -0
- data/vendor/spinel/test/ivar_float_array.rb +59 -0
- data/vendor/spinel/test/ivar_float_array.rb.expected +11 -0
- data/vendor/spinel/test/ivar_op_assign_bitwise_and_shift.rb +22 -0
- data/vendor/spinel/test/ivar_op_assign_bitwise_and_shift.rb.expected +6 -0
- data/vendor/spinel/test/ivar_or_write_basic.rb +57 -0
- data/vendor/spinel/test/ivar_or_write_basic.rb.expected +9 -0
- data/vendor/spinel/test/ivar_polymorphic.rb +87 -0
- data/vendor/spinel/test/ivar_polymorphic.rb.expected +12 -0
- data/vendor/spinel/test/ivar_ternary_mixed.rb +108 -0
- data/vendor/spinel/test/ivar_ternary_mixed.rb.expected +15 -0
- data/vendor/spinel/test/ivar_writer_heterogeneity.rb +34 -0
- data/vendor/spinel/test/ivar_writer_heterogeneity.rb.expected +2 -0
- data/vendor/spinel/test/known_constants.rb +25 -0
- data/vendor/spinel/test/known_constants.rb.expected +4 -0
- data/vendor/spinel/test/kw_nil_default_string_call.rb +6 -0
- data/vendor/spinel/test/kw_nil_default_string_call.rb.expected +2 -0
- data/vendor/spinel/test/kwargs.rb +21 -0
- data/vendor/spinel/test/kwargs.rb.expected +6 -0
- data/vendor/spinel/test/kwargs_param.rb +26 -0
- data/vendor/spinel/test/kwargs_param.rb.expected +2 -0
- data/vendor/spinel/test/kwargs_param_widen.rb +73 -0
- data/vendor/spinel/test/kwargs_param_widen.rb.expected +3 -0
- data/vendor/spinel/test/lrama_features.rb +142 -0
- data/vendor/spinel/test/lrama_features.rb.expected +38 -0
- data/vendor/spinel/test/map_array_block_result.rb +29 -0
- data/vendor/spinel/test/map_array_block_result.rb.expected +2 -0
- data/vendor/spinel/test/map_block_returns_nested_array.rb +53 -0
- data/vendor/spinel/test/map_empty_block.rb +26 -0
- data/vendor/spinel/test/map_empty_block.rb.expected +6 -0
- data/vendor/spinel/test/map_range_recv_array_block.rb +31 -0
- data/vendor/spinel/test/mega.rb +35 -0
- data/vendor/spinel/test/mega.rb.expected +7 -0
- data/vendor/spinel/test/method.rb +21 -0
- data/vendor/spinel/test/method.rb.expected +6 -0
- data/vendor/spinel/test/method_defined.rb +36 -0
- data/vendor/spinel/test/method_defined.rb.expected +17 -0
- data/vendor/spinel/test/method_dispatch_poly_array.rb +35 -0
- data/vendor/spinel/test/method_dispatch_poly_array.rb.expected +2 -0
- data/vendor/spinel/test/method_introspection.rb +24 -0
- data/vendor/spinel/test/method_introspection.rb.expected +6 -0
- data/vendor/spinel/test/method_param_unify_to_poly.rb +40 -0
- data/vendor/spinel/test/method_param_unify_to_poly.rb.expected +2 -0
- data/vendor/spinel/test/misc.rb +49 -0
- data/vendor/spinel/test/misc.rb.expected +7 -0
- data/vendor/spinel/test/mixin.rb +54 -0
- data/vendor/spinel/test/mixin.rb.expected +4 -0
- data/vendor/spinel/test/module_acc_dispatch_param_box.rb +46 -0
- data/vendor/spinel/test/module_acc_dispatch_param_box.rb.expected +2 -0
- data/vendor/spinel/test/module_class_new.rb +17 -0
- data/vendor/spinel/test/module_class_new.rb.expected +3 -0
- data/vendor/spinel/test/module_cls_method_string_return.rb +53 -0
- data/vendor/spinel/test/module_cls_method_string_return.rb.expected +5 -0
- data/vendor/spinel/test/module_const_array_widen.rb +36 -0
- data/vendor/spinel/test/module_const_array_widen.rb.expected +1 -0
- data/vendor/spinel/test/module_dispatch_param_widen.rb +55 -0
- data/vendor/spinel/test/module_dispatch_param_widen.rb.expected +1 -0
- data/vendor/spinel/test/module_function_namespace.rb +58 -0
- data/vendor/spinel/test/module_ivar_hash.rb +61 -0
- data/vendor/spinel/test/module_ivar_hash.rb.expected +7 -0
- data/vendor/spinel/test/module_relative_constant_path.rb +26 -0
- data/vendor/spinel/test/module_relative_constant_path.rb.expected +2 -0
- data/vendor/spinel/test/module_singleton_accessor.rb +65 -0
- data/vendor/spinel/test/module_singleton_accessor.rb.expected +3 -0
- data/vendor/spinel/test/module_singleton_accessor_poly.rb +62 -0
- data/vendor/spinel/test/module_singleton_accessor_poly.rb.expected +7 -0
- data/vendor/spinel/test/multi_arg_block_call.rb +56 -0
- data/vendor/spinel/test/multi_arg_block_call.rb.expected +5 -0
- data/vendor/spinel/test/multi_arg_yield.rb +70 -0
- data/vendor/spinel/test/multi_arg_yield.rb.expected +6 -0
- data/vendor/spinel/test/multi_assign_ivar.rb +33 -0
- data/vendor/spinel/test/multi_assign_ivar.rb.expected +1 -0
- data/vendor/spinel/test/multi_return.rb +35 -0
- data/vendor/spinel/test/multi_return.rb.expected +10 -0
- data/vendor/spinel/test/multi_return_bare.rb +77 -0
- data/vendor/spinel/test/multi_return_bare.rb.expected +16 -0
- data/vendor/spinel/test/multi_write_const.rb +36 -0
- data/vendor/spinel/test/multi_write_const.rb.expected +9 -0
- data/vendor/spinel/test/multi_write_from_poly_recv.rb +34 -0
- data/vendor/spinel/test/multi_write_from_poly_recv.rb.expected +1 -0
- data/vendor/spinel/test/multi_write_ivar.rb +34 -0
- data/vendor/spinel/test/multi_write_ivar.rb.expected +3 -0
- data/vendor/spinel/test/multi_write_ivar_const_from_array_rhs.rb +53 -0
- data/vendor/spinel/test/multi_write_ivar_const_from_array_rhs.rb.expected +6 -0
- data/vendor/spinel/test/multi_write_ivar_widening.rb +10 -0
- data/vendor/spinel/test/multi_write_ivar_widening.rb.expected +2 -0
- data/vendor/spinel/test/multi_write_map_block.rb +31 -0
- data/vendor/spinel/test/multi_write_map_block.rb.expected +7 -0
- data/vendor/spinel/test/multi_write_setter.rb +28 -0
- data/vendor/spinel/test/multi_write_setter.rb.expected +3 -0
- data/vendor/spinel/test/multi_write_typed_array_dispatch.rb +44 -0
- data/vendor/spinel/test/multi_write_typed_array_dispatch.rb.expected +3 -0
- data/vendor/spinel/test/nested_class_in_class.rb +38 -0
- data/vendor/spinel/test/nested_class_in_class.rb.expected +3 -0
- data/vendor/spinel/test/nested_class_module_const_resolution.rb +38 -0
- data/vendor/spinel/test/nested_class_module_const_resolution.rb.expected +2 -0
- data/vendor/spinel/test/nil_ivar.rb +44 -0
- data/vendor/spinel/test/nil_ivar.rb.expected +5 -0
- data/vendor/spinel/test/no_attr_write_shortcut_complex.rb +33 -0
- data/vendor/spinel/test/no_attr_write_shortcut_complex.rb.expected +3 -0
- data/vendor/spinel/test/no_attr_write_shortcut_multi.rb +38 -0
- data/vendor/spinel/test/no_attr_write_shortcut_multi.rb.expected +4 -0
- data/vendor/spinel/test/no_keywords_param.rb +15 -0
- data/vendor/spinel/test/no_keywords_param.rb.expected +2 -0
- data/vendor/spinel/test/nullable.rb +26 -0
- data/vendor/spinel/test/nullable.rb.expected +2 -0
- data/vendor/spinel/test/obj_array.rb +26 -0
- data/vendor/spinel/test/obj_array.rb.expected +6 -0
- data/vendor/spinel/test/object_new_sentinel.rb +18 -0
- data/vendor/spinel/test/object_new_sentinel.rb.expected +3 -0
- data/vendor/spinel/test/object_truthy.rb +31 -0
- data/vendor/spinel/test/object_truthy.rb.expected +5 -0
- data/vendor/spinel/test/op_assign_user_operator.rb +36 -0
- data/vendor/spinel/test/open_class.rb +27 -0
- data/vendor/spinel/test/open_class.rb.expected +4 -0
- data/vendor/spinel/test/optional_string_param_method.rb +11 -0
- data/vendor/spinel/test/optional_string_param_method.rb.expected +3 -0
- data/vendor/spinel/test/param_inference_if_predicate.rb +90 -0
- data/vendor/spinel/test/param_inference_if_predicate.rb.expected +3 -0
- data/vendor/spinel/test/param_narrow_from_body_call.rb +34 -0
- data/vendor/spinel/test/param_narrow_from_body_call.rb.expected +2 -0
- data/vendor/spinel/test/param_widens_when_body_assigns_string.rb +21 -0
- data/vendor/spinel/test/param_widens_when_body_assigns_string.rb.expected +6 -0
- data/vendor/spinel/test/pattern.rb +41 -0
- data/vendor/spinel/test/pattern.rb.expected +9 -0
- data/vendor/spinel/test/poly.rb +24 -0
- data/vendor/spinel/test/poly.rb.expected +9 -0
- data/vendor/spinel/test/poly2.rb +34 -0
- data/vendor/spinel/test/poly2.rb.expected +9 -0
- data/vendor/spinel/test/poly_arith.rb +34 -0
- data/vendor/spinel/test/poly_arith.rb.expected +10 -0
- data/vendor/spinel/test/poly_array_literal_callnode_typed_elem.rb +37 -0
- data/vendor/spinel/test/poly_array_literal_callnode_typed_elem.rb.expected +9 -0
- data/vendor/spinel/test/poly_array_slot_literal.rb +41 -0
- data/vendor/spinel/test/poly_array_slot_sized_default.rb +33 -0
- data/vendor/spinel/test/poly_box_int_array.rb +13 -0
- data/vendor/spinel/test/poly_box_int_array.rb.expected +2 -0
- data/vendor/spinel/test/poly_dispatch_args_ret.rb +45 -0
- data/vendor/spinel/test/poly_dispatch_args_ret.rb.expected +4 -0
- data/vendor/spinel/test/poly_dispatch_arity_padding.rb +36 -0
- data/vendor/spinel/test/poly_dispatch_arity_truncate.rb +45 -0
- data/vendor/spinel/test/poly_dispatch_attr_reader.rb +44 -0
- data/vendor/spinel/test/poly_dispatch_attr_reader.rb.expected +4 -0
- data/vendor/spinel/test/poly_dispatch_builtin.rb +16 -0
- data/vendor/spinel/test/poly_dispatch_builtin.rb.expected +2 -0
- data/vendor/spinel/test/poly_dispatch_builtin_all.rb +34 -0
- data/vendor/spinel/test/poly_dispatch_builtin_all.rb.expected +8 -0
- data/vendor/spinel/test/poly_dispatch_ptr_array.rb +57 -0
- data/vendor/spinel/test/poly_dispatch_ptr_array.rb.expected +6 -0
- data/vendor/spinel/test/poly_equality_mixed_sites.rb +40 -0
- data/vendor/spinel/test/poly_equality_mixed_sites.rb.expected +10 -0
- data/vendor/spinel/test/poly_gc.rb +39 -0
- data/vendor/spinel/test/poly_gc.rb.expected +3 -0
- data/vendor/spinel/test/poly_hash_literal_from_ivar.rb +47 -0
- data/vendor/spinel/test/poly_hash_literal_from_ivar.rb.expected +5 -0
- data/vendor/spinel/test/poly_hash_with_range.rb +36 -0
- data/vendor/spinel/test/poly_hash_with_range.rb.expected +10 -0
- data/vendor/spinel/test/poly_hash_with_time.rb +32 -0
- data/vendor/spinel/test/poly_hash_with_time.rb.expected +8 -0
- data/vendor/spinel/test/poly_int_arith_auto_unify.rb +26 -0
- data/vendor/spinel/test/poly_int_arith_auto_unify.rb.expected +4 -0
- data/vendor/spinel/test/poly_int_bit_index.rb +50 -0
- data/vendor/spinel/test/poly_int_bit_index.rb.expected +14 -0
- data/vendor/spinel/test/poly_int_bitops_auto_unify.rb +20 -0
- data/vendor/spinel/test/poly_int_bitops_auto_unify.rb.expected +5 -0
- data/vendor/spinel/test/poly_is_a.rb +47 -0
- data/vendor/spinel/test/poly_is_a.rb.expected +10 -0
- data/vendor/spinel/test/poly_keyed_hash_method_dedup.rb +37 -0
- data/vendor/spinel/test/poly_keyed_hash_method_dedup.rb.expected +4 -0
- data/vendor/spinel/test/poly_keyed_hash_pipeline.rb +40 -0
- data/vendor/spinel/test/poly_keyed_hash_pipeline.rb.expected +2 -0
- data/vendor/spinel/test/poly_method_args.rb +23 -0
- data/vendor/spinel/test/poly_method_args.rb.expected +2 -0
- data/vendor/spinel/test/poly_method_mixed_return.rb +23 -0
- data/vendor/spinel/test/poly_method_mixed_return.rb.expected +2 -0
- data/vendor/spinel/test/poly_or_returns_value.rb +13 -0
- data/vendor/spinel/test/poly_or_returns_value.rb.expected +4 -0
- data/vendor/spinel/test/poly_recv_aref_box_arm.rb +41 -0
- data/vendor/spinel/test/poly_recv_aref_box_arm.rb.expected +4 -0
- data/vendor/spinel/test/poly_recv_aref_str_key.rb +42 -0
- data/vendor/spinel/test/poly_recv_aref_str_key.rb.expected +2 -0
- data/vendor/spinel/test/poly_recv_bracket_assign.rb +31 -0
- data/vendor/spinel/test/poly_recv_bracket_assign.rb.expected +1 -0
- data/vendor/spinel/test/poly_recv_each.rb +35 -0
- data/vendor/spinel/test/poly_recv_each.rb.expected +7 -0
- data/vendor/spinel/test/poly_return_value_class.rb +66 -0
- data/vendor/spinel/test/poly_return_value_class.rb.expected +7 -0
- data/vendor/spinel/test/poly_self_deref.rb +28 -0
- data/vendor/spinel/test/poly_self_deref.rb.expected +2 -0
- data/vendor/spinel/test/poly_shl_array_push_dispatch.rb +35 -0
- data/vendor/spinel/test/poly_shl_array_push_dispatch.rb.expected +5 -0
- data/vendor/spinel/test/poly_slice_assign.rb +26 -0
- data/vendor/spinel/test/poly_slice_assign.rb.expected +3 -0
- data/vendor/spinel/test/poly_str_append.rb +40 -0
- data/vendor/spinel/test/poly_str_append.rb.expected +2 -0
- data/vendor/spinel/test/poly_to_i_via_str_poly_hash.rb +19 -0
- data/vendor/spinel/test/poly_to_i_via_str_poly_hash.rb.expected +1 -0
- data/vendor/spinel/test/post_execution.rb +17 -0
- data/vendor/spinel/test/post_execution.rb.expected +4 -0
- data/vendor/spinel/test/pre_execution.rb +18 -0
- data/vendor/spinel/test/pre_execution.rb.expected +4 -0
- data/vendor/spinel/test/primitive_method_shadow.rb +48 -0
- data/vendor/spinel/test/primitive_method_shadow.rb.expected +4 -0
- data/vendor/spinel/test/primitive_method_shadow_int_recv.rb +47 -0
- data/vendor/spinel/test/primitive_method_shadow_int_recv.rb.expected +1 -0
- data/vendor/spinel/test/proc.rb +42 -0
- data/vendor/spinel/test/proc.rb.expected +8 -0
- data/vendor/spinel/test/proc_closure.rb +44 -0
- data/vendor/spinel/test/proc_closure.rb.expected +8 -0
- data/vendor/spinel/test/proc_hash_value.rb +27 -0
- data/vendor/spinel/test/proc_hash_value.rb.expected +1 -0
- data/vendor/spinel/test/ptr_array.rb +107 -0
- data/vendor/spinel/test/ptr_array.rb.expected +23 -0
- data/vendor/spinel/test/range.rb +130 -0
- data/vendor/spinel/test/range.rb.expected +61 -0
- data/vendor/spinel/test/redo.rb +263 -0
- data/vendor/spinel/test/redo.rb.expected +71 -0
- data/vendor/spinel/test/reduce_acc_shadow.rb +31 -0
- data/vendor/spinel/test/reduce_acc_shadow.rb.expected +5 -0
- data/vendor/spinel/test/regex.rb +152 -0
- data/vendor/spinel/test/regex.rb.expected +43 -0
- data/vendor/spinel/test/regexp.rb +34 -0
- data/vendor/spinel/test/regexp.rb.expected +12 -0
- data/vendor/spinel/test/reopen_class.rb +33 -0
- data/vendor/spinel/test/reopen_class.rb.expected +5 -0
- data/vendor/spinel/test/require/lib/greeter.rb +9 -0
- data/vendor/spinel/test/require/main.rb +5 -0
- data/vendor/spinel/test/require_dedup/lib/data.rb +2 -0
- data/vendor/spinel/test/require_dedup/lib/types.rb +1 -0
- data/vendor/spinel/test/require_dedup/main.rb +8 -0
- data/vendor/spinel/test/rescue.rb +48 -0
- data/vendor/spinel/test/rescue.rb.expected +7 -0
- data/vendor/spinel/test/rescue_modifier_assign.rb +24 -0
- data/vendor/spinel/test/rescue_modifier_assign.rb.expected +4 -0
- data/vendor/spinel/test/rightward_assign.rb +36 -0
- data/vendor/spinel/test/rightward_assign.rb.expected +6 -0
- data/vendor/spinel/test/runtime_widen_int_to_poly_array.rb +27 -0
- data/vendor/spinel/test/runtime_widen_int_to_poly_array.rb.expected +3 -0
- data/vendor/spinel/test/sample_user_method.rb +20 -0
- data/vendor/spinel/test/scan_ivars_inherited_slot.rb +32 -0
- data/vendor/spinel/test/scan_new_calls_class_scope.rb +35 -0
- data/vendor/spinel/test/scan_new_calls_class_scope.rb.expected +1 -0
- data/vendor/spinel/test/send.rb +15 -0
- data/vendor/spinel/test/send.rb.expected +2 -0
- data/vendor/spinel/test/shareable_constant.rb +10 -0
- data/vendor/spinel/test/shareable_constant.rb.expected +2 -0
- data/vendor/spinel/test/sized_poly_array_nil_n.rb +37 -0
- data/vendor/spinel/test/sized_poly_array_nil_n.rb.expected +3 -0
- data/vendor/spinel/test/source_file.rb +37 -0
- data/vendor/spinel/test/source_file.rb.expected +8 -0
- data/vendor/spinel/test/splat_call.rb +72 -0
- data/vendor/spinel/test/splat_call.rb.expected +35 -0
- data/vendor/spinel/test/splat_destructure.rb +56 -0
- data/vendor/spinel/test/splat_destructure.rb.expected +36 -0
- data/vendor/spinel/test/splat_destructure_poly.rb +26 -0
- data/vendor/spinel/test/splat_destructure_poly.rb.expected +8 -0
- data/vendor/spinel/test/stdlib.rb +28 -0
- data/vendor/spinel/test/stdlib.rb.expected +5 -0
- data/vendor/spinel/test/stringio.rb +84 -0
- data/vendor/spinel/test/stringio.rb.expected +27 -0
- data/vendor/spinel/test/strip_nullable_int_cast.rb +24 -0
- data/vendor/spinel/test/strip_nullable_int_cast.rb.expected +1 -0
- data/vendor/spinel/test/struct.rb +25 -0
- data/vendor/spinel/test/struct.rb.expected +8 -0
- data/vendor/spinel/test/struct_inherit.rb +28 -0
- data/vendor/spinel/test/struct_inherit.rb.expected +7 -0
- data/vendor/spinel/test/struct_kw.rb +16 -0
- data/vendor/spinel/test/struct_kw.rb.expected +5 -0
- data/vendor/spinel/test/subclass_inherits_module_parent.rb +40 -0
- data/vendor/spinel/test/subclass_inherits_module_parent.rb.expected +3 -0
- data/vendor/spinel/test/super_arg_cross_class_cast.rb +39 -0
- data/vendor/spinel/test/super_arg_cross_class_cast.rb.expected +2 -0
- data/vendor/spinel/test/super_forwarding.rb +25 -0
- data/vendor/spinel/test/super_forwarding.rb.expected +3 -0
- data/vendor/spinel/test/sym_case.rb +15 -0
- data/vendor/spinel/test/sym_case.rb.expected +4 -0
- data/vendor/spinel/test/sym_poly_hash_merge.rb +47 -0
- data/vendor/spinel/test/sym_poly_hash_merge.rb.expected +11 -0
- data/vendor/spinel/test/symbol_ivar_reassign.rb +25 -0
- data/vendor/spinel/test/symbol_ivar_reassign.rb.expected +2 -0
- data/vendor/spinel/test/three_level_array_outer_index.rb +87 -0
- data/vendor/spinel/test/three_level_array_outer_index.rb.expected +17 -0
- data/vendor/spinel/test/toplevel_ivar_array.rb +19 -0
- data/vendor/spinel/test/toplevel_ivar_array.rb.expected +4 -0
- data/vendor/spinel/test/truncate_module_method.rb +46 -0
- data/vendor/spinel/test/truncate_module_method.rb.expected +6 -0
- data/vendor/spinel/test/unbox_poly_index_in_dispatch.rb +20 -0
- data/vendor/spinel/test/unbox_poly_index_in_dispatch.rb.expected +1 -0
- data/vendor/spinel/test/undef.rb +33 -0
- data/vendor/spinel/test/undef.rb.expected +2 -0
- data/vendor/spinel/test/user_method_named_like_mutator.rb +30 -0
- data/vendor/spinel/test/user_method_named_like_mutator.rb.expected +2 -0
- data/vendor/spinel/test/value_type_ctor_gc_save.rb +46 -0
- data/vendor/spinel/test/value_type_ctor_gc_save.rb.expected +3 -0
- data/vendor/spinel/test/widen_int_obj_to_poly.rb +29 -0
- data/vendor/spinel/test/yield.rb +67 -0
- data/vendor/spinel/test/yield.rb.expected +5 -0
- data/vendor/spinel/test/yield_method_call_in_method_body.rb +58 -0
- data/vendor/spinel/test/yield_method_call_in_method_body.rb.expected +4 -0
- metadata +778 -0
|
@@ -0,0 +1,1586 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* spinel_parse.c - Prism AST Serializer (C version)
|
|
3
|
+
*
|
|
4
|
+
* Equivalent to spinel_parse.rb but links with libprism directly.
|
|
5
|
+
* Parses Ruby source and outputs line-based text AST for spinel_codegen.
|
|
6
|
+
*
|
|
7
|
+
* Build: cc -O2 -I$(PRISM)/include spinel_parse.c -L$(PRISM)/build -lprism -o spinel_parse
|
|
8
|
+
*
|
|
9
|
+
* Output format:
|
|
10
|
+
* ROOT <id>
|
|
11
|
+
* N <id> <type> - node declaration
|
|
12
|
+
* S <id> <field> <escaped> - string field
|
|
13
|
+
* I <id> <field> <integer> - integer field
|
|
14
|
+
* F <id> <field> <float> - float field
|
|
15
|
+
* R <id> <field> <ref_id> - reference (-1 for nil)
|
|
16
|
+
* A <id> <field> <ids> - array of references
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#include <stdio.h>
|
|
20
|
+
#include <stdlib.h>
|
|
21
|
+
#include <string.h>
|
|
22
|
+
#include <stdarg.h>
|
|
23
|
+
#include <prism.h>
|
|
24
|
+
|
|
25
|
+
/* ---- Output buffer ---- */
|
|
26
|
+
static char **lines;
|
|
27
|
+
static int line_count;
|
|
28
|
+
static int line_cap;
|
|
29
|
+
static int node_counter;
|
|
30
|
+
|
|
31
|
+
static void out_add(const char *fmt, ...) {
|
|
32
|
+
va_list ap;
|
|
33
|
+
va_start(ap, fmt);
|
|
34
|
+
char buf[4096];
|
|
35
|
+
vsnprintf(buf, sizeof(buf), fmt, ap);
|
|
36
|
+
va_end(ap);
|
|
37
|
+
if (line_count >= line_cap) {
|
|
38
|
+
line_cap = line_cap * 2 + 256;
|
|
39
|
+
lines = realloc(lines, sizeof(char *) * line_cap);
|
|
40
|
+
}
|
|
41
|
+
lines[line_count++] = strdup(buf);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* ---- Name from constant pool ---- */
|
|
45
|
+
static const pm_parser_t *g_parser;
|
|
46
|
+
static const char *g_source_file = "";
|
|
47
|
+
static char *g_source_file_escaped = NULL; /* escape_str(g_source_file), set once at init */
|
|
48
|
+
|
|
49
|
+
static char *cstr(pm_constant_id_t id) {
|
|
50
|
+
if (id == 0) return strdup("");
|
|
51
|
+
pm_constant_t *c = &g_parser->constant_pool.constants[id - 1];
|
|
52
|
+
char *buf = malloc(c->length + 1);
|
|
53
|
+
memcpy(buf, c->start, c->length);
|
|
54
|
+
buf[c->length] = '\0';
|
|
55
|
+
return buf;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* ---- String escaping ---- */
|
|
59
|
+
static char *escape_str(const uint8_t *src, size_t len) {
|
|
60
|
+
/* Worst case: every char becomes %XX = 3x */
|
|
61
|
+
char *out = malloc(len * 3 + 1);
|
|
62
|
+
size_t j = 0;
|
|
63
|
+
for (size_t i = 0; i < len; i++) {
|
|
64
|
+
uint8_t c = src[i];
|
|
65
|
+
if (c == '%') { out[j++]='%'; out[j++]='2'; out[j++]='5'; }
|
|
66
|
+
else if (c == '\n') { out[j++]='%'; out[j++]='0'; out[j++]='A'; }
|
|
67
|
+
else if (c == '\r') { out[j++]='%'; out[j++]='0'; out[j++]='D'; }
|
|
68
|
+
else if (c == '\t') { out[j++]='%'; out[j++]='0'; out[j++]='9'; }
|
|
69
|
+
else if (c == ' ') { out[j++]='%'; out[j++]='2'; out[j++]='0'; }
|
|
70
|
+
else out[j++] = c;
|
|
71
|
+
}
|
|
72
|
+
out[j] = '\0';
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static char *escape_pm_string(const pm_string_t *s) {
|
|
77
|
+
return escape_str(pm_string_source(s), pm_string_length(s));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Convert "PM_FOO_BAR_NODE" -> "FooBarNode" into `out`, truncated to
|
|
81
|
+
out_size-1 chars + NUL. Prism's node-type strings are pure ASCII
|
|
82
|
+
upper + underscore so we add 32 to lowercase non-leading letters. */
|
|
83
|
+
static size_t prism_kind_to_pascal(const char *raw, char *out, size_t out_size) {
|
|
84
|
+
if (out_size == 0) return 0;
|
|
85
|
+
if (strncmp(raw, "PM_", 3) == 0) raw += 3;
|
|
86
|
+
size_t j = 0;
|
|
87
|
+
int upper = 1;
|
|
88
|
+
for (; *raw && j < out_size - 1; raw++) {
|
|
89
|
+
if (*raw == '_') { upper = 1; continue; }
|
|
90
|
+
out[j++] = upper ? *raw : (char)(*raw + 32);
|
|
91
|
+
upper = 0;
|
|
92
|
+
}
|
|
93
|
+
out[j] = '\0';
|
|
94
|
+
return j;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* ---- Forward ---- */
|
|
98
|
+
static int flatten(pm_node_t *node);
|
|
99
|
+
|
|
100
|
+
/* ---- Emit helpers ---- */
|
|
101
|
+
static void emit_str(int id, const char *field, const char *val) {
|
|
102
|
+
out_add("S %d %s %s", id, field, val);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static void emit_int(int id, const char *field, long long val) {
|
|
106
|
+
out_add("I %d %s %lld", id, field, val);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
static void emit_float(int id, const char *field, double val) {
|
|
110
|
+
char buf[64];
|
|
111
|
+
snprintf(buf, sizeof(buf), "%.17g", val);
|
|
112
|
+
/* Ensure there's a decimal point (Ruby outputs 0.0, not 0) */
|
|
113
|
+
if (!strchr(buf, '.') && !strchr(buf, 'e') && !strchr(buf, 'E'))
|
|
114
|
+
strcat(buf, ".0");
|
|
115
|
+
out_add("F %d %s %s", id, field, buf);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static void emit_ref(int id, const char *field, pm_node_t *child) {
|
|
119
|
+
int cid = child ? flatten(child) : -1;
|
|
120
|
+
out_add("R %d %s %d", id, field, cid);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static void emit_node_array(int id, const char *field, pm_node_list_t *list) {
|
|
124
|
+
if (!list || list->size == 0) {
|
|
125
|
+
out_add("A %d %s ", id, field);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
int *ids = malloc(sizeof(int) * list->size);
|
|
129
|
+
for (size_t i = 0; i < list->size; i++)
|
|
130
|
+
ids[i] = flatten(list->nodes[i]);
|
|
131
|
+
/* Build comma-separated string */
|
|
132
|
+
char buf[65536];
|
|
133
|
+
int pos = 0;
|
|
134
|
+
for (size_t i = 0; i < list->size; i++) {
|
|
135
|
+
if (i > 0) buf[pos++] = ',';
|
|
136
|
+
pos += snprintf(buf + pos, sizeof(buf) - pos, "%d", ids[i]);
|
|
137
|
+
}
|
|
138
|
+
buf[pos] = '\0';
|
|
139
|
+
out_add("A %d %s %s", id, field, buf);
|
|
140
|
+
free(ids);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* ---- Integer value extraction ---- */
|
|
144
|
+
static long long pm_int_value(pm_integer_t *integer) {
|
|
145
|
+
long long val = 0;
|
|
146
|
+
if (integer->length == 0) {
|
|
147
|
+
val = (long long)integer->value;
|
|
148
|
+
} else {
|
|
149
|
+
/* Large integer - approximate with first word */
|
|
150
|
+
val = (long long)integer->value;
|
|
151
|
+
/* TODO: proper bignum support */
|
|
152
|
+
}
|
|
153
|
+
if (integer->negative) val = -val;
|
|
154
|
+
return val;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* ---- Main flattening ---- */
|
|
158
|
+
static int flatten(pm_node_t *node) {
|
|
159
|
+
if (!node) return -1;
|
|
160
|
+
|
|
161
|
+
int id = node_counter++;
|
|
162
|
+
pm_node_type_t t = PM_NODE_TYPE(node);
|
|
163
|
+
|
|
164
|
+
#define N(type_name) out_add("N %d " type_name, id)
|
|
165
|
+
#define S(field, val) do { char *_e = (val); emit_str(id, field, _e); free(_e); } while(0)
|
|
166
|
+
#define I(field, val) emit_int(id, field, val)
|
|
167
|
+
#define F(field, val) emit_float(id, field, val)
|
|
168
|
+
#define R(field, child) emit_ref(id, field, (pm_node_t *)(child))
|
|
169
|
+
#define A(field, list) emit_node_array(id, field, list)
|
|
170
|
+
#define NAME(field, cid) do { char *_n = cstr(cid); char *_e = escape_str((const uint8_t *)_n, strlen(_n)); emit_str(id, field, _e); free(_e); free(_n); } while(0)
|
|
171
|
+
|
|
172
|
+
switch (t) {
|
|
173
|
+
case PM_PROGRAM_NODE: {
|
|
174
|
+
pm_program_node_t *n = (pm_program_node_t *)node;
|
|
175
|
+
N("ProgramNode");
|
|
176
|
+
R("statements", n->statements);
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
case PM_STATEMENTS_NODE: {
|
|
180
|
+
pm_statements_node_t *n = (pm_statements_node_t *)node;
|
|
181
|
+
N("StatementsNode");
|
|
182
|
+
A("body", &n->body);
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
case PM_CLASS_NODE: {
|
|
186
|
+
pm_class_node_t *n = (pm_class_node_t *)node;
|
|
187
|
+
N("ClassNode");
|
|
188
|
+
R("constant_path", n->constant_path);
|
|
189
|
+
R("superclass", n->superclass);
|
|
190
|
+
R("body", n->body);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
case PM_MODULE_NODE: {
|
|
194
|
+
pm_module_node_t *n = (pm_module_node_t *)node;
|
|
195
|
+
N("ModuleNode");
|
|
196
|
+
R("constant_path", n->constant_path);
|
|
197
|
+
R("body", n->body);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
case PM_SINGLETON_CLASS_NODE: {
|
|
201
|
+
/* `class << self; ...; end` — the singleton class block. We
|
|
202
|
+
only support `expression == SelfNode` today (i.e. the
|
|
203
|
+
enclosing class/module's singleton). The body is flattened
|
|
204
|
+
up one level so codegen sees `attr_accessor :x` / `def foo`
|
|
205
|
+
inside the parent ClassNode/ModuleNode body, and the
|
|
206
|
+
SingletonClassNode marker survives so dispatch can route
|
|
207
|
+
methods/accessors to the class-method path. */
|
|
208
|
+
pm_singleton_class_node_t *n = (pm_singleton_class_node_t *)node;
|
|
209
|
+
N("SingletonClassNode");
|
|
210
|
+
R("expression", n->expression);
|
|
211
|
+
R("body", n->body);
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
case PM_DEF_NODE: {
|
|
215
|
+
pm_def_node_t *n = (pm_def_node_t *)node;
|
|
216
|
+
N("DefNode");
|
|
217
|
+
NAME("name", n->name);
|
|
218
|
+
R("parameters", n->parameters);
|
|
219
|
+
R("body", n->body);
|
|
220
|
+
R("receiver", n->receiver);
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
case PM_CALL_NODE: {
|
|
224
|
+
pm_call_node_t *n = (pm_call_node_t *)node;
|
|
225
|
+
N("CallNode");
|
|
226
|
+
NAME("name", n->name);
|
|
227
|
+
R("receiver", n->receiver);
|
|
228
|
+
R("arguments", n->arguments);
|
|
229
|
+
R("block", n->block);
|
|
230
|
+
if (PM_NODE_FLAG_P(node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) {
|
|
231
|
+
S("call_operator", escape_str((const uint8_t *)"&.", 2));
|
|
232
|
+
}
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
case PM_CONSTANT_WRITE_NODE: {
|
|
236
|
+
pm_constant_write_node_t *n = (pm_constant_write_node_t *)node;
|
|
237
|
+
N("ConstantWriteNode");
|
|
238
|
+
NAME("name", n->name);
|
|
239
|
+
R("value", n->value);
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
case PM_CONSTANT_PATH_WRITE_NODE: {
|
|
243
|
+
pm_constant_path_write_node_t *n = (pm_constant_path_write_node_t *)node;
|
|
244
|
+
N("ConstantPathWriteNode");
|
|
245
|
+
R("value", n->value);
|
|
246
|
+
R("target", n->target);
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
case PM_CONSTANT_READ_NODE: {
|
|
250
|
+
pm_constant_read_node_t *n = (pm_constant_read_node_t *)node;
|
|
251
|
+
N("ConstantReadNode");
|
|
252
|
+
NAME("name", n->name);
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
case PM_CONSTANT_PATH_NODE: {
|
|
256
|
+
pm_constant_path_node_t *n = (pm_constant_path_node_t *)node;
|
|
257
|
+
N("ConstantPathNode");
|
|
258
|
+
R("parent", n->parent);
|
|
259
|
+
NAME("name", n->name);
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
case PM_LOCAL_VARIABLE_WRITE_NODE: {
|
|
263
|
+
pm_local_variable_write_node_t *n = (pm_local_variable_write_node_t *)node;
|
|
264
|
+
N("LocalVariableWriteNode");
|
|
265
|
+
NAME("name", n->name);
|
|
266
|
+
R("value", n->value);
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
case PM_LOCAL_VARIABLE_READ_NODE: {
|
|
270
|
+
pm_local_variable_read_node_t *n = (pm_local_variable_read_node_t *)node;
|
|
271
|
+
N("LocalVariableReadNode");
|
|
272
|
+
NAME("name", n->name);
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: {
|
|
276
|
+
pm_local_variable_operator_write_node_t *n = (pm_local_variable_operator_write_node_t *)node;
|
|
277
|
+
N("LocalVariableOperatorWriteNode");
|
|
278
|
+
NAME("name", n->name);
|
|
279
|
+
NAME("binary_operator", n->binary_operator);
|
|
280
|
+
R("value", n->value);
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
case PM_LOCAL_VARIABLE_OR_WRITE_NODE: {
|
|
284
|
+
pm_local_variable_or_write_node_t *n = (pm_local_variable_or_write_node_t *)node;
|
|
285
|
+
N("LocalVariableOrWriteNode");
|
|
286
|
+
NAME("name", n->name);
|
|
287
|
+
R("value", n->value);
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case PM_LOCAL_VARIABLE_AND_WRITE_NODE: {
|
|
291
|
+
pm_local_variable_and_write_node_t *n = (pm_local_variable_and_write_node_t *)node;
|
|
292
|
+
N("LocalVariableAndWriteNode");
|
|
293
|
+
NAME("name", n->name);
|
|
294
|
+
R("value", n->value);
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
case PM_LOCAL_VARIABLE_TARGET_NODE: {
|
|
298
|
+
pm_local_variable_target_node_t *n = (pm_local_variable_target_node_t *)node;
|
|
299
|
+
N("LocalVariableTargetNode");
|
|
300
|
+
NAME("name", n->name);
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
case PM_INSTANCE_VARIABLE_WRITE_NODE: {
|
|
304
|
+
pm_instance_variable_write_node_t *n = (pm_instance_variable_write_node_t *)node;
|
|
305
|
+
N("InstanceVariableWriteNode");
|
|
306
|
+
NAME("name", n->name);
|
|
307
|
+
R("value", n->value);
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
case PM_INSTANCE_VARIABLE_READ_NODE: {
|
|
311
|
+
pm_instance_variable_read_node_t *n = (pm_instance_variable_read_node_t *)node;
|
|
312
|
+
N("InstanceVariableReadNode");
|
|
313
|
+
NAME("name", n->name);
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
case PM_INSTANCE_VARIABLE_TARGET_NODE: {
|
|
317
|
+
pm_instance_variable_target_node_t *n = (pm_instance_variable_target_node_t *)node;
|
|
318
|
+
N("InstanceVariableTargetNode");
|
|
319
|
+
NAME("name", n->name);
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
case PM_CALL_TARGET_NODE: {
|
|
323
|
+
pm_call_target_node_t *n = (pm_call_target_node_t *)node;
|
|
324
|
+
N("CallTargetNode");
|
|
325
|
+
NAME("name", n->name);
|
|
326
|
+
R("receiver", n->receiver);
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
case PM_CONSTANT_TARGET_NODE: {
|
|
330
|
+
pm_constant_target_node_t *n = (pm_constant_target_node_t *)node;
|
|
331
|
+
N("ConstantTargetNode");
|
|
332
|
+
NAME("name", n->name);
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
|
|
336
|
+
pm_instance_variable_and_write_node_t *n = (pm_instance_variable_and_write_node_t *)node;
|
|
337
|
+
N("InstanceVariableAndWriteNode");
|
|
338
|
+
NAME("name", n->name);
|
|
339
|
+
R("value", n->value);
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: {
|
|
343
|
+
pm_instance_variable_or_write_node_t *n = (pm_instance_variable_or_write_node_t *)node;
|
|
344
|
+
N("InstanceVariableOrWriteNode");
|
|
345
|
+
NAME("name", n->name);
|
|
346
|
+
R("value", n->value);
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: {
|
|
350
|
+
pm_instance_variable_operator_write_node_t *n = (pm_instance_variable_operator_write_node_t *)node;
|
|
351
|
+
N("InstanceVariableOperatorWriteNode");
|
|
352
|
+
NAME("name", n->name);
|
|
353
|
+
NAME("binary_operator", n->binary_operator);
|
|
354
|
+
R("value", n->value);
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
case PM_CLASS_VARIABLE_WRITE_NODE: {
|
|
358
|
+
pm_class_variable_write_node_t *n = (pm_class_variable_write_node_t *)node;
|
|
359
|
+
N("ClassVariableWriteNode");
|
|
360
|
+
NAME("name", n->name);
|
|
361
|
+
R("value", n->value);
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
case PM_CLASS_VARIABLE_READ_NODE: {
|
|
365
|
+
pm_class_variable_read_node_t *n = (pm_class_variable_read_node_t *)node;
|
|
366
|
+
N("ClassVariableReadNode");
|
|
367
|
+
NAME("name", n->name);
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
case PM_INDEX_OPERATOR_WRITE_NODE: {
|
|
371
|
+
pm_index_operator_write_node_t *n = (pm_index_operator_write_node_t *)node;
|
|
372
|
+
N("IndexOperatorWriteNode");
|
|
373
|
+
NAME("binary_operator", n->binary_operator);
|
|
374
|
+
R("receiver", n->receiver);
|
|
375
|
+
R("arguments", n->arguments);
|
|
376
|
+
R("value", n->value);
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
case PM_INDEX_AND_WRITE_NODE: {
|
|
380
|
+
pm_index_and_write_node_t *n = (pm_index_and_write_node_t *)node;
|
|
381
|
+
N("IndexAndWriteNode");
|
|
382
|
+
R("receiver", n->receiver);
|
|
383
|
+
R("arguments", n->arguments);
|
|
384
|
+
R("value", n->value);
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
case PM_INDEX_OR_WRITE_NODE: {
|
|
388
|
+
pm_index_or_write_node_t *n = (pm_index_or_write_node_t *)node;
|
|
389
|
+
N("IndexOrWriteNode");
|
|
390
|
+
R("receiver", n->receiver);
|
|
391
|
+
R("arguments", n->arguments);
|
|
392
|
+
R("value", n->value);
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
case PM_INDEX_TARGET_NODE: {
|
|
396
|
+
pm_index_target_node_t *n = (pm_index_target_node_t *)node;
|
|
397
|
+
N("IndexTargetNode");
|
|
398
|
+
R("receiver", n->receiver);
|
|
399
|
+
R("arguments", n->arguments);
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
case PM_CALL_OPERATOR_WRITE_NODE: {
|
|
403
|
+
pm_call_operator_write_node_t *n = (pm_call_operator_write_node_t *)node;
|
|
404
|
+
N("CallOperatorWriteNode");
|
|
405
|
+
R("receiver", n->receiver);
|
|
406
|
+
NAME("name", n->read_name);
|
|
407
|
+
NAME("binary_operator", n->binary_operator);
|
|
408
|
+
R("value", n->value);
|
|
409
|
+
if (PM_NODE_FLAG_P(node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) {
|
|
410
|
+
S("call_operator", escape_str((const uint8_t *)"&.", 2));
|
|
411
|
+
}
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
case PM_CALL_AND_WRITE_NODE: {
|
|
415
|
+
pm_call_and_write_node_t *n = (pm_call_and_write_node_t *)node;
|
|
416
|
+
N("CallAndWriteNode");
|
|
417
|
+
R("receiver", n->receiver);
|
|
418
|
+
NAME("name", n->read_name);
|
|
419
|
+
R("value", n->value);
|
|
420
|
+
if (PM_NODE_FLAG_P(node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) {
|
|
421
|
+
S("call_operator", escape_str((const uint8_t *)"&.", 2));
|
|
422
|
+
}
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
425
|
+
case PM_CALL_OR_WRITE_NODE: {
|
|
426
|
+
pm_call_or_write_node_t *n = (pm_call_or_write_node_t *)node;
|
|
427
|
+
N("CallOrWriteNode");
|
|
428
|
+
R("receiver", n->receiver);
|
|
429
|
+
NAME("name", n->read_name);
|
|
430
|
+
R("value", n->value);
|
|
431
|
+
if (PM_NODE_FLAG_P(node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) {
|
|
432
|
+
S("call_operator", escape_str((const uint8_t *)"&.", 2));
|
|
433
|
+
}
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
case PM_GLOBAL_VARIABLE_WRITE_NODE: {
|
|
437
|
+
pm_global_variable_write_node_t *n = (pm_global_variable_write_node_t *)node;
|
|
438
|
+
N("GlobalVariableWriteNode");
|
|
439
|
+
NAME("name", n->name);
|
|
440
|
+
R("value", n->value);
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
case PM_GLOBAL_VARIABLE_READ_NODE: {
|
|
444
|
+
pm_global_variable_read_node_t *n = (pm_global_variable_read_node_t *)node;
|
|
445
|
+
N("GlobalVariableReadNode");
|
|
446
|
+
NAME("name", n->name);
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
449
|
+
case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: {
|
|
450
|
+
pm_global_variable_operator_write_node_t *n = (pm_global_variable_operator_write_node_t *)node;
|
|
451
|
+
N("GlobalVariableOperatorWriteNode");
|
|
452
|
+
NAME("name", n->name);
|
|
453
|
+
NAME("binary_operator", n->binary_operator);
|
|
454
|
+
R("value", n->value);
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: {
|
|
458
|
+
pm_global_variable_or_write_node_t *n = (pm_global_variable_or_write_node_t *)node;
|
|
459
|
+
N("GlobalVariableOrWriteNode");
|
|
460
|
+
NAME("name", n->name);
|
|
461
|
+
R("value", n->value);
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: {
|
|
465
|
+
pm_global_variable_and_write_node_t *n = (pm_global_variable_and_write_node_t *)node;
|
|
466
|
+
N("GlobalVariableAndWriteNode");
|
|
467
|
+
NAME("name", n->name);
|
|
468
|
+
R("value", n->value);
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
case PM_GLOBAL_VARIABLE_TARGET_NODE: {
|
|
472
|
+
pm_global_variable_target_node_t *n = (pm_global_variable_target_node_t *)node;
|
|
473
|
+
N("GlobalVariableTargetNode");
|
|
474
|
+
NAME("name", n->name);
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
case PM_NO_KEYWORDS_PARAMETER_NODE: {
|
|
478
|
+
/* `def f(**nil)` -- explicit kwarg rejection. Spinel's keyword-arg
|
|
479
|
+
handling is already conservative (only known keys accepted),
|
|
480
|
+
so the explicit "no keywords" marker is effectively a no-op
|
|
481
|
+
at the codegen level. We emit the node so a ParametersNode
|
|
482
|
+
carrying it doesn't leave a NULL keyword slot, but the
|
|
483
|
+
compile-time effect is nothing. */
|
|
484
|
+
N("NoKeywordsParameterNode");
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
case PM_INTEGER_NODE: {
|
|
488
|
+
pm_integer_node_t *n = (pm_integer_node_t *)node;
|
|
489
|
+
N("IntegerNode");
|
|
490
|
+
I("value", pm_int_value(&n->value));
|
|
491
|
+
break;
|
|
492
|
+
}
|
|
493
|
+
case PM_FLOAT_NODE: {
|
|
494
|
+
pm_float_node_t *n = (pm_float_node_t *)node;
|
|
495
|
+
N("FloatNode");
|
|
496
|
+
F("value", n->value);
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
case PM_STRING_NODE: {
|
|
500
|
+
pm_string_node_t *n = (pm_string_node_t *)node;
|
|
501
|
+
N("StringNode");
|
|
502
|
+
S("content", escape_pm_string(&n->unescaped));
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
case PM_INTERPOLATED_STRING_NODE: {
|
|
506
|
+
pm_interpolated_string_node_t *n = (pm_interpolated_string_node_t *)node;
|
|
507
|
+
N("InterpolatedStringNode");
|
|
508
|
+
A("parts", &n->parts);
|
|
509
|
+
break;
|
|
510
|
+
}
|
|
511
|
+
case PM_EMBEDDED_STATEMENTS_NODE: {
|
|
512
|
+
pm_embedded_statements_node_t *n = (pm_embedded_statements_node_t *)node;
|
|
513
|
+
N("EmbeddedStatementsNode");
|
|
514
|
+
R("statements", n->statements);
|
|
515
|
+
break;
|
|
516
|
+
}
|
|
517
|
+
case PM_SYMBOL_NODE: {
|
|
518
|
+
pm_symbol_node_t *n = (pm_symbol_node_t *)node;
|
|
519
|
+
N("SymbolNode");
|
|
520
|
+
S("value", escape_pm_string(&n->unescaped));
|
|
521
|
+
break;
|
|
522
|
+
}
|
|
523
|
+
case PM_TRUE_NODE:
|
|
524
|
+
N("TrueNode");
|
|
525
|
+
break;
|
|
526
|
+
case PM_FALSE_NODE:
|
|
527
|
+
N("FalseNode");
|
|
528
|
+
break;
|
|
529
|
+
case PM_NIL_NODE:
|
|
530
|
+
N("NilNode");
|
|
531
|
+
break;
|
|
532
|
+
case PM_SELF_NODE:
|
|
533
|
+
N("SelfNode");
|
|
534
|
+
break;
|
|
535
|
+
case PM_ARRAY_NODE: {
|
|
536
|
+
pm_array_node_t *n = (pm_array_node_t *)node;
|
|
537
|
+
N("ArrayNode");
|
|
538
|
+
A("elements", &n->elements);
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
case PM_HASH_NODE: {
|
|
542
|
+
pm_hash_node_t *n = (pm_hash_node_t *)node;
|
|
543
|
+
N("HashNode");
|
|
544
|
+
A("elements", &n->elements);
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
case PM_ASSOC_NODE: {
|
|
548
|
+
pm_assoc_node_t *n = (pm_assoc_node_t *)node;
|
|
549
|
+
N("AssocNode");
|
|
550
|
+
R("key", n->key);
|
|
551
|
+
/* Hash shorthand `{ x: }` lowers to an AssocNode whose value is a
|
|
552
|
+
PM_IMPLICIT_NODE. The top-level PM_IMPLICIT_NODE case below
|
|
553
|
+
handles the unwrap by recursing into n->value at the same id
|
|
554
|
+
slot, so the codegen never sees the implicit wrapper here. */
|
|
555
|
+
R("value", n->value);
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
case PM_KEYWORD_HASH_NODE: {
|
|
559
|
+
pm_keyword_hash_node_t *n = (pm_keyword_hash_node_t *)node;
|
|
560
|
+
N("KeywordHashNode");
|
|
561
|
+
A("elements", &n->elements);
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
case PM_RANGE_NODE: {
|
|
565
|
+
pm_range_node_t *n = (pm_range_node_t *)node;
|
|
566
|
+
N("RangeNode");
|
|
567
|
+
R("left", n->left);
|
|
568
|
+
R("right", n->right);
|
|
569
|
+
/* PM_RANGE_FLAGS_EXCLUDE_END = 4. Codegen reads bit 2 to decide
|
|
570
|
+
whether `..` (inclusive) or `...` (exclusive). */
|
|
571
|
+
I("flags", n->base.flags);
|
|
572
|
+
break;
|
|
573
|
+
}
|
|
574
|
+
case PM_IF_NODE: {
|
|
575
|
+
pm_if_node_t *n = (pm_if_node_t *)node;
|
|
576
|
+
N("IfNode");
|
|
577
|
+
R("predicate", n->predicate);
|
|
578
|
+
R("statements", n->statements);
|
|
579
|
+
R("subsequent", n->subsequent);
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
case PM_ELSE_NODE: {
|
|
583
|
+
pm_else_node_t *n = (pm_else_node_t *)node;
|
|
584
|
+
N("ElseNode");
|
|
585
|
+
R("statements", n->statements);
|
|
586
|
+
break;
|
|
587
|
+
}
|
|
588
|
+
case PM_UNLESS_NODE: {
|
|
589
|
+
pm_unless_node_t *n = (pm_unless_node_t *)node;
|
|
590
|
+
N("UnlessNode");
|
|
591
|
+
R("predicate", n->predicate);
|
|
592
|
+
R("statements", n->statements);
|
|
593
|
+
R("else_clause", n->else_clause);
|
|
594
|
+
break;
|
|
595
|
+
}
|
|
596
|
+
case PM_WHILE_NODE: {
|
|
597
|
+
pm_while_node_t *n = (pm_while_node_t *)node;
|
|
598
|
+
N("WhileNode");
|
|
599
|
+
R("predicate", n->predicate);
|
|
600
|
+
R("statements", n->statements);
|
|
601
|
+
/* PM_LOOP_FLAGS_BEGIN_MODIFIER = 4 (bit 2): begin..end while form,
|
|
602
|
+
which is a post-test loop (body runs at least once). The codegen
|
|
603
|
+
reads bit 2 to decide between `while (cond) {}` and `do {} while (cond);`. */
|
|
604
|
+
I("flags", n->base.flags);
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
case PM_UNTIL_NODE: {
|
|
608
|
+
pm_until_node_t *n = (pm_until_node_t *)node;
|
|
609
|
+
N("UntilNode");
|
|
610
|
+
R("predicate", n->predicate);
|
|
611
|
+
R("statements", n->statements);
|
|
612
|
+
I("flags", n->base.flags);
|
|
613
|
+
break;
|
|
614
|
+
}
|
|
615
|
+
case PM_FOR_NODE: {
|
|
616
|
+
pm_for_node_t *n = (pm_for_node_t *)node;
|
|
617
|
+
N("ForNode");
|
|
618
|
+
R("index", n->index);
|
|
619
|
+
R("collection", n->collection);
|
|
620
|
+
R("statements", n->statements);
|
|
621
|
+
break;
|
|
622
|
+
}
|
|
623
|
+
case PM_CASE_NODE: {
|
|
624
|
+
pm_case_node_t *n = (pm_case_node_t *)node;
|
|
625
|
+
N("CaseNode");
|
|
626
|
+
R("predicate", n->predicate);
|
|
627
|
+
A("conditions", &n->conditions);
|
|
628
|
+
R("else_clause", n->else_clause);
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
case PM_CASE_MATCH_NODE: {
|
|
632
|
+
pm_case_match_node_t *n = (pm_case_match_node_t *)node;
|
|
633
|
+
N("CaseMatchNode");
|
|
634
|
+
R("predicate", n->predicate);
|
|
635
|
+
A("conditions", &n->conditions);
|
|
636
|
+
R("else_clause", n->else_clause);
|
|
637
|
+
break;
|
|
638
|
+
}
|
|
639
|
+
case PM_WHEN_NODE: {
|
|
640
|
+
pm_when_node_t *n = (pm_when_node_t *)node;
|
|
641
|
+
N("WhenNode");
|
|
642
|
+
A("conditions", &n->conditions);
|
|
643
|
+
R("statements", n->statements);
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
case PM_IN_NODE: {
|
|
647
|
+
pm_in_node_t *n = (pm_in_node_t *)node;
|
|
648
|
+
N("InNode");
|
|
649
|
+
R("pattern", n->pattern);
|
|
650
|
+
R("statements", n->statements);
|
|
651
|
+
break;
|
|
652
|
+
}
|
|
653
|
+
case PM_BEGIN_NODE: {
|
|
654
|
+
pm_begin_node_t *n = (pm_begin_node_t *)node;
|
|
655
|
+
N("BeginNode");
|
|
656
|
+
R("statements", n->statements);
|
|
657
|
+
R("rescue_clause", n->rescue_clause);
|
|
658
|
+
R("ensure_clause", n->ensure_clause);
|
|
659
|
+
R("else_clause", n->else_clause);
|
|
660
|
+
break;
|
|
661
|
+
}
|
|
662
|
+
case PM_ENSURE_NODE: {
|
|
663
|
+
pm_ensure_node_t *n = (pm_ensure_node_t *)node;
|
|
664
|
+
N("EnsureNode");
|
|
665
|
+
R("statements", n->statements);
|
|
666
|
+
break;
|
|
667
|
+
}
|
|
668
|
+
case PM_RESCUE_NODE: {
|
|
669
|
+
pm_rescue_node_t *n = (pm_rescue_node_t *)node;
|
|
670
|
+
N("RescueNode");
|
|
671
|
+
A("exceptions", &n->exceptions);
|
|
672
|
+
R("reference", n->reference);
|
|
673
|
+
R("statements", n->statements);
|
|
674
|
+
R("subsequent", n->subsequent);
|
|
675
|
+
break;
|
|
676
|
+
}
|
|
677
|
+
case PM_RESCUE_MODIFIER_NODE: {
|
|
678
|
+
pm_rescue_modifier_node_t *n = (pm_rescue_modifier_node_t *)node;
|
|
679
|
+
N("RescueModifierNode");
|
|
680
|
+
R("expression", n->expression);
|
|
681
|
+
R("rescue_expression", n->rescue_expression);
|
|
682
|
+
break;
|
|
683
|
+
}
|
|
684
|
+
case PM_RETURN_NODE: {
|
|
685
|
+
pm_return_node_t *n = (pm_return_node_t *)node;
|
|
686
|
+
N("ReturnNode");
|
|
687
|
+
R("arguments", n->arguments);
|
|
688
|
+
break;
|
|
689
|
+
}
|
|
690
|
+
case PM_BREAK_NODE:
|
|
691
|
+
N("BreakNode");
|
|
692
|
+
break;
|
|
693
|
+
case PM_NEXT_NODE:
|
|
694
|
+
N("NextNode");
|
|
695
|
+
break;
|
|
696
|
+
case PM_RETRY_NODE:
|
|
697
|
+
N("RetryNode");
|
|
698
|
+
break;
|
|
699
|
+
case PM_YIELD_NODE: {
|
|
700
|
+
pm_yield_node_t *n = (pm_yield_node_t *)node;
|
|
701
|
+
N("YieldNode");
|
|
702
|
+
R("arguments", n->arguments);
|
|
703
|
+
break;
|
|
704
|
+
}
|
|
705
|
+
case PM_BLOCK_NODE: {
|
|
706
|
+
pm_block_node_t *n = (pm_block_node_t *)node;
|
|
707
|
+
N("BlockNode");
|
|
708
|
+
/* Serialize block parameters */
|
|
709
|
+
if (n->parameters) {
|
|
710
|
+
if (PM_NODE_TYPE(n->parameters) == PM_BLOCK_PARAMETERS_NODE) {
|
|
711
|
+
pm_block_parameters_node_t *bp = (pm_block_parameters_node_t *)n->parameters;
|
|
712
|
+
int bpid = node_counter++;
|
|
713
|
+
out_add("N %d BlockParametersNode", bpid);
|
|
714
|
+
if (bp->parameters) {
|
|
715
|
+
emit_ref(bpid, "parameters", (pm_node_t *)bp->parameters);
|
|
716
|
+
}
|
|
717
|
+
out_add("R %d %s %d", id, "parameters", bpid);
|
|
718
|
+
} else if (PM_NODE_TYPE(n->parameters) == PM_NUMBERED_PARAMETERS_NODE) {
|
|
719
|
+
pm_numbered_parameters_node_t *np = (pm_numbered_parameters_node_t *)n->parameters;
|
|
720
|
+
int npid = node_counter++;
|
|
721
|
+
out_add("N %d NumberedParametersNode", npid);
|
|
722
|
+
emit_int(npid, "maximum", np->maximum);
|
|
723
|
+
out_add("R %d %s %d", id, "parameters", npid);
|
|
724
|
+
} else {
|
|
725
|
+
R("parameters", n->parameters);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
R("body", n->body);
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
case PM_PARAMETERS_NODE: {
|
|
732
|
+
pm_parameters_node_t *n = (pm_parameters_node_t *)node;
|
|
733
|
+
N("ParametersNode");
|
|
734
|
+
A("requireds", &n->requireds);
|
|
735
|
+
A("optionals", &n->optionals);
|
|
736
|
+
A("keywords", &n->keywords);
|
|
737
|
+
if (n->rest) R("rest", n->rest);
|
|
738
|
+
if (n->block) R("block", n->block);
|
|
739
|
+
A("posts", &n->posts);
|
|
740
|
+
/* Surface keyword_rest so the new PM_NO_KEYWORDS_PARAMETER_NODE
|
|
741
|
+
case below is reachable. Existing collect_params_str walker
|
|
742
|
+
only acts on KeywordRestParameterNode (`**kw`), so the
|
|
743
|
+
NoKeywordsParameter (`**nil`) marker passes through as a
|
|
744
|
+
no-op which matches its compile-time semantics. */
|
|
745
|
+
if (n->keyword_rest) R("keyword_rest", n->keyword_rest);
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
748
|
+
case PM_REQUIRED_PARAMETER_NODE: {
|
|
749
|
+
pm_required_parameter_node_t *n = (pm_required_parameter_node_t *)node;
|
|
750
|
+
N("RequiredParameterNode");
|
|
751
|
+
NAME("name", n->name);
|
|
752
|
+
break;
|
|
753
|
+
}
|
|
754
|
+
case PM_OPTIONAL_PARAMETER_NODE: {
|
|
755
|
+
pm_optional_parameter_node_t *n = (pm_optional_parameter_node_t *)node;
|
|
756
|
+
N("OptionalParameterNode");
|
|
757
|
+
NAME("name", n->name);
|
|
758
|
+
R("value", n->value);
|
|
759
|
+
break;
|
|
760
|
+
}
|
|
761
|
+
case PM_REST_PARAMETER_NODE: {
|
|
762
|
+
pm_rest_parameter_node_t *n = (pm_rest_parameter_node_t *)node;
|
|
763
|
+
N("RestParameterNode");
|
|
764
|
+
if (n->name) { NAME("name", n->name); }
|
|
765
|
+
break;
|
|
766
|
+
}
|
|
767
|
+
case PM_BLOCK_PARAMETER_NODE: {
|
|
768
|
+
pm_block_parameter_node_t *n = (pm_block_parameter_node_t *)node;
|
|
769
|
+
N("BlockParameterNode");
|
|
770
|
+
if (n->name) { NAME("name", n->name); }
|
|
771
|
+
break;
|
|
772
|
+
}
|
|
773
|
+
case PM_BLOCK_ARGUMENT_NODE: {
|
|
774
|
+
/* `&expr` in call argument position. Wraps the expression that
|
|
775
|
+
* provides the proc to forward (typically a LocalVariableReadNode
|
|
776
|
+
* for a `&block`-captured param, or a SymbolNode for `&:to_s`). */
|
|
777
|
+
pm_block_argument_node_t *n = (pm_block_argument_node_t *)node;
|
|
778
|
+
N("BlockArgumentNode");
|
|
779
|
+
R("expression", n->expression);
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
case PM_BLOCK_LOCAL_VARIABLE_NODE: {
|
|
783
|
+
pm_block_local_variable_node_t *n = (pm_block_local_variable_node_t *)node;
|
|
784
|
+
N("BlockLocalVariableNode");
|
|
785
|
+
NAME("name", n->name);
|
|
786
|
+
break;
|
|
787
|
+
}
|
|
788
|
+
case PM_KEYWORD_REST_PARAMETER_NODE: {
|
|
789
|
+
pm_keyword_rest_parameter_node_t *n = (pm_keyword_rest_parameter_node_t *)node;
|
|
790
|
+
N("KeywordRestParameterNode");
|
|
791
|
+
if (n->name) { NAME("name", n->name); }
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
case PM_REQUIRED_KEYWORD_PARAMETER_NODE: {
|
|
795
|
+
pm_required_keyword_parameter_node_t *n = (pm_required_keyword_parameter_node_t *)node;
|
|
796
|
+
N("RequiredKeywordParameterNode");
|
|
797
|
+
NAME("name", n->name);
|
|
798
|
+
break;
|
|
799
|
+
}
|
|
800
|
+
case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: {
|
|
801
|
+
pm_optional_keyword_parameter_node_t *n = (pm_optional_keyword_parameter_node_t *)node;
|
|
802
|
+
N("OptionalKeywordParameterNode");
|
|
803
|
+
NAME("name", n->name);
|
|
804
|
+
R("value", n->value);
|
|
805
|
+
break;
|
|
806
|
+
}
|
|
807
|
+
case PM_PARENTHESES_NODE: {
|
|
808
|
+
pm_parentheses_node_t *n = (pm_parentheses_node_t *)node;
|
|
809
|
+
N("ParenthesesNode");
|
|
810
|
+
R("body", n->body);
|
|
811
|
+
break;
|
|
812
|
+
}
|
|
813
|
+
case PM_AND_NODE: {
|
|
814
|
+
pm_and_node_t *n = (pm_and_node_t *)node;
|
|
815
|
+
N("AndNode");
|
|
816
|
+
R("left", n->left);
|
|
817
|
+
R("right", n->right);
|
|
818
|
+
break;
|
|
819
|
+
}
|
|
820
|
+
case PM_OR_NODE: {
|
|
821
|
+
pm_or_node_t *n = (pm_or_node_t *)node;
|
|
822
|
+
N("OrNode");
|
|
823
|
+
R("left", n->left);
|
|
824
|
+
R("right", n->right);
|
|
825
|
+
break;
|
|
826
|
+
}
|
|
827
|
+
case PM_DEFINED_NODE: {
|
|
828
|
+
pm_defined_node_t *n = (pm_defined_node_t *)node;
|
|
829
|
+
N("DefinedNode");
|
|
830
|
+
R("value", n->value);
|
|
831
|
+
break;
|
|
832
|
+
}
|
|
833
|
+
case PM_SOURCE_LINE_NODE: {
|
|
834
|
+
N("SourceLineNode");
|
|
835
|
+
int32_t line = pm_newline_list_line(&g_parser->newline_list, node->location.start, g_parser->start_line);
|
|
836
|
+
I("start_line", (long long)line);
|
|
837
|
+
break;
|
|
838
|
+
}
|
|
839
|
+
case PM_SOURCE_FILE_NODE: {
|
|
840
|
+
/* `__FILE__`. Spinel inlines `require`/`require_relative` at parse
|
|
841
|
+
time so we cannot recover the per-call-site source file; we
|
|
842
|
+
always return the toplevel script path passed to spinel_parse,
|
|
843
|
+
documented in test/source_file.rb. The escaped form is cached
|
|
844
|
+
in g_source_file_escaped at init since it never changes. */
|
|
845
|
+
N("SourceFileNode");
|
|
846
|
+
emit_str(id, "content", g_source_file_escaped);
|
|
847
|
+
break;
|
|
848
|
+
}
|
|
849
|
+
case PM_SOURCE_ENCODING_NODE: {
|
|
850
|
+
/* `__ENCODING__`. CRuby returns an Encoding object; Spinel has
|
|
851
|
+
no Encoding runtime, so we return the canonical name as a
|
|
852
|
+
frozen string. All Spinel sources are UTF-8. */
|
|
853
|
+
N("SourceEncodingNode");
|
|
854
|
+
break;
|
|
855
|
+
}
|
|
856
|
+
case PM_IMPLICIT_NODE: {
|
|
857
|
+
/* Wraps an implicit value reference, e.g. the value side of a
|
|
858
|
+
hash-shorthand `{x:}`. Lowers to its inner value at the same
|
|
859
|
+
id slot so the codegen never sees the implicit wrapper. Covers
|
|
860
|
+
PM_IMPLICIT_NODE in any context (AssocNode value, kwarg
|
|
861
|
+
shorthand inside KeywordHashNode, future Prism evolutions). */
|
|
862
|
+
pm_implicit_node_t *n = (pm_implicit_node_t *)node;
|
|
863
|
+
node_counter--;
|
|
864
|
+
return flatten(n->value);
|
|
865
|
+
}
|
|
866
|
+
case PM_MISSING_NODE: {
|
|
867
|
+
/* Prism emits MissingNode as an error-recovery placeholder. main()
|
|
868
|
+
bails out before flatten() runs when parser.error_list is
|
|
869
|
+
non-empty, so reaching this case means Prism produced a
|
|
870
|
+
MissingNode without flagging an error -- a contract violation we
|
|
871
|
+
surface clearly rather than silently miscompile. */
|
|
872
|
+
fprintf(stderr, "spinel_parse: internal error: MissingNode reached flatten() at byte offset %td; parse error not in error_list\n",
|
|
873
|
+
node->location.start - g_parser->start);
|
|
874
|
+
exit(1);
|
|
875
|
+
}
|
|
876
|
+
case PM_SHAREABLE_CONSTANT_NODE: {
|
|
877
|
+
/* `# shareable_constant_value: literal` magic comment that wraps
|
|
878
|
+
a constant write. Spinel has no Ractor support, so the
|
|
879
|
+
shareability state is a no-op. We lower at parse time by
|
|
880
|
+
flattening the inner write directly into THIS node slot and
|
|
881
|
+
discarding the wrapper. Many later codegen scanner passes
|
|
882
|
+
look for ConstantWriteNode at the top level of statements;
|
|
883
|
+
lowering here lets all of them work without modification. */
|
|
884
|
+
pm_shareable_constant_node_t *n = (pm_shareable_constant_node_t *)node;
|
|
885
|
+
/* Re-flatten the inner write at *this* id by rewinding the counter. */
|
|
886
|
+
node_counter--;
|
|
887
|
+
return flatten(n->write);
|
|
888
|
+
}
|
|
889
|
+
case PM_SPLAT_NODE: {
|
|
890
|
+
pm_splat_node_t *n = (pm_splat_node_t *)node;
|
|
891
|
+
N("SplatNode");
|
|
892
|
+
R("expression", n->expression);
|
|
893
|
+
break;
|
|
894
|
+
}
|
|
895
|
+
case PM_SUPER_NODE: {
|
|
896
|
+
pm_super_node_t *n = (pm_super_node_t *)node;
|
|
897
|
+
N("SuperNode");
|
|
898
|
+
R("arguments", n->arguments);
|
|
899
|
+
break;
|
|
900
|
+
}
|
|
901
|
+
case PM_FORWARDING_SUPER_NODE:
|
|
902
|
+
N("ForwardingSuperNode");
|
|
903
|
+
break;
|
|
904
|
+
case PM_MULTI_WRITE_NODE: {
|
|
905
|
+
pm_multi_write_node_t *n = (pm_multi_write_node_t *)node;
|
|
906
|
+
N("MultiWriteNode");
|
|
907
|
+
A("lefts", &n->lefts);
|
|
908
|
+
if (n->rest) R("rest", n->rest);
|
|
909
|
+
A("rights", &n->rights);
|
|
910
|
+
R("value", n->value);
|
|
911
|
+
break;
|
|
912
|
+
}
|
|
913
|
+
case PM_IMPLICIT_REST_NODE:
|
|
914
|
+
N("ImplicitRestNode");
|
|
915
|
+
break;
|
|
916
|
+
case PM_LAMBDA_NODE: {
|
|
917
|
+
pm_lambda_node_t *n = (pm_lambda_node_t *)node;
|
|
918
|
+
N("LambdaNode");
|
|
919
|
+
if (n->parameters) {
|
|
920
|
+
if (PM_NODE_TYPE(n->parameters) == PM_BLOCK_PARAMETERS_NODE) {
|
|
921
|
+
pm_block_parameters_node_t *bp = (pm_block_parameters_node_t *)n->parameters;
|
|
922
|
+
if (bp->parameters) {
|
|
923
|
+
R("parameters", bp->parameters);
|
|
924
|
+
}
|
|
925
|
+
} else if (PM_NODE_TYPE(n->parameters) != PM_NUMBERED_PARAMETERS_NODE) {
|
|
926
|
+
R("parameters", n->parameters);
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
if (n->body) R("body", n->body);
|
|
930
|
+
break;
|
|
931
|
+
}
|
|
932
|
+
case PM_X_STRING_NODE: {
|
|
933
|
+
pm_x_string_node_t *n = (pm_x_string_node_t *)node;
|
|
934
|
+
N("XStringNode");
|
|
935
|
+
S("content", escape_pm_string(&n->unescaped));
|
|
936
|
+
break;
|
|
937
|
+
}
|
|
938
|
+
case PM_INTERPOLATED_X_STRING_NODE: {
|
|
939
|
+
pm_interpolated_x_string_node_t *n = (pm_interpolated_x_string_node_t *)node;
|
|
940
|
+
N("InterpolatedXStringNode");
|
|
941
|
+
A("parts", &n->parts);
|
|
942
|
+
break;
|
|
943
|
+
}
|
|
944
|
+
case PM_REGULAR_EXPRESSION_NODE: {
|
|
945
|
+
pm_regular_expression_node_t *n = (pm_regular_expression_node_t *)node;
|
|
946
|
+
N("RegularExpressionNode");
|
|
947
|
+
S("unescaped", escape_pm_string(&n->unescaped));
|
|
948
|
+
/* Emit Prism's regex flags so the codegen can pass /i, /x, /m
|
|
949
|
+
through to the engine. PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE=4,
|
|
950
|
+
_EXTENDED=8, _MULTI_LINE=16. */
|
|
951
|
+
I("flags", n->base.flags);
|
|
952
|
+
break;
|
|
953
|
+
}
|
|
954
|
+
case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
|
|
955
|
+
/* `/foo_#{x}/`. Same shape as InterpolatedStringNode -- carries
|
|
956
|
+
`parts` -- plus a flags integer matching RegularExpressionNode.
|
|
957
|
+
Codegen builds the pattern string via compile_interpolated and
|
|
958
|
+
feeds it to sp_re_runtime_compile at execution time. */
|
|
959
|
+
pm_interpolated_regular_expression_node_t *n = (pm_interpolated_regular_expression_node_t *)node;
|
|
960
|
+
N("InterpolatedRegularExpressionNode");
|
|
961
|
+
A("parts", &n->parts);
|
|
962
|
+
I("flags", n->base.flags);
|
|
963
|
+
break;
|
|
964
|
+
}
|
|
965
|
+
case PM_NUMBERED_REFERENCE_READ_NODE: {
|
|
966
|
+
pm_numbered_reference_read_node_t *n = (pm_numbered_reference_read_node_t *)node;
|
|
967
|
+
N("NumberedReferenceReadNode");
|
|
968
|
+
I("number", n->number);
|
|
969
|
+
break;
|
|
970
|
+
}
|
|
971
|
+
case PM_MATCH_WRITE_NODE: {
|
|
972
|
+
pm_match_write_node_t *n = (pm_match_write_node_t *)node;
|
|
973
|
+
N("MatchWriteNode");
|
|
974
|
+
R("call", n->call);
|
|
975
|
+
break;
|
|
976
|
+
}
|
|
977
|
+
case PM_MATCH_REQUIRED_NODE: {
|
|
978
|
+
/* Rightward assignment: `expr => var` (Ruby 3.0+). When the
|
|
979
|
+
pattern is a single LocalVariableTargetNode, this is just
|
|
980
|
+
`var = expr` and we lower it to a LocalVariableWriteNode so
|
|
981
|
+
the codegen reuses the regular assignment path. Full pattern
|
|
982
|
+
matching (array / hash patterns, pinned vars) is out of scope
|
|
983
|
+
and falls through to the unknown-node passthrough. */
|
|
984
|
+
pm_match_required_node_t *n = (pm_match_required_node_t *)node;
|
|
985
|
+
if (n->pattern && PM_NODE_TYPE_P(n->pattern, PM_LOCAL_VARIABLE_TARGET_NODE)) {
|
|
986
|
+
pm_local_variable_target_node_t *t = (pm_local_variable_target_node_t *)n->pattern;
|
|
987
|
+
N("LocalVariableWriteNode");
|
|
988
|
+
NAME("name", t->name);
|
|
989
|
+
R("value", n->value);
|
|
990
|
+
} else {
|
|
991
|
+
N("MatchRequiredNode");
|
|
992
|
+
R("value", n->value);
|
|
993
|
+
R("pattern", n->pattern);
|
|
994
|
+
}
|
|
995
|
+
break;
|
|
996
|
+
}
|
|
997
|
+
case PM_ALTERNATION_PATTERN_NODE: {
|
|
998
|
+
pm_alternation_pattern_node_t *n = (pm_alternation_pattern_node_t *)node;
|
|
999
|
+
N("AlternationPatternNode");
|
|
1000
|
+
R("left", n->left);
|
|
1001
|
+
R("right", n->right);
|
|
1002
|
+
break;
|
|
1003
|
+
}
|
|
1004
|
+
case PM_NUMBERED_PARAMETERS_NODE: {
|
|
1005
|
+
pm_numbered_parameters_node_t *n = (pm_numbered_parameters_node_t *)node;
|
|
1006
|
+
N("NumberedParametersNode");
|
|
1007
|
+
I("maximum", n->maximum);
|
|
1008
|
+
break;
|
|
1009
|
+
}
|
|
1010
|
+
case PM_ARGUMENTS_NODE: {
|
|
1011
|
+
pm_arguments_node_t *n = (pm_arguments_node_t *)node;
|
|
1012
|
+
N("ArgumentsNode");
|
|
1013
|
+
A("arguments", &n->arguments);
|
|
1014
|
+
break;
|
|
1015
|
+
}
|
|
1016
|
+
case PM_BLOCK_PARAMETERS_NODE: {
|
|
1017
|
+
pm_block_parameters_node_t *n = (pm_block_parameters_node_t *)node;
|
|
1018
|
+
N("BlockParametersNode");
|
|
1019
|
+
if (n->parameters) R("parameters", n->parameters);
|
|
1020
|
+
break;
|
|
1021
|
+
}
|
|
1022
|
+
case PM_IT_PARAMETERS_NODE:
|
|
1023
|
+
/* Ruby 3.4 implicit `it` is semantically `_1` — lower to a
|
|
1024
|
+
NumberedParametersNode so the codegen's existing
|
|
1025
|
+
NumberedParametersNode arity path (get_block_param) handles it
|
|
1026
|
+
transparently. The block body's `it` references separately
|
|
1027
|
+
become PM_IT_LOCAL_VARIABLE_READ_NODE, also lowered below. */
|
|
1028
|
+
N("NumberedParametersNode");
|
|
1029
|
+
I("maximum", 1);
|
|
1030
|
+
break;
|
|
1031
|
+
case PM_IT_LOCAL_VARIABLE_READ_NODE:
|
|
1032
|
+
/* `it` inside the block body. Lowered to a regular
|
|
1033
|
+
LocalVariableReadNode named "_1" so it pairs with the
|
|
1034
|
+
lowered NumberedParametersNode { maximum: 1 } above. */
|
|
1035
|
+
N("LocalVariableReadNode");
|
|
1036
|
+
S("name", escape_str((const uint8_t *)"_1", 2));
|
|
1037
|
+
break;
|
|
1038
|
+
case PM_INTERPOLATED_SYMBOL_NODE: {
|
|
1039
|
+
/* `:"foo_#{x}"`. Carries `parts` like InterpolatedStringNode;
|
|
1040
|
+
codegen builds the string the same way and uses it directly --
|
|
1041
|
+
Spinel treats dynamic symbols as their assembled string value
|
|
1042
|
+
since it doesn't intern non-literal symbols. */
|
|
1043
|
+
pm_interpolated_symbol_node_t *n = (pm_interpolated_symbol_node_t *)node;
|
|
1044
|
+
N("InterpolatedSymbolNode");
|
|
1045
|
+
A("parts", &n->parts);
|
|
1046
|
+
break;
|
|
1047
|
+
}
|
|
1048
|
+
case PM_REDO_NODE:
|
|
1049
|
+
/* `redo`. Re-run the current iteration of the enclosing loop
|
|
1050
|
+
without re-evaluating the loop guard or advancing the
|
|
1051
|
+
iterator. Codegen emits a labeled `goto` to a label installed
|
|
1052
|
+
at the top of the iteration body. */
|
|
1053
|
+
N("RedoNode");
|
|
1054
|
+
break;
|
|
1055
|
+
case PM_BACK_REFERENCE_READ_NODE: {
|
|
1056
|
+
/* `$&`, `$~`, `$'`, $`. Spinel populates sp_re_match_str / _pre /
|
|
1057
|
+
_post during regex matches alongside sp_re_captures (which the
|
|
1058
|
+
NumberedReferenceReadNode arm already reads). */
|
|
1059
|
+
pm_back_reference_read_node_t *n = (pm_back_reference_read_node_t *)node;
|
|
1060
|
+
N("BackReferenceReadNode");
|
|
1061
|
+
NAME("name", n->name);
|
|
1062
|
+
break;
|
|
1063
|
+
}
|
|
1064
|
+
case PM_MULTI_TARGET_NODE: {
|
|
1065
|
+
/* Nested LHS in destructuring multi-assign:
|
|
1066
|
+
`a, (b, c), d = 1, [2, 3], 4`. The inner (b, c) parenthesized
|
|
1067
|
+
group becomes a MultiTargetNode that recursively unpacks its
|
|
1068
|
+
slot of the RHS into the inner targets. */
|
|
1069
|
+
pm_multi_target_node_t *n = (pm_multi_target_node_t *)node;
|
|
1070
|
+
N("MultiTargetNode");
|
|
1071
|
+
A("lefts", &n->lefts);
|
|
1072
|
+
if (n->rest) R("rest", n->rest);
|
|
1073
|
+
A("rights", &n->rights);
|
|
1074
|
+
break;
|
|
1075
|
+
}
|
|
1076
|
+
case PM_EMBEDDED_VARIABLE_NODE: {
|
|
1077
|
+
/* `"foo #@bar"` shorthand for `"foo #{@bar}"`. The cleanest
|
|
1078
|
+
implementation is parser-side lowering: synthesize an
|
|
1079
|
+
EmbeddedStatementsNode wrapping a StatementsNode whose single
|
|
1080
|
+
body element is the variable read. The existing interpolation
|
|
1081
|
+
path then handles it without any codegen change.
|
|
1082
|
+
|
|
1083
|
+
Same lowering trick as PM_IT_LOCAL_VARIABLE_READ_NODE -- emit
|
|
1084
|
+
a different node type at the same `id` slot so parent walks
|
|
1085
|
+
(parts list of the surrounding InterpolatedString) keep the
|
|
1086
|
+
slot unchanged. The wrapped StatementsNode gets a fresh id
|
|
1087
|
+
allocated via node_counter++. */
|
|
1088
|
+
pm_embedded_variable_node_t *n = (pm_embedded_variable_node_t *)node;
|
|
1089
|
+
N("EmbeddedStatementsNode");
|
|
1090
|
+
int var_id = flatten(n->variable);
|
|
1091
|
+
int stmts_id = node_counter++;
|
|
1092
|
+
out_add("N %d StatementsNode", stmts_id);
|
|
1093
|
+
out_add("A %d body %d", stmts_id, var_id);
|
|
1094
|
+
out_add("R %d statements %d", id, stmts_id);
|
|
1095
|
+
break;
|
|
1096
|
+
}
|
|
1097
|
+
case PM_ALIAS_METHOD_NODE: {
|
|
1098
|
+
/* `alias new old` -- compile-time method-name aliasing inside a
|
|
1099
|
+
class body. new_name and old_name are nodes representing the
|
|
1100
|
+
names (typically SymbolNode literals; InterpolatedSymbolNode is
|
|
1101
|
+
tolerated and silently skipped by the codegen helper). Spinel
|
|
1102
|
+
registers a duplicate method-table entry under the new name
|
|
1103
|
+
pointing to the same body, so dispatch on `.greet` lands on the
|
|
1104
|
+
same C function as `.hello`. */
|
|
1105
|
+
pm_alias_method_node_t *n = (pm_alias_method_node_t *)node;
|
|
1106
|
+
N("AliasMethodNode");
|
|
1107
|
+
R("new_name", n->new_name);
|
|
1108
|
+
R("old_name", n->old_name);
|
|
1109
|
+
break;
|
|
1110
|
+
}
|
|
1111
|
+
case PM_POST_EXECUTION_NODE: {
|
|
1112
|
+
/* `END { ... }`. CRuby runs END blocks in REVERSE registration
|
|
1113
|
+
order at program exit. Spinel emits each as a static C
|
|
1114
|
+
function and registers them via atexit() at main() startup --
|
|
1115
|
+
atexit naturally invokes handlers LIFO, matching CRuby. */
|
|
1116
|
+
pm_post_execution_node_t *n = (pm_post_execution_node_t *)node;
|
|
1117
|
+
N("PostExecutionNode");
|
|
1118
|
+
R("statements", n->statements);
|
|
1119
|
+
break;
|
|
1120
|
+
}
|
|
1121
|
+
case PM_PRE_EXECUTION_NODE: {
|
|
1122
|
+
/* `BEGIN { ... }`. CRuby runs all BEGIN blocks in source order
|
|
1123
|
+
BEFORE any other top-level statements. Spinel collects the
|
|
1124
|
+
bodies during a pre-pass and emits them at the very top of
|
|
1125
|
+
main() in source-encounter order. */
|
|
1126
|
+
pm_pre_execution_node_t *n = (pm_pre_execution_node_t *)node;
|
|
1127
|
+
N("PreExecutionNode");
|
|
1128
|
+
R("statements", n->statements);
|
|
1129
|
+
break;
|
|
1130
|
+
}
|
|
1131
|
+
case PM_UNDEF_NODE: {
|
|
1132
|
+
/* `undef foo, bar` inside a class body. CRuby raises NoMethodError
|
|
1133
|
+
at runtime when an undef'd method is called; Spinel's AOT model
|
|
1134
|
+
resolves dispatch at compile time, so we record the undefs but
|
|
1135
|
+
leave compile-time enforcement of "calling an undef'd method
|
|
1136
|
+
fails" to a future pass. */
|
|
1137
|
+
pm_undef_node_t *n = (pm_undef_node_t *)node;
|
|
1138
|
+
N("UndefNode");
|
|
1139
|
+
A("names", &n->names);
|
|
1140
|
+
break;
|
|
1141
|
+
}
|
|
1142
|
+
case PM_ALIAS_GLOBAL_VARIABLE_NODE: {
|
|
1143
|
+
/* `alias $copy $orig` -- compile-time gvar aliasing. The
|
|
1144
|
+
new_name and old_name slots are GlobalVariableReadNodes whose
|
|
1145
|
+
`name` field carries the literal $-prefixed name. Spinel
|
|
1146
|
+
resolves $copy to $orig everywhere the alias is in scope, so
|
|
1147
|
+
the C output uses one storage slot for both. */
|
|
1148
|
+
pm_alias_global_variable_node_t *n = (pm_alias_global_variable_node_t *)node;
|
|
1149
|
+
N("AliasGlobalVariableNode");
|
|
1150
|
+
R("new_name", n->new_name);
|
|
1151
|
+
R("old_name", n->old_name);
|
|
1152
|
+
break;
|
|
1153
|
+
}
|
|
1154
|
+
default: {
|
|
1155
|
+
/* Previously emitted UnknownNode_<n> which silently degraded to
|
|
1156
|
+
"0" in codegen. Now emit a hard-error sentinel carrying the
|
|
1157
|
+
Prism node kind name (in human-friendly Ruby vocabulary) + the
|
|
1158
|
+
source line so codegen refuses to compile and tells the user
|
|
1159
|
+
exactly what's wrong. */
|
|
1160
|
+
char pretty[128];
|
|
1161
|
+
size_t plen = prism_kind_to_pascal(pm_node_type_to_str(t), pretty, sizeof(pretty));
|
|
1162
|
+
int32_t line = pm_newline_list_line(&g_parser->newline_list, node->location.start, g_parser->start_line);
|
|
1163
|
+
|
|
1164
|
+
N("UnsupportedNode");
|
|
1165
|
+
char *kind_e = escape_str((const uint8_t *)pretty, plen);
|
|
1166
|
+
emit_str(id, "kind", kind_e);
|
|
1167
|
+
free(kind_e);
|
|
1168
|
+
emit_int(id, "source_line", (long long)line);
|
|
1169
|
+
break;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
#undef N
|
|
1174
|
+
#undef S
|
|
1175
|
+
#undef I
|
|
1176
|
+
#undef F
|
|
1177
|
+
#undef R
|
|
1178
|
+
#undef A
|
|
1179
|
+
#undef NAME
|
|
1180
|
+
|
|
1181
|
+
return id;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
/* ---- require_relative resolution ---- */
|
|
1185
|
+
static char *read_file(const char *path) {
|
|
1186
|
+
FILE *f = fopen(path, "rb");
|
|
1187
|
+
if (!f) return NULL;
|
|
1188
|
+
fseek(f, 0, SEEK_END);
|
|
1189
|
+
long len = ftell(f);
|
|
1190
|
+
fseek(f, 0, SEEK_SET);
|
|
1191
|
+
char *buf = malloc(len + 1);
|
|
1192
|
+
size_t nread = fread(buf, 1, len, f);
|
|
1193
|
+
buf[nread] = '\0';
|
|
1194
|
+
fclose(f);
|
|
1195
|
+
return buf;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
/* Track files already inlined so duplicate requires/require_relatives in
|
|
1199
|
+
different files don't re-emit (and re-define structs/classes) the same
|
|
1200
|
+
content. Dynamic so we don't silently drop entries on large projects. */
|
|
1201
|
+
static char **sp_included_paths = NULL;
|
|
1202
|
+
static int sp_included_count = 0;
|
|
1203
|
+
static int sp_included_cap = 0;
|
|
1204
|
+
|
|
1205
|
+
/* Resolve a path to its canonical form for dedup. realpath() returns NULL
|
|
1206
|
+
on missing files; in that case fall back to the literal path. */
|
|
1207
|
+
static char *sp_canonical_path(const char *path) {
|
|
1208
|
+
#ifdef _WIN32
|
|
1209
|
+
char *real = _fullpath(NULL, path, 0);
|
|
1210
|
+
#else
|
|
1211
|
+
char *real = realpath(path, NULL);
|
|
1212
|
+
#endif
|
|
1213
|
+
return real ? real : strdup(path);
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
static int sp_path_already_included(const char *canonical) {
|
|
1217
|
+
for (int i = 0; i < sp_included_count; i++) {
|
|
1218
|
+
if (strcmp(sp_included_paths[i], canonical) == 0) return 1;
|
|
1219
|
+
}
|
|
1220
|
+
return 0;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
static void sp_mark_path_included(const char *canonical) {
|
|
1224
|
+
if (sp_included_count >= sp_included_cap) {
|
|
1225
|
+
sp_included_cap = sp_included_cap == 0 ? 16 : sp_included_cap * 2;
|
|
1226
|
+
sp_included_paths = (char **)realloc(sp_included_paths,
|
|
1227
|
+
sizeof(char *) * sp_included_cap);
|
|
1228
|
+
}
|
|
1229
|
+
sp_included_paths[sp_included_count++] = strdup(canonical);
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
/* Free the included-paths table at end of run. The process is short-lived,
|
|
1233
|
+
so this matters mostly for tools (leak checkers, embedders) that
|
|
1234
|
+
scrutinise end-of-run state. */
|
|
1235
|
+
static void sp_includes_free(void) {
|
|
1236
|
+
for (int i = 0; i < sp_included_count; i++) {
|
|
1237
|
+
free(sp_included_paths[i]);
|
|
1238
|
+
}
|
|
1239
|
+
free(sp_included_paths);
|
|
1240
|
+
sp_included_paths = NULL;
|
|
1241
|
+
sp_included_count = 0;
|
|
1242
|
+
sp_included_cap = 0;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
/* Simple require_relative resolver: replace lines matching
|
|
1246
|
+
require_relative "path" with the file content. Files that have
|
|
1247
|
+
already been included once are silently skipped on subsequent
|
|
1248
|
+
requires (matching Ruby's load-once semantics). */
|
|
1249
|
+
static char *resolve_requires(const char *source, const char *source_path) {
|
|
1250
|
+
/* Get base directory */
|
|
1251
|
+
char *path_copy = strdup(source_path);
|
|
1252
|
+
char *dir = strdup(path_copy);
|
|
1253
|
+
/* Find last / */
|
|
1254
|
+
char *slash = strrchr(dir, '/');
|
|
1255
|
+
if (slash) *slash = '\0';
|
|
1256
|
+
else { free(dir); dir = strdup("."); }
|
|
1257
|
+
free(path_copy);
|
|
1258
|
+
|
|
1259
|
+
char *result = strdup(source);
|
|
1260
|
+
char *pos;
|
|
1261
|
+
char *scan_from = result;
|
|
1262
|
+
while ((pos = strstr(scan_from, "require_relative")) != NULL) {
|
|
1263
|
+
/* Check it's at start of line. If the match is mid-line (e.g.
|
|
1264
|
+
the word appears in a comment or string), advance past it and
|
|
1265
|
+
keep scanning the rest of the file — don't abort the whole
|
|
1266
|
+
loop, since later lines may have legitimate require_relative
|
|
1267
|
+
statements. */
|
|
1268
|
+
if (pos != result && *(pos - 1) != '\n') {
|
|
1269
|
+
scan_from = pos + 1;
|
|
1270
|
+
continue;
|
|
1271
|
+
}
|
|
1272
|
+
char *line_end = strchr(pos, '\n');
|
|
1273
|
+
if (!line_end) line_end = pos + strlen(pos);
|
|
1274
|
+
|
|
1275
|
+
/* Extract quoted path */
|
|
1276
|
+
char *q1 = strchr(pos, '"');
|
|
1277
|
+
char *q2 = strchr(pos, '\'');
|
|
1278
|
+
char quote_char;
|
|
1279
|
+
char *start;
|
|
1280
|
+
if (q1 && q1 < line_end && (!q2 || q1 < q2)) {
|
|
1281
|
+
quote_char = '"';
|
|
1282
|
+
start = q1 + 1;
|
|
1283
|
+
} else if (q2 && q2 < line_end) {
|
|
1284
|
+
quote_char = '\'';
|
|
1285
|
+
start = q2 + 1;
|
|
1286
|
+
} else { scan_from = pos + 1; continue; }
|
|
1287
|
+
|
|
1288
|
+
char *end = strchr(start, quote_char);
|
|
1289
|
+
if (!end || end > line_end) { scan_from = pos + 1; continue; }
|
|
1290
|
+
|
|
1291
|
+
size_t path_len = end - start;
|
|
1292
|
+
char rel_path[512];
|
|
1293
|
+
snprintf(rel_path, sizeof(rel_path), "%.*s", (int)path_len, start);
|
|
1294
|
+
|
|
1295
|
+
/* Build full path */
|
|
1296
|
+
char full_path[1024];
|
|
1297
|
+
snprintf(full_path, sizeof(full_path), "%s/%s", dir, rel_path);
|
|
1298
|
+
{
|
|
1299
|
+
size_t fl = strlen(full_path);
|
|
1300
|
+
if (fl < sizeof(full_path) - 4 && (fl < 3 || strcmp(full_path + fl - 3, ".rb") != 0))
|
|
1301
|
+
strcat(full_path, ".rb");
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
char *canonical = sp_canonical_path(full_path);
|
|
1305
|
+
char *content;
|
|
1306
|
+
if (sp_path_already_included(canonical)) {
|
|
1307
|
+
/* Already inlined once -- replace require with empty content */
|
|
1308
|
+
content = strdup("# require_relative skipped (already included)");
|
|
1309
|
+
free(canonical);
|
|
1310
|
+
} else {
|
|
1311
|
+
sp_mark_path_included(canonical);
|
|
1312
|
+
content = read_file(full_path);
|
|
1313
|
+
if (!content) {
|
|
1314
|
+
content = strdup("# require_relative not found");
|
|
1315
|
+
} else {
|
|
1316
|
+
/* Recursively resolve */
|
|
1317
|
+
char *resolved = resolve_requires(content, full_path);
|
|
1318
|
+
free(content);
|
|
1319
|
+
content = resolved;
|
|
1320
|
+
}
|
|
1321
|
+
free(canonical);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
/* Replace the line */
|
|
1325
|
+
size_t line_len = (line_end - pos) + ((*line_end == '\n') ? 1 : 0);
|
|
1326
|
+
size_t content_len = strlen(content);
|
|
1327
|
+
size_t result_len = strlen(result);
|
|
1328
|
+
size_t before_len = pos - result;
|
|
1329
|
+
|
|
1330
|
+
char *new_result = malloc(result_len - line_len + content_len + 2);
|
|
1331
|
+
memcpy(new_result, result, before_len);
|
|
1332
|
+
memcpy(new_result + before_len, content, content_len);
|
|
1333
|
+
if (content_len > 0 && content[content_len - 1] != '\n')
|
|
1334
|
+
new_result[before_len + content_len++] = '\n';
|
|
1335
|
+
memcpy(new_result + before_len + content_len, pos + line_len, result_len - before_len - line_len + 1);
|
|
1336
|
+
|
|
1337
|
+
free(result);
|
|
1338
|
+
result = new_result;
|
|
1339
|
+
/* Buffer reallocated; restart scan from the top of the new buffer. */
|
|
1340
|
+
scan_from = result;
|
|
1341
|
+
free(content);
|
|
1342
|
+
}
|
|
1343
|
+
free(dir);
|
|
1344
|
+
return result;
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
/* ---- Plain require resolution ---- */
|
|
1348
|
+
static char *resolve_plain_requires(char *source, const char *exe_path) {
|
|
1349
|
+
/* Find lib/ directory relative to this executable */
|
|
1350
|
+
char lib_dir[1024];
|
|
1351
|
+
strncpy(lib_dir, exe_path, sizeof(lib_dir) - 1);
|
|
1352
|
+
char *slash = strrchr(lib_dir, '/');
|
|
1353
|
+
if (slash) *slash = '\0';
|
|
1354
|
+
else strcpy(lib_dir, ".");
|
|
1355
|
+
strcat(lib_dir, "/lib");
|
|
1356
|
+
|
|
1357
|
+
char *result = source;
|
|
1358
|
+
char *pos;
|
|
1359
|
+
while ((pos = strstr(result, "\nrequire ")) != NULL ||
|
|
1360
|
+
(pos == NULL && result == source && strncmp(result, "require ", 8) == 0 && (pos = result))) {
|
|
1361
|
+
if (pos != result) pos++; /* skip \n */
|
|
1362
|
+
if (pos != result && *(pos - 1) != '\n') break;
|
|
1363
|
+
char *line_end = strchr(pos, '\n');
|
|
1364
|
+
if (!line_end) line_end = pos + strlen(pos);
|
|
1365
|
+
|
|
1366
|
+
/* Must be: require "name" or require 'name' */
|
|
1367
|
+
char *q1 = strchr(pos + 7, '"');
|
|
1368
|
+
char *q2 = strchr(pos + 7, '\'');
|
|
1369
|
+
char *start; char quote_char;
|
|
1370
|
+
if (q1 && q1 < line_end && (!q2 || q1 < q2)) { quote_char = '"'; start = q1 + 1; }
|
|
1371
|
+
else if (q2 && q2 < line_end) { quote_char = '\''; start = q2 + 1; }
|
|
1372
|
+
else break;
|
|
1373
|
+
char *end = strchr(start, quote_char);
|
|
1374
|
+
if (!end || end > line_end) break;
|
|
1375
|
+
|
|
1376
|
+
char lib_name[256];
|
|
1377
|
+
snprintf(lib_name, sizeof(lib_name), "%.*s", (int)(end - start), start);
|
|
1378
|
+
char lib_path[1024];
|
|
1379
|
+
snprintf(lib_path, sizeof(lib_path), "%s/%s", lib_dir, lib_name);
|
|
1380
|
+
{
|
|
1381
|
+
size_t fl = strlen(lib_path);
|
|
1382
|
+
if (fl < sizeof(lib_path) - 4 && (fl < 3 || strcmp(lib_path + fl - 3, ".rb") != 0))
|
|
1383
|
+
strcat(lib_path, ".rb");
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
/* Same dedup as resolve_requires: a file pulled in via plain `require`
|
|
1387
|
+
must not be re-inlined if a previous `require` or `require_relative`
|
|
1388
|
+
already pulled it. Otherwise mixing the two forms for the same lib
|
|
1389
|
+
still produces struct-redefinition errors. */
|
|
1390
|
+
char *canonical = sp_canonical_path(lib_path);
|
|
1391
|
+
char *content;
|
|
1392
|
+
if (sp_path_already_included(canonical)) {
|
|
1393
|
+
content = strdup("# require skipped (already included)");
|
|
1394
|
+
free(canonical);
|
|
1395
|
+
} else {
|
|
1396
|
+
sp_mark_path_included(canonical);
|
|
1397
|
+
free(canonical);
|
|
1398
|
+
content = read_file(lib_path);
|
|
1399
|
+
if (!content) {
|
|
1400
|
+
content = strdup("# require not resolved");
|
|
1401
|
+
} else {
|
|
1402
|
+
char *resolved = resolve_requires(content, lib_path);
|
|
1403
|
+
free(content);
|
|
1404
|
+
content = resolved;
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
size_t line_len = (line_end - pos) + ((*line_end == '\n') ? 1 : 0);
|
|
1409
|
+
size_t content_len = strlen(content);
|
|
1410
|
+
size_t result_len = strlen(result);
|
|
1411
|
+
size_t before_len = pos - result;
|
|
1412
|
+
char *new_result = malloc(result_len - line_len + content_len + 2);
|
|
1413
|
+
memcpy(new_result, result, before_len);
|
|
1414
|
+
memcpy(new_result + before_len, content, content_len);
|
|
1415
|
+
if (content_len > 0 && content[content_len - 1] != '\n')
|
|
1416
|
+
new_result[before_len + content_len++] = '\n';
|
|
1417
|
+
memcpy(new_result + before_len + content_len, pos + line_len, result_len - before_len - line_len + 1);
|
|
1418
|
+
free(result);
|
|
1419
|
+
result = new_result;
|
|
1420
|
+
free(content);
|
|
1421
|
+
}
|
|
1422
|
+
return result;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
/* ---- Syntax sugar rewriting ---- */
|
|
1426
|
+
static char *rewrite_syntax_sugar(char *source) {
|
|
1427
|
+
/* Rewrite .send(:method, args) → .method(args) */
|
|
1428
|
+
/* Rewrite &:symbol → { |_spx| _spx.symbol } */
|
|
1429
|
+
size_t len = strlen(source);
|
|
1430
|
+
size_t cap = len * 2 + 256;
|
|
1431
|
+
char *out = malloc(cap);
|
|
1432
|
+
size_t oi = 0;
|
|
1433
|
+
size_t i = 0;
|
|
1434
|
+
|
|
1435
|
+
#define OUT_CHAR(c) do { if (oi >= cap - 1) { cap *= 2; out = realloc(out, cap); } out[oi++] = (c); } while(0)
|
|
1436
|
+
#define OUT_STR(s) do { const char *_s = (s); while (*_s) { OUT_CHAR(*_s); _s++; } } while(0)
|
|
1437
|
+
|
|
1438
|
+
while (i < len) {
|
|
1439
|
+
/* .send(:symbol ...) */
|
|
1440
|
+
if (i + 7 < len && strncmp(source + i, ".send(:", 7) == 0) {
|
|
1441
|
+
i += 7; /* skip .send(: */
|
|
1442
|
+
/* Extract method name */
|
|
1443
|
+
size_t ns = i;
|
|
1444
|
+
while (i < len && (source[i] == '_' || (source[i] >= 'a' && source[i] <= 'z') ||
|
|
1445
|
+
(source[i] >= 'A' && source[i] <= 'Z') || (source[i] >= '0' && source[i] <= '9') ||
|
|
1446
|
+
source[i] == '?' || source[i] == '!' || source[i] == '+' || source[i] == '-' ||
|
|
1447
|
+
source[i] == '*' || source[i] == '/' || source[i] == '<' || source[i] == '>' ||
|
|
1448
|
+
source[i] == '=' || source[i] == '&' || source[i] == '|' || source[i] == '^' ||
|
|
1449
|
+
source[i] == '~' || source[i] == '%')) i++;
|
|
1450
|
+
size_t name_len = i - ns;
|
|
1451
|
+
if (name_len > 0) {
|
|
1452
|
+
OUT_CHAR('.');
|
|
1453
|
+
size_t k; for (k = 0; k < name_len; k++) OUT_CHAR(source[ns + k]);
|
|
1454
|
+
/* Skip optional comma + space, then copy remaining args until ) */
|
|
1455
|
+
if (i < len && source[i] == ')') {
|
|
1456
|
+
i++; /* no args */
|
|
1457
|
+
} else if (i < len && source[i] == ',') {
|
|
1458
|
+
i++; /* skip comma */
|
|
1459
|
+
while (i < len && source[i] == ' ') i++;
|
|
1460
|
+
OUT_CHAR('(');
|
|
1461
|
+
/* Copy args until matching ) */
|
|
1462
|
+
int depth = 1;
|
|
1463
|
+
while (i < len && depth > 0) {
|
|
1464
|
+
if (source[i] == '(') depth++;
|
|
1465
|
+
else if (source[i] == ')') { depth--; if (depth == 0) { i++; break; } }
|
|
1466
|
+
OUT_CHAR(source[i]); i++;
|
|
1467
|
+
}
|
|
1468
|
+
OUT_CHAR(')');
|
|
1469
|
+
}
|
|
1470
|
+
continue;
|
|
1471
|
+
}
|
|
1472
|
+
/* Failed to parse, output original */
|
|
1473
|
+
OUT_STR(".send(:");
|
|
1474
|
+
continue;
|
|
1475
|
+
}
|
|
1476
|
+
/* (&:symbol) → { |_spx| _spx.symbol } — also remove enclosing parens */
|
|
1477
|
+
if (i + 2 < len && source[i] == '&' && source[i + 1] == ':') {
|
|
1478
|
+
/* Check if preceded by ( and remove it */
|
|
1479
|
+
int had_paren = 0;
|
|
1480
|
+
if (oi > 0 && out[oi - 1] == '(') { oi--; had_paren = 1; }
|
|
1481
|
+
i += 2;
|
|
1482
|
+
size_t ns = i;
|
|
1483
|
+
while (i < len && (source[i] == '_' || (source[i] >= 'a' && source[i] <= 'z') ||
|
|
1484
|
+
(source[i] >= 'A' && source[i] <= 'Z') || (source[i] >= '0' && source[i] <= '9') ||
|
|
1485
|
+
source[i] == '?' || source[i] == '!')) i++;
|
|
1486
|
+
size_t name_len = i - ns;
|
|
1487
|
+
if (name_len > 0) {
|
|
1488
|
+
/* Skip closing paren if we removed opening */
|
|
1489
|
+
if (had_paren && i < len && source[i] == ')') i++;
|
|
1490
|
+
OUT_STR(" { |_spx| _spx.");
|
|
1491
|
+
size_t k; for (k = 0; k < name_len; k++) OUT_CHAR(source[ns + k]);
|
|
1492
|
+
OUT_STR(" }");
|
|
1493
|
+
continue;
|
|
1494
|
+
}
|
|
1495
|
+
if (had_paren) OUT_CHAR('('); /* restore if failed */
|
|
1496
|
+
OUT_STR("&:");
|
|
1497
|
+
continue;
|
|
1498
|
+
}
|
|
1499
|
+
OUT_CHAR(source[i]);
|
|
1500
|
+
i++;
|
|
1501
|
+
}
|
|
1502
|
+
out[oi] = '\0';
|
|
1503
|
+
free(source);
|
|
1504
|
+
return out;
|
|
1505
|
+
#undef OUT_CHAR
|
|
1506
|
+
#undef OUT_STR
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
/* ---- Main ---- */
|
|
1510
|
+
int main(int argc, char **argv) {
|
|
1511
|
+
if (argc < 2) {
|
|
1512
|
+
fprintf(stderr, "Usage: spinel_parse input.rb [output.ast]\n");
|
|
1513
|
+
return 1;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
const char *source_file = argv[1];
|
|
1517
|
+
char *source = read_file(source_file);
|
|
1518
|
+
if (!source) {
|
|
1519
|
+
fprintf(stderr, "spinel_parse: cannot open '%s'\n", source_file);
|
|
1520
|
+
return 1;
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
/* Resolve require_relative and plain require */
|
|
1524
|
+
char *resolved = resolve_requires(source, source_file);
|
|
1525
|
+
free(source);
|
|
1526
|
+
source = resolve_plain_requires(resolved, argv[0]);
|
|
1527
|
+
source = rewrite_syntax_sugar(source);
|
|
1528
|
+
|
|
1529
|
+
size_t source_len = strlen(source);
|
|
1530
|
+
|
|
1531
|
+
/* Parse with Prism */
|
|
1532
|
+
pm_parser_t parser;
|
|
1533
|
+
pm_parser_init(&parser, (const uint8_t *)source, source_len, NULL);
|
|
1534
|
+
pm_node_t *root = pm_parse(&parser);
|
|
1535
|
+
|
|
1536
|
+
if (parser.error_list.size > 0) {
|
|
1537
|
+
fprintf(stderr, "Parse errors in '%s':\n", source_file);
|
|
1538
|
+
pm_diagnostic_t *diag;
|
|
1539
|
+
for (diag = (pm_diagnostic_t *)parser.error_list.head; diag; diag = (pm_diagnostic_t *)diag->node.next) {
|
|
1540
|
+
fprintf(stderr, " %s\n", diag->message);
|
|
1541
|
+
}
|
|
1542
|
+
pm_node_destroy(&parser, root);
|
|
1543
|
+
pm_parser_free(&parser);
|
|
1544
|
+
free(source);
|
|
1545
|
+
return 1;
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
g_parser = &parser;
|
|
1549
|
+
g_source_file = source_file;
|
|
1550
|
+
g_source_file_escaped = escape_str((const uint8_t *)g_source_file, strlen(g_source_file));
|
|
1551
|
+
|
|
1552
|
+
/* Flatten AST to text */
|
|
1553
|
+
lines = NULL;
|
|
1554
|
+
line_count = 0;
|
|
1555
|
+
line_cap = 0;
|
|
1556
|
+
node_counter = 0;
|
|
1557
|
+
|
|
1558
|
+
int root_id = flatten(root);
|
|
1559
|
+
|
|
1560
|
+
/* Output */
|
|
1561
|
+
FILE *out = stdout;
|
|
1562
|
+
if (argc >= 3) {
|
|
1563
|
+
out = fopen(argv[2], "wb");
|
|
1564
|
+
if (!out) {
|
|
1565
|
+
fprintf(stderr, "spinel_parse: cannot write '%s'\n", argv[2]);
|
|
1566
|
+
return 1;
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
fprintf(out, "ROOT %d\n", root_id);
|
|
1571
|
+
for (int i = 0; i < line_count; i++) {
|
|
1572
|
+
fprintf(out, "%s\n", lines[i]);
|
|
1573
|
+
free(lines[i]);
|
|
1574
|
+
}
|
|
1575
|
+
free(lines);
|
|
1576
|
+
|
|
1577
|
+
if (out != stdout) fclose(out);
|
|
1578
|
+
|
|
1579
|
+
pm_node_destroy(&parser, root);
|
|
1580
|
+
pm_parser_free(&parser);
|
|
1581
|
+
free(source);
|
|
1582
|
+
free(g_source_file_escaped); /* paired with the escape_str() in init */
|
|
1583
|
+
g_source_file_escaped = NULL;
|
|
1584
|
+
sp_includes_free();
|
|
1585
|
+
return 0;
|
|
1586
|
+
}
|