Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

block_var! in ripper gives nil for opt_bv_decl and not false #8094

Open
enebo opened this issue Feb 8, 2024 · 2 comments
Open

block_var! in ripper gives nil for opt_bv_decl and not false #8094

enebo opened this issue Feb 8, 2024 · 2 comments

Comments

@enebo
Copy link
Member

enebo commented Feb 8, 2024

jruby -rripper -e 'p Ripper.sexp_raw("foo { |a| a }")'
[:program, [:stmts_add, [:stmts_new], [:method_add_block, [:method_add_arg, [:fcall, [:@ident, "foo", [1, 0]]], [:args_new]], [:brace_block, [:block_var, [:params, [[:@ident, "a", [1, 7]]], nil, nil, nil, nil, nil, nil], nil], [:stmts_add, [:stmts_new], [:var_ref, [:@ident, "a", [1, 10]]]]]]]]

It should be:

[:program, [:stmts_add, [:stmts_new], [:method_add_block, [:method_add_arg, [:fcall, [:@ident, "foo", [1, 0]]], [:args_new]], [:brace_block, [:block_var, [:params, [[:@ident, "a", [1, 7]]], nil, nil, nil, nil, nil, nil], false], [:stmts_add, [:stmts_new], [:var_ref, [:@ident, "a", [1, 10]]]]]]]]

It seems there is a barely visible yet significant difference to resolve in parsing. Ruby 3.1 uses escape_Qundef which will look to see if the value is Qundef and if so replace it with nil. Otherwise it uses the value passed. In this particular case it passes '0' which I think becomes false.

In JRuby, we pass null and our escape_Qundef looks at null and makes nil and not false. Since there are many callers of escape_Qundef I need to figure out what I need to do to fix this.

@enebo
Copy link
Member Author

enebo commented Feb 8, 2024

Blerg. So my problem is we just use null all over the .y file and this is fine for regular parsing. In ripper they differentiate
by Qnone and Qnull. There are still random 0 for NULL but those as far as I can tell only affect parsing pieces of parse.y.

The work to fix this is to audit the entire grammar file and match up the Qnone and Qnull. The extra twist to all this is that Qnull is Qundef (which gets translated to false during dispatch). Why not just false? I suspect this is that Qundef leaks into values another way.

@enebo
Copy link
Member Author

enebo commented Feb 8, 2024

The extra extra wrinkle is that signatures need a Qnone and ripper and ruby both will have different values for it but n Java signatures have parameters which have to accept these values and those parameters have differing Java types. To do this correctly I would need n Qnone types and n Qnull types which have differing types between ripper and ruby but would at least properly type to the methods which accept them OR I can just make all parameters accepting these values as Object then runtime cast the value in the method which accepts them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant