From 13d685b61bbc2eb2be0c38d1d983bafd2ee17d3c Mon Sep 17 00:00:00 2001 From: Herwin Date: Sat, 22 Jun 2024 13:09:31 +0200 Subject: [PATCH 1/3] Support instance variable target in for loop --- lib/natalie/compiler/args.rb | 7 +++++++ lib/natalie/compiler/pass1.rb | 1 + spec/language/for_spec.rb | 10 ++++------ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/natalie/compiler/args.rb b/lib/natalie/compiler/args.rb index 37ccce548..6c0b7c50c 100644 --- a/lib/natalie/compiler/args.rb +++ b/lib/natalie/compiler/args.rb @@ -46,6 +46,8 @@ def transform_arg(arg) when ::Prism::ArrayNode clean_up_keyword_args transform_destructured_arg(arg) + when ::Prism::InstanceVariableTargetNode + transform_instance_variable_arg(arg) when ::Prism::RequiredParameterNode clean_up_keyword_args transform_required_arg(arg) @@ -158,6 +160,11 @@ def transform_destructured_arg(arg) @instructions << PopInstruction.new end + def transform_instance_variable_arg(arg) + @instructions << ArrayShiftInstruction.new + @instructions << InstanceVariableSetInstruction.new(arg.name) + end + def transform_rest_arg(arg) if (name = arg.name) @instructions << variable_set(name) diff --git a/lib/natalie/compiler/pass1.rb b/lib/natalie/compiler/pass1.rb index 091b9019b..23b6bdf1b 100644 --- a/lib/natalie/compiler/pass1.rb +++ b/lib/natalie/compiler/pass1.rb @@ -2665,6 +2665,7 @@ def maximum_arg_count(args) args.count do |arg| %i[ + instance_variable_target_node local_variable_target_node multi_target_node optional_parameter_node diff --git a/spec/language/for_spec.rb b/spec/language/for_spec.rb index e52b77e29..88f1f15a9 100644 --- a/spec/language/for_spec.rb +++ b/spec/language/for_spec.rb @@ -69,13 +69,11 @@ def obj.each it "allows an instance variable as an iterator name" do m = [1,2,3] n = 0 - #for @var in m - #n += 1 - #end - #@var.should == 3 - NATFIXME 'Support Prism::InstanceVariableTargetNode', exception: SpecFailedException do - n.should == 3 + for @var in m + n += 1 end + @var.should == 3 + n.should == 3 end it "allows a class variable as an iterator name" do From 1bb837370bf0fd6b5ab5f11810e98f7e8a4bc91e Mon Sep 17 00:00:00 2001 From: Herwin Date: Sat, 22 Jun 2024 13:11:58 +0200 Subject: [PATCH 2/3] Support class variable target in for loop --- lib/natalie/compiler/args.rb | 7 +++++++ lib/natalie/compiler/pass1.rb | 1 + spec/language/for_spec.rb | 10 ++++------ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/natalie/compiler/args.rb b/lib/natalie/compiler/args.rb index 6c0b7c50c..ef2090b83 100644 --- a/lib/natalie/compiler/args.rb +++ b/lib/natalie/compiler/args.rb @@ -48,6 +48,8 @@ def transform_arg(arg) transform_destructured_arg(arg) when ::Prism::InstanceVariableTargetNode transform_instance_variable_arg(arg) + when ::Prism::ClassVariableTargetNode + transform_class_variable_arg(arg) when ::Prism::RequiredParameterNode clean_up_keyword_args transform_required_arg(arg) @@ -165,6 +167,11 @@ def transform_instance_variable_arg(arg) @instructions << InstanceVariableSetInstruction.new(arg.name) end + def transform_class_variable_arg(arg) + @instructions << ArrayShiftInstruction.new + @instructions << ClassVariableSetInstruction.new(arg.name) + end + def transform_rest_arg(arg) if (name = arg.name) @instructions << variable_set(name) diff --git a/lib/natalie/compiler/pass1.rb b/lib/natalie/compiler/pass1.rb index 23b6bdf1b..acfadf79f 100644 --- a/lib/natalie/compiler/pass1.rb +++ b/lib/natalie/compiler/pass1.rb @@ -2665,6 +2665,7 @@ def maximum_arg_count(args) args.count do |arg| %i[ + class_variable_target_node instance_variable_target_node local_variable_target_node multi_target_node diff --git a/spec/language/for_spec.rb b/spec/language/for_spec.rb index 88f1f15a9..b4278e928 100644 --- a/spec/language/for_spec.rb +++ b/spec/language/for_spec.rb @@ -80,13 +80,11 @@ def obj.each class OFor m = [1,2,3] n = 0 - #for @@var in m - #n += 1 - #end - #@@var.should == 3 - NATFIXME 'Support Prism::ClassVariableTargetNode', exception: SpecFailedException do - n.should == 3 + for @@var in m + n += 1 end + @@var.should == 3 + n.should == 3 end end From a7afe4b26f5f36299953e06daac291c73f7eb5b5 Mon Sep 17 00:00:00 2001 From: Herwin Date: Sat, 22 Jun 2024 13:17:38 +0200 Subject: [PATCH 3/3] Support constant target in for loop --- lib/natalie/compiler/args.rb | 8 ++++++++ lib/natalie/compiler/pass1.rb | 1 + spec/language/for_spec.rb | 12 ++++++------ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/natalie/compiler/args.rb b/lib/natalie/compiler/args.rb index ef2090b83..5574451e4 100644 --- a/lib/natalie/compiler/args.rb +++ b/lib/natalie/compiler/args.rb @@ -50,6 +50,8 @@ def transform_arg(arg) transform_instance_variable_arg(arg) when ::Prism::ClassVariableTargetNode transform_class_variable_arg(arg) + when ::Prism::ConstantTargetNode + transform_constant_arg(arg) when ::Prism::RequiredParameterNode clean_up_keyword_args transform_required_arg(arg) @@ -172,6 +174,12 @@ def transform_class_variable_arg(arg) @instructions << ClassVariableSetInstruction.new(arg.name) end + def transform_constant_arg(arg) + @instructions << ArrayShiftInstruction.new + @instructions << PushSelfInstruction.new + @instructions << ConstSetInstruction.new(arg.name) + end + def transform_rest_arg(arg) if (name = arg.name) @instructions << variable_set(name) diff --git a/lib/natalie/compiler/pass1.rb b/lib/natalie/compiler/pass1.rb index acfadf79f..8938efbcd 100644 --- a/lib/natalie/compiler/pass1.rb +++ b/lib/natalie/compiler/pass1.rb @@ -2666,6 +2666,7 @@ def maximum_arg_count(args) args.count do |arg| %i[ class_variable_target_node + constant_target_node instance_variable_target_node local_variable_target_node multi_target_node diff --git a/spec/language/for_spec.rb b/spec/language/for_spec.rb index b4278e928..5fc8a21cf 100644 --- a/spec/language/for_spec.rb +++ b/spec/language/for_spec.rb @@ -92,15 +92,15 @@ class OFor class OFor m = [1,2,3] n = 0 - NATFIXME 'Support Prism::ConstantTargetNode', exception: SpecFailedException do + NATFIXME 'Complain when assigning to initialized constant', exception: SpecFailedException, message: /should have printed a warning/ do -> { - #for CONST in m - #n += 1 - #end + for CONST in m + n += 1 + end }.should complain(/already initialized constant/) - CONST.should == 3 - n.should == 3 end + CONST.should == 3 + n.should == 3 end end