Closed jennalwise closed 2 years ago
Yeah, that looks good to me. I think what happened is that I implemented Or and was going to return and implement and but never got around to it.
I would suggest the following slight refactoring of your code, to factor out only the part that differs between &&
and ||
:
ops += new IR.Op.AssignVar(tmp, logical.operation match {
case LogicalOperation.Or => new IR.Expr.Not(condition)
case LogicalOperation.And => condition
})
Also, this is something that should be tested, probably as an IR integration test, like the ones in src/test/resources/ir
. The way I add tests for these is to create the .c0
file containing the element under test (see logical.c0
as an example test for ||
). Create an empty file with the same name, but ending with .ir.c0
(see the logical.ir.c0
file for example), then run the tests. The tests will fail with a message containing the expected code. Copy this code, inspect it to make sure it matches what you expect, and then paste it into the .ir.c0
file and rerun to make sure it passes.
If you'd rather, feel free to commit your suggested changes and I could take care of adding the test.
Bug fix committed here: bdc2f0f
In the list.c0 example that I am working on we have both:
and
Transformer turns the first code snippet into:
This is correct, because when list is not NULL in the logical Or we must evaluate the left hand side of the Or, val <= list->val to determine whether to take the true or false branch of the last if statement. Otherwise, when list == NULL, then the true branch of the last if statement is guaranteed to execute.
However, Transformer turns the second code snippet into:
This is incorrect, because we are dealing with logical And in this case. We want when curr->next != NULL is true to also check that curr->next->val < val, i.e. we want the true branch of the if statement to execute when curr->next != NULL. However, due to the negation in
_5 := !_4
, the true branch of the if will never execute when curr->next != NULL. To make this translation semantically correct, all we have to do is remove the negation from_5 := !_4
. But, we need to preserve it for logical Or.I've narrowed the problem down to this bit of Transformer code:
In particular, this code always applies that negation, which is correct for logical Ors but incorrect for logical Ands.
Therefore, I propose the following code changes to fix the bug, which handles each Ors and Ands distinctly:
Please, review the proposed change. If it is correct, please make the change and commit the bug fix. Thanks!