Re: Kat's goto

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

My issues with the GOTO are purely a matter of implemention. The basic idea 
behind coding the goto is fairly simple. You have a table that holds the 
position of the goto. I'll use line numbers here for convenience:

 10 foo:

will get you a table like this:

	goto	at
	foo:	10

When you reference the GOTO, you just look it up in the table:

 10 foo:
 20 print "endless loop"
 30 goto foo:

becomes (more or less)

 10 rem foo:
 20 print "endless loop"
 30 goto 10

If you reference a GOTO before that label is defined, you need to set up a 
backpatch table, so once the GOTO is defined, you can fill it in. For example:

 10: goto bar:

creates an entry into the backpatch table:

	bar	10

and an instruction:

 10: goto -1

when bar: is finally encountered:

  20: bar:

the backpatch table is searched to see if there are any addresses that need 
to be patched. There are, and the code becomes:

 10: goto 20
 20: rem bar:

If, during runtime, you encounter a:

 goto -1

you know you've reached an undefined GOTO, and searching the backpatch table 
will tell you what that GOTO was. At the end of compilation, you have any 
values left in your backpatch table, it's a similar error.

So, on a conceptual basis, implementing GOTO is fairly easy. The issue is 
whether the language itself will support it. I'll give a few non-Euphoria 
examples to show how the language might not allow a GOTO.

First of all, the language might not compile to bytecodes. For example, Awk 
and a number of other languages store the program in data structures - 
typically a binary tree:

   struct {
      opcode
      data
      left_node
      right_node
   }

So a 'while' loop:

   while <some test>
      <some code>
   wend

might be encoded:

   { OP_WHILE, NULL, <some test>, <some code> }

There's no way to implement a GOTO in this kind of environment. And even if 
you had bytecodes, there is no guarantee that a GOTO could be coded. For 
example, the WHILE loop might be implemented as:

   <WHILE TEST> <ADDRESS OF CODE>

with a JUMP to the WHILE block, instead of inlining the code (see, for 
example, the demo interperter in "The Unix Programming Environment", by Brian 
W. Kernighan and Rob Pike).

Finally, there are stack issues. I'll use FORTH loops as an example. FORTH 
has two stack: a DATA stack to hold values, and a RETURN stack to hold the 
address to return to. The FOR loop looks something like this:

   1 10 DO
      ." Hello, world!"
   +LOOP

This prints "Hello, world!" 10 times. The way it works is a bit tricky: FORTH 
sticks the loop values on the RETURN stack for convenience. As a result, if 
you just did a GOTO out of the loop, you would end up with garbage on the 
stack. Leaving junk on the DATA stack is bad enough, but leaving it on the 
RETURN stack is fatal, since it will try to jump to that address.

So implementing a GOTO isn't really an issue of philosophy as it is language 
design. There may be design issues in Euphoria which make it next to 
impossible to implement a GOTO.

I suspect that a GOTO could be supported by keeping track of the nesting 
level that the label was on. When a GOTO was called, it would then EXIT until 
the correct nesting level had been arrived at, and then JUMP to the code.

This would mean modifying the code for all the block structures (for, while) 
to support the new EXIT, adding code to keep track of how deep the nesting 
was at interpret and runtime, and tables for backpatching, etc. Not entirely 
trivial.

-- David Cuny

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

Search



Quick Links

User menu

Not signed in.

Misc Menu