A bug in the interpreter
- Posted by Daryl Border <Darylb5 at aol.com> Feb 28, 2006
- 493 views
I was experimenting with some code recently, when I discovered a bug in the parser. The following code will parse without complaint, but does not work properly.
include get.e integer ch for n = 1 to 10 do if 4 < n < 8 then ? n end if end for ch = wait_key()
This program should display the numbers 5,6,and 7. It actually displays the number 1 through 10. The problem is with function rexpr() in parser.e which parses the expression 4 < n < 8. If the value of n is 1, it calcualtes 4 < 1 which is FALSE. It then calculates FALSE < 8 which is meaningless because FALSE is not a number. Because TRUE and FALSE are represented by the numbers 1 and 0, the computer can perform the calcualtion. And because both 0 and 1 are less than 8, the expression will evaluate to TRUE no matter what value n contains. Here's a modified version of function rexpr() I believe will correct the problem. It requires the procedure TempKeep() in emit.e be made global.
function rexpr() token tok integer id, opnd sequence patches patches = {} tok = cexpr() if tok[T_ID] <= GREATER and tok[T_ID] >= LESS then id = tok[T_ID] tok = cexpr() emit_op(id) opnd = Code[$-1] -- preserve the previous rhs value to be used as the next lhs value if tok[T_ID] <= GREATER and tok[T_ID] >= LESS then TempKeep(opnd) if short_circuit then emit_op(SC1_AND) patches &= length(Code) emit_addr(0) end if end if while tok[T_ID] <= GREATER and tok[T_ID] >= LESS do id = tok[T_ID] emit_opnd(opnd) -- push operand onto cg_stack tok = cexpr() -- get next operand emit_op(id) if short_circuit then emit_op(SC2_NULL) end if opnd = Code[$-1] if tok[T_ID] <= GREATER and tok[T_ID] >= LESS then TempKeep(opnd) if short_circuit then emit_op(SC1_AND) patches &= length(Code) emit_addr(0) end if end if if not short_circuit then emit_op(AND) end if end while opnd = Code[$] for n = 1 to length(patches) do backpatch(patches[n],opnd) backpatch(patches[n]+1,length(Code)+1) end for end if return tok end function
Thanks Daryl Border