Variable update expression statements should be extended to allow complex expressions
For example
!x * 2
!x + 1
will double x and add 1, but unfortunately, this
!x * 2 + 1
doesn't work. It should do the same thing. An expression e written in a statement context and containing one !v subexpression should be treated as equivalent to ?v = e, with the !v in e replaced by just v.
Recognising this might be an issue. I think we would only "know" a statement is an expression after type checking, but flattening would destroy the structure we're looking for before we ever get to type check
Agreed. I think separating flattening from type checking was probably a mistake. It keeps causing problems. It's one of those "it seemed like a good idea at the time" things.
I think you could still recognise it, but it's dubious. You need to find a chain of "expressions", with the first having a single !, and then all subsequent, bar the last have exactly one output. Then you just need to change the first ! to a ? and add the output in the final statement
That would handle these cases, and should generalised pretty well.
!x * 2
# flattened as
*(!x, 2)
# transformed to
*(x, 2, ?x)
!x * 2 + 1
# as
*(!x, 2, ?t)
+(t, 1)
# to
*(x, 2, ?t)
+(t, 1, ?x)
3 * (!x * 2) + 1
# as
*(!x, 2, ?t0)
*(3, t0, ?t1)
+(t, 1)
# to
*(x, 2, ?t0)
*(3, t0, ?t1)
+(t1, 1, ?x)
I'm not sure this would work though, as it would have to occur in mode checking due to the modes being misaligned in the leading call, but would fail type checking because the final call has the wrong arity.