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

Test of COMPILE,

27 views
Skip to first unread message

Krishna Myneni

unread,
Nov 26, 2011, 11:20:01 AM11/26/11
to
I realized that the implementation of COMPILE, in kForth is broken. In
fixing the problem, I devised a few tests. However, the following test
does not seem to load in Gforth:

2 constant two ok
: test [ ' two compile, 3 ] - 1 = ;

Gforth fails to load the definition of TEST

--
:2: unstructured
: test [ ' two compile, 3 ] - 1 = >>>;<<<
Backtrace:
$7F6A74418C28 throw
$7F6A744292E0 c(abort")
$7F6A744368B0 def?
$7F6A744224E8 ;-hook
$7F6A744205C8 execute
--

The test loads and runs properly under my patches for kForth. Is there
a problem with the definition of TEST ?

Krishna

Andrew Haley

unread,
Nov 26, 2011, 12:36:44 PM11/26/11
to
It doesn't seem to be a standard Forth program. What is the compiler
supposed to do with that 3 you left on the stack?

Andrew.

Marcel Hendrix

unread,
Nov 26, 2011, 11:41:57 AM11/26/11
to
Krishna Myneni <krishna...@ccreweb.org> wrote Re: Test of COMPILE,
[..]
> 2 constant two ok
> : test [ ' two compile, 3 ] - 1 = ;
[..]
> Gforth fails to load the definition of TEST
[..]

Don't you mean

2 constant two
: test [ ' two compile, 3 ] literal 1- = ;

Accepted by Win32Forth, VfxForth, SwiftForth and gForth.

iForth rejects it because the interpretation semantics of
COMPILE, are undefined. After : COMPILE, COMPILE, ; it
`works` to.

All compilers accept ...

: test [ ' two compile, -12 allot 3 ] literal 1- = ;

... with various interesting results. E.g. VfxForth seems not
to notice the -12 allot at all, SwiftForth exits silently and
gForth gives a good error report (It has head damage but not
critical).

-marcel


Krishna Myneni

unread,
Nov 26, 2011, 12:44:02 PM11/26/11
to
On Nov 26, 11:36 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
A stack comment helps.

: test ( n -- flag ) [ ' two compile, 3 ] - 1 = ;

The 3 should be placed on the stack when TEST is compiled, since we
are in interpretation state. Then, when we run TEST right after its
definition, it should produce a true flag on the stack.

I can't see what's non-standard about this usage.

Krishna

Krishna Myneni

unread,
Nov 26, 2011, 12:51:14 PM11/26/11
to
On Nov 26, 10:41 am, m...@iae.nl (Marcel Hendrix) wrote:
> Krishna Myneni <krishna.myn...@ccreweb.org> wrote Re: Test of COMPILE,
> [..]> 2 constant two  ok
> > : test [ ' two compile, 3 ] - 1 = ;
> [..]
> > Gforth fails to load the definition of TEST
>
> [..]
>
> Don't you mean
>
> 2 constant two
> : test [ ' two compile, 3 ] literal 1- = ;
>
> Accepted by Win32Forth, VfxForth, SwiftForth and gForth.
>
> iForth rejects it because the interpretation semantics of
> COMPILE, are undefined. After : COMPILE, COMPILE, ; it
> `works` to.
>

Ah! Ok, I missed the spec where it says interpretation semantics of
COMPILE, are undefined. That explains the different behavior in
different systems. I was confused by the original mini-oof word "::"
which is defined with COMPILE, but "::" itself is used in
interpretation state, as in the mini-oof example,

:noname bold [ button :: draw ] normal ;

where the definition of "::" is

: :: ( class "name" -- ) ' >body @ + @ compile, ;

Krishna


Alex McDonald

unread,
Nov 26, 2011, 1:01:33 PM11/26/11
to
On Nov 26, 4:41 pm, m...@iae.nl (Marcel Hendrix) wrote:
> Krishna Myneni <krishna.myn...@ccreweb.org> wrote Re: Test of COMPILE,
My compiler optimizes the whole lot away in the first case, and does
what's asked of it in the second case. That's because the headers and
the code are maintained in separate sections from data at HERE.

STC Experimental Version: 0.05.01 Build: 439
2 constant two ok
: test [ ' two compile, 3 ] literal 1- = ; ok
test . -1 ok
see test
: test ( ? -- ? ) \ std call compiles
\ len=9 type=20
\ in (console)
( $424114 ' test ) mov $-4 [ebp], eax \ 8945FC
( $424117 ' test+$3 ) or eax, # $-1 \ 83C8FF
( $42411A ' test+$6 ) sub ebp, # $4 \ 83ED04
( $42411D ' test+$9 ) ret near \ C3
( end ) ok

here . 8414048 ok
: test [ ' two compile, -12 allot 3 ] literal 1- = ;
^
Warning -4100 test is redefined ok
here . 8414036 ok
test . -1 ok

Marcel Hendrix

unread,
Nov 26, 2011, 1:25:36 PM11/26/11
to
Alex McDonald <bl...@rivadpm.com> writes Re: Test of COMPILE,
[..]
> My compiler optimizes the whole lot away in the first case,
[..]

I guess you have in some way made sure that the Forth code
executed between [ and ], if it affects the definition in
progress, has no other way then to go through COMPILE, .

For iForth I can not prove this because code and data are
in the same memory area and therefore [ $C9 C, ] is a
counterexample. Even if the areas were separated, there'd
be kernel words to write to code space, (e.g. the assembler)
making optimization impossible.

Although AFAIR it is not allowed to manipulate code space
when the definition is not yet finished, that is theory,
and I felt sure existing programs were doing this.

It might be a good idea to simply not support such practices
anymore.

-marcel

Krishna Myneni

unread,
Nov 26, 2011, 2:23:35 PM11/26/11
to
What does your compiler do with the following?

--

\ Test compilecomma
\
: ?passed ( flag -- ) IF ." Passed." ELSE ." Failed!" THEN ;

: test1 [ ' true compile, ] ;
cr .( test1 ... ) test1 ?passed

2 constant two
: test2 [ ' two compile, ] 1- ;
cr .( test2 ... ) test2 ?passed

: test3 [ ' two compile, 3 ] - 1 = ;
cr .( test3 ... ) test3 ?passed

: test4a compile, ; immediate
: test4 [ ' true ] test4a ;
cr .( test4 ... ) test4 ?passed

--
Krishna

Krishna Myneni

unread,
Nov 26, 2011, 3:14:26 PM11/26/11
to
On Nov 26, 11:36 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
More fundamentally, would the following be considered non-standard? If
so, why?

--
Gforth 0.7.9-20101227, Copyright (C) 1995-2011 Free Software
Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
: test [ 3 ] ;
:1: unstructured
: test [ 3 ] >>>;<<<
Backtrace:
$7FBC85886C28 throw
$7FBC858972E0 c(abort")
$7FBC858A48B0 def?
$7FBC858904E8 ;-hook
$7FBC8588E5C8 execute
--

Krishna

Bernd Paysan

unread,
Nov 26, 2011, 3:31:11 PM11/26/11
to
Krishna Myneni wrote:
>> iForth rejects it because the interpretation semantics of
>> COMPILE, are undefined. After : COMPILE, COMPILE, ; it
>> `works` to.
>>
>
> Ah! Ok, I missed the spec where it says interpretation semantics of
> COMPILE, are undefined. That explains the different behavior in
> different systems. I was confused by the original mini-oof word "::"
> which is defined with COMPILE, but "::" itself is used in
> interpretation state, as in the mini-oof example,
>
> :noname bold [ button :: draw ] normal ;
>
> where the definition of "::" is
>
> : :: ( class "name" -- ) ' >body @ + @ compile, ;

To be honest, I don't understand why the interpretation semantics of
compile, is declared undefined. compile, needs a current definition,
yes, but that's it.

--
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

Krishna Myneni

unread,
Nov 26, 2011, 5:09:49 PM11/26/11
to
If it's an arbitrary restriction, but there is in reality no problem
for system implementors to give interpretation semantics when a colon
definition is in progress, then we should look at revising the
standard.

Krishna

Alex McDonald

unread,
Nov 26, 2011, 5:48:02 PM11/26/11
to
STC Experimental Version: 0.05.01 Build: 440
\ Test compilecomma ok
\ ok
: ?passed ( flag -- ) IF ." Passed." ELSE ." Failed!" THEN ; ok
ok
: test1 [ ' true compile, ] ; ok
cr .( test1 ... ) test1 ?passed
test1 ... Passed. ok
ok
2 constant two ok
: test2 [ ' two compile, ] 1- ; ok
cr .( test2 ... ) test2 ?passed
test2 ... Passed. ok
ok
: test3 [ ' two compile, 3 ] - 1 = ;
^
Error -320 ; stack changed
: test4a compile, ; immediate ok
: test4 [ ' true ] test4a ; ok
cr .( test4 ... ) test4 ?passed
test4 ... Passed. ok

Alex McDonald

unread,
Nov 26, 2011, 6:04:55 PM11/26/11
to
On Nov 26, 6:25 pm, m...@iae.nl (Marcel Hendrix) wrote:
> Alex McDonald <b...@rivadpm.com> writes Re: Test of COMPILE,
> [..]> My compiler optimizes the whole lot away in the first case,
>
> [..]
>
> I guess you have in some way made sure that the Forth code
> executed between [ and ], if it affects the definition in
> progress, has no other way then to go through COMPILE, .

There are no standard words that can affect the definition in
progress, since it's not being built in the area pointed at by HERE --
with the exception of COMPILE, CODE : and :NONAME. LITERAL is not
allowed in interpret mode.

: test 1 2 3 [ : test2 10 ; ] 4 ;

TEST is undefined, since TEST2 has usurped it. The compiler carries on
quite happily, wasting code space, and TEST2 ends up as valid and
executable code preceded and followed by the wreckage of TEST.

>
> For iForth I can not prove this because code and data are
> in the same memory area and therefore [ $C9 C, ] is a
> counterexample. Even if the areas were separated, there'd
> be kernel words to write to code space, (e.g. the assembler)
> making optimization impossible.
>
> Although AFAIR it is not allowed to manipulate code space
> when the definition is not yet finished, that is theory,
> and I felt sure existing programs were doing this.

It's not deliberate in my compiler, just a side effect of separate
code, data and header areas.

Alex McDonald

unread,
Nov 26, 2011, 6:08:23 PM11/26/11
to
There's rubbish on the stack from the compilation between : and ;.
Many Forths complain about this, including Win32forth and mine. What
will pass is

3 : test [ ' two compile, ] - 1 = ;

Krishna Myneni

unread,
Nov 26, 2011, 7:03:16 PM11/26/11
to
The basic example I gave was,

: test [ 3 ] ;

Apparently, many implementations of Forth expect the stack to be
restored at ";" to the state following ";". Is this required by the
present Forth-94 standard?

Krishna

Krishna Myneni

unread,
Nov 26, 2011, 7:00:00 PM11/26/11
to
Thanks for running the tests. It looks as though most Forth systems
support interpretation semantics for COMPILE, with consistent
behavior. Even in iForth, it appears to be trivial to redefine
COMPILE, to obtain the same behavior in interpretation state.

The one test that fails to compile, above, also seems to be pretty
consistent in failing across various Forth systems, with the exception
of my system. Although, I don't understand yet what it is about the
Forth-94 standard which precludes a colon definition from placing
something on the stack between ":" and ";".

Krishna

Krishna Myneni

unread,
Nov 26, 2011, 7:12:50 PM11/26/11
to
On Nov 26, 6:03 pm, Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
...
> : test [ 3 ] ;
>
> Apparently, many implementations of Forth expect the stack to be
> restored at ";" to the state following ";". Is this required by the
> present Forth-94 standard?
>

A typo -- I meant, "... restored at ';' to the state following ':'. "

Krishna

Coos Haak

unread,
Nov 26, 2011, 8:09:46 PM11/26/11
to
Op Sat, 26 Nov 2011 16:00:00 -0800 (PST) schreef Krishna Myneni:

<snip>
> The one test that fails to compile, above, also seems to be pretty
> consistent in failing across various Forth systems, with the exception
> of my system. Although, I don't understand yet what it is about the
> Forth-94 standard which precludes a colon definition from placing
> something on the stack between ":" and ";".
>
> Krishna

: aap [ 3 ] ;
fails on all the Forths I tested, because of the presence of !CSP and ?CSP
or something like that.
I think this behavior is also helpful to signal unfinished control
structures:

: noot if else ;

--
Coos

CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html

Krishna Myneni

unread,
Nov 26, 2011, 9:11:14 PM11/26/11
to
Apparently, the restriction is an implicit one by the allowance in
Forth-94 for the flow control stack to be the same as the data stack.
However, implementations which do not use the data stack for the flow
control stack should be able to place items onto the data stack during
word definitions, without side effects. Whether or not such a practice
has any benefits is not clear.

Also, systems which do not use the data stack to hold control
structure information during compilation can also detect incomplete
structures, e.g., in kForth:

: app [ 3 ] ;
ok
: noot if else ;
Line 2: Compiler Error(6): Incomplete IF...THEN structure
: noot if else ;


Krishna

Elizabeth D. Rather

unread,
Nov 26, 2011, 10:10:40 PM11/26/11
to
On 11/26/11 2:03 PM, Krishna Myneni wrote:
...
> Apparently, many implementations of Forth expect the stack to be
> restored at ";" to the state following ";". Is this required by the
> present Forth-94 standard?
>
> Krishna

In Forth94, : leaves a 'colon-sys' on the stack, and ; expects one. The
nature of a colon-sys is "implementation-dependent" meaning you don't
know what it is (if anything).

The whole purpose of this is to permit compilers to check, if they wish,
that nothing has been left on the stack at the end of a colon
definition. That is valuable to people who, assuming that the
control-flow stack is the data stack at compile time, use a data stack
imbalance around a colon definition as a diagnostic of an incomplete
control flow structure. Systems vary widely in the extent to which this
is policed.

As an implementor, you're perfectly at liberty to ignore the whole
thing, but programs that *assume* you can have an unbalanced stack
around a : ... ; set are portable only to systems that also ignore it.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

Krishna Myneni

unread,
Nov 26, 2011, 10:33:21 PM11/26/11
to
> Los Angeles, CA 90045http://www.forth.com
>
> "Forth-based products and Services for real-time
> applications since 1973."
> ==================================================

Thanks for the clarification, Elizabeth. I had reached somewhat the
same conclusion, but you response helps. I think it can be agreed that
a program which creates an unbalanced stack between ":" and ";" is non-
standard under Forth-94.

What is your opinion of the use of COMPILE, in interpretation state,
while a word is being defined? Many systems seem to support this
behavior, although it is considered an ambiguous condition by DPANS94.
Should this be codified as a standard behavior in a future standard,
or would some Forth system architectures inherently be unable to
implement such behavior?

Krishna

Elizabeth D. Rather

unread,
Nov 26, 2011, 11:28:22 PM11/26/11
to
On 11/26/11 5:33 PM, Krishna Myneni wrote:
...
> What is your opinion of the use of COMPILE, in interpretation state,
> while a word is being defined? Many systems seem to support this
> behavior, although it is considered an ambiguous condition by DPANS94.
> Should this be codified as a standard behavior in a future standard,
> or would some Forth system architectures inherently be unable to
> implement such behavior?
>
> Krishna

I'm afraid I'm not enough of a compiler guru to know all the
consequences of using COMPILE, in interpretation state. It has been
noted that it's meaningless unless you have a definition under
construction, and I don't know how one could test for that -- it would
be up to the programmer to know. And if the system's COMPILE, is capable
of doing some sort of optimization, I can imagine difficulties. If your
' finds different versions of words in compile mode, that would be an
issue as well.

Not an awful lot of help, I'm afraid.

Marcel Hendrix

unread,
Nov 27, 2011, 1:01:27 AM11/27/11
to
Coos Haak <chf...@hccnet.nl> wrote Re: Test of COMPILE,

> Op Sat, 26 Nov 2011 16:00:00 -0800 (PST) schreef Krishna Myneni:

<snip>
>> The one test that fails to compile, above, also seems to be pretty
>> consistent in failing across various Forth systems, with the exception
>> of my system. Although, I don't understand yet what it is about the
>> Forth-94 standard which precludes a colon definition from placing
>> something on the stack between ":" and ";".

>> Krishna

> : aap [ 3 ] ;
> fails on all the Forths I tested, because of the presence of !CSP and ?CSP
> or something like that.
> I think this behavior is also helpful to signal unfinished control
> structures:

> : noot if else ;

It is possible to detect the problem with 'noot' while still allowing 'aap'.
(iForth does not use the datastack to store control flow information,)

[1] iForth x64 server 1.03 (console), Nov 4 2011, 21:17:27.
[2] Stuffed iForth at $00FF4440 [entry: $01000000]
[3] Having a Windows terminal.
[4] Console is active.
[5] Sound devices are internal.
[6] Executing include/iforth.prf

Creating --- LOCATE utility Version 1.10 ---
Creating --- Several utilities Version 3.12 ---
Creating --- Extended OS words Version 3.17 ---
Creating --- Terminal Driver Version 3.14 ---
Creating --- Command line Editor Version 1.30 ---
Creating --- Online help Version 1.36 ---
Creating --- Glossary Generator Version 1.05 ---
Creating --- Disassembler Version 2.40 ---

iForth version 4.0.753, generated 13:01:18, October 8, 2011.
x86_64 binary, native floating-point, extended precision.
Copyright 1996 - 2011 Marcel Hendrix.

FORTH> : aap [ 3 ] ; ok
[1]FORTH> .s
Data: 3 ---
System: ---
Float: --- ok
[1]FORTH> . 3 ok
FORTH> : noot if else ;
Error -22
[;] : Structure not balanced ?

-marcel

Gerry

unread,
Nov 27, 2011, 3:09:04 AM11/27/11
to
Forth systems requiring stack depth to be the same across a colon
definition has long been a source of irritation when writing portable
programs in ANS Forth. For example to pass data into and out of a
colon definition requires a trick such as PASS

: pass >r ' execute r> ; immediate

(if I've remembered it correctly)

Usage e.g. 3 pass : foo ... ;

Gerry

Mark Wills

unread,
Nov 27, 2011, 3:47:25 AM11/27/11
to
Agreed. WRT to catching unbalanced constructs such as IF...THEN etc, I
simply implemented reference counting. Since IF (for example) is
immediate it simply increments an 'IF' counter (a dedicated cell in
memory, not stored on the stack). THEN simply decrements the same
counter. The word ; contains checks the various reference counters. If
a counter > 0 then the appropriate error condition is reported e.g.
"Error:Unbalanced IF/THEN". It's probably not fool proof, but it does
mean that the stack is yours before, during, and after compilation!

Mark

Marcel Hendrix

unread,
Nov 27, 2011, 3:48:39 AM11/27/11
to
Mark Wills <forth...@gmail.com> writes Re: Test of COMPILE,

> On Nov 27, 8:09 am, Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
[..]
>> Forth systems requiring stack depth to be the same across a colon
>> definition has long been a source of irritation when writing portable
>> programs in ANS Forth. For example to pass data into and out of a
>> colon definition requires a trick such as PASS

>> : pass >r ' execute r> ; immediate

>> (if I've remembered it correctly)

>> Usage e.g. 3 pass : foo ... ;

>> Gerry

> Agreed. WRT to catching unbalanced constructs such as IF...THEN etc, I
> simply implemented reference counting. Since IF (for example) is
> immediate it simply increments an 'IF' counter (a dedicated cell in
> memory, not stored on the stack). THEN simply decrements the same
> counter. The word ; contains checks the various reference counters. If
> a counter > 0 then the appropriate error condition is reported e.g.
> "Error:Unbalanced IF/THEN". It's probably not fool proof, but it does
> mean that the stack is yours before, during, and after compilation!

And where do you temporarily store the patch addresses needed by THEN ?

-marcel

Andrew Haley

unread,
Nov 27, 2011, 5:21:45 AM11/27/11
to
Krishna Myneni <krishna...@ccreweb.org> wrote:
> The basic example I gave was,
>
> : test [ 3 ] ;
>
> Apparently, many implementations of Forth expect the stack to be
> restored at ";" to the state following ";". Is this required by the
> present Forth-94 standard?

Yes.

6.1.0450 :
colon CORE

( C: "<spaces>name" -- colon-sys )

6.1.0460 ;
semicolon CORE

Interpretation: Interpretation semantics for this word are undefined.

Compilation: ( C: colon-sys -- )

colon-sys is some number of items on the stack. If you put something
on the stack after : , you must remove it before ; . That's what the
colon-sys implies.

Andrew.

Coos Haak

unread,
Nov 27, 2011, 8:09:11 AM11/27/11
to
Op Sun, 27 Nov 2011 08:01:27 +0200 schreef Marcel Hendrix:
As an aside, control structures in my assembler don't have to be complete:

code ?dup
test bx, bx
0= if
next
end-code

code dup
then
push bx
next
end-code

Mark Wills

unread,
Nov 27, 2011, 8:24:59 AM11/27/11
to
On Nov 27, 8:48 am, m...@iae.nl (Marcel Hendrix) wrote:
> Mark Wills <forthfr...@gmail.com> writes Re: Test of COMPILE,
They're on the stack; the 'classical' method of resolving addresses
(i.e. on the stack) is used. But there's no colon-sys or equivalent in
play.

Mark

Anton Ertl

unread,
Nov 27, 2011, 9:02:56 AM11/27/11
to
Krishna Myneni <krishna...@ccreweb.org> writes:
>What is your opinion of the use of COMPILE, in interpretation state,
>while a word is being defined? Many systems seem to support this
>behavior, although it is considered an ambiguous condition by DPANS94.

It's not. The interpretation semantics of COMPILE, is not defined,
but the execution semantics are defined in a STATE-independent way.

So

: foo [ ' + compile, ] ;

is not compliant, but

: my-compile, compile, ;
: bar [ ' + my-compile, ] ;

is compliant.

Some other interesting cases:

\ outside a definition
' + compile,

This is non-standard because of the lack of interpretation semantics
and because there is no current definition.

: [compile,] compile, ;
' + ] [compile,] [

This is non-standard because there is no current definition, but the
interpretation semantics of COMPILE, don't come into play here.

>Should this be codified as a standard behavior in a future standard,
>or would some Forth system architectures inherently be unable to
>implement such behavior?

Standard Forth systems must be able to implement COMPILE, with
interpretation semantics. In fact it's trivial to convert a standard
system without interpretation semantics for COMPILE, into one with
interpretation semantics for COMPILE,:

: compile, compile, ;

This is a standard program, and a standard system is still standard
after this definition, but now it has a COMPILE, with interpretation
semantics.

So yes, we could remove the "undefined interpretation semantics"
clause.

- 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
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2011: http://www.euroforth.org/ef11/

Anton Ertl

unread,
Nov 27, 2011, 9:17:38 AM11/27/11
to
Krishna Myneni <krishna...@ccreweb.org> writes:
>I was confused by the original mini-oof word "::"
>which is defined with COMPILE, but "::" itself is used in
>interpretation state, as in the mini-oof example,
>
>:noname bold [ button :: draw ] normal ;
>
>where the definition of "::" is
>
>: :: ( class "name" -- ) ' >body @ + @ compile, ;

Note that the compilation sematics of COMPILE, does not come into play
here; COMPILE, is performed by the text interpreter in compile state,
so the compilation semantics of COMPILE, is performed. Later, during
execution of ::, the execution semantics of COMPILE, is performed.
This is just like

: compile, compile, ;

Krishna Myneni

unread,
Nov 27, 2011, 11:42:19 AM11/27/11
to
On Nov 27, 8:02 am, an...@mips.complang.tuwien.ac.at (Anton Ertl)
wrote:
> ...  The interpretation semantics of COMPILE, is not defined,
> but the execution semantics are defined in a STATE-independent way.
>

Not quite true for my (non-standard) system, as it performs a deferred
compilation even in interpretation state, so I have to switch the
virtual opcode vectors based on STATE. But, I see your point for
standard systems.

...
> Standard Forth systems must be able to implement COMPILE, with
> interpretation semantics.  In fact it's trivial to convert a standard
> system without interpretation semantics for COMPILE, into one with
> interpretation semantics for COMPILE,:
>
> : compile, compile, ;
>
> This is a standard program, and a standard system is still standard
> after this definition, but now it has a COMPILE, with interpretation
> semantics.
>
> So yes, we could remove the "undefined interpretation semantics"
> clause.
>

A good set of tests for COMPILE, which check compliance to the
existing Forth-94 standard, and provide extended tests for the
interpretation state behavior of COMPILE, would give us a starting
point to amend the spec.

Krishna

BruceMcF

unread,
Nov 27, 2011, 12:08:21 PM11/27/11
to
On Nov 26, 10:33 pm, Krishna Myneni <krishna.myn...@ccreweb.org>
wrote:
> I think it can be agreed that
> a program which creates an unbalanced stack between ":" and ";" is non-
> standard under Forth-94.

Or rather that they have an implementation dependency on ( colon-sys )
either not being on the data stack or being a nul (the latter perhaps
more common than the former). After all, the standard does not
*require* an implementation to balk at an unbalanced data stack
between ":" and ";",

Lots of things can be "standard but not necessarily very portable"
with declaration of the appropriate implementation dependencies.

Albert van der Horst

unread,
Nov 27, 2011, 4:08:48 PM11/27/11
to
In article <d9103622-67ae-4f35...@n10g2000vbg.googlegroups.com>,
Gerry <ge...@jackson9000.fsnet.co.uk> wrote:
>On Nov 27, 2:11=A0am, Krishna Myneni <krishna.myn...@ccreweb.org> wrote:
>> On Nov 26, 7:09=A0pm, Coos Haak <chfo...@hccnet.nl> wrote:
>>
>>
>>
>> > Op Sat, 26 Nov 2011 16:00:00 -0800 (PST) schreef Krishna Myneni:
>>
>> > <snip>
>>
>> > > The one test that fails to compile, above, also seems to be pretty
>> > > consistent in failing across various Forth systems, with the exceptio=
>n
>> > > of my system. Although, I don't understand yet what it is about the
>> > > Forth-94 standard which precludes a colon definition from placing
>> > > something on the stack between ":" and ";".
>>
>> > > Krishna
>>
>> > : aap [ 3 ] ;
>> > fails on all the Forths I tested, because of the presence of !CSP and ?=
>CSP
>> > or something like that.
>> > I think this behavior is also helpful to signal unfinished control
>> > structures:
>>
>> > : noot if else ;
>>
>> > --
>> > Coos
>>
>> > CHForth, 16 bit DOS applicationshttp://home.hccnet.nl/j.j.haak/forth.ht=
>ml
>>
>> Apparently, the restriction is an implicit one by the allowance in
>> Forth-94 for the flow control stack to be the same as the data stack.
>> However, implementations which do not use the data stack for the flow
>> control stack should be able to place items onto the data stack during
>> word definitions, without side effects. Whether or not such a practice
>> has any benefits is not clear.
>>
>> Also, systems which do not use the data stack to hold control
>> structure information during compilation can also detect incomplete
>> structures, e.g., in kForth:
>>
>> : app [ 3 ] ;
>> =A0ok
>> : noot if else ;
>> Line 2: Compiler Error(6): Incomplete IF...THEN structure
>> : noot if else ;
>>
>
>Forth systems requiring stack depth to be the same across a colon
>definition has long been a source of irritation when writing portable
>programs in ANS Forth. For example to pass data into and out of a
>colon definition requires a trick such as PASS
>
>: pass >r ' execute r> ; immediate
>
>(if I've remembered it correctly)
>
>Usage e.g. 3 pass : foo ... ;

For systems that just put a single cell on the stack at :,
you need no extra word ( _ puts a don't care on the stack )
3 : foo [ _ SWAP do-your-thing ] LITERAL ... ; DROP

For me this technique suffices.
This not as portable as your technique, but yours is not fully
compliant either.

Or straightforward :

VARIABLE temp
3 temp !
..... temp @ .....
'temp HIDDEN ( for the paranoid )

Not reentrant ? We are compiling here, so.

>
>Gerry

Groetjes Albert

--
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Gerry Jackson

unread,
Nov 27, 2011, 4:18:38 PM11/27/11
to
On 27/11/2011 21:08, Albert van der Horst wrote:
[...]
As you apparently don't care about portability that's fine for you but
hardly to be recommended. Different systems put varying numbers of cells
on the stack - I've seen 0, 1, 2 and 3 cells.

> This not as portable as your technique,
Given that I was talking about portable programs, ISTM that your
technique above is irrelevant.

but yours is not fully
> compliant either.

Why not? Of course the value passed in has to be used before the ; but
that doesn't make it non-compliant. Incidentally I didn't invent it,
AFAIK it was Michael Gassanenko.
>
> Or straightforward :

To a beginner probably not.

>
> VARIABLE temp
> 3 temp !
> ..... temp @ .....
> 'temp HIDDEN ( for the paranoid )
>
> Not reentrant ? We are compiling here, so.
>


--
Gerry

Krishna Myneni

unread,
Nov 27, 2011, 6:00:50 PM11/27/11
to
Gerry,

Can you provide an example of where it is necessary to pass a value on
the stack to a word under construction? Is there a reason why we
couldn't use "[ ... ] literal" to achieve the same result?

Krishna

BruceMcF

unread,
Nov 27, 2011, 7:58:56 PM11/27/11
to
On Nov 27, 4:08 pm, Albert van der Horst <alb...@spenarnc.xs4all.nl>
wrote:
> In article <d9103622-67ae-4f35-8347-28971e754...@n10g2000vbg.googlegroups.com>,

>> : pass >r ' execute r> ; immediate

>> (if I've remembered it correctly)

>> Usage e.g. 3 pass : foo ... ;

> This not as portable as your technique, but yours is not fully compliant either.

pass has an implementation dependency on the return stack not being
used as the control-flow stack, but that's met by a lot of
implementations.

Gerry Jackson

unread,
Nov 28, 2011, 6:39:48 AM11/28/11
to
I can't remember the details of when I first came across it as a problem
and I avoid doing it these days. I think it was when setting up some
data structure and passing the address into a colon definition, which
worked on my Forth as it has a separate control flow stack and doesn't
check stack depth across a colon definition, but failed miserably when I
tested the code on other Forths.

There is the point that ALLOT C, etc, say for creating anonymous
objects, cannot be used portably inside the [ ... ] when compiling. Also
if the code inside the [ ... ] is more than a few words it seems better
to do it outside the colon definition.

IMO using the data stack as the control-flow stack and checking stack
depths before and after a colon definition is a legacy from the days of
resource-limited computers and has no place in a modern Forth. But then
I don't use resource-limited processors so I would say that. But then
again I get the impression that code for such processors tends to be
non-standard anyway.

--
Gerry

Anton Ertl

unread,
Nov 28, 2011, 7:03:43 AM11/28/11
to
BruceMcF <agi...@netscape.net> writes:
>On Nov 27, 4:08=A0pm, Albert van der Horst <alb...@spenarnc.xs4all.nl>
>wrote:
>> In article <d9103622-67ae-4f35-8347-28971e754...@n10g2000vbg.googlegroups=
>.com>,
>
>>> : pass >r ' execute r> ; immediate
>
>>> (if I've remembered it correctly)
>
>>> Usage e.g. 3 pass : foo ... ;
>
>> This not as portable as your technique, but yours is not fully compliant =
>either.
>
>pass has an implementation dependency on the return stack not being
>used as the control-flow stack

The control-flow stack may be on the data stack or separate, but it
certainly must not be on the return stack. So

: pass >r ' execute r> ; immediate
3 pass : foo literal ;

is a standard program. If it does not port to some non-standard
systems, I doubt that the use of the return stack is the cause.

Andrew Haley

unread,
Nov 28, 2011, 7:25:26 AM11/28/11
to
Krishna Myneni <krishna...@ccreweb.org> wrote:

> Can you provide an example of where it is necessary to pass a value on
> the stack to a word under construction? Is there a reason why we
> couldn't use "[ ... ] literal" to achieve the same result?

The simplest case is

here 0 , : counter ( -- n) literal 1 over +! @ ;

It's a singleton: like DOES> but with only a single child.

Andrew.

Alex McDonald

unread,
Nov 28, 2011, 7:52:19 AM11/28/11
to
On Nov 28, 11:39 am, Gerry Jackson <ge...@jackson9000.fsnet.co.uk>
wrote:
The use of the data stack for control flow is really very simple to
implement, since it doesn't require another stack. The requirement to
have matching stack depths at : and ; is a very minor inconvenience,
and when they don't, 99 times out of a 100 it's because I've miscoded.

Krishna Myneni

unread,
Nov 28, 2011, 8:05:24 AM11/28/11
to
On Nov 28, 5:39 am, Gerry Jackson <ge...@jackson9000.fsnet.co.uk>
wrote:

>
> IMO using the data stack as the control-flow stack and checking stack
> depths before and after a colon definition is a legacy from the days of
> resource-limited computers and has no place in a modern Forth. But then
> I don't use resource-limited processors so I would say that. But then
> again I get the impression that code for such processors tends to be
> non-standard anyway.
> ...

Although I'm a big believer that Forth can do much on the desktop,
including developing large maintainable apps (with the right
infrastructure -- we're not there yet IMO despite the one or two cases
that are mentioned from time to time), I prefer to give as much
latitude as possible to supporting Forth on small systems. That is one
area in which Forth is still commercially viable.

Krishna


Gerry Jackson

unread,
Nov 28, 2011, 1:05:01 PM11/28/11
to
On 28/11/2011 12:52, Alex McDonald wrote:
> On Nov 28, 11:39 am, Gerry Jackson<ge...@jackson9000.fsnet.co.uk>
> wrote:

[...]

>> IMO using the data stack as the control-flow stack and checking stack
>> depths before and after a colon definition is a legacy from the days of
>> resource-limited computers and has no place in a modern Forth. But then
>> I don't use resource-limited processors so I would say that. But then
>> again I get the impression that code for such processors tends to be
>> non-standard anyway.
>>

>
> The use of the data stack for control flow is really very simple to
> implement, since it doesn't require another stack.

Which is why, presumably, the data stack was used in early
implementations of Forth. Implementing another stack is hardly difficult
- ease of use, particularly for beginners, ought to be a more important
consideration than a minor inconvenience for implementers.

The requirement to
> have matching stack depths at : and ; is a very minor inconvenience,

But why have even a minor inconvenience when it is easily avoided?

> and when they don't, 99 times out of a 100 it's because I've miscoded.

As pointed out elsethread, in a well designed system a stack mismatch
will be detected anyway without a depth check as there won't be a
colon-sys on the stack for ; to check.

However it's not that important an issue, just an occasional irritation.

--
Gerry

Andrew Haley

unread,
Nov 28, 2011, 1:45:32 PM11/28/11
to
Gerry Jackson <ge...@jackson9000.fsnet.co.uk> wrote:
> On 28/11/2011 12:52, Alex McDonald wrote:
>> On Nov 28, 11:39 am, Gerry Jackson<ge...@jackson9000.fsnet.co.uk>
>> wrote:
>
> [...]
>
>>> IMO using the data stack as the control-flow stack and checking stack
>>> depths before and after a colon definition is a legacy from the days of
>>> resource-limited computers and has no place in a modern Forth. But then
>>> I don't use resource-limited processors so I would say that. But then
>>> again I get the impression that code for such processors tends to be
>>> non-standard anyway.
>>
>> The use of the data stack for control flow is really very simple to
>> implement, since it doesn't require another stack.
>
> Which is why, presumably, the data stack was used in early
> implementations of Forth. Implementing another stack is hardly difficult
> - ease of use, particularly for beginners, ought to be a more important
> consideration than a minor inconvenience for implementers.

How would a separate control-flow stack make things easier for anyone,
let alone a beginner? I really don't see this one.

> The requirement to
>> have matching stack depths at : and ; is a very minor inconvenience,
>
> But why have even a minor inconvenience when it is easily avoided?

Partly, it's a philosophical thing. Forth is the way it is because of
a ruthless approach to simplification. It has things that are needed,
and nothing else, or at least that's the idea. Some might argue that
Standard Forth has somewhat deviated from this ideal. ;-)

In any case, it's not that easy to avoid. Every task that can compile
would need its own control-flow stack, and you'd have to find
somewhere to put it.

>> and when they don't, 99 times out of a 100 it's because I've miscoded.
>
> As pointed out elsethread, in a well designed system a stack mismatch
> will be detected anyway without a depth check as there won't be a
> colon-sys on the stack for ; to check.

Really well-designed systems don't put *anything* on the stack at : ,
IMO.

Andrew.

Gerry Jackson

unread,
Nov 28, 2011, 3:17:23 PM11/28/11
to
On 28/11/2011 18:45, Andrew Haley wrote:
> Gerry Jackson<ge...@jackson9000.fsnet.co.uk> wrote:
>> On 28/11/2011 12:52, Alex McDonald wrote:
>>> On Nov 28, 11:39 am, Gerry Jackson<ge...@jackson9000.fsnet.co.uk>
>>> wrote:
>>
>> [...]
>>
>>>> IMO using the data stack as the control-flow stack and checking stack
>>>> depths before and after a colon definition is a legacy from the days of
>>>> resource-limited computers and has no place in a modern Forth. But then
>>>> I don't use resource-limited processors so I would say that. But then
>>>> again I get the impression that code for such processors tends to be
>>>> non-standard anyway.
>>>
>>> The use of the data stack for control flow is really very simple to
>>> implement, since it doesn't require another stack.
>>
>> Which is why, presumably, the data stack was used in early
>> implementations of Forth. Implementing another stack is hardly difficult
>> - ease of use, particularly for beginners, ought to be a more important
>> consideration than a minor inconvenience for implementers.
>
> How would a separate control-flow stack make things easier for anyone,
> let alone a beginner? I really don't see this one.

If the data stack is used for the control-flow stack, whatever the
compiler puts onto the data stack can get in the user's way e.g. see the
ANS Forth standard section A3.2.2.2 (actually misnumbered - ought to be
A3.2.3.2) where OF and ENDOF are implemented: "Note the maintenance of
the data stack to prevent interference with the possible control-flow
stack usage".

>
>> The requirement to
>>> have matching stack depths at : and ; is a very minor inconvenience,
>>
>> But why have even a minor inconvenience when it is easily avoided?
>
> Partly, it's a philosophical thing. Forth is the way it is because of
> a ruthless approach to simplification. It has things that are needed,
> and nothing else, or at least that's the idea. Some might argue that
> Standard Forth has somewhat deviated from this ideal. ;-)

Put like that it certainly has.

>
> In any case, it's not that easy to avoid. Every task that can compile
> would need its own control-flow stack, and you'd have to find
> somewhere to put it.
>
>>> and when they don't, 99 times out of a 100 it's because I've miscoded.
>>
>> As pointed out elsethread, in a well designed system a stack mismatch
>> will be detected anyway without a depth check as there won't be a
>> colon-sys on the stack for ; to check.
>
> Really well-designed systems don't put *anything* on the stack at : ,
> IMO.

That means most Forth systems that I've seen are not "really
well-designed" ;-)

--
Gerry

BruceMcF

unread,
Nov 28, 2011, 3:29:51 PM11/28/11
to
On Nov 28, 1:45 pm, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> In any case, it's not that easy to avoid.  Every task that can compile
> would need its own control-flow stack, and you'd have to find
> somewhere to put it.

If you can't nest compilation, then it would seem you only need one.

>> As pointed out elsethread, in a well designed system a stack mismatch
>> will be detected anyway without a depth check as there won't be a
>> colon-sys on the stack for ; to check.

> Really well-designed systems don't put *anything* on the stack at : ,
> IMO.

Relentless simplification on a processor without a retrievable stack
index entails using techniques that do not require checking the stack
depth> In particular, consider an FPGA two stack processor where not
having a retrievable stack index may *itself* be a hardware design
simplification.

IMHO, a defined colon-sys token in that hardware context is a
reasonable solution if the implementer wants colon-sys enforcement.

Alex McDonald

unread,
Nov 28, 2011, 5:22:13 PM11/28/11
to
On Nov 28, 8:17 pm, Gerry Jackson <ge...@jackson9000.fsnet.co.uk>
Now you want it both ways! It doesn't get in the user's way; it gets
in the implementers way, which is, as you say, a minor inconvenience.

Gerry Jackson

unread,
Nov 29, 2011, 3:08:22 AM11/29/11
to
Not at all, I was simply quoting a published example that demonstrated
control-flow information obstructing use of the data stack - albeit a
trivial example.

It doesn't get in the user's way; it gets
> in the implementers way, which is, as you say, a minor inconvenience.
>

[...]

--
Gerry

Andrew Haley

unread,
Nov 29, 2011, 5:49:32 AM11/29/11
to
Gerry Jackson <ge...@jackson9000.fsnet.co.uk> wrote:
> On 28/11/2011 18:45, Andrew Haley wrote:
>> Gerry Jackson<ge...@jackson9000.fsnet.co.uk> wrote:
>>> On 28/11/2011 12:52, Alex McDonald wrote:
>>>> On Nov 28, 11:39 am, Gerry Jackson<ge...@jackson9000.fsnet.co.uk>
>>>> wrote:
>>>
>>> [...]
>>>
>>>> The use of the data stack for control flow is really very simple to
>>>> implement, since it doesn't require another stack.
>>>
>>> Which is why, presumably, the data stack was used in early
>>> implementations of Forth. Implementing another stack is hardly difficult
>>> - ease of use, particularly for beginners, ought to be a more important
>>> consideration than a minor inconvenience for implementers.
>>
>> How would a separate control-flow stack make things easier for anyone,
>> let alone a beginner? I really don't see this one.
>
> If the data stack is used for the control-flow stack, whatever the
> compiler puts onto the data stack can get in the user's way e.g. see the
> ANS Forth standard section A3.2.2.2 (actually misnumbered - ought to be
> A3.2.3.2) where OF and ENDOF are implemented: "Note the maintenance of
> the data stack to prevent interference with the possible control-flow
> stack usage".

But if the data stack is the control-flow stack you can make a version
of CASE that's much simpler than this one. The problem is that you
don't know whether it is or not.

>>> As pointed out elsethread, in a well designed system a stack mismatch
>>> will be detected anyway without a depth check as there won't be a
>>> colon-sys on the stack for ; to check.
>>
>> Really well-designed systems don't put *anything* on the stack at : ,
>> IMO.
>
> That means most Forth systems that I've seen are not "really
> well-designed" ;-)

That's almost certainly so.

Andrew.

Andrew Haley

unread,
Nov 29, 2011, 5:53:46 AM11/29/11
to
BruceMcF <agi...@netscape.net> wrote:
> On Nov 28, 1:45?pm, Andrew Haley <andre...@littlepinkcloud.invalid>
> wrote:
>> In any case, it's not that easy to avoid. ?Every task that can compile
>> would need its own control-flow stack, and you'd have to find
>> somewhere to put it.
>
> If you can't nest compilation, then it would seem you only need one.

Every *task* that can compile needs it own control-flow stack.
They're asynchronous.

>> Really well-designed systems don't put *anything* on the stack at : ,
>> IMO.
>
> Relentless simplification on a processor without a retrievable stack
> index entails using techniques that do not require checking the stack
> depth. In particular, consider an FPGA two stack processor where not
> having a retrievable stack index may *itself* be a hardware design
> simplification.
>
> IMHO, a defined colon-sys token in that hardware context is a
> reasonable solution if the implementer wants colon-sys enforcement.

But a well-designed system would not have "colon-sys enforcement",
IMHO. It's pointless.

Andrew.

Anton Ertl

unread,
Nov 29, 2011, 6:04:42 AM11/29/11
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>BruceMcF <agi...@netscape.net> wrote:
>> IMHO, a defined colon-sys token in that hardware context is a
>> reasonable solution if the implementer wants colon-sys enforcement.
>
>But a well-designed system would not have "colon-sys enforcement",
>IMHO. It's pointless.

The point of "colon-sys enforcement" is detecting and reporting
incomplete control flow, like

: foo if ;
1 foo

Andrew Haley

unread,
Nov 29, 2011, 6:42:17 AM11/29/11
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>BruceMcF <agi...@netscape.net> wrote:
>>> IMHO, a defined colon-sys token in that hardware context is a
>>> reasonable solution if the implementer wants colon-sys enforcement.
>>
>>But a well-designed system would not have "colon-sys enforcement",
>>IMHO. It's pointless.
>
> The point of "colon-sys enforcement" is detecting and reporting
> incomplete control flow, like
>
> : foo if ;
> 1 foo

Yes, I know that's the idea, but it's a bad one. IMHO.

Andrew.

Anton Ertl

unread,
Nov 29, 2011, 10:46:29 AM11/29/11
to
Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>> The point of "colon-sys enforcement" is detecting and reporting
>> incomplete control flow, like
>>
>> : foo if ;
>> 1 foo
>
>Yes, I know that's the idea, but it's a bad one. IMHO.

Detecting and reporting incomplete control flow is a bad idea? Or
"colon-sys enforcement" as its implementation? It's certainly a
simple implementation of the idea, which is a property you value.

Gerry Jackson

unread,
Nov 29, 2011, 10:50:56 AM11/29/11
to
As you seem to like "a ruthless approach to simplification" presumably
you wouldn't have any check and just let things fail?

--
Gerry

Andrew Haley

unread,
Nov 29, 2011, 10:59:58 AM11/29/11
to
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
>>Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>>> The point of "colon-sys enforcement" is detecting and reporting
>>> incomplete control flow, like
>>>
>>> : foo if ;
>>> 1 foo
>>
>>Yes, I know that's the idea, but it's a bad one. IMHO.
>
> Detecting and reporting incomplete control flow is a bad idea?

Yes. It might be useful in a Standard-compatibility checker, I
suppose.

> Or "colon-sys enforcement" as its implementation?

Yes.

> It's certainly a simple implementation of the idea, which is a
> property you value.

That's a property that everyone here values, I hope.

Andrew.

Gerry Jackson

unread,
Nov 29, 2011, 11:00:39 AM11/29/11
to
On 29/11/2011 10:49, Andrew Haley wrote:
> Gerry Jackson<ge...@jackson9000.fsnet.co.uk> wrote:
>> On 28/11/2011 18:45, Andrew Haley wrote:
>>> Gerry Jackson<ge...@jackson9000.fsnet.co.uk> wrote:
>>>> On 28/11/2011 12:52, Alex McDonald wrote:
>>>>> On Nov 28, 11:39 am, Gerry Jackson<ge...@jackson9000.fsnet.co.uk>
>>>>> wrote:
>>>>
>>>> [...]
>>>>
>>>>> The use of the data stack for control flow is really very simple to
>>>>> implement, since it doesn't require another stack.
>>>>
>>>> Which is why, presumably, the data stack was used in early
>>>> implementations of Forth. Implementing another stack is hardly difficult
>>>> - ease of use, particularly for beginners, ought to be a more important
>>>> consideration than a minor inconvenience for implementers.
>>>
>>> How would a separate control-flow stack make things easier for anyone,
>>> let alone a beginner? I really don't see this one.
>>
>> If the data stack is used for the control-flow stack, whatever the
>> compiler puts onto the data stack can get in the user's way e.g. see the
>> ANS Forth standard section A3.2.2.2 (actually misnumbered - ought to be
>> A3.2.3.2) where OF and ENDOF are implemented: "Note the maintenance of
>> the data stack to prevent interference with the possible control-flow
>> stack usage".
>
> But if the data stack is the control-flow stack you can make a version
> of CASE that's much simpler than this one.

Not always - GForth sticks 3 cells onto the data stack for each
control-flow item.

--
Gerry

Andrew Haley

unread,
Nov 29, 2011, 11:01:55 AM11/29/11
to
Yes. Or succeed: the "unbalanced control" might be deliberate. I
wouldn't check the input to every @ either.

Andrew.

Elizabeth D. Rather

unread,
Nov 29, 2011, 1:55:32 PM11/29/11
to
On 11/29/11 5:46 AM, Anton Ertl wrote:
> Andrew Haley<andr...@littlepinkcloud.invalid> writes:
>> Anton Ertl<an...@mips.complang.tuwien.ac.at> wrote:
>>> The point of "colon-sys enforcement" is detecting and reporting
>>> incomplete control flow, like
>>>
>>> : foo if ;
>>> 1 foo
>>
>> Yes, I know that's the idea, but it's a bad one. IMHO.
>
> Detecting and reporting incomplete control flow is a bad idea? Or
> "colon-sys enforcement" as its implementation? It's certainly a
> simple implementation of the idea, which is a property you value.
>
> - anton

An even simpler "implementation" is the practice of checking the stack
after compiling new code, which is second-nature to many experienced
Forth programmers.

Cheers,
Elizabeth

--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com

"Forth-based products and Services for real-time
applications since 1973."
==================================================

Tarkin

unread,
Nov 29, 2011, 4:07:32 PM11/29/11
to
On Nov 29, 10:50 am, Gerry Jackson <ge...@jackson9000.fsnet.co.uk>
wrote:
> On 29/11/2011 11:42, Andrew Haley wrote:
>
>
>
> > Anton Ertl<an...@mips.complang.tuwien.ac.at>  wrote:
> >> Andrew Haley<andre...@littlepinkcloud.invalid>  writes:
> >>> BruceMcF<agil...@netscape.net>  wrote:
> >>>> IMHO, a defined colon-sys token in that hardware context is a
> >>>> reasonable solution if the implementer wants colon-sys enforcement.
>
> >>> But a well-designed system would not have "colon-sys enforcement",
> >>> IMHO.  It's pointless.
>
> >> The point of "colon-sys enforcement" is detecting and reporting
> >> incomplete control flow, like
>
> >> : foo if ;
> >> 1 foo
>
> > Yes, I know that's the idea, but it's a bad one.  IMHO.
>
> As you seem to like "a ruthless approach to simplification" presumably
> you wouldn't have any check and just let things fail?
>
> --
> Gerry

IMHO, as a fan of "ruthless approaches to simplification":
fail hard and fail fast.
It's that way with assembler and C pointers, so why not Forth?


TTFN,
Tarkin

BruceMcF

unread,
Nov 29, 2011, 8:04:53 PM11/29/11
to
On Nov 29, 5:53 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> Every *task* that can compile needs it own control-flow stack.
> They're asynchronous.

Then how does it work with a single common data stack when you have
multiple asynchronous tasks compiling into the same dictionary via the
same "," and "COMPILE," and such? I don't see how use of a single data
stack is OK but use of a single task-specific external stack is not.

Elizabeth D. Rather

unread,
Nov 29, 2011, 8:52:07 PM11/29/11
to
In a multitasked Forth, every task has its own data stack and return
stack. What Andrew is saying is that if there's a separate control-flow
stack, each task would need one of those, *too*. So the complexity spreads.

BruceMcF

unread,
Nov 30, 2011, 12:29:22 AM11/30/11
to
On Nov 29, 8:52 pm, "Elizabeth D. Rather" <erat...@forth.com> wrote:

> In a multitasked Forth, every task has its own data stack and return
> stack.

Certainly not in *every* multi-tasked Forth, but in some, true.

> What Andrew is saying is that if there's a separate control-flow
> stack, each task would need one of those, *too*.
> So the complexity spreads.

I still have difficulty seeing how asynchronous multi-tasking tasks
each compile without walking all over what each is doing to the common
dictionary. If only one task can be be compiling a definition at any
one time, then one task can own the control flow stack until the
compilation of the definition is complete, and there would never be
need for more than one control flow stack.

Elizabeth D. Rather

unread,
Nov 30, 2011, 12:52:25 AM11/30/11
to
It is done by having a shared dictionary, plus a private one for each
task, linked at the bottom to the shared dictionary. It is possible to
permanently attach a private dictionary to the global one in some
circumstances. But you're quite right, it's not feasible for everyone
to be adding to the shared dictionary dynamically.

Rod Pemberton

unread,
Nov 30, 2011, 5:58:23 AM11/30/11
to
"Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
news:2011Nov2...@mips.complang.tuwien.ac.at...
> Andrew Haley <andr...@littlepinkcloud.invalid> writes:
> >Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> >> The point of "colon-sys enforcement" is detecting and reporting
> >> incomplete control flow, like
> >>
> >> : foo if ;
> >> 1 foo
> >
> >Yes, I know that's the idea, but it's a bad one. IMHO.
>
> Detecting and reporting incomplete control flow is a bad idea?

For C? Absolutely, no. For Forth? Apparently, yes.

Certain solutions in Forth seem to need "wrappers", i.e., one word placed
before and one word placed after some other word. In which case, someone
may need to split control flow so that part of it is in one word and the
remainder in another. Unless there is a standard method of eliminating
"wrappers" in Forth, which I've not seen and have asked about a few times
now, then "yes" is the answer.


Rod Pemberton



Alex McDonald

unread,
Nov 30, 2011, 6:07:23 AM11/30/11
to
On Nov 30, 10:58 am, "Rod Pemberton" <do_not_h...@noavailemail.cmm>
wrote:
> "Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
>
> news:2011Nov2...@mips.complang.tuwien.ac.at...
>
> > Andrew Haley <andre...@littlepinkcloud.invalid> writes:
> > >Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> > >> The point of "colon-sys enforcement" is detecting and reporting
> > >> incomplete control flow, like
>
> > >> : foo if ;
> > >> 1 foo
>
> > >Yes, I know that's the idea, but it's a bad one.  IMHO.
>
> > Detecting and reporting incomplete control flow is a bad idea?
>
> For C?  Absolutely, no.  For Forth?  Apparently, yes.
>
> Certain solutions in Forth seem to need "wrappers", i.e., one word placed
> before and one word placed after some other word.  In which case, someone
> may need to split control flow so that part of it is in one word and the
> remainder in another.  Unless there is a standard method of eliminating
> "wrappers" in Forth, which I've not seen and have asked about a few times
> now, then "yes" is the answer.
>
> Rod Pemberton

Can you give an example? I can't quite see what words or algorithms
require wrapping.

BruceMcF

unread,
Nov 30, 2011, 10:49:46 AM11/30/11
to
On Nov 30, 12:52 am, "Elizabeth D. Rather" <erat...@forth.com> wrote:
> It is done by having a shared dictionary, plus a private one for each
> task, linked at the bottom to the shared dictionary.

Then there you have the space for the control-structure stack.

I still feel that whether one resorts to a separate control structure
stack ought to be a pragmatic question of what works best for the
control structures being supported and the hardware supporting the
data stack, rather than being some grand philosophical question of
what is the "right way" to program in Forth.

BruceMcF

unread,
Nov 30, 2011, 10:54:35 AM11/30/11
to
On Nov 30, 5:58 am, "Rod Pemberton" <do_not_h...@noavailemail.cmm>
wrote:
> "Anton Ertl" <an...@mips.complang.tuwien.ac.at> wrote in message
>
> news:2011Nov2...@mips.complang.tuwien.ac.at...
>
> > Andrew Haley <andre...@littlepinkcloud.invalid> writes:
> > >Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> > >> The point of "colon-sys enforcement" is detecting and reporting
> > >> incomplete control flow, like
>
> > >> : foo if ;
> > >> 1 foo
>
> > >Yes, I know that's the idea, but it's a bad one.  IMHO.
>
> > Detecting and reporting incomplete control flow is a bad idea?
>
> For C?  Absolutely, no.  For Forth?  Apparently, yes.
>
> Certain solutions in Forth seem to need "wrappers", i.e., one
> word placed before and one word placed after some other word.

> In which case, someone may need to split control flow so that part
> of it is in one word and the remainder in another.

> Unless there is a standard method of eliminating "wrappers" in Forth,
> which I've not seen and have asked about a few times now, then "yes"
> is the answer.

This seems to be confusing the compile time of the wrapper word with
the compile time of the word within which the wrappers are used. When
the wrapper words are being defined, they will not be *executing* the
partial control flow, they will be compiling that partial control flow
so that when they *execute*, the control flow behavior will execute.

But those wrappers will be *executing* the control flow inside the
same word, so one of the things that catching incomplete control flow
structures will catch is incorrect use of those wrapper words that
include control flow behavior.

Andrew Haley

unread,
Nov 30, 2011, 11:19:38 AM11/30/11
to
BruceMcF <agi...@netscape.net> wrote:
> On Nov 30, 12:52?am, "Elizabeth D. Rather" <erat...@forth.com> wrote:
>> It is done by having a shared dictionary, plus a private one for each
>> task, linked at the bottom to the shared dictionary.
>
> Then there you have the space for the control-structure stack.

As it stands, there's just the user area, the dictionary, and a couple
of stacks. Everything else (PAD, the word buffer, etc.) is at offsets
from the dictionary pointer. There's nowhere obvious to put an extra
stack of unknown size.

> I still feel that whether one resorts to a separate control structure
> stack ought to be a pragmatic question of what works best for the
> control structures being supported and the hardware supporting the
> data stack, rather than being some grand philosophical question of
> what is the "right way" to program in Forth.

So do we all. The core *pragmatic* rule is "If it's not needed, don't
include it." This is the opposite of some grand philosophical
question: it's the rule of thumb that prevents everything but the
kitchen sink from being piled into Forth.

Andrew.

Andrew Haley

unread,
Nov 30, 2011, 11:45:01 AM11/30/11
to
0 constant case immediate

: of postpone over postpone = postpone if postpone drop ; immediate

: endof postpone else ; immediate

: endcase
postpone drop
begin ?dup while postpone then repeat ; immediate

This is not portable: it will, of course, fail if the top item pushed
on the control stack by IF or ELSE is zero, in which case you'll need
a different sentinel.

Andrew.

BruceMcF

unread,
Nov 30, 2011, 3:19:00 PM11/30/11
to
On Nov 30, 11:19 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> So do we all.  The core *pragmatic* rule is "If it's not
> needed, don't include it."  This is the opposite of some
> grand philosophical question: it's the rule of thumb that
> prevents everything but the kitchen sink from being piled
> into Forth.

If the claim was that the control flow stack should *normally* be on
the data stack, unless there was some specific reason for doing
otherwise, that would be one thing. But a claim that the control flow
stack should *never* be placed in a separate stack, no matter what the
circumstances, that's not a pragmatic rule, its a dogma.

Andrew Haley

unread,
Nov 30, 2011, 3:31:02 PM11/30/11
to
BruceMcF <agi...@netscape.net> wrote:
> On Nov 30, 11:19?am, Andrew Haley <andre...@littlepinkcloud.invalid>
> wrote:
>> So do we all. ?The core *pragmatic* rule is "If it's not
>> needed, don't include it." ?This is the opposite of some
>> grand philosophical question: it's the rule of thumb that
>> prevents everything but the kitchen sink from being piled
>> into Forth.
>
> If the claim was that the control flow stack should *normally* be on
> the data stack, unless there was some specific reason for doing
> otherwise, that would be one thing. But a claim that the control
> flow stack should *never* be placed in a separate stack, no matter
> what the circumstances, that's not a pragmatic rule, its a dogma.

And which claim was that?

Andrew.

Gerry Jackson

unread,
Dec 1, 2011, 3:58:21 AM12/1/11
to
OK you win. I'd rather have something that was guaranteed to work on all
ANS Forth systems.

--
Gerry

BruceMcF

unread,
Dec 1, 2011, 12:46:32 PM12/1/11
to
On Nov 29, 5:49 am, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> But if the data stack is the control-flow stack you can make a version
> of CASE that's much simpler than this one.  The problem is that you
> don't know whether it is or not.

Which implementation doesn't document whether the control-flow stack
is on the data stack or not?

Andrew Haley

unread,
Dec 1, 2011, 1:00:28 PM12/1/11
to
BruceMcF <agi...@netscape.net> wrote:
> On Nov 29, 5:49?am, Andrew Haley <andre...@littlepinkcloud.invalid>
I have no idea, but that's really not the point: a standard program
can't assume that it is.

Andrew.

BruceMcF

unread,
Dec 1, 2011, 1:36:51 PM12/1/11
to
On Nov 30, 3:31 pm, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:

> > If the claim was that the control flow stack should *normally* be on
> > the data stack, unless there was some specific reason for doing
> > otherwise, that would be one thing. But a claim that the control
> > flow stack should *never* be placed in a separate stack, no matter
> > what the circumstances, that's not a pragmatic rule, its a dogma.

> And which claim was that?

QUOTE: [ >> is Alex McDonald, > is Gerry Jackson ]

How would a separate control-flow stack make things easier for anyone,
let alone a beginner? I really don't see this one.

>> The requirement to
>> have matching stack depths at : and ; is a very minor inconvenience,

> But why have even a minor inconvenience when it is easily avoided?

Partly, it's a philosophical thing. Forth is the way it is because of
a ruthless approach to simplification. It has things that are needed,
and nothing else, or at least that's the idea. Some might argue that
Standard Forth has somewhat deviated from this ideal. ;-)

In any case, it's not that easy to avoid. Every task that can compile
would need its own control-flow stack, and you'd have to find
somewhere to put it.

UNQUOTE

Why we *have to have* have matching stack depths, here, is "a
philosophical thing". That implies that a "ruthless approach to
simplification" will *always* lead to a control-flow stack on the data
stack and data stack depth required to be equal at the beginning and
ending of a colon definition.

That it will *often* lead to that design may well be why we have to
allow for the requirement, as Forth94 does, but the fact that it will
not *always* lead to that design is why we also have to allow for the
possibility that the control flow stack is elsewhere.

Indeed, on hardware where the data stack index is not retrievable,
checking the control-flow stack depth and having the control-flow
stack on the data stack is an either-or design choice.

As far as ruthless simplification and the portability goals of
Forth94, they are in intrinsic goal conflict ~ ruthless simplification
will lead to different specific implementation design decisions for
different specific contexts, and that will increase the complexity of
the task of devising ways to support portable source code for a range
of such implementations.

Andrew Haley

unread,
Dec 1, 2011, 2:08:30 PM12/1/11
to
BruceMcF <agi...@netscape.net> wrote:
> On Nov 30, 3:31?pm, Andrew Haley <andre...@littlepinkcloud.invalid>
> wrote:
>
>> > If the claim was that the control flow stack should *normally* be on
>> > the data stack, unless there was some specific reason for doing
>> > otherwise, that would be one thing. But a claim that the control
>> > flow stack should *never* be placed in a separate stack, no matter
>> > what the circumstances, that's not a pragmatic rule, its a dogma.
>
>> And which claim was that?
>
> QUOTE: [ >> is Alex McDonald, > is Gerry Jackson ]
>
> How would a separate control-flow stack make things easier for anyone,
> let alone a beginner? I really don't see this one.
>
>>> The requirement to have matching stack depths at : and ; is a very
>>> minor inconvenience,
>
>> But why have even a minor inconvenience when it is easily avoided?
>
> Partly, it's a philosophical thing. Forth is the way it is because
> of a ruthless approach to simplification. It has things that are
> needed, and nothing else, or at least that's the idea. Some might
> argue that Standard Forth has somewhat deviated from this ideal.
> ;-)
>
> In any case, it's not that easy to avoid. Every task that can compile
> would need its own control-flow stack, and you'd have to find
> somewhere to put it.
>
> UNQUOTE
>
> Why we *have to have* have matching stack depths, here, is "a
> philosophical thing".

I think I also said "partly". But my reply was not specific: it's a
response to the rather abstract question "But why have even a minor
inconvenience when it is easily avoided?" rather than to "Why do we
have to have matching control-flow stack depths?" Clearly, we don't
need to have matching control-flow stack depths, as discussed.

> That implies that a "ruthless approach to simplification" will
> *always* lead to a control-flow stack on the data stack and data
> stack depth required to be equal at the beginning and ending of a
> colon definition.

It doesn't imply any such thing.

> That it will *often* lead to that design may well be why we have to
> allow for the requirement, as Forth94 does, but the fact that it
> will not *always* lead to that design is why we also have to allow
> for the possibility that the control flow stack is elsewhere.

Perhaps.

> Indeed, on hardware where the data stack index is not retrievable,
> checking the control-flow stack depth and having the control-flow
> stack on the data stack is an either-or design choice.

Indeed. But there is no requirement to check control-flow stack depth
anyware in Standard Forth, as far as I know.

> As far as ruthless simplification and the portability goals of
> Forth94, they are in intrinsic goal conflict ~ ruthless
> simplification will lead to different specific implementation design
> decisions for different specific contexts, and that will increase
> the complexity of the task of devising ways to support portable
> source code for a range of such implementations.

That doesn't follow. If the goal is portability, then you can't
simplify beyond the point at which code can be portable or you won't
meet the goal.

Andrew.

BruceMcF

unread,
Dec 2, 2011, 1:04:54 AM12/2/11
to
On Dec 1, 2:08 pm, Andrew Haley <andre...@littlepinkcloud.invalid>
wrote:
> I think I also said "partly".
Yes, partly the philosophical issue, and partly the issue of where to
put the control-flow stack in the specific case of some implementation
that has multiple tasks that can compile asynchronously.

> But my reply was not specific: it's a
> response to the rather abstract question "But why have even a minor
> inconvenience when it is easily avoided?" rather than to "Why do we
> have to have matching control-flow stack depths?"

Given the quoting, I read it as a specific reply to the question in
the context of "why do we have to have matching control-flow stack
depths". It makes more sense as a general reply to the question.
0 new messages