-
Notifications
You must be signed in to change notification settings - Fork 6
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
Type Qualifier modifiers problem #147
Comments
Yeah, there is a lot that could be improved with the design of injection in ableC. I would chat with @TravisCarlson about this, he originally implemented the injection/runtime modification stuff. |
The problem as I understand it is that injecting code that transforms an expression that is an lvalue into an expression that is not an lvalue breaks programmer-written code. For example, if the programmer writes:
this is fine at the host-language level. But it's not ok if we do something at the injectable level that transforms the expression
However, this problem is unique to the operators like Another example:
And suppose we inject on array subscripting to generate:
This is not broken. So I'd say it appears that the operators that require lvalues on their operands are different than the other operators, that injection on those operators only is broken in this way, and that a fix should probably touch only the broken injection code on those operators. Because as you mention, the statement expressions are useful in that they prevent the expression from being evaluated more than once, and I'd prefer not to remove that where we don't have to. So the above is my response to the current problems with injection in ableC. Am I misunderstanding or not thinking of anything? Below is my response regarding the specific use case this is intended to be used for. If I understand the specific use case, the programmer-written code is something like:
and the desired generated code is:
but the actual (erroneous) generated code is:
There are three productions that construct the In contrast to this dimensional example, it is possible to use I still don't fully understand the problem that this solution is intending to solve. Are we sure that this is the best (or only) way to solve it? |
@TravisCarlson, I think that is more or less the situation. @counc009, I do agree with Travis on this - are you sure there isn't a better approach? Have you even considered just defining a new attribute over all of ableC that translates a piece of code into one where the variables have been modified as required? |
Yeah, that seems accurate. Yeah, the problem is really isolated to productions expecting lValues. A solution that is more direct would probably be better. @krame505 Yeah, that might be a better implementation. To do this, is there a good list of all nonterminals who children may include |
Unfortunately the answer to "which nonterminals have children that may include No, For now the quickest option is probably to go look at the history of ableC and find the substitution grammar from before last week when we switched everything over to use reflection - we had a whole bunch of aspect stubs for all of ableC that just have |
The way that the applyMods (and applyLhsRhsMods) functions work to apply RuntimeMods causes problems with lot of the productions they can operate on, because the function uses stmtExpr in wrapping the modified expressions. Because of this, any injectable production that expects an lValue (such as pre and post increment and decrement) will fail if we try to use qualifiers to modify the expression (since a stmtExpr must always be an rValue).
I think it is safe to remove this stmtExpr, the risk this introduces would be for the original expression to be evaluated multiple times, however using a stmtExpr means that anywhere that requires an lValue will be an error.
Looking at a longer term fix to this, it seems like the model used for handling qualifiers in CallExpr might work better in general, where it is possible to inject Stmt before and after the expression itself, transforming the expression into a stmtExpr that does setup, evaluates the expression, and then does more afterwards, finally returning the value from the function call. This model would work for any production that produces an rValue. The only productions I can think of that produce lValues are the dereferenceExpr and arraySubscriptExpr, though in both of these cases the children are rValues, and so a stmtExpr for each child can be used.
I don't know whether this is the correct fix, or what it is, but I thought it was something worth bringing up. I'm going to make a pull request for the initial idea (just removing the stmtExpr), but I think further discussion of how to better handle this may be needed.
The text was updated successfully, but these errors were encountered: