Here's what I ended up doing:
First, read tokens from the stream until we reach an unmatched bracket or a semicolon. That gives us a stream of tokens like so:
2 + 3 * (5 + 4) / (7 + 6)
Next, search for brackets. If an open bracket is found, recurse to this step again starting from the next token.
When we find a close bracket, evaluate the expression between the brackets (See below), and generate I-code. Return from this function.
When we evaluate expressions, we just go through each operator precedence level and evaluate them.
So, sample:
2 + 3 * (5 + 4) / (7 + 6)
Seek for brackets, find first one so recurse:
5 + 4) / (7 + 6)
Find close bracket, so evaluate and return:
CODE(5, 4, +) / (7 + 6)
Seek for brackets, find first one so recurse:
7 + 6)
Find close bracket, so evaluate and return:
CODE(5, 4, +) / CODE(7, 6, +)
That gives us:
2 + 3 * CODE(5, 4, +) / CODE(7, 6, +)
So, evaluate in precedence order, left to right:
-> 2 + 3 * CODE(5, 4, +) / CODE(7, 6, +)
-> 2 + CODE(3, 5, 4, +, *) / CODE(7, 6, +)
-> 2 + CODE(3, 5, 4, +, *, 7, 6, +, /)
-> CODE(2, 3, 5, 4, +, *, 7, 6, +, /, +)
I think that's right anyway...
That leaves a stack of operands and operators in reverse polish notation, which, evaluates as:
2, 3, [5, 4, +], *, 7, 6, +, /, +
=2, 3, 9, *, 7, 6, +, /, +
2, [3, 9, *], 7, 6, +, /, +
= 2, 27, 7, 6, +, /, +
2, 27, [7, 6, +], /, +
= 2, 27, 13, /, +
2, [27, 13, /], +
= 2, 2.08, +
[2, 2.08, +]
= 4.08
Which is the correct answer. Yay!
I need to add support for finctions, conditionals, etc etc and test it more, but it's looking promising. Wheeeeee...
Do you intend to support string literals/macros? I'm attempting to support macros at various levels (eg before or after splitting to tokens) which is causing me grief (having to reparse the string at various points).