A bug in the interpreter

new topic     » topic index » view thread      » older message » newer message

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

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu