[comp.lang.forth] Forth calls C

wmb@MITCH.ENG.SUN.COM (02/15/91)

> There is one way I could agree to shrinking the ANSI wordset
> thereby eliminating all of these controversies over the string or file
> or ... wordsets.  Define a standard way of calling C functions from
> forth.  Then anyone could use all the functions in libc.a or any other C
> library and not need to reinvent the wheel (or words) in forth.
> Think about it, interface to C in an standard sequence and all the
> issues of strings, files, floating point, networking, GUI are
> mostly solved.  Use the C names, with the C specified arguments in a
> forth context. real easy.  But I figure this will never fly because
> the forth hackers of the world have their egos too wrapped up
> in reinventing the wheel in the forth way to get any real work done
> and make money using forth.

Many of my Forth products have this capability, but it is a major-league
support headache.  The problem is the diversity of calling conventions
and linker formats across different machines, across different C
implementations on the same machine, and even across different sets
of system routines supplied by the system vendor.

For instance, the Atari ST has about 5 different system interface levels,
each with different calling conventions, not to mention the 3 or 4 different
C compilers that have been popular at various times in the machines lifetime.

Even OS-9, which is in general a very well-designed operating system, has
about 4 or 5 different linkage mechanisms for various system interface
components.

Mitch Bradley, wmb@Eng.Sun.COM

wmb@MITCH.ENG.SUN.COM (02/22/91)

> ... discussion of allowing Forth to call external (e.g. C) library routines
>       Am I missing something or could this be easily solved by
> a Vendor supplying a standard ( ANS ) system interface that has
> built in support ( ie primitives ) for alternate form/sequence parameters?

In principle, it would be possible to do something like this.  The key
is to develop a specification language to describe the routine that is
to be called.

I have a fair amount of experience in this area;  I have developed "call
compilers" to allow Forth to call external routines for about a dozen
different forms of external routines/calling sequences/linkage mechanisms.

Here are some of the issues that a "call compiler" has to address:

        1) The name of the Forth word the calls the external routine (easy!)
        2) The stack diagram of the Forth word (easy!)
        3) The place to put the arguments to the external procedure
           (can be fairly tricky)
        4) Data type translation (for example, Forth and C have different
           string representations)
        5) Execution environment maintenance (for example, Macintosh system
           calls require particular handling of the A6 register).
        6) Linkage - how to find the actual address of the external routine,
           or its trap number or whatever, and how to get the routine loaded
           into memory.
        7) Callbacks - Forth calling C is only half the problem; most people
           eventually want C to be able to call back into Forth too (e.g. for
           I/O services)
        8) Error returns - many system call interfaces report errors
           separately from their normal return value mechanism.

I have yet to develop a specification mechanism that can handle the full
range of problems across all the environments that I have dealt with.
I usually end up "tweaking" my specification syntax to some extent for
each new system that I have to deal with.

This is one of those problems that appears straightforward from a
conceptual standpoint, but once you get down to the details, it tends
to get overwhelming in a combinatorial sense.

I cannot imagine in my wildest dreams that the ANS committee would ever
standardize something like this.  It is just too complicated.  Witness the
tremendous amount of discussion that has resulted from the CATCH/THROW
wordset.  CATCH and THROW is a simple, elegant, easy to describe, essentially
complete solution to a problem that pretty much everybody understands.
Yet it is has taken a lot of flak about being "experimental".

The external call problem has none of that simplicity and elegance.
I have never seen a proposed solution that I think is even reasonably
complete, and I have probably designed and implemented more approximate
solutions to this problem than anybody else.

Mitch Bradley, wmb@Eng.Sun.COM

cwpjr@cbnewse.att.com (clyde.w.jr.phillips) (02/26/91)

In article <9102221434.AA04459@ucbvax.Berkeley.EDU>, wmb@MITCH.ENG.SUN.COM writes:
> > ... discussion of allowing Forth to call external (e.g. C) library routines
> >       Am I missing something or could this be easily solved by
> > a Vendor supplying a standard ( ANS ) system interface that has
> > built in support ( ie primitives ) for alternate form/sequence parameters?
> 
> In principle, it would be possible to do something like this.  The key
> is to develop a specification language to describe the routine that is
> to be called.
> 
> I have a fair amount of experience in this area;  I have developed "call
> compilers" to allow Forth to call external routines for about a dozen
> different forms of external routines/calling sequences/linkage mechanisms.
> 
> Here are some of the issues that a "call compiler" has to address:
> 
>         1) The name of the Forth word the calls the external routine (easy!)
>         2) The stack diagram of the Forth word (easy!)
>         3) The place to put the arguments to the external procedure
>            (can be fairly tricky)
>         4) Data type translation (for example, Forth and C have different
>            string representations)
>         5) Execution environment maintenance (for example, Macintosh system
>            calls require particular handling of the A6 register).
>         6) Linkage - how to find the actual address of the external routine,
>            or its trap number or whatever, and how to get the routine loaded
>            into memory.
>         7) Callbacks - Forth calling C is only half the problem; most people
>            eventually want C to be able to call back into Forth too (e.g. for
>            I/O services)
>         8) Error returns - many system call interfaces report errors
>            separately from their normal return value mechanism.
> 
> I have yet to develop a specification mechanism that can handle the full
> range of problems across all the environments that I have dealt with.
> I usually end up "tweaking" my specification syntax to some extent for
> each new system that I have to deal with.
> 
> This is one of those problems that appears straightforward from a
> conceptual standpoint, but once you get down to the details, it tends
> to get overwhelming in a combinatorial sense.
> 
> I cannot imagine in my wildest dreams that the ANS committee would ever
> standardize something like this.  It is just too complicated.  Witness the
> tremendous amount of discussion that has resulted from the CATCH/THROW
> wordset.  CATCH and THROW is a simple, elegant, easy to describe, essentially
> complete solution to a problem that pretty much everybody understands.
> Yet it is has taken a lot of flak about being "experimental".
> 
> The external call problem has none of that simplicity and elegance.
> I have never seen a proposed solution that I think is even reasonably
> complete, and I have probably designed and implemented more approximate
> solutions to this problem than anybody else.
> 
> Mitch Bradley, wmb@Eng.Sun.COM

I had something simpler in mind. It may be that what I see is useful
but won't solve the complete problem ( from a vendor or user pov ).

One service would be support for argument conversion.
This is essentially point 4 above. Being ignorant of the current
dpANS string wordset I can't spell it out here. Seems
a counted AND null padded string could be used counted for FORTH
and address +1 could be handed to C routines.

Does issue 3 above refer to non-stack passed calls?

Clyde