1. Procedure calls and the impossible triangle

I've been busy with school the past few months and have just gotten back to
Euphoria.  Today I converted 600 lines of BASIC code to Euphoria.  I made a
.e file with all of the procedures.  The problem is that they have calls to
each other, and I can't get them in the right order (in other words you can't
make a call to one that is written after the one that is calling)... it's
like one of those impossible triangles.  For example, A calls to B, B calls
to C, and C calls to A.  For A to call to B, it must be after B.  B must be
after C for the same reason.  But, A must be before C, but it can't because
it's after B.  I can probably fix this by making more than one .e file or
duplicating code, but is there an easier way?

Derek Brown

new topic     » topic index » view message » categorize

2. Re: Procedure calls and the impossible triangle

Maybe the problem is the structure of your code.
The basic program may be not structured properly ( spagetti code format )

You need to define each procedure and function first.
then use a Primary ( or Main ) Procedure to call each of your procedures.
Do not let one procedure call another procedure.

The main procedure can pass things back and forth between procedures but is
in complete control of the program.

new topic     » goto parent     » topic index » view message » categorize

3. Re: Procedure calls and the impossible triangle

Derek wrote:

> The problem is that they have calls to each other, and I can't get
> them in the right order ...

Despite what Bernie wrote, this is not necessarily spaghetti code, or even
bad coding practice. There are a lot of algorithms that require mutually
recursive routines. This is especially true if you are writing a parser.

Typically, only a few routines in your code are really mutually recursive.
You can run the code through eBasic, which will try to automatically
re-order the code and attempt to remove dependancies. It probably won't be
able to work with your code, but it might be helpful in ordering the code.

Once you've determined which routines are actually mutually recursive, you
can use routine_id() to handle the forward references. For example, let's
say that Foo and Bar were mutually recursive:

    procedure Foo( integer i )
        Bar( i )
    end procedure

    procedure Bar( integer j )
        Foo( j )
    end procedure

You could fix this by writing *prototypes* for Foo and Bar like this:

    integer xFoo
    procedure Foo( integer i )
        call_proc( xFoo, {i} )
    end procedure

    integer xBar
    procedure Bar( integer j )
        call_proc( xBar, {j} )
    end procedure

These prototypes are callable routines - they just don't know what their
behavior is, because xFoo and xBar haven't been assigned yet. You can then
write the actual Foo and Bar behaviors as:

    procedure zFoo( integer i )
        Bar( i )
    end procedure
    xFoo = routine_id("zFoo")

    procedure zBar( integer j )
        Foo( j )
    end procedure
    xBar = routine_id("zBar")

Because the prototypes have been defined, you can write the code without
bothering with forward references.

The above example is inefficient for this particular case. Typically, you
would only need to define a prototype for the *first* mutually recursive
routine. In this case:

    integer xBar
    procedure Bar( integer j )
        call_proc( xBar, {j} )
    end procedure

    procedure Foo( integer i )
        Bar( i )
    end procedure

    procedure zBar( integer j )
        Foo( j )
    end procedure
    xBar = routine_id("zBar")

If Robert added prototypes to Euphoria to do this automatically, it would
make life a lot easier. You could then write something like this:

    prototype Bar( integer j )        -- forward reference

    procedure Foo( integer i )
        Bar( i )
    end procedure

    procedure Bar( integer j )    -- resolve forward reference
        Foo( j )
    end procedure

If the Euphoria interpreter had this built in, you wouldn't have the
overhead of call_proc, and it would make a lot of BASIC and C code easy to
convert - and probable help get more Euphoria converts.

Hope this helps!

-- David Cuny

new topic     » goto parent     » topic index » view message » categorize

4. Re: Procedure calls and the impossible triangle

Thanks for all the help.  What I did was make a procedure called
control_flow() which not only called up all the other procedures but removed
calls from procedures.  In other words, if A calls B under a certain
condition, then in control_flow() I just put B right after A (with the
appropriate condition statements), which eliminated the link between the two,
which then made it easier to arrange.

Thanks,
Derek Brown

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu