I haven't really read much into your sources but your approach to "3. Expressions: a digit" and "4. Addition" is completely backwards.
The correct procedure is to convert your infix (normal left-right expressions) to postfix using a stack. Then it's almost a 1:1 conversion directly to assembly.http://www.maths.abdn.ac.uk/~igc/tch/mx ... ode74.html
The compiler has input an expression in normal form from your program. It has decided that it is grammatically correct and has converted it into postfix form. Now it has to understand it -- i.e. work out what it is asking for. The compiler does not actually perform the operations called for by the expression (that is done when you run the program) but it generates a stream of machine instructions that will have the effect of evaluating the expression. To give you a taste of what happens let me invent a totally fictitious compiler and equally fictitious machine language.
The expression (a + b)*(c + d ) would be converted into something like the following
fetch value of a into register
add value of b to register
put result into temporary store T
fetch value of c into register
add value of d to register
multiply value of T into register
The point is that the actual machine operations are usually rather elementary things (on small computers there would probably be far more instructions used than in this example simply because the instructions are that much more elementary).
Let's get on with the problem. The beauty of postfix expressions is that they are very easy to evaluate. That's why I converted into postfix in the first place. And here is the evaluation algorithm, which once more uses the two `predicates' isvar(x) and isop(x):
01 algorithm evaluate(s,n)
02 // s is a postfix string of length n
03 for i = 1 to n begin
04 if isvar( s(i) ) then push(value of s(i) )
05 if isop( s(i) ) then begin
06 x = pop
07 y = pop
08 do y s(i) x and push result (note the order)
11 x = pop
12 return x
The basic action is this: as each variable appears in the expression its value is pushed onto the stack (4). When an operation appears (5) the top two values are taken off the stack (6,7) and this operation is performed on them. The result is pushed back onto the stack (8). This means that, at any stage, the next operator applies to the previous two values on the stack. At the end there should be just one value left in the stack -- the result. Pop this (11) and return it as the answer.
A compiler, as I said, does not actually perform the calculation -- you are not running the program yet. At line 8 the compiler will write the machine code for performing the operation, rather than actually performing it.
Considering the wide range of platforms today I would rather see a concerted effort writing a compiler which parses the source code to C or C++. That way you can leverage the compilers that have already been written for other platforms without having to learn the actual assembly.