Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ANS Forth is not more powerful than ANSI C

14 views
Skip to first unread message

Michael L Gassanenko

unread,
Sep 23, 2003, 4:09:49 AM9/23/03
to
Alas....


Let us consider the following task:

Define two macros, ENTERING and EXITING, that, when used in any
function <func-name> will print the text "entering <func-name>"
and "exiting <func-name>", corresponingly.

The ANSI C solution is:


---- x.c ----
#define ENTERING printf("\nEntering %s",__func__);
#define EXITING printf("\nExiting %s",__func__);

int foo()
{
ENTERING
EXITING
}
int main()
{
ENTERING
foo();
EXITING
}
--- eof ---

$ a.exe

Entering main
Entering foo
Exiting foo
Exiting main

=========================
The Forth (but not ANS Forth) solution is:

---- x.f -----
: PLEASE$ POSTPONE S$ POSTPONE EVALUATE ; IMMEDIATE

: ENTERING
PLEASE$ { CR ." Entering " [ LATEST COUNT ] SLITERAL TYPE } ; IMMEDIATE
: EXITING
PLEASE$ { CR ." Exiting " [ LATEST COUNT ] SLITERAL TYPE } ; IMMEDIATE

: foo ENTERING EXITING ;
: main ENTERING foo EXITING ;
--- eof ---

The macros occupy 2 lines of code because there's a 80-char limit.

Of course, one could write
: ENTERING PLEASE$ {CR ." Entering "[ LATEST COUNT ] SLITERAL TYPE} ; IMMEDIATE
and that would fit the limit...

Anyway,


main

Entering main
Entering foo
Exiting foo
Exiting main ok[Dec]

So, between what is possible in Forth and ANS Forth there is what is possible in C.


Now, a quotation from the ANSI C standard (last draft):

> [#1] The identifier __func__ shall be implicitly declared by
> the translator as if, immediately following the opening
> brace of each function definition, the declaration
>
> static const char __func__[] = "function-name";
>
> appeared, where function-name is the name of the lexically-
> enclosing function.51)
>
[...]
>
> [#3] EXAMPLE Consider the code fragment:
>
> #include <stdio.h>
> void myfunc(void)
> {
> printf("%s\n", __func__);
> /* ... */
> }
> Each time the function is called, it will print to the
> standard output stream:
>
> myfunc
>

--
Just don't do any mistakes, and you will have no problems.

Jeff Massung

unread,
Sep 23, 2003, 12:57:17 PM9/23/03
to
Michael L Gassanenko <m_l...@yahoo.com> wrote in
news:3F6FFFCD...@yahoo.com:

> Alas....
>
>
> Let us consider the following task:
>
> Define two macros, ENTERING and EXITING, that, when used in any
> function <func-name> will print the text "entering <func-name>"
> and "exiting <func-name>", corresponingly.
>
> The ANSI C solution is:

[snipped a solution in C]

From the subject, certainly sounds like a troll, but...

1. Try and do this in C at compile time :)
2. The Forth version can be much easier (using SwiftForth):

: (entering) ." Entering: " code> >name count type cr ;
: (leaving) ." Leaving: " code> >name count type cr ;

: .: ( -- addr ) : here dup ['] (literal) compile,
-4 allot , ['] (entering) compile, ;

: .; ( addr -- ) postpone literal postpone (leaving)
postpone ; ; immediate

Now everything is very nice and neat:

.: SQ DUP * .;

4 SQ Entering: SQ
16
Leaving: SQ

--
Best regards,
Jeff mailto:j...@mfire.com
http://www.simforth.com

Elko Tchernev

unread,
Sep 23, 2003, 1:54:59 PM9/23/03
to
Michael L Gassanenko wrote:
> Alas....
>

Yes, really sad. Instead of whining how something is not possible
in ANS Forth, you could just think a little more. There are things that
are impossible in ANS Forth, true, but this is not one of them.

ANS Forth solution (can be optimized, but why bother):
-------------------------------------
CREATE current-name 256 CHARS ALLOT

: name-buff-place ( addr len -- )
255 MIN
DUP current-name C!
current-name CHAR+ SWAP CMOVE
;

: postpone"
postpone s"
; immediate

: entering
postpone" entering " postpone sliteral postpone type
current-name count postpone sliteral postpone type
postpone cr
; immediate

: exiting
postpone" exiting " postpone sliteral postpone type
current-name count postpone sliteral postpone type
postpone cr
; immediate

: :
>in @ >R
bl word count name-buff-place
R> >in !
:
;

: foo
entering
exiting
;

: main
entering
foo
exiting
;

: michael_doesn't_know_ANS:
entering
main
[ cr current-name count type cr ]
exiting
;
-------------------------------------

Michael L Gassanenko

unread,
Sep 23, 2003, 4:35:20 PM9/23/03
to
Elko Tchernev wrote:

> : michael_doesn't_know_ANS:

IMO a bit too personal, but finally the subject line has been a provocation

>
> Michael L Gassanenko wrote:
> > Alas....
> >
>
> Yes, really sad. Instead of whining how something is not possible
> in ANS Forth, you could just think a little more. There are things that
> are impossible in ANS Forth, true, but this is not one of them.
>
> ANS Forth solution (can be optimized, but why bother):

It is a screen of code (not counting foo and main); the C solution
is two lines of code.

In addition, it redefines ":" .

And at third, :NONAME entering ; EXECUTE can give surprizing results....

Anyway, the ANS Forth solution is 25 non-empty lines of code.
Well, 3 lines are not realy needed. So we've got 22 vs 2 LOC.
An order of magnitude, I would say.

So the more correct assertion is: it *is* possible in ANS Forth, but requires
a redefinition of : ( and :NONAME ), and takes an order of magnitude more LOC.

I can add that such solution does not affect OOP & other extensions
if they are present in the system.

[snip]


> > The Forth (but not ANS Forth) solution is:

[snip]

Jeff Massung

unread,
Sep 23, 2003, 4:06:05 PM9/23/03
to
Michael L Gassanenko <m_l...@yahoo.com> wrote in
news:3F70AE88...@yahoo.com:

>> ANS Forth solution (can be optimized, but why bother):

Check out the other solution.. and I'm sure mine could be improved as
well.

> It is a screen of code (not counting foo and main); the C solution
> is two lines of code.

*cough* The C solution is 2 lines because the compiler supports that 1
particular feature. And perhaps the C compiler you use for your next
project won't? The beauty of Forth is that it is *extensible* The fact
that it can be done, without inherent support is wonderful.

I'm currently porting over a C project into Forth. I have a very large
file filled with:

#define SOME_CONST some_number

I did not feel like making a new version of this file and swapping over
text to make it say:

some_number CONSTANT SOME_CONST

So, it was very easy to just code #DEFINE that did it for me. Try making
your C compiler import a Forth file filled with constants...

> In addition, it redefines ":" .

That is something of beauty! Not something to sneer at. And the
redefinitions made add no additional runtime overhead (other than
printing of the name, same as C); everything is done at compile time.

Elko Tchernev

unread,
Sep 23, 2003, 4:41:02 PM9/23/03
to
Michael L Gassanenko wrote:
> Elko Tchernev wrote:
>
>
>>: michael_doesn't_know_ANS:
>
>
> IMO a bit too personal, but finally the subject line has been a provocation
>
>
Yes, I was hoping you would see it this way; no offense was
intended. I should have used "michael_doesn't_know_ANS:-)" instead. :-)


>>
>>ANS Forth solution (can be optimized, but why bother):
>
>
> It is a screen of code (not counting foo and main); the C solution
> is two lines of code.
>

Your complaint was that it is not possible, not that it is long. As
I said, it could be probably made much shorter; I have no interest in
trying.


> In addition, it redefines ":" .
>

Yes, of course. Why not? I don't see that as something bad - the
original action of ":" is preserved. You can chain redefinitions of ":"
that way, and transparently add enhancements. This is (one of the ways)
how you extend Forth.

> And at third, :NONAME entering ; EXECUTE can give surprizing results....
>

Yes. And what does the C macro display on a nameless function?


> Anyway, the ANS Forth solution is 25 non-empty lines of code.
> Well, 3 lines are not realy needed. So we've got 22 vs 2 LOC.
> An order of magnitude, I would say.
>
> So the more correct assertion is: it *is* possible in ANS Forth, but requires
> a redefinition of : ( and :NONAME ), and takes an order of magnitude more LOC.
>

OK. I have no problem with this; it is is a fair description of
what goes on, and in no way demonstrates any C superiority. Why? -
because in a simplistic language like C, you only have one type of
function, and its name can be readily supplied by "__func__". In Forth,
you have not only ":", but :NONAME and the children of DOES> too. What
should ENTERING and EXITING display when they are in a DOES> section -
the name of the CREATEd word? Then you need to change CREATE and DOES>
too. And what about CODE words - you can't just plug in the same macro.
You definitely need a different one, if a macro can do it there.
But this is a moot point. As Jeff Massung shows with the SwiftForth
example, if you really need such a thing, presumably for debugging, you
can use the non-standard facilities of whatever Forth you use for the
project, and it will be short. After all, debugging is outside of the
scope of the Standard.

--
I want to be a nothing-knower, Elko Tchernev
a little ant on any hill; etc...@cs.umbc.edu
for time is dead, the sun is over www.gl.umbc.edu/~etcher1
and there is nothing left to kill.

Coos Haak

unread,
Sep 23, 2003, 5:23:09 PM9/23/03
to
On Tue, 23 Sep 2003 16:57:17 -0000, Jeff Massung
<j...@NOSPAM.mfire.com> wrote:

>: .: ( -- addr ) : here dup ['] (literal) compile,
> -4 allot , ['] (entering) compile, ;

What is it: is 4 the size of one or two
cells?
I won't even think of compiling this!

Coos

Jeff Massung

unread,
Sep 23, 2003, 5:41:19 PM9/23/03
to
Coos Haak <j.j....@hccnet.nl> wrote in
news:g6e1nvogq7q4olvpn...@4ax.com:

> On Tue, 23 Sep 2003 16:57:17 -0000, Jeff Massung
> <j...@NOSPAM.mfire.com> wrote:
>
>>: .: ( -- addr ) : here dup ['] (literal) compile,
>> -4 allot , ['] (entering) compile, ;
>
> What is it: is 4 the size of one or two
> cells?

I stated that it was SwiftForth *only* So there is no problem with
compiling and using this code. -4 was just easier to type that CELL
NEGATE.

> I won't even think of compiling this!

I'll never understand why sometimes people here are so critical of code
that is not displayed for usage, but rather for theory and concept (read:
it was slapped together in < a minute).

Gary Chanson

unread,
Sep 23, 2003, 11:35:25 PM9/23/03
to

"Jeff Massung" <j...@NOSPAM.mfire.com> wrote in message
news:vn1ffvd...@corp.supernews.com...

> Coos Haak <j.j....@hccnet.nl> wrote in
> news:g6e1nvogq7q4olvpn...@4ax.com:
>
> > On Tue, 23 Sep 2003 16:57:17 -0000, Jeff Massung
> > <j...@NOSPAM.mfire.com> wrote:
> >
> >>: .: ( -- addr ) : here dup ['] (literal) compile,
> >> -4 allot , ['] (entering) compile, ;
> >
> > What is it: is 4 the size of one or two
> > cells?
>
> I stated that it was SwiftForth *only* So there is no problem with
> compiling and using this code. -4 was just easier to type that CELL
> NEGATE.

Then try "-1 CELLS".

--

-GJC
-Software Consultant (Embedded systems and Real Time Controls)
-gcha...@mvps.org

-Abolish public schools


andr...@littlepinkcloud.invalid

unread,
Sep 24, 2003, 5:16:25 AM9/24/03
to
Michael L Gassanenko <m_l...@yahoo.com> wrote:
> Elko Tchernev wrote:

>> : michael_doesn't_know_ANS:

> IMO a bit too personal, but finally the subject line has been a provocation

>>
>> Michael L Gassanenko wrote:
>> > Alas....
>> >
>>
>> Yes, really sad. Instead of whining how something is not possible
>> in ANS Forth, you could just think a little more. There are things that
>> are impossible in ANS Forth, true, but this is not one of them.
>>
>> ANS Forth solution (can be optimized, but why bother):

> It is a screen of code (not counting foo and main); the C solution
> is two lines of code.

That's because you're using a function that is already a C builtin,
but in Forth, which is a relatively minimal language, you have to
write it yourself. What's your point, exactly?

> In addition, it redefines ":" .

Yes. And?

Andrew.

Michael L Gassanenko

unread,
Sep 24, 2003, 6:08:45 PM9/24/03
to
andr...@littlepinkcloud.invalid wrote:
> What's your point, exactly?

Access to the name of the last definition should be
there in the Forth standard.

I was telling this before, now I repeat this with one more
justification: C HAS IT.


--

As to redefining : , I dislike it because the purpose of this redefinition
is to get access to what is already accessed by it. By defining the name
buffer one invents a new wheel and attaches it to the vehicle whereas
what is wanted is one more seat.

BTW, my code would be shorter if I defined
: _func_ LATEST COUNT [COMPILE] SLITERAL ; IMMEDIATE

In addition, it would be more portable, since _func_ would be a single
system-dependent definition.

Its implementation may or may not require redefinition of : and friends.

IIRC, __func__ is not the only thing present in C but missing
in ANS Forth. For example, the C standard is aware of multiple
executions of a program...
It also has a standard NULL ...

I thought that such criticism of the 1994 standard would be useful,
but now I doubt it.

OTOH, we anyway need a list of ANS Forth shortcomings.
(Although who is 'we' is arguable.)

Regnirps

unread,
Sep 24, 2003, 8:43:10 PM9/24/03
to
andr...@littlepinkcloud.invalid wrote:

<< That's because you're using a function that is already a C builtin,
but in Forth, which is a relatively minimal language, you have to
write it yourself. What's your point, exactly? >>

Actually, isn't he using a built in function to find the name plus an external
library for the printf? There is quite a bit of code involved in those "two
lines".

-- Charlie Springer

PhiHo Hoang

unread,
Sep 25, 2003, 12:41:03 AM9/25/03
to
Hi,

> ---- x.c ----
>
> #define ENTERING printf("\nEntering %s",__func__);
> #define EXITING printf("\nExiting %s",__func__);

#define E_TING(x) printf("\n%s %s", x, __func__);

---- y.f ----


>
> : entering
> postpone" entering " postpone sliteral postpone type
> current-name count postpone sliteral postpone type
> postpone cr
> ; immediate
>
> : exiting
> postpone" exiting " postpone sliteral postpone type
> current-name count postpone sliteral postpone type
> postpone cr
> ; immediate

In the tradition of Forth, how can I define this word e_ting" :

: e_ting" ( -- )
???
; ???

such that :

: entering ( -- )
e_ting" entering "
; \ immediate ?

: exiting ( -- )
e_ting" exiting "
; \ immediate ?


Thanks for your help.

PhiHo.

"Elko Tchernev" <etch...@acm.org> wrote in message
news:bkq1cr$4mohl$1...@ID-198329.news.uni-berlin.de...

Elko Tchernev

unread,
Sep 25, 2003, 1:49:21 AM9/25/03
to
PhiHo Hoang wrote:

Just split the definition and postpone postpone" , like this:


: ing


postpone sliteral postpone type
current-name count postpone sliteral postpone type
postpone cr
;

: e_ting"
postpone postpone"
postpone ing
; immediate

: entering
e_ting" entering "
; immediate

: exiting
e_ting" exiting "
; immediate


andr...@littlepinkcloud.invalid

unread,
Sep 25, 2003, 5:51:17 AM9/25/03
to
Michael L Gassanenko <m_l...@yahoo.com> wrote:
> andr...@littlepinkcloud.invalid wrote:
>> What's your point, exactly?

> Access to the name of the last definition should be there in the
> Forth standard.

Well, you just failed to prove it.

> I was telling this before, now I repeat this with one more
> justification: C HAS IT.

How does that get to be a justification? C has a ton of stuff that
Forth doesn't have. Forth is [still] a small language.

> As to redefining : , I dislike it because the purpose of this
> redefinition is to get access to what is already accessed by it.

Okay, so you personally dislike it. But what is that to anyone but
you?

> By defining the name buffer one invents a new wheel and attaches it
> to the vehicle whereas what is wanted is one more seat.

> IIRC, __func__ is not the only thing present in C but missing
> in ANS Forth.

No kidding! Who would have thought so? :-)

> For example, the C standard is aware of multiple executions of a
> program...

Come again?

> It also has a standard NULL ...

Gosh, I actually agree with this point! But it's pretty trivial to
generate an address that will not be used for any object.

Andrew.

PhiHo Hoang

unread,
Sep 25, 2003, 3:07:44 PM9/25/03
to

Elko Tchernev wrote :

>
> Just split the definition and postpone postpone" , like this:
>
>
> : ing
> postpone sliteral postpone type
> current-name count postpone sliteral postpone type
> postpone cr
> ;
>
> : e_ting"
> postpone postpone"
> postpone ing
> ; immediate
>
> : entering
> e_ting" entering "
> ; immediate
>
> : exiting
> e_ting" exiting "
> ; immediate
>
>

Thanks, that works as expected.

I guess ing can be further refactored :

: ing
PostponeSliteralPostponeType
current-name count
PostponeSliteralPostponeType
postpone cr
;

Cheers,

PhiHo.


Jeff Massung

unread,
Sep 26, 2003, 11:40:03 AM9/26/03
to
Michael L Gassanenko <m_l...@yahoo.com> wrote in
news:3F7215ED...@yahoo.com:

> For example, the C standard is aware of multiple
> executions of a program...

That is just plain wrong. Where did you learn programming?

Anton Ertl

unread,
Sep 27, 2003, 1:41:56 AM9/27/03
to
Michael L Gassanenko <m_l...@yahoo.com> writes:
>andr...@littlepinkcloud.invalid wrote:
>> What's your point, exactly?
>
>Access to the name of the last definition should be
>there in the Forth standard.

Would be nice, but it's obviously not necessary.

>I was telling this before, now I repeat this with one more
>justification: C HAS IT.

So what? C also has qsort. Would you also claim that this has any
effect on the expressive power of C vs. Forth?

I would rather say that the example you gave showed that Forth is more
powerful: In C you need __func__ as special built-in feature, because
you cannot recreate it yourself; in Forth you can recreate it
yourself, so you don't need it as built-in.

>IIRC, __func__ is not the only thing present in C but missing
>in ANS Forth. For example, the C standard is aware of multiple
>executions of a program...

Can you elaborate on that?

>It also has a standard NULL ...

Well, defining

variable NULL

is easy enough, but it would certainly be nice if the standard
guaranteed that no memory area allocated by standard means includes
the address 0. My programs have that environmental dependency all
over the place.

>I thought that such criticism of the 1994 standard would be useful,

Sure, make a list of them (and possibly proposed amendmends, like
<http://www.complang.tuwien.ac.at/forth/ansforth/proposals.html>), and
hopefully when there will be another standard, they will hopefully be
integrated.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
EuroForth: http://www.micross.co.uk/euroforth2003/Call_for_Participation.html

Dave Thompson

unread,
Sep 29, 2003, 12:11:19 AM9/29/03
to
On Tue, 23 Sep 2003 11:09:49 +0300, Michael L Gassanenko
<m_l...@yahoo.com> wrote:

> Alas....
>
>
> Let us consider the following task:
>
> Define two macros, ENTERING and EXITING, that, when used in any
> function <func-name> will print the text "entering <func-name>"
> and "exiting <func-name>", corresponingly.
>
> The ANSI C solution is:
>
>
> ---- x.c ----
> #define ENTERING printf("\nEntering %s",__func__);
> #define EXITING printf("\nExiting %s",__func__);
>

Nit: only in the 1999 revision, aka C99, or if you are so picky as to
mean ANSI-rather-than-ISO C00 because it took several months for the
formal approval. Which (either way) is not yet widely implemented,
though GCC has had __FUNCTION__ as a C90 extension for some time.

Also, to be *completely* standard, you must terminate or follow at
least the final output with a newline \n; C can be (and has been)
implemented on systems where an unterminated or "partial" last line
doesn't work, so the standard deliberately allows for this. Usually
it's easiest to just end rather than begin each output line with \n.

- David.Thompson1 at worldnet.att.net

Michael L Gassanenko

unread,
Oct 6, 2003, 5:08:41 PM10/6/03
to
Anton Ertl wrote:
>
> >It also has a standard NULL ...
>
> Well, defining
>
> variable NULL
>
> is easy enough,

Provided that special care have been taken to guarantee that
NULL cannot be defined twice.

> but it would certainly be nice if the standard
> guaranteed that no memory area allocated by standard means includes
> the address 0.

by standard means in standard programs

(ALLOT is a standard means, but it can (sometimes) allocate memory at 0,
but such use should have an environmental dependency)

Michael L Gassanenko

unread,
Oct 6, 2003, 5:22:30 PM10/6/03
to
Anton Ertl wrote:
>
> >IIRC, __func__ is not the only thing present in C but missing
> >in ANS Forth. For example, the C standard is aware of multiple
> >executions of a program...
>
> Can you elaborate on that?

: 23)The term constant address means that two pointers to the
: object constructed at possibly different times will
: compare equal. The address may be different during two
: different executions of the same program.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


: [#2] An object whose identifier is declared with external or
: internal linkage, or with the storage-class specifier static
: has static storage duration. For such an object, storage is
: reserved and its stored value is initialized only once,
: prior to program startup. The object exists, has a constant
: address, and retains its last-stored value throughout the
: execution of the entire program.23)


The current Forth standard ignores such things as program
startup and program termination.


--
One always has a choice: to do something, or to find a number of reasons
why that cannot and/or should not be done.

andr...@littlepinkcloud.invalid

unread,
Oct 7, 2003, 5:13:48 AM10/7/03
to
Michael L Gassanenko <m_l...@yahoo.com> wrote:

> The current Forth standard ignores such things as program
> startup and program termination.

I'm not sure what you mean by this. After all, : is Forth's "program
startup" and EXIT is Forth's "program termination".

Unless perhaps you're talking about executing a Forth system as a
sub-process of an external OS, and the Forth standard quite rightly
has nothing to say about that. After all, there doesn't have to be an
external OS.

Andrew.

Stephane Richard

unread,
Oct 7, 2003, 7:18:25 AM10/7/03
to
<andr...@littlepinkcloud.invalid> wrote in message
news:vo50uc8...@news.supernews.com...

I'm thinking maybe he's saying that forth has no "exe header info" in his
executable compiled format? As in when you compile your forth code into an
EXE application?

I dont know enough to answer that. But I'm curious to know so I throw the
Mic to all you Forth Gurus :-)
--
Stéphane Richard
Software Developer


jonah thomas

unread,
Oct 7, 2003, 8:59:04 AM10/7/03
to

Lots of Forths have used BYE to terminate, or possibly COLD .

I'm not sure how we could standardise methods to start up Forth when
there isn't already a Forth running. That's an OS issue. Similarly
calling Forth from code written in other languages.

The current standard says nothing about initiating or communicating with
programs that are not written in Forth, except CODE . CODE doesn't do
much for portability since there isn't much you can standardise about it
beyond the name. I guess the major thing it does is to establish that
standard programs are allowed to have CODE words.

Starting new Forths from an existing Forth would be part of
multitasking. There isn't enough common practice in multitasking. It
would be hard to standardise, I don't know what it would take to set up
code that would work the same way whether you're using pre-emptive
versus round-robin multitasking. (I think it would be hard. I haven't
tried.)

The only real candidate I see here for standardisation is BYE .
Application programs usually wouldn't use BYE , it would belong in the
Tools Extension wordset. We haven't missed out on much with it not there.

clvrmnky

unread,
Oct 7, 2003, 11:56:20 AM10/7/03
to
andr...@littlepinkcloud.invalid wrote:

> Michael L Gassanenko <m_l...@yahoo.com> wrote:
>
>
>>The current Forth standard ignores such things as program
>>startup and program termination.
>
>
> I'm not sure what you mean by this. After all, : is Forth's "program
> startup" and EXIT is Forth's "program termination".
>

Hmmm. Isn't : just another word, one that directs the Forth interpreter
and input stream to start compiling byte code (I'm over-simplifying
here, I know...)?

Since the interpreter is always running, there really isn't a "program
start" in the traditional run-from-linked-object-code sense. If the
start of any Forth word is the outer interpreter, wouldn't QUIT be more
correct as a "start", if we needed to talk about one?

Note that I'm hand-waving any implementation-specific constructs like
being able to make some kind of platform-dependent executable that one
can run from a single user-gesture (a mouse click, hitting enter, etc.).
To my mind, such constructs are part of the vendor implementation for
a given development and target platform, and not necessarily part of the
Forth language.

I like to think of the Forth interpreter as the ultimate starting point:
a toolbox full of handy bits and pieces I can use to describe the
solution to my problem, and one that comes with a nice interactive
debugger. That is, once you get past the platform- or
implementation-specific semantics of launching your program, the Forth
interpreter(s) take over by launching your top-level word(s).

Astrobe

unread,
Oct 7, 2003, 12:18:57 PM10/7/03
to
andr...@littlepinkcloud.invalid wrote in message news:<vo50uc8...@news.supernews.com>...

" Return control to the host operating system, if any."
BYE, Andrew :)

Amicalement,
Astrobe

Anton Ertl

unread,
Oct 7, 2003, 12:41:11 PM10/7/03
to
jonah thomas <j2th...@cavtel.net> writes:
>The only real candidate I see here for standardisation is BYE .
>Application programs usually wouldn't use BYE , it would belong in the
>Tools Extension wordset.

The TC must have had similar thoughts when they put 15.6.2.0830 BYE in
the TOOLS EXT wordset.

jonah thomas

unread,
Oct 7, 2003, 12:51:10 PM10/7/03
to
Anton Ertl wrote:
> jonah thomas <j2th...@cavtel.net> writes:

>>The only real candidate I see here for standardisation is BYE .
>>Application programs usually wouldn't use BYE , it would belong in the
>>Tools Extension wordset.

> The TC must have had similar thoughts when they put 15.6.2.0830 BYE in
> the TOOLS EXT wordset.

Oops! :)

Anton Ertl

unread,
Oct 7, 2003, 2:32:48 PM10/7/03
to
Michael L Gassanenko <m_l...@yahoo.com> writes:
>Anton Ertl wrote:
>>
>> >IIRC, __func__ is not the only thing present in C but missing
>> >in ANS Forth. For example, the C standard is aware of multiple
>> >executions of a program...
>>
>> Can you elaborate on that?
>
>: 23)The term constant address means that two pointers to the
>: object constructed at possibly different times will
>: compare equal. The address may be different during two
>: different executions of the same program.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
>
>: [#2] An object whose identifier is declared with external or
>: internal linkage, or with the storage-class specifier static
>: has static storage duration. For such an object, storage is
>: reserved and its stored value is initialized only once,
>: prior to program startup. The object exists, has a constant
>: address, and retains its last-stored value throughout the
>: execution of the entire program.23)
>
>
>The current Forth standard ignores such things as program
>startup and program termination.

Well, there is BYE. And I have not seen much more in the C standard
(ok, there is argc and argv). The examples you show appear pretty
superfluous to me, especially in the context of the Forth standard:

Since the Forth standard deals with only one timeline in the
text-interpretation of a standard program, there is no need for
verbiage like your second example: objects are created when the
appropriate standard word is executed, and unless it is destroyed
because of some other standard word, it continues to exist as long as
the system runs.

For the first example, if the C standard gave guarantees of equality
of the address, then that would be interesting. But it does not; do
you claim that this makes the C standard any better than the Forth
standard, which does not provide any such guarantees, either?

Of course, one could add verbiage like that to the Forth standard, but
what would be gained by it? Would we get better Forth systems or
better Forth programs? To me it sounds just like bloat, and a number
of people complain about the size of the standard already, and that it
is hard to read etc.

Guido Draheim

unread,
Oct 7, 2003, 3:54:21 PM10/7/03
to

Michael L Gassanenko wrote:
> Anton Ertl wrote:
>
>>>IIRC, __func__ is not the only thing present in C but missing
>>>in ANS Forth. For example, the C standard is aware of multiple
>>>executions of a program...
>>
>>Can you elaborate on that?
>
>
> : 23)The term constant address means that two pointers to the
> : object constructed at possibly different times will
> : compare equal. The address may be different during two
> : different executions of the same program.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
>
> : [#2] An object whose identifier is declared with external or
> : internal linkage, or with the storage-class specifier static
> : has static storage duration. For such an object, storage is
> : reserved and its stored value is initialized only once,
> : prior to program startup. The object exists, has a constant
> : address, and retains its last-stored value throughout the
> : execution of the entire program.23)
>
>
> The current Forth standard ignores such things as program
> startup and program termination.
>

I was just holding a lecture expanding the students knowledge
on C providing them with the pieces that let us refer to C as
a kind of highlevel assembler. Among the differences to plain
assembly of opcodes to a text segment we see that:
- C is able to assign a size and segment location to all
symbols - a static variable declared inside a function
will make the variable be placed in the .data segment and
the rest of the function in the .text segment with the
executable code carrying a pointer to the .data
- the segments are assembled into an object wrapper or exe
wrapper. The operating system however is allowed to handle
each segment separatly, possibly binding them to very
different adresses. References between the segments are
properly relocated. It is allowed to combine segments of
the same type from different .o files, the relink operation
will take care to fix up all references.

Take special notice that you can not take the sizeof() any
symbol in the forth area. Neither do we have segmentation
differentations in the forth standard that the forth programmer
could use - while of course some forth compiler vendors actually
invented extensions for just that. It's a saner approach.

Furthermore, there is no standardized way to express the
need for a relocation info on the source level, and multisegment
relinkable binaries are pretty much unknown in the forth world.
It makes forth stuck in the area of which in CC/LD we say they
are static-linked self-hosted applications with no dependency
on other binaries or libraries at startup, running directly on
the kernel traps, - and yes, quite often pre-compilation into
a binary is not done anyway, using forth as a readably and
modifiable form of byte code being not optimized deeply.

Hope this helps, and incremental ALLOT is evil, right Krishna? :-)=)
-- cheers, guido


andr...@littlepinkcloud.invalid

unread,
Oct 7, 2003, 4:13:10 PM10/7/03
to
Guido Draheim <guidod...@gmx.de> wrote:

> Take special notice that you can not take the sizeof() any
> symbol in the forth area. Neither do we have segmentation
> differentations in the forth standard that the forth programmer
> could use - while of course some forth compiler vendors actually
> invented extensions for just that.

There's no standard way in C to differentiate segments either.

> It's a saner approach.

> Furthermore, there is no standardized way to express the need for a
> relocation info on the source level, and multisegment relinkable
> binaries are pretty much unknown in the forth world.

Right, but given that Forth sometimes compiles from source faster than
conventional linkers link, I would have thought that a plus.

Andrew.

Guido Draheim

unread,
Oct 7, 2003, 4:42:08 PM10/7/03
to

andr...@littlepinkcloud.invalid wrote:
> Guido Draheim <guidod...@gmx.de> wrote:
>
>
>>Take special notice that you can not take the sizeof() any
>>symbol in the forth area. Neither do we have segmentation
>>differentations in the forth standard that the forth programmer
>>could use - while of course some forth compiler vendors actually
>>invented extensions for just that.
>
>
> There's no standard way in C to differentiate segments either.

They are assigned implicitly by the compiler, and they will
_always_ do that. Even B was doing it. Explicit segment association
by the programmer does exist but it is not standardized to a
common syntax. Forth does not do any segmentation by default.


>
>
>>It's a saner approach.
>
>
>>Furthermore, there is no standardized way to express the need for a
>>relocation info on the source level, and multisegment relinkable
>>binaries are pretty much unknown in the forth world.
>
>
> Right, but given that Forth sometimes compiles from source faster than
> conventional linkers link, I would have thought that a plus.
>

Yes, it is, but see how forth compiler vendors will disagree
promptly and put up references on the advantages of highly
optimized code in forth binaries. It seems that the current
forth standard has made provisions for native code forth but
not for binaries in native code, a difference with other
language specifications. In a way, forth is stuck at being
an optimized scripting language, not a compiler - but the
current forth compiler vendors have shown that it is in fact
possible to turn forth into a compiler language. There are
just not the least provisions for it in the forth specification.
So the question is there again, is C more powerful, and may
be that it was the case for the last thirty years?


andr...@littlepinkcloud.invalid

unread,
Oct 8, 2003, 5:09:44 AM10/8/03
to
Guido Draheim <guidod...@gmx.de> wrote:
> andr...@littlepinkcloud.invalid wrote:
>> Guido Draheim <guidod...@gmx.de> wrote:
>>
>>
>>>Take special notice that you can not take the sizeof() any
>>>symbol in the forth area. Neither do we have segmentation
>>>differentations in the forth standard that the forth programmer
>>>could use - while of course some forth compiler vendors actually
>>>invented extensions for just that.
>>
>>
>> There's no standard way in C to differentiate segments either.

> They are assigned implicitly by the compiler, and they will
> _always_ do that. Even B was doing it. Explicit segment association
> by the programmer does exist but it is not standardized to a
> common syntax. Forth does not do any segmentation by default.

Well, it depends on what you mean by that. I've certainly used Forths
that have separate memory areas for code and data -- in fact I've
written one. The C standard says nothing about segmentation.

I'm trying to figure out whether your point is a about common practice
or formal standardization.

>>>It's a saner approach.
>>
>>>Furthermore, there is no standardized way to express the need for a
>>>relocation info on the source level, and multisegment relinkable
>>>binaries are pretty much unknown in the forth world.
>>
>> Right, but given that Forth sometimes compiles from source faster
>> than conventional linkers link, I would have thought that a plus.

> Yes, it is, but see how forth compiler vendors will disagree
> promptly and put up references on the advantages of highly optimized
> code in forth binaries. It seems that the current forth standard has
> made provisions for native code forth but not for binaries in native
> code, a difference with other language specifications.

In what way does the C standard make provision for a binary in native
code? By my reading of that document it, a fully interpreted C
implementation is just as compliant as a compiled one.

> In a way, forth is stuck at being an optimized scripting language,
> not a compiler - but the current forth compiler vendors have shown
> that it is in fact possible to turn forth into a compiler
> language. There are just not the least provisions for it in the
> forth specification.

It would help if you provided references to the C standard that permit
such things and show that they are missing in the Forth standard. I
already know about argv. I suppose there's the notion of a "main"
function, which is something that Forth doesn't have. Is there
anything else?

I reckon most of the utility associated with C comes from common
practice: things like Makefiles, linkers, libraries, and so on are not
part of the C standard.

Andrew.

Astrobe

unread,
Oct 8, 2003, 7:56:28 AM10/8/03
to
Guido Draheim <guidod...@gmx.de> wrote in message news:<blv5g9$2hc$00$1...@news.t-online.com>...

Excuse me...
Forth is often compared to C for the only reason that C is one of the
most popular language. It should be clear for every one that C and
Forth are not in the same category; if nothing else, C is a strongly
typed language whereas Forth is not - hence the lack of a thing like
sizeof().

Amicalement,
Astrobe

Guido Draheim

unread,
Oct 8, 2003, 8:18:41 AM10/8/03
to


Ahh, I see your point, and you are right the C language spec does
only describe the language and not the way it is compiled into some
output. And yes, the Forth language spec is quite similar in that.

One basic difference is that the C language had always been
differentiating between function symbols and data symbols quite
strictly to be compiled into an output binary. I am not sure
how that is enforced in a forth compiler pushing the parts to
different segments. No extra words needed in surplus of ANS forth?
You wrote one, you tell.

As for the other, there is a definite section in the ANS forth
spec that a "solid dict" approach is assumed - subsequent
incremental allocations from the forth dict space are expected
to yield adjascent memory areas. All words that might break
that assumption are marked in the ANS forth spec. Especially,
there is no "end of allocations" mark to hint a compiler to
possibly put a break in, and consequently a forth word does
not have a direct sizeof() unless by implication of the start
of the next symbol.

And last, in forth we handle compilation by direct reference
to adresses, not symbols. In C each function symbol or data
symbol does not have an adress during compilation, the actual
adress is assigned during (re)linking or loading to execute.
Some forths have expanded on that with words that tell the
compiler to say what an adress is that possibly needs
relocation by the loader.

Note that .o objects do relocation by symbol - some forths
have been doing the approach of mere `single offset value`
to support relocation. That kills dynamic binding of
multiple segments / objects and interrelations like the
import of symbols from another library.

May be there is more, I would simply maintain a mere
ANS forth compliant forth compiler does not fit into the
contemporary toolchain to compile source code to .o
objects being handled by a linker or loader. That accounts
to both old C ld/ldso or modern java/dotnet object linkage.
In a way, forth is stuck in its own area while in other
programming realms a lot of work has been done to allow linking
of objects from different input source languages. The
current dotnet platform heading off in functionality here.

Btw, does anyone have an object linker for native code
forth that can relink multiple object modules? Expanded
to allow loader linkage? Any of those Forth OS perhaps?

cheers, guido http://PFE.sf.net

Guido Draheim

unread,
Oct 8, 2003, 8:20:31 AM10/8/03
to

B was typeless for the most part either. That does not hold off the
existance of a sizeof attribution for a symbol. -- cheers, guido


andr...@littlepinkcloud.invalid

unread,
Oct 8, 2003, 9:27:29 AM10/8/03
to
Guido Draheim <guidod...@gmx.de> wrote:

> Ahh, I see your point, and you are right the C language spec does
> only describe the language and not the way it is compiled into some
> output. And yes, the Forth language spec is quite similar in that.

> One basic difference is that the C language had always been
> differentiating between function symbols and data symbols quite
> strictly to be compiled into an output binary. I am not sure how
> that is enforced in a forth compiler pushing the parts to different
> segments. No extra words needed in surplus of ANS forth? You wrote
> one, you tell.

I didn't attempt to make my Forth ANS. I think it could be done, but
I'd have to try to be sure.

> As for the other, there is a definite section in the ANS forth
> spec that a "solid dict" approach is assumed - subsequent
> incremental allocations from the forth dict space are expected
> to yield adjascent memory areas.

That's true, but the bodies of colon definitions (and, I think, the
dictionary headers) don't have to go into the dictionary at HERE.
They can go somewhere else. There's no problem obvious to me that
would prevent you from generating symbols in a .o file for every
definition and putting those definitions into a .o file in the .text
section, along with the dictionary space in the .data section. I've
never seen a compelling reason for doing so.

> All words that might break that assumption are marked in the ANS
> forth spec. Especially, there is no "end of allocations" mark to
> hint a compiler to possibly put a break in, and consequently a forth
> word does not have a direct sizeof() unless by implication of the
> start of the next symbol.

True enough, but remember that in the pre-ELF days, symbol sizes
weren't usually available to the linker either.

> And last, in forth we handle compilation by direct reference
> to adresses, not symbols.

Do we? Are you sure about that? According to ANS, what we actually
have is an execution token. This has to fit into a cell but otherwise
can be anything at all, including a symbol reference.

> In C each function symbol or data symbol does not have an adress
> during compilation, the actual adress is assigned during (re)linking
> or loading to execute. Some forths have expanded on that with words
> that tell the compiler to say what an adress is that possibly needs
> relocation by the loader.

> Note that .o objects do relocation by symbol - some forths have been
> doing the approach of mere `single offset value` to support
> relocation. That kills dynamic binding of multiple segments /
> objects and interrelations like the import of symbols from another
> library.

> May be there is more, I would simply maintain a mere ANS forth
> compliant forth compiler does not fit into the contemporary
> toolchain to compile source code to .o objects being handled by a
> linker or loader.

Sure, I'm not arguing with that. But you're comparing typical
implementations, not standards.

The real bugbear about generating .o files and then linking before any
execution is possible is the lack of interactivity that implies.

Andrew.

Guido Draheim

unread,
Oct 8, 2003, 11:20:58 AM10/8/03
to

True, symbol sizes are only available in the C compiler context,
the linker only handles (symbolic) start adresses. That's why
C needs header files to tell other compilation modules about the
type/size of a symbol which will be given an adress later during
linkage. Modern approaches put a lot more information into the
object files, java et co do not need header files but just the
object modules they want to import/link with.


>
>
>>And last, in forth we handle compilation by direct reference
>>to adresses, not symbols.
>
>
> Do we? Are you sure about that? According to ANS, what we actually
> have is an execution token. This has to fit into a cell but otherwise
> can be anything at all, including a symbol reference.

I meant the HERE problem which Krishna might be able to put more
light on. To resolve interrelations between words, or even in the
same word, we just compile the adress. May be mark> resolve> might
be better choice to kill the usage of HERE? What about interrelations
in the data body of create/does words that comma's a here backreference?
In C all those would be symbol.offsetmember with the base adress of the
symbol left out, and in code they are local labels that can be seen
in cc -S intermediate assembly output.

Surely, the introduction of `xt` and `compile,` has been helping the
situation in code parts but we see reference to HERE still a lot in
real code where programmers want to create their own control structures
in code or complex data containers. May be one can invent a set of
words to kill the usage of HERE adresses completly, and push it into
a standard wordset? Only using symbolic IDs generated/expected by
their (ID-specific) words? May be.

>
>
>>In C each function symbol or data symbol does not have an adress
>>during compilation, the actual adress is assigned during (re)linking
>>or loading to execute. Some forths have expanded on that with words
>>that tell the compiler to say what an adress is that possibly needs
>>relocation by the loader.
>
>
>>Note that .o objects do relocation by symbol - some forths have been
>>doing the approach of mere `single offset value` to support
>>relocation. That kills dynamic binding of multiple segments /
>>objects and interrelations like the import of symbols from another
>>library.
>
>
>>May be there is more, I would simply maintain a mere ANS forth
>>compliant forth compiler does not fit into the contemporary
>>toolchain to compile source code to .o objects being handled by a
>>linker or loader.
>
>
> Sure, I'm not arguing with that. But you're comparing typical
> implementations, not standards.
>
> The real bugbear about generating .o files and then linking before any
> execution is possible is the lack of interactivity that implies.
>

Aye, interactive C implementations are rare but they do exist, i.e.
scripting with C syntax. Same for most other languages under the
sun, it just happens that the interactivity is largely limited
while in forth it has been in common from its first days.

cheers, guido

andr...@littlepinkcloud.invalid

unread,
Oct 8, 2003, 12:06:28 PM10/8/03
to
Guido Draheim <guidod...@gmx.de> wrote:
>>
>>>And last, in forth we handle compilation by direct reference
>>>to adresses, not symbols.
>>
>>
>> Do we? Are you sure about that? According to ANS, what we actually
>> have is an execution token. This has to fit into a cell but otherwise
>> can be anything at all, including a symbol reference.

> I meant the HERE problem which Krishna might be able to put more
> light on. To resolve interrelations between words, or even in the
> same word, we just compile the adress.

I see your point. There is a problem where you use , to compile the
address of a word in a different module, and yes you'd need a
relocation for that. I suspect that you could -- if you really wanted
to -- find a way to generate that relocation automatically and still
be ANS compliant. But the issue in my mind is why you'd want to do
that. How would it make the world a better place? What would
generating a bunch of relocatable objects achieve?

Andrew.

Guido Draheim

unread,
Oct 8, 2003, 1:15:33 PM10/8/03
to

That's about established processes,
(a) large highly optimized applications for one part,
where the development process only touches a few
modules that get compiled into the target format
with the help of expensive optimization routines.
Then relink the application with other modules
that do not need to get recompiled, and assume
the relinking to be a fast process in here.
That is the 'linker processing'.
(b) update a process context with new libraries and
binaries from which processes are started dynamically.
The loader can bind modules into different memory
areas and resolve interdependencies, they can be
unloaded and reloaded as the processing continues.
No need to hold all modules in memory at all time.
That is the 'loader processing'.
(c) While the earlier is established practice in
legacy operating systems, some realtime systems
use interface ports. The target module of a
call can be replaced during execution of any
process using the services. The old and new
module probably exist at the same time for a
short period and in different memory areas.
We would call that a `defer` execution in forth,
otherwise one may call it callgate processing.

Nothing is impossible in forth, any of these are done
with a third side infrastructure. It just needs ways
to properly build modules from forth source code and
attach attributions that can be used by the infrastructure.
The `solid dict` approach in forth is more pointed to
boot solid applications and runtime environments with
no dynamics like loading/unloading/rebinding - where
forth itself handles all interdepencies with no other
infrastructure involved.

cheers, guido

andr...@littlepinkcloud.invalid

unread,
Oct 8, 2003, 1:50:35 PM10/8/03
to
Guido Draheim <guidod...@gmx.de> wrote:


> andr...@littlepinkcloud.invalid wrote:
>> Guido Draheim <guidod...@gmx.de> wrote:
>>
>>>>>And last, in forth we handle compilation by direct reference
>>>>>to adresses, not symbols.
>>>>
>>>>
>>>>Do we? Are you sure about that? According to ANS, what we actually
>>>>have is an execution token. This has to fit into a cell but otherwise
>>>>can be anything at all, including a symbol reference.
>>
>>
>>>I meant the HERE problem which Krishna might be able to put more
>>>light on. To resolve interrelations between words, or even in the
>>>same word, we just compile the adress.
>>
>>
>> I see your point. There is a problem where you use , to compile the
>> address of a word in a different module, and yes you'd need a
>> relocation for that. I suspect that you could -- if you really wanted
>> to -- find a way to generate that relocation automatically and still
>> be ANS compliant. But the issue in my mind is why you'd want to do
>> that. How would it make the world a better place? What would
>> generating a bunch of relocatable objects achieve?
>>

> That's about established processes,
> (a) large highly optimized applications for one part,
> where the development process only touches a few
> modules that get compiled into the target format
> with the help of expensive optimization routines.

"Help"? :-)

> Then relink the application with other modules
> that do not need to get recompiled, and assume
> the relinking to be a fast process in here.

I will assume no such thing! I wrote this whole message while waiting
for a library to link.

> That is the 'linker processing'.
> (b) update a process context with new libraries and
> binaries from which processes are started dynamically.
> The loader can bind modules into different memory
> areas and resolve interdependencies, they can be
> unloaded and reloaded as the processing continues.
> No need to hold all modules in memory at all time.
> That is the 'loader processing'.
> (c) While the earlier is established practice in
> legacy operating systems, some realtime systems
> use interface ports. The target module of a
> call can be replaced during execution of any
> process using the services. The old and new
> module probably exist at the same time for a
> short period and in different memory areas.
> We would call that a `defer` execution in forth,
> otherwise one may call it callgate processing.

> Nothing is impossible in forth, any of these are done with a third
> side infrastructure. It just needs ways to properly build modules
> from forth source code and attach attributions that can be used by
> the infrastructure.

When Chuck Moore invented Forth, much of what you describe was common
practice. It still is. Chuck decided that all these complex tools
were part of the problem set, not the solution set, so he invented a
way to avoid having to use them. All of that reasoning is just as
appropriate today as it was then.

I'm quite sure that there are perfectly good Forth ways of doing what
you describe here without resorting to such heavyweight solutions.

Think about what Forth is good for. One of the great advantages of
Forth, a Unique Selling Point, is that you don't have to do all this
messing about with loaders and linkers.

Andrew.

Guido Draheim

unread,
Oct 8, 2003, 2:04:13 PM10/8/03
to

I won't deny that. But it makes forth a niche system - w/o need.
All that complexity about loaders and linkers helps in some areas,
and forth can't match there. At the moment I am perfectly fine
with using forth in a form of readable portable bytecode with our
graphical frontend generating a few megabytes of forth source code,
and the forth interpreter being the "loader" compiling it to
threaded (possibly native threaded) runtime application in memory.
However, I see the benefit of dotnet objects as well, and possibly
moving over as a second plan.


Elizabeth D. Rather

unread,
Oct 8, 2003, 2:39:44 PM10/8/03
to
Guido Draheim wrote:

> ...


> >>Furthermore, there is no standardized way to express the need for a
> >>relocation info on the source level, and multisegment relinkable
> >>binaries are pretty much unknown in the forth world.
> >
> > Right, but given that Forth sometimes compiles from source faster than
> > conventional linkers link, I would have thought that a plus.
>
> Yes, it is, but see how forth compiler vendors will disagree
> promptly and put up references on the advantages of highly
> optimized code in forth binaries. It seems that the current
> forth standard has made provisions for native code forth but
> not for binaries in native code, a difference with other
> language specifications. In a way, forth is stuck at being
> an optimized scripting language, not a compiler - but the
> current forth compiler vendors have shown that it is in fact
> possible to turn forth into a compiler language. There are
> just not the least provisions for it in the forth specification.
> So the question is there again, is C more powerful, and may
> be that it was the case for the last thirty years?

Forth compilers that generate optimized machine code can
_still_ compile from source faster than conventional linkers
link, and not having to mess with all that infrastructure
is a big plus for rapid development turnarounds.

So far in all this discussion, all the things you've cited that
"C can do but Forth can't" are in the category of "thank
God we don't have to do any of that".

Cheers,
Elizabeth


Elizabeth D. Rather

unread,
Oct 8, 2003, 2:47:20 PM10/8/03
to
Guido Draheim wrote:

> ...there is a definite section in the ANS forth


> spec that a "solid dict" approach is assumed - subsequent
> incremental allocations from the forth dict space are expected
> to yield adjascent memory areas. All words that might break

> that assumption are marked in the ANS forth spec. ...

No, no, no! that section of the Standard isn't talking about
"dictionary space" at all, it's very explicitly and carefully
discussing "data space". Data space may be in the
dictionary, but may not be. Indeed, in cross-compilers
it's almost always elsewhere, since the dictionary may
be in ROM or flash, and data space in RAM. Standard
programs cannot explicitly allocate dictionary space.


Michael L Gassanenko

unread,
Oct 8, 2003, 3:51:57 PM10/8/03
to

Probably, yes; depends on the verbiage.

> To me it sounds just like bloat, and a number
> of people complain about the size of the standard already, and that it
> is hard to read etc.
>

What we have now is:

SAVE is unstandard; it is alowed to impose additional
restrictions on functionality for standard programs,
( http://forth.sourceforge.net/Standard+/rof/index.html )
for example: "all addressess, including execution tokens,
must be stored into memory in a base-relative form,
at least if they are expected to survive multiple
program executions".

There *is* something to gain, yeah?


--
Your system is running low on virtual memory and should have been replaced.

andr...@littlepinkcloud.invalid

unread,
Oct 8, 2003, 2:57:44 PM10/8/03
to
Guido Draheim <guidod...@gmx.de> wrote:

> But it makes forth a niche system - w/o need.

That's the nature of Forth. What you're describing is more or less C
written in Reverse Polish. I believe that such a system would not
increase the takeup of Forth.

> All that complexity about loaders and linkers helps in some areas,
> and forth can't match there.

It can, if people want it to. But it's a lot of work.

> At the moment I am perfectly fine with using forth in a form of
> readable portable bytecode with our graphical frontend generating a
> few megabytes of forth source code, and the forth interpreter being
> the "loader" compiling it to threaded (possibly native threaded)
> runtime application in memory. However, I see the benefit of dotnet
> objects as well, and possibly moving over as a second plan.

I see the benefit of .net objects too. But that doesn't strike me as
any less of a niche!

I'm just thinking back to how this conversation started. I think you
implied that the fact that C works with linkers and object files,
whereas Forth doesn't, was a consequence of their respective language
standards, and I denied that. On reflection, I changed my position a
bit: it is to some extent a consequence of the way the respective
languages work. However, it's just as much a consequence of the way
the users of the languages think.

I note that none of the features you mentioned are part of Standard C
either.

Andrew.

Michael L Gassanenko

unread,
Oct 8, 2003, 4:00:34 PM10/8/03
to

I was talking about executing a Forth program as:
- a sub-process of an external OS
- the program that gets [re]started upon power-on/reset and sometimes shut down
- in any different way (can somebody remember one?)

(And yes, there is BYE , which is good.)

Anyway, we sometimes have binaries: on disk, in ROM, in FLASH.
And the standard is written as if binaries do not exist.
That is, everything about binaries is unstandard.

Michael L Gassanenko

unread,
Oct 8, 2003, 4:08:07 PM10/8/03
to
andr...@littlepinkcloud.invalid wrote:
> things like Makefiles, linkers, libraries, and so on are not
> part of the C standard.

But C does not pretend to compile at run-time either.

In Forth, standard code may compile but nobody knows what will
happen with it after it is SAVEd and run.

Sort of, the behaviour of the compiler is defined, but behaviour
of the compiled code is not.

Gary Chanson

unread,
Oct 8, 2003, 3:08:27 PM10/8/03
to

"Elizabeth D. Rather" <era...@forth.com> wrote in message
news:3F8459D5...@forth.com...

>
> Forth compilers that generate optimized machine code can
> _still_ compile from source faster than conventional linkers
> link, and not having to mess with all that infrastructure
> is a big plus for rapid development turnarounds.
>
> So far in all this discussion, all the things you've cited that
> "C can do but Forth can't" are in the category of "thank
> God we don't have to do any of that".

Agreed! It takes me longer to compile and link a minor change to a
fairly large C program in MS Visual C then it does to completely compile a
similar size Forth program in Quest32 which is not even an optimized Forth
(although it does compile very fast).

-GJC


Alex McDonald

unread,
Oct 8, 2003, 6:38:59 PM10/8/03
to
"Michael L Gassanenko" <m_l...@yahoo.com> wrote in message
news:3F846EA7...@yahoo.com...

I'm not quite sure this is the right point in the thread, but here goes
anyhow;

Some observations:

1. ANS Forth does not define SAVE.
2. ANS Forth does not define the environment in which it operates.

Given that these are the case (and I'm not proposing that they're
standardised in any way)

(1) leads to the problem that saved code has no ANS defined behaviour (as
Michael points out). However, the behaviour of any useful SAVEable Forth
system must be definable. (2) -- the environment is real too, and again, any
usable Forth has a definable environment.

For modern PCs, (1) and (2) are serious problems, as they are written to
support C type languages; compiled, linked, relocated while loading --
classic executables. And Forth has a tertiary problem; the interactivity
that makes development fast and easy makes building executables very hard.

There are other problems too, secondary to point 1 (it presumes a save) and
2 (it's dependant on the OS);

3. ANS Forth does not recognise the requirement for relocation (although it
deals with addresses)

As someone who has worked with Win32Forth on and off for the last year, and
struggled to see how these issues might be resolved, I'm looking for advice
on how to proceed.

Here's how W32F currently operates (the version described here is a little
different form TJZ's version).

1. A meta compiler builds a simple image (a "kernel"). The kernel has 3 segm
ents; a code space, a data space and a dictionary space. The image file is a
combination of the three "segments" with a header that explains where the
code, data and dictionary sections are to be loaded.

2. The image is loaded by a simple C wrapper that reads the header,
allocates memory for the segments and writes them to memory. It then jumps
to the entry point. (The wrapper doesn't provide any screen or window
handling; that is done by a separate "console" DLL called by the kernel.)

3. The meta compiler supports two image types; a relocatable and a fixed
loadpoint. In a relocatable load point image, the addresses are computed
relative to the wrapper-selected load address (a register holds this
constant for speed). In a fixed loadpoint, the wrapper is told the addresses
at which each segment expects to be loaded; addresses are absolute.

4. External addresses (for instance, parameters to Windows) must pass
through a REL>ABS word in a relocatable load point image to make the
addresses absolute. Correspondingly, ABS>REL is used to turn address
parameters returned from Windows into relative addresses. In a fixed load
point image, both REL>ABS and ABS>REL are effectively null operations.

5. The kernel can be extended by FLOADing (file load) external Forth files.
A fully extended kernel can then be FSAVEd (file SAVEd). The image has an
identical format to the meta compiled image (header, 3 sections) and is the
same format as the original meta compiled image (that is, fixed or
relocatable). By this point, the image can be quite large; some space can be
saved by throwing away the dictionary segment. That introduces some specific
coding restrictions; for instance, EVALUATE can't be supported.

The image format bears a resemblance to an object or executable file, except
that there are no address relocations, and the wrapper is effectively a
primitive loader. I think that we can reasonably say that point 1 (ANS
doesn't define SAVE) isn't a major issue; and W32F defines the nature of
SAVEd and run image.

This is where point 2 comes in; there's no way to build a true Windows
executable. W32F only just fits its environment.

1. We're missing a resource compiler (although there's a primitive dialog
compiler, there are no strings, icons and the other paraphernalia).
2. We could (just about, some work went into this) create an executable by
modifying the header; a post-image linker if you like.
3. We could (just about) create a DLL, but it would be huge (image sized),
and would require the use of a relocatable image as its source, as there's
no way to do identify addresses and therefore do relocation.
4. COM as per DLL.
5. We could (just about) use PInvoke from a managed .Net component to run
the image in a .Net environment (not that I would know where to start
currently).

We're basically missing a few tools; a resource compiler and a linkage
editor. Is the following a reasonable plan:

1. Build an image to COFF (or somesuch format) converter so a standard
resource compiler & linkage editor could be used.
2. Build an image stripper that removes colon defs/areas that aren't used
from some root word (main in C parlance) to reduce the size of the EXE
and/or DLL and/or COM object we may care to generate.
3. Something else?

If we could do this, then Forth (W32F anyhow) could be as powerful as C on a
Windows platform. More powerful, really; beacuse we'd still have a fully
interactive environment and be able to compile at run time. Suggestions
welcomed.

--
Regards
Alex McDonald


Guido Draheim

unread,
Oct 8, 2003, 7:04:38 PM10/8/03
to

Alex McDonald wrote:
>
> We're basically missing a few tools; a resource compiler and a linkage
> editor. Is the following a reasonable plan:
>
> 1. Build an image to COFF (or somesuch format) converter so a standard
> resource compiler & linkage editor could be used.

same for unixish ELF formats and the unix compiler tools which are
preinstalled in almost all systems with the system C compiler.

> 2. Build an image stripper that removes colon defs/areas that aren't used
> from some root word (main in C parlance) to reduce the size of the EXE
> and/or DLL and/or COM object we may care to generate.

The Extendable Linker Format might make it easier to adapt the forth
(header) dictionary to the formats of symbol table and debug infos,
simply because debug info is largely standardized in modern systems
to an extendable format as well.

> 3. Something else?

The W32F model uses relative adresses for relocatable objects, it would
be nice to provide a common mechanism to express a hint to the compiler
about possible needs to add fixup information. However, the usual .so
binaries are PIC themselves, so a common approach on compiling with
relative adresses might help as well - along with the above, a forth
module would be expressed in a container of an ELF .so.

>
> If we could do this, then Forth (W32F anyhow) could be as powerful as C on a
> Windows platform. More powerful, really; beacuse we'd still have a fully
> interactive environment and be able to compile at run time. Suggestions
> welcomed.
>

The dotnet/java platforms define a virtual machine and loader concept
in the environment. A common approach to run forth modules that would
be an interesting approach but one ever has to fear the discussions
about them. All forth system makers define their own VM and loader for now.

Gary Chanson

unread,
Oct 8, 2003, 7:22:42 PM10/8/03
to

"Alex McDonald" <alex...@btopenworld.com> wrote in message
news:bm23m1$426$1...@sparta.btinternet.com...

>
> The image format bears a resemblance to an object or executable file,
except
> that there are no address relocations, and the wrapper is effectively a
> primitive loader. I think that we can reasonably say that point 1 (ANS
> doesn't define SAVE) isn't a major issue; and W32F defines the nature of
> SAVEd and run image.
>
> This is where point 2 comes in; there's no way to build a true Windows
> executable. W32F only just fits its environment.

Quest32 saves its image in a standard Windows PE executable file. It
can be done but it isn't easy!

> If we could do this, then Forth (W32F anyhow) could be as powerful as C on
a
> Windows platform. More powerful, really; beacuse we'd still have a fully
> interactive environment and be able to compile at run time. Suggestions
> welcomed.

True (as Quest32 proves).

--
--

-GJC [MS Windows SDK MVP]
-Software Consultant (Embedded systems and Real Time Controls)
-gcha...@mvps.org

-Abolish public schools


Stephen Pelc

unread,
Oct 8, 2003, 8:33:27 PM10/8/03
to comp.lang.forth
On Wed, 08 Oct 2003 14:18:41 +0200, Guido Draheim
<guidod...@gmx.de> wrote:

>Btw, does anyone have an object linker for native code
>forth that can relink multiple object modules? Expanded
>to allow loader linkage? Any of those Forth OS perhaps?

See LIB\OVERLAY.FTH in any VFX Forth for Windows. The "linked"
objects are separately compiled modules, and reference nesting
to any level is permitted. However, these are not .OBJ files.

Stephen
--
Stephen Pelc, steph...@INVALID.mpeltd.demon.co.uk
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
web: http://www.mpeltd.demon.co.uk - free VFX Forth downloads

andr...@littlepinkcloud.invalid

unread,
Oct 9, 2003, 4:38:01 AM10/9/03
to
Michael L Gassanenko <m_l...@yahoo.com> wrote:
> andr...@littlepinkcloud.invalid wrote:
>> things like Makefiles, linkers, libraries, and so on are not
>> part of the C standard.

> But C does not pretend to compile at run-time either.

> In Forth, standard code may compile but nobody knows what will
> happen with it after it is SAVEd and run.

Well, that's because some systems have a broken SAVE.

> Sort of, the behaviour of the compiler is defined, but behaviour
> of the compiled code is not.

This is utter rubbish, as you must surely know. The compiler
behaviour is well defined, as is the behaviour of compiled code. What
is not well defined is the behaviour of a word that has no standard
definition.

Andrew.

Stephen Pelc

unread,
Oct 9, 2003, 6:13:26 AM10/9/03
to comp.lang.forth
On Wed, 8 Oct 2003 22:38:59 +0000 (UTC), "Alex McDonald"
<alex...@btopenworld.com> wrote:

>1. ANS Forth does not define SAVE.
>2. ANS Forth does not define the environment in which it operates.

If I SAVE a system, I expect the reloaded system to behave identically
to the system that I SAVEd. How this done is an implementation issue,
and should not be defined by the standard.

W32F avoids the relocation issue in its VM design. This leads to
REL>ABS and friends, and to the consequent Windows interfacing
nightmares. Consider the car analogy. Any chassis has a
lifetime. After a while you have to discard the existing
chassis and design a new one.

There are several Windows Forths around, including VFX Forth,
which threw out the old chassis. The modern Windows Forths
generate optimised native code, do not use a wrapper, can
be relocated at load, and SAVE to a single Windows PE file.
To do this without access to the source code of an existing
solution requires a great deal of thought and work.

Guido Draheim

unread,
Oct 10, 2003, 6:37:09 AM10/10/03
to

Stephen Pelc wrote:
> There are several Windows Forths around, including VFX Forth,
> which threw out the old chassis. The modern Windows Forths
> generate optimised native code, do not use a wrapper, can
> be relocated at load, and SAVE to a single Windows PE file.

[and finally]


> To do this without access to the source code of an existing
> solution requires a great deal of thought and work.

because the solution is complex as no simple means was
provisioned for the standard forth language?!

What means would be needed to (almost easily) allow the
generation of OS loadable binaries from forth sources?

I guess the question is uneasy, as the proposition of
extensions would require a good deal of prior work to
actually identify the problematic areas and that would in
turn require work on a such a system under the restrictions
of the current language type.

-- guido http://PFE.sf.net


andr...@littlepinkcloud.invalid

unread,
Oct 10, 2003, 7:01:23 AM10/10/03
to
Guido Draheim <guidod...@gmx.de> wrote:

> Stephen Pelc wrote:
>> There are several Windows Forths around, including VFX Forth,
>> which threw out the old chassis. The modern Windows Forths
>> generate optimised native code, do not use a wrapper, can
>> be relocated at load, and SAVE to a single Windows PE file.
> [and finally]
>> To do this without access to the source code of an existing
>> solution requires a great deal of thought and work.

> because the solution is complex as no simple means was
> provisioned for the standard forth language?!

I don't think he was saying that. He was saying that a good quality
SAVE can be done with the standard language, but implementation on
some operating systems can be complicated. But it's important to
realize that this complication is caused by the OS, not by the Forth
standard.

> What means would be needed to (almost easily) allow the generation
> of OS loadable binaries from forth sources?

That depends on the OS. Not every OS requires executables to be
relocated at startup.

Andrew.

Stephen Pelc

unread,
Oct 10, 2003, 8:01:01 AM10/10/03
to comp.lang.forth
On Fri, 10 Oct 2003 12:37:09 +0200, Guido Draheim
<guidod...@gmx.de> wrote:

>Stephen Pelc wrote:
>> To do this without access to the source code of an existing
>> solution requires a great deal of thought and work.

>What means would be needed to (almost easily) allow the


>generation of OS loadable binaries from forth sources?

Assume that you want to type
SAVE <filename>
to generate an OS executable file in all its glory.
The complexity of this operation depends on the OS and
some design decisions made about the implementation of
the Forth kernel.

If SAVE is to be standardised, I really do not want
to be involved in the wording process: there are just
too many special cases that will require weasel words.
For example, some systems load a Forth image with a
wrapper/loader. The Forth image in these cases is NOT
an OS executable file. Do you want to specify the reload
for execution process as well?

Alex McDonald

unread,
Oct 10, 2003, 1:53:52 PM10/10/03
to

"Stephen Pelc" <steph...@INVALID.mpeltd.demon.co.uk> wrote in message
news:3f869c12....@192.168.0.1...

> On Fri, 10 Oct 2003 12:37:09 +0200, Guido Draheim
> <guidod...@gmx.de> wrote:
>
> >Stephen Pelc wrote:
> >> To do this without access to the source code of an existing
> >> solution requires a great deal of thought and work.
>
> >What means would be needed to (almost easily) allow the
> >generation of OS loadable binaries from forth sources?
>
> Assume that you want to type
> SAVE <filename>
> to generate an OS executable file in all its glory.
> The complexity of this operation depends on the OS and
> some design decisions made about the implementation of
> the Forth kernel.
>
> If SAVE is to be standardised, I really do not want
> to be involved in the wording process: there are just
> too many special cases that will require weasel words.
> For example, some systems load a Forth image with a
> wrapper/loader. The Forth image in these cases is NOT
> an OS executable file. Do you want to specify the reload
> for execution process as well?

I was certainly looking to be pragmatic; standardising the OS interfaces is
not worth the effort, I agree. I can't see that a design decision between
STC, ITC, generated code etc (you chassis analogy) changes the problem of
relocation under Windows; how do you cope with DLLs for instance? I saw a
suggestion here (can't find the post) that you "compile" twice at different
addresses and compare the result; anything that doesn't match needs
relocation (and the difference is an indication of the relocation offset).
Is that a possible route?

>
> Stephen
> --
> Stephen Pelc, steph...@INVALID.mpeltd.demon.co.uk
> MicroProcessor Engineering Ltd - More Real, Less Time
> 133 Hill Lane, Southampton SO15 5AF, England
> tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
> web: http://www.mpeltd.demon.co.uk - free VFX Forth downloads

--
Regards
Alex McDonald


Guido Draheim

unread,
Oct 10, 2003, 4:30:32 PM10/10/03
to

Alex McDonald wrote:
> "Stephen Pelc" <steph...@INVALID.mpeltd.demon.co.uk> wrote in message
> news:3f869c12....@192.168.0.1...
>
>>On Fri, 10 Oct 2003 12:37:09 +0200, Guido Draheim
>><guidod...@gmx.de> wrote:
>>
>>
>>>Stephen Pelc wrote:
>>>
>>>>To do this without access to the source code of an existing
>>>>solution requires a great deal of thought and work.
>>
>>>What means would be needed to (almost easily) allow the
>>>generation of OS loadable binaries from forth sources?
>>
>>Assume that you want to type
>> SAVE <filename>
>>to generate an OS executable file in all its glory.
>>The complexity of this operation depends on the OS and
>>some design decisions made about the implementation of
>>the Forth kernel.
>>
>>If SAVE is to be standardised, I really do not want
>>to be involved in the wording process: there are just
>>too many special cases that will require weasel words.
>>For example, some systems load a Forth image with a
>>wrapper/loader. The Forth image in these cases is NOT
>>an OS executable file. Do you want to specify the reload
>>for execution process as well?

Current VM systems do just that but I'd more interested
in compiling to the native format of the operating system
and adaption to its loader format. With code/data, stabs,
reloc, init/fini sections it should be possible to get a
matching loader variant that can be a forth compiler target,
and these exist in modern binariy containers everywhere,
may that be those coff/pe or elf/whatever binary containers.

Note however that I'd find that only interesting, but I am not
inclined to ask for an ABI like suggested below. It's just
that I expect that forth applications are advised to follow
a certain programming model to be allowed to be compiled
to a binary. The ANS forth is quite good as providing a
programming model that allows both ITC or whatever threaded
code _and_ true native code as the compiler target. whereas
prior to that some assumptions were common for ITC, right?

Now we have some freedom at the actual compilation target,
and sometimes it's been as simple as a `compile,` to replace the
earlier `,`. From what I get in these discussions up to now
then the difference between a native code forth application
/ module and a native code operating system appliation / library
is not really big but just some special cases need attention.

Bringing up a list would be the task, and find a solution that
`traditional` systems can get away with as the input source.
One would be HERE..., that would need a fix, just like a good
programmer would avoid expressing a control structure with
HERE....BRANCH , and insted use <MARK..<RESOLVE if they exist.
There are other places for sure.

>
>
> I was certainly looking to be pragmatic; standardising the OS interfaces is
> not worth the effort, I agree. I can't see that a design decision between
> STC, ITC, generated code etc (you chassis analogy) changes the problem of
> relocation under Windows; how do you cope with DLLs for instance? I saw a
> suggestion here (can't find the post) that you "compile" twice at different
> addresses and compare the result; anything that doesn't match needs
> relocation (and the difference is an indication of the relocation offset).
> Is that a possible route?
>
>

Only when you load from byte zero and target a solid module. There are
problems with imports of adresses from the process environment and
modules loaded by the operating system instead of the forth system.
If the relocation detector environment has full control an _all_
possible adresses possibly be compiled then it is a known and well
working method AFAIR. From my own experiences, it is possible for
full forth applications but a very complex topic when using forth as
a backside scripting language inside another's application context.

Anton Ertl

unread,
Oct 11, 2003, 4:45:16 AM10/11/03
to
Guido Draheim <guidod...@gmx.de> writes:
>I was just holding a lecture expanding the students knowledge
>on C providing them with the pieces that let us refer to C as
>a kind of highlevel assembler. Among the differences to plain
>assembly of opcodes to a text segment we see that:
>- C is able to assign a size and segment location to all
> symbols - a static variable declared inside a function
> will make the variable be placed in the .data segment and
> the rest of the function in the .text segment with the
> executable code carrying a pointer to the .data

Many C compilers do that, but that's not something that is in the C
language, and the programmer has very little influence on it.

By contrast, the Unix assemblers give the programmers full control
over these things.

Since many Unix C compilers output assembly language as an
intermediate stage even when compiling to .o files, it is clear that
these assemblers must be at least as powerful as C.

>- the segments are assembled into an object wrapper or exe
> wrapper. The operating system however is allowed to handle
> each segment separatly, possibly binding them to very
> different adresses. References between the segments are
> properly relocated. It is allowed to combine segments of
> the same type from different .o files, the relink operation
> will take care to fix up all references.

I don't see the difference to Unix assemblers.

>Take special notice that you can not take the sizeof() any
>symbol in the forth area.

It is not hard to get the size of the data area associated with a
word. If you have

defining-word name ... \ optional further data allocations

then you can get the size afterwards with

here ' name -

Granted, it's not possible in the standard to get the size after you
have defined another word, but I have never missed that possibility.

The main reason that C has sizeof() is for making the code portable
across different type sizes. Forth has CHARS CELLS FLOATS ALIGNED
FALIGNED SFLOATS SFALIGNED DFLOATS DFALIGNED for that.

> Neither do we have segmentation
>differentations in the forth standard that the forth programmer
>could use - while of course some forth compiler vendors actually
>invented extensions for just that. It's a saner approach.

Neither has C. Forth systems are free to put data space, headers,
threaded code, native code, the stacks, and ALLOCATEd memory in
different segments, or some of them in the same segment, and there is
quite some variation among Forth systems, just as among C systems.
E.g, on my Linux-Intel box Gforth-0.6.2 has the following mappings:

(annotated, with inode numbers left away for space reasons)
08048000-0805d000 r-xp 00000000 03:47 /home/anton/gforth/gforth code
0805d000-08061000 rw-p 00014000 03:47 /home/anton/gforth/gforth data
08061000-08078000 rwxp 00000000 00:00 bss
40000000-40013000 r-xp 00000000 03:4a /lib/ld-2.1.3.so code
40013000-40014000 rw-p 00012000 03:4a /lib/ld-2.1.3.so data
40014000-40015000 rw-p 00000000 00:00 bss
4001e000-40020000 r-xp 00000000 03:4a /lib/libdl-2.1.3.so code
40020000-40022000 rw-p 00001000 03:4a /lib/libdl-2.1.3.so data
40022000-4003e000 r-xp 00000000 03:4a /lib/libm-2.1.3.so code
4003e000-4003f000 rw-p 0001b000 03:4a /lib/libm-2.1.3.so data
4003f000-4012c000 r-xp 00000000 03:4a /lib/libc-2.1.3.so code
4012c000-40130000 rw-p 000ec000 03:4a /lib/libc-2.1.3.so data
40130000-40134000 rw-p 00000000 00:00 C malloced memory
40134000-40162000 rwxp 00000000 03:47 /home/anton/gforth/gforth.fi image
40162000-40535000 rwxp 0002e000 00:00 dictionary (data space, headers, TC)
40536000-4053a000 rwxp 00000000 00:00 data stack
4053b000-4053f000 rwxp 00000000 00:00 fp stack
40540000-40544000 rwxp 00000000 00:00 return stack
40545000-40549000 rwxp 00000000 00:00 locals stack
4054a000-4058a000 rwxp 00000000 00:00 native code
4058b000-405cb000 rwxp 00000000 00:00 more native code
405cc000-405d0000 rwxp 00000000 00:00 sigaltstack stack
bfffb000-c0000000 rwxp ffffc000 00:00 C stack

You can consider each of these mappings as a separate segment (except
that the dictionary consists of both the image and the dictionary
mappings).

>Furthermore, there is no standardized way to express the
>need for a relocation info on the source level, and multisegment
>relinkable binaries are pretty much unknown in the forth world.

bigForth supports (or supported?) binary linkable modules. However,
given the speed at which Forth (at least Gforth) compiles, I see
little point in such a feature. If I wanted to do improvements in
this area, I would go for increasing compilation speed before looking
at such complications.

>It makes forth stuck in the area of which in CC/LD we say they
>are static-linked self-hosted applications with no dependency
>on other binaries or libraries at startup, running directly on
>the kernel traps, - and yes, quite often pre-compilation into
>a binary is not done anyway, using forth as a readably and
>modifiable form of byte code being not optimized deeply.

Ok, let's take this apart:

- static-linked: I have yet to encounter a situation where dynamic
linking of Forth code would provide a significant benefit; if I do, I
will think about how to get that benefit. Traditional native (i.e.,
non-hosted) Forth systems got the benefits of dynamic linking (sharing
of library code) by running in a single address space. On hosted
systems there are usually not enough Forth processes running at the
same time to get much benefit from sharing. Another benefit of shared
libraries is that bugfixes in the shared library immediately affect
all applications using the library. If you take the approach I
advocate (compiling the code from the source on startup instead of
using an image), you get the same benefit.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
EuroForth: http://www.micross.co.uk/euroforth2003/Call_for_Participation.html

Anton Ertl

unread,
Oct 11, 2003, 5:52:43 AM10/11/03
to
Guido Draheim <guidod...@gmx.de> writes:

>
>
>andr...@littlepinkcloud.invalid wrote:
>> Right, but given that Forth sometimes compiles from source faster than
>> conventional linkers link, I would have thought that a plus.
>>
>
>Yes, it is, but see how forth compiler vendors will disagree
>promptly and put up references on the advantages of highly
>optimized code in forth binaries.

Can you provide references to such disagreement? And what does
"highly optimized" Forth code have to do with it?

> It seems that the current
>forth standard has made provisions for native code forth but
>not for binaries in native code, a difference with other
>language specifications.

Can you provide references to such provisions in other language
standards?

> In a way, forth is stuck at being
>an optimized scripting language, not a compiler

What does one thing have to do with the other? Or do you mean
"non-interactive hurdle for programmers" when you write "compiler".
Then, yes, Forth is stuck at not being that, and that's good.

Anyway, given the increasing popularity of scripting languages (see
<2003Feb...@a0.complang.tuwien.ac.at>), being taken seriously as
a scripting language is not such a bad thing.

Anton Ertl

unread,
Oct 11, 2003, 6:07:46 AM10/11/03
to
Guido Draheim <guidod...@gmx.de> writes:
>One basic difference is that the C language had always been
>differentiating between function symbols and data symbols quite
>strictly to be compiled into an output binary. I am not sure
>how that is enforced in a forth compiler pushing the parts to
>different segments. No extra words needed in surplus of ANS forth?
>You wrote one, you tell.

There is an analogous difference in Forth:

: and :NONAME produce something corresponding to function symbols; the
code can be anywhere. CREATE produces headers that have to point
HERE. VARIABLEs and CONSTANTs can put their data anywhere.

>As for the other, there is a definite section in the ANS forth


>spec that a "solid dict" approach is assumed - subsequent
>incremental allocations from the forth dict space are expected
>to yield adjascent memory areas. All words that might break
>that assumption are marked in the ANS forth spec.

So you recognize that data space is broken into separate objects.
Implementing it sequentially has advantages in a system where you can
only allocate fixed-size regions, but other implementations are
possible.

> Especially,
>there is no "end of allocations" mark to hint a compiler to
>possibly put a break in, and consequently a forth word does
>not have a direct sizeof() unless by implication of the start
>of the next symbol.

You mean, there is not dedicated word that breaks a contiguous regions
without doing anything else (who needs it?). But you can certainly
end a contiguous region in some other way, e.g. with ":noname ; drop".

As for the "start of the next symbol", a definition is not necessarily
named.

>And last, in forth we handle compilation by direct reference

>to adresses, not symbols. In C each function symbol or data


>symbol does not have an adress during compilation, the actual
>adress is assigned during (re)linking or loading to execute.
>Some forths have expanded on that with words that tell the
>compiler to say what an adress is that possibly needs
>relocation by the loader.

If one wanted to do this, the main problem I see is the existence of
address arithmetic at compile time (i.e., before the arbitrary
compile-time/run-time cut that you have to make, if you want such a
scheme). The way to deal with this would be to have the "compiler"
track how the symbols are used in the computation. This would be very
unlike current Forth systems, more along the lines of Jonah's
ANS-Forth-program checker; as an added benefit, such a system would
probably take quite a bit more time in processing the source code,
thus justifying the need for separate compilation to the ignorant.

In C using addresses is not allowed in a number of places (e.g., IIRC
not as case labels) to make the compiler's job easier.

>May be there is more, I would simply maintain a mere
>ANS forth compliant forth compiler does not fit into the
>contemporary toolchain to compile source code to .o
>objects being handled by a linker or loader.

Yes, Forth is too powerful to fit well into that framework. That's
the main reason why hardly any Forth system tries to produce .o files.

> That accounts
>to both old C ld/ldso or modern java/dotnet object linkage.

Good point to mention that. Java and .NET don't use that framework,
either, probably because they don't fit. OTOH, the Java framework
behaves quite similarly in many respects, so unlike for languages like
Forth and Lisp, I don't see a direct advantage to it.

>In a way, forth is stuck in its own area while in other
>programming realms a lot of work has been done to allow linking
>of objects from different input source languages. The
>current dotnet platform heading off in functionality here.

Hardly. In Unix one can usually only compile and link a few
FORTRAN/Algol languages (Fortran, C, Pascal, C++), and even that did
not fit C++ very well, and had to be extended significantly. No Lisp,
Prolog, Smalltalk, Forth, Perl, Python, or Ruby there.

The other frameworks are even worse in not supporting even C, Fortran,
and C++: The Java framework can only do Java (ok, there have been some
experiments with a few other languages, but I am not aware of any of
these becoming popular; in any case, that framwork is too restrictive
for languages like C, C++ and Fortran). .NET is reportedly less
restrictive than the Java framework, but still not able to deal with
the unaltered languages.

Anton Ertl

unread,
Oct 11, 2003, 7:26:47 AM10/11/03
to
Guido Draheim <guidod...@gmx.de> writes:
>
>
>andr...@littlepinkcloud.invalid wrote:
>> The real bugbear about generating .o files and then linking before any
>> execution is possible is the lack of interactivity that implies.
>>
>
>Aye, interactive C implementations are rare but they do exist, i.e.
>scripting with C syntax.

These scripting languages are ANSI C supersets? The compile to .o
files and are still interactive? Name one!

Anton Ertl

unread,
Oct 11, 2003, 7:34:40 AM10/11/03
to
Michael L Gassanenko <m_l...@yahoo.com> writes:
>andr...@littlepinkcloud.invalid wrote:
>> things like Makefiles, linkers, libraries, and so on are not
>> part of the C standard.
>
>But C does not pretend to compile at run-time either.

Neither does Forth pretend, it just does.

>In Forth, standard code may compile but nobody knows what will
>happen with it after it is SAVEd and run.

C does not offer snapshotting ability, either. If it did, Gforth's
image processing would be much simpler. On most of the systems I use,
the program can be made to dump core, but turning the core dump into
an executable program is not easy (last I looked, GNU Emacs used this
approach, however).

>Sort of, the behaviour of the compiler is defined, but behaviour
>of the compiled code is not.

The behaviour of the compiled code is defined, too. SAVE is not defined.

Anton Ertl

unread,
Oct 11, 2003, 7:40:27 AM10/11/03
to
"Alex McDonald" <alex...@btopenworld.com> writes:
>I saw a
>suggestion here (can't find the post) that you "compile" twice at different
>addresses and compare the result; anything that doesn't match needs
>relocation (and the difference is an indication of the relocation offset).
>Is that a possible route?

That's what Gforth does. Read all about it at

http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Image-File-Background.html
http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/gforthmi.html

Anton Ertl

unread,
Oct 11, 2003, 7:56:06 AM10/11/03
to
Michael L Gassanenko <m_l...@yahoo.com> writes:
>Anton Ertl wrote:
>>
>> Michael L Gassanenko <m_l...@yahoo.com> writes:
>> >: compare equal. The address may be different during two
>> >: different executions of the same program.
...

>> Of course, one could add verbiage like that to the Forth standard, but
>> what would be gained by it? Would we get better Forth systems or
>> better Forth programs?
>
>Probably, yes; depends on the verbiage.

Well, verbiage like that: "may be different during two different
executions". What is it that would be gained? I don't see that Forth
systems would become better because that's what they already satisfy
(I don't see a way not to satisfy it), and Forth programs already take
this into account.

>> To me it sounds just like bloat, and a number
>> of people complain about the size of the standard already, and that it
>> is hard to read etc.
>>
>
>What we have now is:
>
>SAVE is unstandard;

So what you are asking for is the inclusion is SAVE in the standard,
not some superfluous verbiage as in ANSI C. Note that ANSI C has
nothing like SAVE, either.

Stephen Pelc

unread,
Oct 11, 2003, 8:13:59 AM10/11/03
to comp.lang.forth
On Fri, 10 Oct 2003 17:53:52 +0000 (UTC), "Alex McDonald"
<alex...@btopenworld.com> wrote:

>how do you cope with DLLs for instance? I saw a
>suggestion here (can't find the post) that you "compile" twice at different
>addresses and compare the result; anything that doesn't match needs
>relocation (and the difference is an indication of the relocation offset).

AFAIR there was an article in DDJ (by Joe Barnhart perhaps) a
long time ago about Forth relocatable overlays. This should be
a good start on Google.

Guido Draheim

unread,
Oct 11, 2003, 12:36:07 PM10/11/03
to

Anton Ertl wrote:
> Guido Draheim <guidod...@gmx.de> writes:
>
>>
>>andr...@littlepinkcloud.invalid wrote:
>>
>>>The real bugbear about generating .o files and then linking before any
>>>execution is possible is the lack of interactivity that implies.
>>>
>>
>>Aye, interactive C implementations are rare but they do exist, i.e.
>>scripting with C syntax.
>
>
> These scripting languages are ANSI C supersets? The compile to .o
> files and are still interactive? Name one!
>

Oh my..... not from mere memory! - for daily scripting I use real
highlevel languages and if there's a need for lowlevel access
and interactivity then we all know a good choice, plus the fact
that PFE is a good choice. Why bother with the limitations of C
in this area, actually whenever I came across a scripting and/or
interactive variant of C then it did always feel inferior. It
should be possible to just google around for a C scriping variant
and see how close it is with the standard spec. Your second
question might imply that is impossible for such a C variant to
achieve this feature but that's not the case - I am daily working
with the vxworks shell which is running directly inside the
(embedded) target system and all available commands are just symbols
from the symbol table, all command calls are contructing a C call
frame (in the local ABI) to be executed, including "ls" and "cd".
The shell allows expressions in C syntax as arguments, and creates
variables directly in the symbol table from the command line shell.
AFAIR, it does not compile functions into the symbol table but
that's not a necessary limitation of the C syntax but just a case of
that shell to be lightweight as to be always available in the embedded
system. Since other C scripting variants have shown ways of direct
parsing and extending of a symbol table I assume it would be
possible here if the system vendor wants that. Personally, I am not
interested to spent hours to check the multi dozen C-type scripting
variants for their current feature set, especially since I am not
advocating these, and I am never ever going to check if they are
really useful as alternatives, let me hint that just in case you
got me wrong on that point. Those C enthusiast shall march on their
own trying to get full interactivity into their language of choice.
It's not of my interest, and definitly none of my business. If you
want to be pointy haired on that, you may say that I did just assume
those maniacs are already there having all the features in _one_
system (a.k.a. `name _one_`), simply because I have _seen_ all the
necessary features been implemented in one variant or the other.
Thank you, bye, guido


Guido Draheim

unread,
Oct 11, 2003, 2:45:35 PM10/11/03
to

Anton Ertl wrote:
> [function / data seperation present in forth and implicit
> seperation of allocation space per name/noname entry]

yes, that's the result of discussions in the last days,
thanks for pointing out direct examples. It seems that
the initial provision for these in the C design does not
make it specific. In a lot of cases we seem to compare
"traditional" implementation variants of Forth vs C,
whereas looking harder we see points that can yield
equivalent results. It's just different how easy it is
to express things or what "workaround" can be used in
the other model - the noname:drop break is kinda cool
but I dunno who's been using it in real code.

> [...]


>>symbol does not have an adress during compilation, the actual
>>adress is assigned during (re)linking or loading to execute.
>>Some forths have expanded on that with words that tell the
>>compiler to say what an adress is that possibly needs
>>relocation by the loader.
>
>
> If one wanted to do this, the main problem I see is the existence of
> address arithmetic at compile time (i.e., before the arbitrary
> compile-time/run-time cut that you have to make, if you want such a
> scheme). The way to deal with this would be to have the "compiler"
> track how the symbols are used in the computation. This would be very
> unlike current Forth systems, more along the lines of Jonah's
> ANS-Forth-program checker; as an added benefit, such a system would
> probably take quite a bit more time in processing the source code,
> thus justifying the need for separate compilation to the ignorant.

I just don't get this, sorry.

>
> In C using addresses is not allowed in a number of places (e.g., IIRC
> not as case labels) to make the compiler's job easier.

Hmmm, using adress as the case label value, interesting thing.
The old C design does ask for "compile-time constant" things
to be only valid as case label arguments. However, adding a
data reloc fixup should be possible as well, so the label
value would be therefore program execution. IIRC, it is
invalid because the way C compilers build the switch's jump
table as a numerically _ordered_ list of case' values and
case' adresses to jump to. And since each portion in C can
be `load`ed into a different place in memory, that ordering
is not ensured.

BTW, coming back to the forth way of doing allocations,
we had the discussion on adjascent allocations that might
be broken by some words into pieces with gaps - but are
these gaps? Traditional forth sources will expect a strict
ordering of allocations, right? I am not sure if that is
in the ANS Forth standard, it was atleast a nice assertion
for implemenations of FORGET to detect the "defined earlier"
attribution for a word.

>
>
>>May be there is more, I would simply maintain a mere
>>ANS forth compliant forth compiler does not fit into the
>>contemporary toolchain to compile source code to .o
>>objects being handled by a linker or loader.
>
>
> Yes, Forth is too powerful to fit well into that framework. That's
> the main reason why hardly any Forth system tries to produce .o files.

*grin* what a perspective! Now, what limitations would be needed
to make it work?! Is it possible to jot down an easy list that
a common forth programmer can get away with, w/o forgetting about
it next corner because it is too inconvenient?

>
>
>>That accounts
>>to both old C ld/ldso or modern java/dotnet object linkage.
>
>
> Good point to mention that. Java and .NET don't use that framework,
> either, probably because they don't fit. OTOH, the Java framework
> behaves quite similarly in many respects, so unlike for languages like
> Forth and Lisp, I don't see a direct advantage to it.
>
>
>>In a way, forth is stuck in its own area while in other
>>programming realms a lot of work has been done to allow linking
>>of objects from different input source languages. The
>>current dotnet platform heading off in functionality here.
>
>
> Hardly. In Unix one can usually only compile and link a few
> FORTRAN/Algol languages (Fortran, C, Pascal, C++), and even that did
> not fit C++ very well, and had to be extended significantly. No Lisp,
> Prolog, Smalltalk, Forth, Perl, Python, or Ruby there.
>
> The other frameworks are even worse in not supporting even C, Fortran,
> and C++: The Java framework can only do Java (ok, there have been some
> experiments with a few other languages, but I am not aware of any of
> these becoming popular; in any case, that framwork is too restrictive
> for languages like C, C++ and Fortran). .NET is reportedly less
> restrictive than the Java framework, but still not able to deal with
> the unaltered languages.
>

Oh, that's kind a trick question. Most of the limitations of the
net vm languages come from its `sandbox` approach, the dotnet
machines have been given the ability to load `unmanaged` objects
to help integration into legacy operating system environments with
their c/fortran based series of functions and data parts. Hmmm.
The binary objects also have a lot of extra information in contrast
to c/fortran modules but that's because they import symbol attributes
directly from the binaires and not some header file. Hmmm. Actually,
I want to express that the other binary container formats are
taylored to the execution framework, so they can avoid abuse of
traditional segments. The specific need to switch to a totally
different binarycontainer format, hmmm, may be due to security
reasons and `signed applets`, hmmm, otoh I remember a project to
add signature segments to ELF binaries to be check in the kernel.
So, that's all relative, nothing should be impossible for an
engineer unless the base ground is all _too_ limited.

Guido Draheim

unread,
Oct 11, 2003, 6:47:31 PM10/11/03
to

Anton Ertl wrote:
> [after a lot of facts...]


>
>>It makes forth stuck in the area of which in CC/LD we say they
>>are static-linked self-hosted applications with no dependency
>>on other binaries or libraries at startup, running directly on
>>the kernel traps, - and yes, quite often pre-compilation into
>>a binary is not done anyway, using forth as a readably and
>>modifiable form of byte code being not optimized deeply.
>
>
> Ok, let's take this apart:
>
> - static-linked: I have yet to encounter a situation where dynamic
> linking of Forth code would provide a significant benefit; if I do, I
> will think about how to get that benefit. Traditional native (i.e.,
> non-hosted) Forth systems got the benefits of dynamic linking (sharing
> of library code) by running in a single address space. On hosted
> systems there are usually not enough Forth processes running at the
> same time to get much benefit from sharing. Another benefit of shared
> libraries is that bugfixes in the shared library immediately affect
> all applications using the library. If you take the approach I
> advocate (compiling the code from the source on startup instead of
> using an image), you get the same benefit.
>

And that's another fact but we have an hen-egg problem here as we
do not know how system makers would use a shared module system
until it springs into existance. At my employer we have a project
series with a few thousand modules that are sometimes "stacked"
in that a modules dependes on a preloaded module which in turn
depends on another preloaded module - writing down the dependencies
would yield a tree. The binary of each module is saved and later
the binary is used - current system uses a C based loader that
throws away any non-data in the module but a few years back the
loader was forth itself. Now, how about sharing the same base
stuff (currently the module named "base" is only 150k while the
upper layers may be in the megabyte range)? Yes, in fact we have
written up a reloc detector for the these specific module variants
which can grok the dictionary layout of all words allowed for
writing these modules (a limited number actullay), so after all
the loader has a good chance to share "base" module infos and
infos from other modules put out as a dependency. Now, "what if"
there would be general concept of shared modules? I dunno, really.

So much for another fact.

Michael L Gassanenko

unread,
Oct 19, 2003, 8:37:51 PM10/19/03
to
andr...@littlepinkcloud.invalid wrote:
>
> > ... Especially, there is no "end of allocations" mark to

> > hint a compiler to possibly put a break in, and consequently a forth
> > word does not have a direct sizeof() unless by implication of the
> > start of the next symbol.

Indeed.

CREATE tmp1 $100 CELLS ALLOT
HERE $200 CELLS ALLOT CONSTANT tmp2

Is this one data structure or two data structures?
I think, two, but what about

CREATE tmp1 $300 CELLS ALLOT HERE $200 CELLS - CONSTANT tmp2

?

>
> True enough, but remember that in the pre-ELF days, symbol sizes
> weren't usually available to the linker either.


In practice, the lirary file is manually marked up.

E.g.

// tmp1
CREATE tmp1 $100 CELLS ALLOT
// tmp2
HERE $200 CELLS ALLOT CONSTANT tmp2
// <nextname>
...

or

// tmp1
CREATE tmp1 $300 CELLS ALLOT HERE $200 CELLS - CONSTANT tmp2
// tmp2
LINK tmp1
// <nextname>
...

Michael L Gassanenko

unread,
Oct 19, 2003, 8:51:08 PM10/19/03
to
andr...@littlepinkcloud.invalid wrote:

[.o modules or .img files -- does not mater]

> I suspect that you could -- if you really wanted
> to -- find a way to generate that relocation automatically and still
> be ANS compliant.

The problem is that with _any_ approach to relocation you would be ANS-compliant.
Even if you must store/fetch execution tokens using REL@ and REL! .
What survives a save&load is outside the scope of the standard.

> But the issue in my mind is why you'd want to do
> that. How would it make the world a better place? What would
> generating a bunch of relocatable objects achieve?
>

If your customer wants a .dll, you cannot tell him that a directory of
source files would do. Esp. in view of that he wants to call the .dll
from a big C++ program (mostly C++, but probably some Basic etc.).

andr...@littlepinkcloud.invalid

unread,
Oct 20, 2003, 6:12:06 AM10/20/03
to
Michael L Gassanenko <m_l...@yahoo.com> wrote:
> andr...@littlepinkcloud.invalid wrote:

> [.o modules or .img files -- does not mater]

>> I suspect that you could -- if you really wanted to -- find a way
>> to generate that relocation automatically and still be ANS
>> compliant.

> The problem is that with _any_ approach to relocation you would be
> ANS-compliant. Even if you must store/fetch execution tokens using
> REL@ and REL! . What survives a save&load is outside the scope of
> the standard.

I know that, but it's not my point. There's no reason that SAVE needs
to break anything. A SAVE that does break things may be ANS
compliant, but that doesn't seem to be relevant here.

>> But the issue in my mind is why you'd want to do
>> that. How would it make the world a better place? What would
>> generating a bunch of relocatable objects achieve?

> If your customer wants a .dll, you cannot tell him that a directory
> of source files would do. Esp. in view of that he wants to call the
> .dll from a big C++ program (mostly C++, but probably some Basic
> etc.).

Yes, but you don't need to generate a .dll to achieve that.

Andrew.

Alex McDonald

unread,
Oct 20, 2003, 7:17:35 AM10/20/03
to

<andr...@littlepinkcloud.invalid> wrote in message
news:vp7d7mb...@news.supernews.com...

Fascinated -- what's the alternative?

>
> Andrew.

--
Regards
Alex McDonald


andr...@littlepinkcloud.invalid

unread,
Oct 20, 2003, 10:29:27 AM10/20/03
to
Alex McDonald <alex...@btopenworld.com> wrote:

> <andr...@littlepinkcloud.invalid> wrote in message
> news:vp7d7mb...@news.supernews.com...

>> >> But the issue in my mind is why you'd want to do


>> >> that. How would it make the world a better place? What would
>> >> generating a bunch of relocatable objects achieve?
>>
>> > If your customer wants a .dll, you cannot tell him that a directory
>> > of source files would do. Esp. in view of that he wants to call the
>> > .dll from a big C++ program (mostly C++, but probably some Basic
>> > etc.).
>>
>> Yes, but you don't need to generate a .dll to achieve that.

> Fascinated -- what's the alternative?

Use a trampoline loader written in some other programming language.
Call Forth from that.

Andrew.

mlg

unread,
Oct 23, 2003, 3:12:00 PM10/23/03
to
andr...@littlepinkcloud.invalid wrote:

> Alex McDonald <alex...@btopenworld.com> wrote:
>
>
>><andr...@littlepinkcloud.invalid> wrote in message
>>news:vp7d7mb...@news.supernews.com...
>
>
>>>>>But the issue in my mind is why you'd want to do
>>>>>that. How would it make the world a better place? What would
>>>>>generating a bunch of relocatable objects achieve?
>>>
>>>>If your customer wants a .dll, you cannot tell him that a directory
>>>>of source files would do. Esp. in view of that he wants to call the
>>>>.dll from a big C++ program (mostly C++, but probably some Basic
>>>>etc.).
>>>
>>>Yes, but you don't need to generate a .dll to achieve that.
>

I am not sure what you mean.
If the customers want a DLL, you have to create a DLL.

>
>>Fascinated -- what's the alternative?
>
>
> Use a trampoline loader written in some other programming language.
> Call Forth from that.
>

The loader was written in C and called from the DLL.
But since DLL cannot know for sure that some memory address
is not used by the calling application, relocation was needed.

In fact, there are two files: the .dll an the .dat file with
the Forth dictionary image. Both must be in the same directory,
else the 1st one will not find the 2nd one.

Compiling at loading-time was not acceptable.
OTOH, something like F-Code could be acceptable
(that is, bytecode-encoded source compiled at startup-time),
but relocation would still be needed for the pre-compiled
part of the Forth system.

andr...@littlepinkcloud.invalid

unread,
Oct 23, 2003, 3:32:41 PM10/23/03
to
mlg <m_l...@yahoo.com> wrote:
> andr...@littlepinkcloud.invalid wrote:

>> Alex McDonald <alex...@btopenworld.com> wrote:
>>
>>
>>><andr...@littlepinkcloud.invalid> wrote in message
>>>news:vp7d7mb...@news.supernews.com...
>>
>>
>>>>>>But the issue in my mind is why you'd want to do
>>>>>>that. How would it make the world a better place? What would
>>>>>>generating a bunch of relocatable objects achieve?
>>>>
>>>>>If your customer wants a .dll, you cannot tell him that a directory
>>>>>of source files would do. Esp. in view of that he wants to call the
>>>>>.dll from a big C++ program (mostly C++, but probably some Basic
>>>>>etc.).
>>>>
>>>>Yes, but you don't need to generate a .dll to achieve that.

> I am not sure what you mean.
> If the customers want a DLL, you have to create a DLL.

Well, I thought we were having a technical discussion about features
and benefits. If a customer wants something specific, then that's
their right. But my question "why you'd want to do that?" extends to
the customer too.

>>>Fascinated -- what's the alternative?
>>
>>
>> Use a trampoline loader written in some other programming language.
>> Call Forth from that.

> The loader was written in C and called from the DLL.
> But since DLL cannot know for sure that some memory address
> is not used by the calling application, relocation was needed.

Sure, but that doesn't require the Forth itself to be a DLL, or to be
in a DLL. It just requires the code to be relocatable.

> In fact, there are two files: the .dll an the .dat file with
> the Forth dictionary image. Both must be in the same directory,
> else the 1st one will not find the 2nd one.

> Compiling at loading-time was not acceptable.
> OTOH, something like F-Code could be acceptable
> (that is, bytecode-encoded source compiled at startup-time),
> but relocation would still be needed for the pre-compiled
> part of the Forth system.

This make no sense at all. Why is compiling from bytecode better than
compiling from source? Who cares?

Andrew.

Michael L Gassanenko

unread,
Oct 25, 2003, 4:28:07 AM10/25/03
to
andr...@littlepinkcloud.invalid wrote:
>
> > Compiling at loading-time was not acceptable.
> > OTOH, something like F-Code could be acceptable
> > (that is, bytecode-encoded source compiled at startup-time),
> > but relocation would still be needed for the pre-compiled
> > part of the Forth system.
>
> This make no sense at all. Why is compiling from bytecode better than
> compiling from source? Who cares?
>

1) the company that releases software is not willing to give away source
2) customers prefer not to depend upon the integrity of the source.

andr...@littlepinkcloud.invalid

unread,
Oct 31, 2003, 7:13:18 AM10/31/03
to
Michael L Gassanenko <m_l...@yahoo.com> wrote:

I can understand 1, but not 2. Can you amplify it a little?

Andrew.

Anton Ertl

unread,
Nov 1, 2003, 4:53:16 AM11/1/03
to
Guido Draheim <guidod...@gmx.de> writes:
>
>
>Anton Ertl wrote:
[Guido Draheim:]

>>>symbol does not have an adress during compilation, the actual
>>>adress is assigned during (re)linking or loading to execute.
>>>Some forths have expanded on that with words that tell the
>>>compiler to say what an adress is that possibly needs
>>>relocation by the loader.
>>
>>
>> If one wanted to do this, the main problem I see is the existence of
>> address arithmetic at compile time (i.e., before the arbitrary
>> compile-time/run-time cut that you have to make, if you want such a
>> scheme). The way to deal with this would be to have the "compiler"
>> track how the symbols are used in the computation. This would be very
>> unlike current Forth systems, more along the lines of Jonah's
>> ANS-Forth-program checker; as an added benefit, such a system would
>> probably take quite a bit more time in processing the source code,
>> thus justifying the need for separate compilation to the ignorant.
>
>I just don't get this, sorry.

Consider the following code:

create a 20 cells allot
here constant b
100 cells allocate throw 10 cells - constant c

: foo [ c a 2* - b 2* + ] literal ;

\ or, equivalently, but slightly easier
: foo [ b a - 2* c + ] literal ;

\ or think of the XOR doubly-linked list trick and create such a list
\ at compile time. I'm just too lazy to do that now.

If you want to put such stuff into a relocatable and linkable image,
the image format needs to be able to represent all kind of address
arithmetic allowed by the Forth system. In order to do that in the
general case, the Forth interpreter needs to keep track of what
address computation is performed.

E.g., just before the CONSTANT, tyhe interpreter would have a
descriptor on the top of stack saying something like

[allocated object #123]-10cells

and just after the first 2* it would have the following on the stack:

[allocated object #123]-10cells 2*[alloted object #234]

Now for the fun stuff: Consider that you have a structure definition S
and a field definition F in a separately compiled file x.o. In the
file y.fs that we want to compile into y.o we have:

here S %size allot constant bar
5 bar F !

Now consider what should happen if we change x.o such that the size of
S and the offset of F changes, and then want to relink with y.o. In
order for that to work, the linker would have to do pretty much
everything that a normal Forth system does when processing the two
lines above. I.e., there would be very little difference between such
a linker and an ordinary Forth system, especially in speed, and the .o
files would also contain most of the information in the source files
(minus comments). But then it's unclear why you would not just use an
ordinary Forth system and use the source (or maybe obfuscated source)
files instead of another format.

Now one can think up restrictions on the language used to produce such
.o files and on linking; these restrictions would allow simpler .o
formats and simpler and faster linkers. The various image formats and
relocatiors of the Forth systems around are such compromizes. You
seem to find them too restrictive, but it's unclear to me where you
would draw the line.

Let's look at what other languages do in these respects:

In C/C++ structure and field definitions are not represented in image
files, and you have to recompile y.o if you change the definition of
S. If you fail to do that and link an old y.o to a new x.o, you will
probably get a broken program (and no warning about that).

In the JVM .class format structure and field sizes are represented,
and using an old y.class with a new x.class would work as intended.
The cost you pay for this is that there is no static data in the
.class files (everything has to be produced dynamically on class
loading instead, and Java is a less convenient language than Forth for
such things), and there are a number of challenging in implementing
this efficiently (mainly due to the somewhat arbitrary requirement to
do the initialization when first referencing something from a class).

>> In C using addresses is not allowed in a number of places (e.g., IIRC
>> not as case labels) to make the compiler's job easier.
>
>Hmmm, using adress as the case label value, interesting thing.
>The old C design does ask for "compile-time constant" things
>to be only valid as case label arguments. However, adding a
>data reloc fixup should be possible as well, so the label
>value would be therefore program execution. IIRC, it is
>invalid because the way C compilers build the switch's jump
>table as a numerically _ordered_ list of case' values and
>case' adresses to jump to. And since each portion in C can
>be `load`ed into a different place in memory, that ordering
>is not ensured.

There are various ways to implement switch (jump tables, hash tables,
binary search trees), and many compilers use several of them,
depending on the number and sparsity of the case labels. For each of
these ways, the linker would become vastly more complex if it was to
support linkable addresses as case labels.

>BTW, coming back to the forth way of doing allocations,
>we had the discussion on adjascent allocations that might
>be broken by some words into pieces with gaps - but are
>these gaps? Traditional forth sources will expect a strict
>ordering of allocations, right? I am not sure if that is
>in the ANS Forth standard, it was atleast a nice assertion
>for implemenations of FORGET to detect the "defined earlier"
>attribution for a word.

The Forth standard does not make any guarantee of that. If a system
implementor chooses to do it in a different way and wants to implement
FORGET, he will have to find another way; but that's the consequence
of his implementation choices (he could also choose to do it in the
traditional way).

>> Yes, Forth is too powerful to fit well into that framework. That's
>> the main reason why hardly any Forth system tries to produce .o files.
>
>*grin* what a perspective! Now, what limitations would be needed
>to make it work?! Is it possible to jot down an easy list that
>a common forth programmer can get away with, w/o forgetting about
>it next corner because it is too inconvenient?

As to the latter, maybe, maybe not: I have no trouble remembering to
use CELLS etc. instead of doing the address arithmetoc in my head and
just writing down the result, but when I use Gforth's cross compiler,
I always forget to tag addresses.

As to the former, I have thought up a possible implementation for
producing a.out/ELF-style .o files, and can enumerate some
restructions following from that, but I don't know if they are
exhaustive:

Ok, the Forth system loads all the .o files it needs for producing the
current file, then compiles the source code; it does this twice to
different addresses (the offset between these files is probably best
kept the same each time), in order to distinguish addresses from
integers. For each address a you find, look into which memory-object
it points, and record a linker relocation request containing two
symbol+offset pairs (one for the address where a is stored, and one
for a itself); the symbol+offset pair describe the memory-object and
the offset within that memory object.

Some of the restrictions from this scheme:

- You can only have addresses pointing into a memory-object in stuff
you want to put into a .o file (with a little variation you can also
have addresses pointing to the end of memory-objects).

- You cannot do compile-time computations with constants from other .o
files (or you have to recompile when the constant changes there).

>> The other frameworks are even worse in not supporting even C, Fortran,
>> and C++: The Java framework can only do Java (ok, there have been some
>> experiments with a few other languages, but I am not aware of any of
>> these becoming popular; in any case, that framwork is too restrictive
>> for languages like C, C++ and Fortran). .NET is reportedly less
>> restrictive than the Java framework, but still not able to deal with
>> the unaltered languages.
>>
>
>Oh, that's kind a trick question. Most of the limitations of the
>net vm languages come from its `sandbox` approach,

I actually was thinking about modifications to the languages in order
to fit the .NET exception and inheritance models that I had read
about.

Anton Ertl

unread,
Nov 1, 2003, 6:28:19 AM11/1/03
to
Michael L Gassanenko <m_l...@yahoo.com> writes:
>andr...@littlepinkcloud.invalid wrote:
>>
>> > ... Especially, there is no "end of allocations" mark to
>> > hint a compiler to possibly put a break in, and consequently a forth
>> > word does not have a direct sizeof() unless by implication of the
>> > start of the next symbol.
>
>Indeed.
>
>CREATE tmp1 $100 CELLS ALLOT
>HERE $200 CELLS ALLOT CONSTANT tmp2
>
>Is this one data structure or two data structures?

As far as an ANS Forth system is concerned, there is only one
contiguous region here. As a programmer, you are free to think of it
as two data structures. If it was the other way round, you would have
a problem.

>I think, two, but what about
>
>CREATE tmp1 $300 CELLS ALLOT HERE $200 CELLS - CONSTANT tmp2

Also one contiguous region ($300 cells starting at tmp1).

0 new messages