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
Implement passing values by reference to CLIPPER methods #51
Comments
Comment from Matt Slay: BTW - FoxPro also has "pass by reference". From VFP Help:
|
Robert created Issue # 67 on GitHub to handle track this matter... |
Matt, |
Assigning the locals back to the param array has been implemented. Will now start work on handling the parameters by reference (assigning the values back to the original location) on the side of the calling code. The design has been made. Now we "only" have to implement is. |
See https://github.com/X-Sharp/XSharpDev/blob/master/XSharp/src/Compiler/XSharpCodeAnalysis/LocalRewriter/LocalRewriter_ClipperCall.cs. |
The problem here is that the work cannot be done (entirely) at the lowering phase because at that point the REF or ADDROF have already been bound (and any related errors already generated). So, it is at least necessary to prevent resolving them at the expression binder when they are arguments to a CLIPPER method. However, they are normally bound before the binder determines that it will call a CLIPPER method (the resolved arguments are needed to determine the best candidate). I need to think about this... |
Do whatever it takes to make this work. We really need this, also for the FoxPro dialect. |
I have a working implementation of this, but only with the REF keyword. The ADDROF ('@') does not work, and is very tricky (and nasty) to implement; it would require binding the arguments twice (which comes with an assorted speed penatly) before resolving the call, keeping any errors in temporaries and throwing the errors after the call is bound. Very error prone. So, if we can live with just the REF implementation, I strongly suggest to leave @ alone... |
Nikos, |
This won't help much because the compiler would still need to re-bind the arguments. I'll try to find another solution. |
Nikos, |
Robert, it still needs to be resolved in other cases to AddressOf though, since this also used a lot in old code... |
OK, I now have a working implementation that takes care of ADDROF as well. It's rather ugly and hacky, but it works (I must do some improvements before pushing it). It works by binding ADDROF normally and then un-binding it when the method is resolved. As you can see this is not very robust as it breaks the normal compilation flow, but it seems to be working. However, it will only work if the ADDROF can be correctly bound (i.e. generates no errors). Is this OK? |
Ugly and Hacky is not really a problem for me. What could cause binding of ADDROF to fail ? Btw : I have changed the way in which memvars and aliased fields are processed in the last weeks. They are now transformed into identities with a special syntax and in BindXsIdentifier(where you added support for undeclared variables) I am now handling this special syntax and creating the XsVariableSymbol with a getter/setter for Memvars or Fields. The memvar identifier is now something like "Xs$MemVar->Name" and the Field identifiers are "Alias->FieldName" and "Xs$Field->FIeldName". When resolving identifiers I am checking for the alias operator inside the name . See This change made the code in the transform phase much simpler because I no longer have to do special things for assignment operators and this also support the += , -= etc operators. |
Sure, it's not a problem until the bugs it hides come out... I like your new approach for memvars/dbfields. It's better to keep the tree transformation as simple as possible and have all the logic in the binding phase. |
In the end, memvars will not work even with the REF keyword because I changed the implementation due to problems with indexed items (e.g. array elements)... |
Can you create a new branch and push this, so I can have a look ? |
I want to debug the REF arguments to a CLIPPER constructor before pushing it. Currently the XNode is modified somewhere, so when it reaches the lowering phase it is not of the CtorCallContext type (!). This means that the REF behavior is not correctly detected... |
No, it's not the constructor declaration, it's the CtorCallContext that gets changed into a PrimaryExpressionContext. When created at the tree transformation it's correct, but something happens later. I'm looking into it. |
OK, found it. It is the xform of primaryExpression that forwards the CsNode, so this happens for all primary expressions (so, I changed the lowering code to handle it correctly). I pushed to the main compiler branch. Please try it and let me know of any problems. |
I am on my way to Phoenix, just met Fabrice at the airport, so it will take a while... |
Yes, a REF local is generated for each REF argument; this is expected. The local is assigned a reference to the original argument, and is used in its place when constructing the params array. Then, it is assigned back the modified element when the call returns. |
Nikos |
Frankly, I'm not sure what the DO does. But if it ends up calling a CLIPPER function, then generating an @ or REF should be enough; with preference to the REF because its handling is slightly more elegant (compiler-wise). |
Oh, and remember that the HasRefArguments of the xnode must be true! |
I have added some code to also make this work for DO statements. Ticket closed ! |
* [Compiler] Fixes #/issues/1147 Also adds test case for this issue * [script] Fix script dialect, include app RT assemblies, fix return value behavior * [script] Minor fix for VO script return value Co-authored-by: Nikos Kokkalis <nikos.v.kokkalis@gmail.com>
No description provided.
The text was updated successfully, but these errors were encountered: