Operator precedence not respected
kevin-dp opened this issue · 2 comments
I want to define an operator >>=
which performs member access (i.e. is equivalent to .
).
My first attempt does not compile:
operator >>= left 19 = (left, right) => {
return #`${left}.${right}]`;
};
My second attempt (using computed member access) works but not as expected:
operator >>= left 19 = (left, right) => {
let r = right.name.token.value; // string representation of an identifier
let dummy = #`dummy`.get(0);
return #`${left} [${fromStringLiteral(dummy, r)}]`;
};
I deliberately give my >>=
operator precedence 19, which is the same precedence as javascript's member access operator (see JS operator precedence).
Based on the given precedence i would expect this to be possible:
var obj = {
foo: function() {
// return a promise
}
};
obj>>=foo.then(res => { console.log(res); })
However, this does not compile. For some reason the right
argument of my >>=
operator is a call expression (i.e. foo.then(...)
).
So, based on the given precedence i would expect obj>>=foo.then(...)
to be equivalent to (obj>>=foo).then(...)
, however it seems to be interpreted as obj>>=(foo.then(...))
.
If i manually add the parentheses as follows (obj>>=foo).then(...)
, then it works.
Yeah this is expected. All the forms that MDN calls precedence 19 (static/computed member access, new
, call) are not really operators in the sense that Sweet understands. This is because they all have grammar restrictions that make them more specialized than a normal binary/unary operator and so expand "below" the level of Sweet's operator precedence rules.
Ok, that's a pitty.
But, why doesn't my first attempt compile, whereas my second attempt does?