Operator precedence

A project log for Bitlang

Minimalistic language for Turing machines and beyond.

joelsJoelS 08/20/2014 at 23:240 Comments

Operator precedence is important for some applications, but it can also be dangerous. As an example, what does (1 + 2 % 2)  or (2 * 3  % 2) do? I've been bitten by this one before. For Bitlang we can't really define operator precedence, since that's up to the developer.

Let's consider some cases:

-3 + 5 <= It doesn't matter much here, but it would be good if the - was applied first.

3 - 5 <= We mean 3 + (-5), but cannot assume that here. What if order is important for some type?

3 * -5 <= Hmm, tricky one. We have two operators here but that could be one (&&, *=, << etc have two chars.)

right.index - left.index <= We mean (right.index) - (left.index), not ((right.index) - left)

1 + 3 * 5 - 4 <= Important to get the order right.

1 / 4 * 5 <= We mean (1 / 4) * 5.

We can study this as mathematics but that's not really needed. Let's just keep it simple and categorize the operators into two groups: greedy and non-greedy. Addition is an example of a greedy operation since it eats the whole multiplication-expression, while * is a non-greedy one as it doesn't eat the -4. Now, we can say that operators that begin an expression is left-unary and sticks to the immediate operand next right to it. If the operand is a variable or symbol on the other hand, the following (if any) operator is applied - UNLESS it's a greedy one, as it then have to wait for all non-greedy ones following.

How do we solve the problem where we mix +- and */? It will solve itself. But, what about the ambiguous %-operator? What about the &&, || or == as commonly used in other languages?

(a + b == c * d && e * f == g + h)

We don't want to add parentheses here. How can this be solved? It actually is solved, it works given that greedy operators eat other greedy operators - with the order being left-to-right. 1 + 2 + 3 would be computed as 1 + (2 + 3). This is something you have to deal with if you're greedy, and it's commonly reflected in mathematics too: multiplication might be order-dependent, but addition/subtraction usually isn't. And if it is, you need to have parentheses.

(a + b && c + d == e + f && g + h)

Some moron came from C and wrote this, and now his code doesn't work. Also, we have the %-problems to deal with. Ok, here are three ideas: Either bucket everythng up in more than one bucket (like conventional languages do) - we could even have one bucket for % and the like that gives warning unless you have parentheses explicitly. Or, make some operators friends, and ban others - need for parentheses all over the place. Or: Have predefined buckets, and remove % and call it .modulo with .isEven and .isOdd shortcuts. Warning on every ambiguous use that needs parentheses. This also prevents people from abusing operators. I like this last one best!