Re: Goto (Was Re: Open Source)

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

Juergen Luethje wrote:
> 
> Pete Lomax wrote:
> 
> > Juergen Luethje wrote:
> > > 
> > > this is my translated code (untested):
> > 
> > Your code worked perfectly on the second test set, and gave initially
> > correct
> > answers on the first set, before yielding negative highvalues...
> > 
> > I toyed with the idea of challenging you to find the bug smile
> > 
> > The mistake you made is this:
> > > Pete Lomax wrote:
> > > > Try this then:
> > > > function find_combination(integer jumpToDa200)
> > > >     if jumpToDa200 then goto da200 end if
> > > > da200::
> > you translated this as:
> > > 
> > > function find_combination(integer jumpToDa200)
> > >    if not jumpToDa200 then
> > >    end if
> > >    while 1 do
> > >       if not jumpToDa200 then
> > >       end if
> > >       if jumpToDa200 or flag = TRUE then
> > <da200:: was here>
> > >       end if
> > >    end while      
> > > 
> > The original jumped to da200 from the top of the routine, whereas you test
> > the
> > parameter again on every iteration around the loop. Clearing the flag at the
> > point where the label used to be fixes it.
> 
> I see.
> 
> >  From the number of tests it passed despite this flaw, I feel lucky to have
> > spotted it at all.
> > 
> > > I created code for Matt's OOEU, which does support GOTO. Then I removed
> > > the GOTOs step by step and so in the end I had a program for the
> > > standard Eu interpreter.
> > Not really the answer though, installing two different interpreters, is it?
> 
> Up to now, I have encountered this special problem only once. Since I
> registered Euphoria in April 2002, this means only once in 5+ years --
> pretty much the same what you wrote. And in this rare situation I used
> an appropriate tool to solve the special problem. That was/is fine with
> me.
> What is the answer in your opinion?
> 
> Regards,
>    Juergen
> 
> 
> PS: IMHO it would be very cool if there were a kind of pre-processor,
> that could automagically translate GOTOs into more structured code.
> This would be a nice challenge for you and other "senior programmers",
> no? smile
> (I am curious whether this is actually possible from a theoretical point
> of view.)

It is, but might be pretty inefficient.
I'm assuming goto-ing inside a for loop is not permitted - otherwise extra steps
are needed to re-initialise loop variables and reenter a for loop.

So the point is to jump from inside a few while and if blocks to another point,
also inside a few while and if blocks. So, the problems breas up into:
1/ exiting nested if/while blocks, so as to be in a block containing the target;
2a/ inside this block, jumping forward to start of block containing target;
2b/ jumping to start of block, so as to apply 2a;
2c/ inside this block, jumping backward to start of block containing target;
3/ moving into a while loop;
4a/ moving inside an if block
4b/ moving inside an elsif block
4c/ moving inside an else block

For each goto statement in program, create a flag (I'll call it goto_flag_154),
which will be zero except while the sequence of statements translating the given
goto is being executed. So, at the location of the original goto statement,
you'll have goto_flag_154=1, and on its target goto_flag_154=0.
Also, for each etra while loop created during the process, create a flag called
exit_flag_197.

1a/ to break out of a while loop, use
if goto_flag_154 then exit end if

1b/ to break out of an if statement:
- wrap it inside 
while 1 do...if not goto_flag_154 then exit end if end while

- if there's any exit statement inside that section then
* precede each by }}}
<eucode>exit_flag_197=1}}}
<eucode>
* add after the above end while statement
if exit_flag_197 then exit_flag_197=0 exit end if

- goto 1a/

2a/ move forward inside a while loop using
if not goto_flag_154 then...end if

2b+c/: if inside an if block, exit it first using 1b/ and then 4/
       if inside a while loop, wrap origin and destination into
while 1 do ... if not goto_flag_154 then exit end if end while

and modify in case any exit statement is trapped, as in 1b/

3/ prepend }}}
<eucode>goto_flag_154 or</eucode>
{{{
 to the header of the while loop

4a/ same as 3/
4b/ prepend to the conditional of the main if and all skipped elsif clauses
not goto_flag_154 and

. Use 3/ on the elsif clause you want to
reach into.
4c/ use 4b/ on all if/elsif clauses.

As you have certainly figured out, the preprocessor must remember where evry
block starts and ends, together with its type, and update that data whenever code
is being modified, including as part of the above. Also, you must find a variable
name for goto_flag_154 and exit_flag_197 that will not conflict with any
subsequently declared global symbol.
Implementing inside the interpreter is _way_ simpler. I tried both. 
I didn't release the preprocessor (idEu) because debugging with a 300 line limit
was so much of a hell, at the time. The update proess which I mentioned above was
not working properly.

CChris

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

Search



Quick Links

User menu

Not signed in.

Misc Menu