I'm having trouble implementing these functions in the stack. My first impulse is to compare the values with a subtraction and use a jump to set the return value, but then I run into the problem of the jump label name being reused throughout the program. My next thought is to create random values in python to use as jump labels, but that's just a hacky workaround. This would be so much easier if I could push the instruction pointer to the stack or if there was a flags register.
Is it possible to do these calculations and get the correct return values without doing jumps?
It seems as though that's the only way to do it. It doesn't seem that much harder, it simply involves throwing in a class variable in my python code, it just seems unnecessary for this purpose. If the VM represented all 0's as false and (anything other than 0) as true, I think the jumps wouldn't be necessary. Or again, simple access to the instruction pointer would make it trivial.
In general you don't want producers of boolean values to be allowed to produce any nonzero value and call it good.
A real good example of why this is so can be had with the ctype library in C. For performance reasons, functions such as isupper() return a 0 if False and something other than zero if true. So now let's assume that you want to do something if two characters are either both uppercase or both not uppercase. You realize that this could be written as
if (isupper(x) == isupper(y)) doSomething();
and you discover that most of the time when x and y are both uppercase letters is doesn't do the something.
Because isupper(x) is returning 70 while isupper(y) is returning 82 and since 70 does not equal 82, the expression is False.
And, yes, things would be easier if the Hack had direct access to the program counter. Things would also be easier if the Hack had a barrel shifter, or this, or that, or about twenty other things. But that's not the framework that the Hack and the N2T project are coming from.