Thursday, May 20, 2010

Ambiguity with assignment

I just collided with an annoying ambiguity in my own language.
On one hand, one of the types of right lists is the assignment right list, which is a left list, an assignment symbol and another right list, like this:
x, y = y, x;
This is very useful(for example, the code above could be used for variable swapping.
However, not everything in PineDL is a list.
For instance, array accessing is made with a simple expression, like this:
a[b + c]
And, of course, we want assignment expressions like we have in C:
a[b = c]
Which will set b to the same value as c and access that index.

Of course, now we have two types of assignment: list assignment and expression assignment.
This wouldn't be a problem if expressions and lists were isolated, but they are not.
Consider the following code in the context of a right list:
a, b = c, d
Is that a list assignment(as in left list = right list, which is a valid statement as we saw before), or is it a plain right list, with three elements, where the second is an assignment?
a, (b = c), d
This is a problem. And one we must solve.

There are a few possible solutions to this ambiguity:
1. Prevent list assignment - Undesirable because the swap use case and much of the language is made around this convenient operation;
2. Prevent value assignment - Not bad because it can be emulated anyway using the list compacter operator, although inconvenient
a[(b = c)] instead of a[b=c]
3. Allow both, but specifically mention how to get around this ambiguity. Kind of like the dangling else problem in C, which is clearly defined.

I'm going with the third option. I'm going to define that, when possible, list assignment is preferred to expression assignment.
So:
a, b = c, d;
//List assignment

3, b = c, d;
//Expression assignment, because 3, b is not a valid left list

a, b = c, 3;
//List assignment, because c, 3 is a valid right list

a, b = c, d = e, f;
//Two list assignments

a, b = 3, c = d, e;
//List assignment, where the right operand is a list that
// includes an expression assignment
//Same end result as:
//a, b = 3, (c = d), e;

a, b = c, d = e, 3;
//Two list assignments, because e, 3 is a valid right list.
I believe this solves the problem. Of course, you can still force PineDL to emulate the other meaning, like this:
a, (b = c), d;
Of course, b = c is a list assignment itself(remember this is the list compacter, so it applies to a right list), but nobody has to know, right? For all purposes, this behaves like expected.
In fact, you can write
a, (b = c), d = e;
This is because (b = c) means automatically that it can't be a left list.
Note that (b = c) is itself a list assignment(although it behaves like an expression assignment for all practical purposes), d = e is a real expression assignment.

No comments:

Post a Comment