• GOTO and LABEL / CONTINUE and BREAK

    From minforth@arcor.de@21:1/5 to All on Fri Mar 10 09:34:56 2023
    Now and then I happen to write code where a simple GOTO would be
    just too convenient. The same situation happens now and then with
    loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    Guessing that I am not alone in this, how do you manage? Any magic tricks
    up the sleeve to (ab)use standard Forth's control flow words? I don't
    expect that someone parses Forth definitions twice just to resolve
    backward jumps to preceding labels, or do we..?

    PS I don't want to revive that old structured programming yawner:
    "don't GOTO, it is evil"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ruvim@21:1/5 to minf...@arcor.de on Sat Mar 11 00:37:54 2023
    On 2023-03-10 17:34, minf...@arcor.de wrote:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient. The same situation happens now and then with
    loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    Guessing that I am not alone in this, how do you manage? Any magic tricks
    up the sleeve to (ab)use standard Forth's control flow words? I don't
    expect that someone parses Forth definitions twice just to resolve
    backward jumps to preceding labels, or do we..?

    PS I don't want to revive that old structured programming yawner:
    "don't GOTO, it is evil"


    It can look as:

    : foo
    [label a ]
    ...
    if goto( b ) then
    ...
    if goto( a ) then
    ...
    [label b ]
    ;



    This problem can be solved easier if:
    1. we are limited by the cases when the Forth system uses the data stack
    as the control-flow stack (so, it's an environmental dependency),
    2. we don't cross DO ... LOOP and the definition boundaries.

    Thus, a backward goto can be implemented using begin...again,
    and a forward goto can be implemented using ahead...then.

    We need to properly save names of goto/label and orig/dest into a list,
    and properly resolve them. Also we need to nest this list on a new
    definition (or use special wrapper like with-goto{ ... }with-goto to
    nest this list).



    If we don't rely on the data stack, we have to redefine all control-flow
    words to know the controls depth in every point. After that we can use
    CS-ROLL to deepen orig/dest and CS-PICK to get it for resolving.



    --
    Ruvim

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@arcor.de@21:1/5 to Ruvim on Fri Mar 10 23:25:53 2023
    Ruvim schrieb am Samstag, 11. März 2023 um 01:37:58 UTC+1:
    On 2023-03-10 17:34, minf...@arcor.de wrote:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient. The same situation happens now and then with
    loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    Guessing that I am not alone in this, how do you manage? Any magic tricks up the sleeve to (ab)use standard Forth's control flow words? I don't expect that someone parses Forth definitions twice just to resolve backward jumps to preceding labels, or do we..?

    PS I don't want to revive that old structured programming yawner:
    "don't GOTO, it is evil"
    It can look as:

    : foo
    [label a ]
    ...
    if goto( b ) then
    ...
    if goto( a ) then
    ...
    [label b ]
    ;

    This problem can be solved easier if:
    1. we are limited by the cases when the Forth system uses the data stack
    as the control-flow stack (so, it's an environmental dependency),
    2. we don't cross DO ... LOOP and the definition boundaries.

    Thus, a backward goto can be implemented using begin...again,
    and a forward goto can be implemented using ahead...then.

    We need to properly save names of goto/label and orig/dest into a list,
    and properly resolve them. Also we need to nest this list on a new definition (or use special wrapper like with-goto{ ... }with-goto to
    nest this list).

    If we don't rely on the data stack, we have to redefine all control-flow words to know the controls depth in every point. After that we can use CS-ROLL to deepen orig/dest and CS-PICK to get it for resolving.

    Thanks for your ideas. I had been thinking that
    - to jump out of a DO..LOOP one could put an UNLOOP before goto(
    - labels targeted by more than one gotos would need some control flow
    stack cleaning like LEAVE, but
    - it would be difficult to not mess with other items on the cfs because
    usually Forth does not mark those items in order to being able to allow
    "extended" structures like BEGIN..WHILE..WHILE..REPEAT..THEN

    With backward jumps like in
    .. LABEL A ..
    .. LABEL B ..
    IF .. GOTO A ..
    ELSE .. GOTO B ..
    THEN ..
    labels are "passive" i.e. they only put their address on the cfs, and
    gotos are "active" i.e. they have to resolve the back jumps.

    Whereas with forward jumps like in
    .. IF .. GOTO A ..
    ELSE .. GOTO B ..
    THEN
    .. LABEL A ..
    .. LABEL B ..
    gotos are "passive" i.e. they only put their address on the cfs, and
    labels are "active" i.e. they have to resolve the forward jumps.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to minf...@arcor.de on Sat Mar 11 08:09:53 2023
    "minf...@arcor.de" <minforth@arcor.de> writes:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient.

    When I implemented IIRC the unification of the Prolog implementation
    Aristo (in 1990), I at first used a very local view of the cases (and
    the respective control flow), so I used gotos, and I thought that this
    was necessary. My superior was not happy, and tasked me to eliminate
    the gotos, so I drew a control-flow graph and found how to rearrange
    the code to use whiles and ifs instead. And the result was nice, and
    reflected the structure of the data.

    Since then, I have not found any need for a direct goto, maybe with
    the very rare exception of leaving a nested search loop (and there a
    lack of GOTO in Forth is usually worked around by using EXIT).

    That leaves us with indirect branches, which are of course heavily
    used for threaded code, and I also used it once for implementing a
    finite state machine for a lexical scanner; but I think you don't mean
    indirect gotos, right.

    The same situation happens now and then with
    loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    Guessing that I am not alone in this, how do you manage?

    Development Gforth has

    case
    ... ?of ... endof \ jumps behin ENDCASE/NEXT-CASE
    ... ?of ... contof \ jumps to the CASE
    ...
    next-case \ loops back, or alternatively endcase if it should not loop

    I find this quite convenient, and it makes it easy to express the
    control flow. Of course, you can express the same stuff with standard
    Forth words, and you can actually turn it into standard Forth
    mechanically (and usually it works without [ ... cs-roll ]), but the
    use of CASE usually makes the code easier to understand (if you are
    familiar with this extension of CASE).

    - 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: https://forth-standard.org/
    EuroForth 2022: https://euro.theforth.net

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@arcor.de@21:1/5 to Anton Ertl on Sat Mar 11 02:19:51 2023
    Anton Ertl schrieb am Samstag, 11. März 2023 um 10:20:45 UTC+1:
    "minf...@arcor.de" <minf...@arcor.de> writes:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient.
    When I implemented IIRC the unification of the Prolog implementation
    Aristo (in 1990), I at first used a very local view of the cases (and
    the respective control flow), so I used gotos, and I thought that this
    was necessary. My superior was not happy, and tasked me to eliminate
    the gotos, so I drew a control-flow graph and found how to rearrange
    the code to use whiles and ifs instead. And the result was nice, and reflected the structure of the data.

    Since then, I have not found any need for a direct goto, maybe with
    the very rare exception of leaving a nested search loop (and there a
    lack of GOTO in Forth is usually worked around by using EXIT).

    That leaves us with indirect branches, which are of course heavily
    used for threaded code, and I also used it once for implementing a
    finite state machine for a lexical scanner; but I think you don't mean indirect gotos, right.

    Guessing that you mean indirect gotos to be like gcc's computed goto
    in Forth, one could perhaps implement it within one's own system
    with all "carnal knowledge" involved.

    But it wouldn't be portable since standard Forth does not give you any
    means to access the instruction pointer.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ruvim@21:1/5 to minf...@arcor.de on Mon Mar 13 01:25:56 2023
    On 2023-03-11 07:25, minf...@arcor.de wrote:
    Ruvim schrieb am Samstag, 11. März 2023 um 01:37:58 UTC+1:
    On 2023-03-10 17:34, minf...@arcor.de wrote:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient. The same situation happens now and then with
    loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    Guessing that I am not alone in this, how do you manage? Any magic tricks >>> up the sleeve to (ab)use standard Forth's control flow words? I don't
    expect that someone parses Forth definitions twice just to resolve
    backward jumps to preceding labels, or do we..?

    PS I don't want to revive that old structured programming yawner:
    "don't GOTO, it is evil"
    It can look as:

    : foo
    [label a ]
    ...
    if goto( b ) then
    ...
    if goto( a ) then
    ...
    [label b ]
    ;

    This problem can be solved easier if:
    1. we are limited by the cases when the Forth system uses the data stack
    as the control-flow stack (so, it's an environmental dependency),
    2. we don't cross DO ... LOOP and the definition boundaries.

    Thus, a backward goto can be implemented using begin...again,
    and a forward goto can be implemented using ahead...then.

    We need to properly save names of goto/label and orig/dest into a list,
    and properly resolve them. Also we need to nest this list on a new
    definition (or use special wrapper like with-goto{ ... }with-goto to
    nest this list).

    If we don't rely on the data stack, we have to redefine all control-flow
    words to know the controls depth in every point. After that we can use
    CS-ROLL to deepen orig/dest and CS-PICK to get it for resolving.

    Thanks for your ideas. I had been thinking that
    - to jump out of a DO..LOOP one could put an UNLOOP before goto(

    Yes. Then, we have to redefine DO...LOOP to know the number of "UNLOOP" commands to produce. And we should not allow to goto inside DO...LOOP
    from outside (an error should be raised).


    - labels targeted by more than one gotos would need some control flow
    stack cleaning like LEAVE, but
    - it would be difficult to not mess with other items on the cfs because
    usually Forth does not mark those items in order to being able to allow
    "extended" structures like BEGIN..WHILE..WHILE..REPEAT..THEN

    In a limited implementation the orig and dest for label/goto are taken
    from the data stack and stored into own data structure — so they are not mixed with other items on the control-flow stack.


    With backward jumps like in
    .. LABEL A ..
    .. LABEL B ..
    IF .. GOTO A ..
    ELSE .. GOTO B ..
    THEN ..
    labels are "passive" i.e. they only put their address on the cfs, and
    gotos are "active" i.e. they have to resolve the back jumps.

    Whereas with forward jumps like in
    .. IF .. GOTO A ..
    ELSE .. GOTO B ..
    THEN
    .. LABEL A ..
    .. LABEL B ..
    gotos are "passive" i.e. they only put their address on the cfs, and
    labels are "active" i.e. they have to resolve the forward jumps.

    Yes. And all the forward jumps shall be resolved, otherwise it's an error.

    It isn't difficult to implement as per se, but some advanced data
    structures are required, which the standard Forth does not provide.
    And implementing such data structures is more difficult than "goto" itself.

    I have played with Lisp flavored cons pairs and lists, and implemented a
    list of names (actually key-value) over a cons-based list in a simple
    manner (without much care about run-time efficiency).
    Than I use this namelist in implementation of "goto" to store labels and orig/dest marks [1]

    Despite of extensive use of dynamic memory, memory management turned out
    to be simple and almost invisible in the source code.


    [1] PoF: Example of implementation GOTO in the standard Forth https://github.com/ruv/puzzle-in-forth https://github.com/ruv/puzzle-in-forth/blob/main/extension/goto.fth
    (the main file for 'goto')

    --
    Ruvim

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Heinrich Hohl@21:1/5 to minf...@arcor.de on Mon Mar 13 02:48:28 2023
    On Friday, March 10, 2023 at 6:34:57 PM UTC+1, minf...@arcor.de wrote:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient. The same situation happens now and then with
    loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    You can find definitions for LABEL and GOTO on Wil Baden's homepage:

    http://www.wilbaden.com/neil_bawd

    http://www.wilbaden.com/neil_bawd/goto.txt

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Hans Bezemer@21:1/5 to minf...@arcor.de on Mon Mar 13 03:30:55 2023
    On Saturday, March 11, 2023 at 8:25:54 AM UTC+1, minf...@arcor.de wrote:
    gotos are "passive" i.e. they only put their address on the cfs, and
    labels are "active" i.e. they have to resolve the forward jumps.

    Yes - there is a distinction between jumping to an already defined label and one that has to be resolved later. Not only that - there may be multiple GOTOs to be resolved.

    I use a dedicated control stack that also holds the references - aka a "label" that signifies the kind of control structure. It helps to trap certain errors and
    trap them early IMHO.

    Now - GOTO is a horrible match with that structure. E.g. if you jump out of a BEGIN..REPEAT it will find an unresolved GOTO reference in the midst of
    WHILE and BEGIN references - probably even embedded in an IF.

    That IF reference is also a problem with BREAK and CONTINUE. Again, I can't resolve the IF reference when there is still a BREAK (or CONTINUE) reference. In case of BREAK I can't even resolve that, because I have no idea where REPEAT or UNTIL is going to be. Of course, you can break the LIFO consistency of the control stack - but that's called "dirty" in my book.

    WHILE is not much of a problem, since all other constructs are resolved before the next WHILE comes in (in 4tH anyway). And: WHILE is a "branch if zero" instruction - i.e. it has its conditional component built in, whereas BREAK and CONTINUE are unconditional branches, always depending on an "IF".

    I don't see the use of BREAK - it's perfectly serviced by WHILE. CONTINUE - may be,
    but often an IF solves that problem. I got some C code lying around for some time,
    but I never felt the need to apply it to the current branch.

    The same for GOTO. It's neat, but more trouble than it's worth IMHO. If I really want
    to jump back somewhere I just throw an exception. Works fine.

    I find Antons CONTOF intriguing, though. Gotta contemplate that one a bit.

    Hans Bezemer

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@arcor.de@21:1/5 to Hans Bezemer on Mon Mar 13 04:45:02 2023
    Hans Bezemer schrieb am Montag, 13. März 2023 um 11:30:57 UTC+1:
    On Saturday, March 11, 2023 at 8:25:54 AM UTC+1, minf...@arcor.de wrote:
    gotos are "passive" i.e. they only put their address on the cfs, and labels are "active" i.e. they have to resolve the forward jumps.
    Yes - there is a distinction between jumping to an already defined label and one that has to be resolved later. Not only that - there may be multiple GOTOs
    to be resolved.

    I use a dedicated control stack that also holds the references - aka a "label"
    that signifies the kind of control structure. It helps to trap certain errors and
    trap them early IMHO.

    Now - GOTO is a horrible match with that structure. E.g. if you jump out of a
    BEGIN..REPEAT it will find an unresolved GOTO reference in the midst of WHILE and BEGIN references - probably even embedded in an IF.

    That IF reference is also a problem with BREAK and CONTINUE. Again, I can't resolve the IF reference when there is still a BREAK (or CONTINUE) reference.
    In case of BREAK I can't even resolve that, because I have no idea where REPEAT
    or UNTIL is going to be. Of course, you can break the LIFO consistency of the
    control stack - but that's called "dirty" in my book.

    WHILE is not much of a problem, since all other constructs are resolved before
    the next WHILE comes in (in 4tH anyway). And: WHILE is a "branch if zero" instruction - i.e. it has its conditional component built in, whereas BREAK and
    CONTINUE are unconditional branches, always depending on an "IF".

    I don't see the use of BREAK - it's perfectly serviced by WHILE. CONTINUE - may be,
    but often an IF solves that problem. I got some C code lying around for some time,
    but I never felt the need to apply it to the current branch.

    The same for GOTO. It's neat, but more trouble than it's worth IMHO. If I really want
    to jump back somewhere I just throw an exception. Works fine.

    I find Antons CONTOF intriguing, though. Gotta contemplate that one a bit.


    Good summary of the problems to expect when overloading the standard control structures
    like Wil Baden did. Particularly DO..LOOPs can become nasty then. BEGIN.. loops can be
    handled.

    I believe it would be more straightforward to work on the CS control flow stack directly,
    although I haven't tested the idea yet. CS-PICK and CS-ROLL would not be sufficient
    as primitives, >CS and CS> would have to be introduced to complement them.

    But then it would not be portable. Different Forth systems might not even use a CS
    or might put address references (perhaps with flags) on the CS in a peculiar way.
    CS elements like orig are even implementation dependent data types of unknown size or
    unknown physical meaning, f.ex. like Ruvim's cons+lists concept.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to minf...@arcor.de on Tue Mar 14 00:03:07 2023
    On 13/03/2023 10:45 pm, minf...@arcor.de wrote:
    ...
    Good summary of the problems to expect when overloading the standard control structures
    like Wil Baden did. Particularly DO..LOOPs can become nasty then. BEGIN.. loops can be
    handled.

    I believe it would be more straightforward to work on the CS control flow stack directly,
    although I haven't tested the idea yet. CS-PICK and CS-ROLL would not be sufficient
    as primitives, >CS and CS> would have to be introduced to complement them.

    But then it would not be portable. Different Forth systems might not even use a CS
    or might put address references (perhaps with flags) on the CS in a peculiar way.
    CS elements like orig are even implementation dependent data types of unknown size or
    unknown physical meaning, f.ex. like Ruvim's cons+lists concept.

    Wil Baden was responsible for the CS words in ANS. My understanding is he didn't
    do it because forth was lacking control structures; but rather for completeness.
    He wanted to be able to express control flow used in classical languages in forth.
    He wasn't promoting GOTO et al. If I can find where he explained his position, I'll post it. Closest to it I've found is this:

    https://groups.google.com/g/comp.lang.forth/c/ZXGrOtI1gtM/m/6ZC_JUPyHy8J

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@arcor.de@21:1/5 to dxforth on Mon Mar 13 08:02:47 2023
    dxforth schrieb am Montag, 13. März 2023 um 14:03:11 UTC+1:
    On 13/03/2023 10:45 pm, minf...@arcor.de wrote:
    ...
    Good summary of the problems to expect when overloading the standard control structures
    like Wil Baden did. Particularly DO..LOOPs can become nasty then. BEGIN.. loops can be
    handled.

    I believe it would be more straightforward to work on the CS control flow stack directly,
    although I haven't tested the idea yet. CS-PICK and CS-ROLL would not be sufficient
    as primitives, >CS and CS> would have to be introduced to complement them.

    But then it would not be portable. Different Forth systems might not even use a CS
    or might put address references (perhaps with flags) on the CS in a peculiar way.
    CS elements like orig are even implementation dependent data types of unknown size or
    unknown physical meaning, f.ex. like Ruvim's cons+lists concept.
    Wil Baden was responsible for the CS words in ANS. My understanding is he didn't
    do it because forth was lacking control structures; but rather for completeness.
    He wanted to be able to express control flow used in classical languages in forth.
    He wasn't promoting GOTO et al. If I can find where he explained his position,
    I'll post it. Closest to it I've found is this:

    https://groups.google.com/g/comp.lang.forth/c/ZXGrOtI1gtM/m/6ZC_JUPyHy8J

    Should one really rummage in Wil Baden's past "responsibleness" and past position papers?
    He may have changed his mind over time..

    Be it. Having a GOTO is very handy sometimes. In my observation it is about 3/4 jumping forward
    from one or more code positions to one single target, the rest is jumping backward to one
    single target. More would mean spaghetti code; to be avoided.

    This can be handled by only 4 simple words
    GOTO> >LABEL to jump forward, several gotos allowed
    LABEL< <GOTO to jump backward, several gotos allowed
    Restriction: only one of each label type allowed per word definition.

    Advantage: no namespace cluttering with label names, no interference with the CS because
    this simple scheme can be realized with 2 separate small arrays/stacks for holding GOTO
    jump locations.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Marcel Hendrix@21:1/5 to Ruvim on Mon Mar 13 11:51:12 2023
    On Monday, March 13, 2023 at 2:26:01 AM UTC+1, Ruvim wrote:
    [..]
    And we should not allow to goto inside DO...LOOP
    from outside (an error should be raised).

    For symmetry reasons I have to ask: why not?

    In TAOCP Knuth uses GOTO all the time, if not exclusively.

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ruvim@21:1/5 to Marcel Hendrix on Mon Mar 13 20:07:44 2023
    On 2023-03-13 18:51, Marcel Hendrix wrote:
    On Monday, March 13, 2023 at 2:26:01 AM UTC+1, Ruvim wrote:
    [..]
    And we should not allow to goto inside DO...LOOP
    from outside (an error should be raised).

    For symmetry reasons I have to ask: why not?

    It's possible to implement a jump from inside DO-LOOP (to outside). It's
    just needed to perform some number of UNLOOP before a jump.

    But if we jump inside DO-LOOP, it's impossible to correctly set the loop
    limit and loop index.



    In TAOCP Knuth uses GOTO all the time, if not exclusively.


    I don't have an idea how it did work (if any) for a loop construct that
    has its internal state. Probably, he didn't have such constructs.

    I.e., in his cases, the state of a loop construct is maintained in usual variables, which are accessible and can be set from outside the construct.


    --
    Ruvim

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Marcel Hendrix on Mon Mar 13 13:13:24 2023
    Marcel Hendrix <mhx@iae.nl> writes:
    And we should not allow to goto inside DO...LOOP ...
    In TAOCP Knuth uses GOTO all the time, if not exclusively.

    The code in TAOCP is in assembly language, and his informal algorithm descriptions are unstructured (no DO loops), so he can't do much else.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Marcel Hendrix@21:1/5 to Ruvim on Mon Mar 13 13:43:21 2023
    On Monday, March 13, 2023 at 9:07:48 PM UTC+1, Ruvim wrote:
    [..]
    But if we jump inside DO-LOOP, it's impossible to correctly set the loop limit and loop index.

    Assume an optimizing compiler: the limit and index will be in registers.

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Marcel Hendrix@21:1/5 to Paul Rubin on Mon Mar 13 13:50:59 2023
    On Monday, March 13, 2023 at 9:13:27 PM UTC+1, Paul Rubin wrote:
    Marcel Hendrix <m...@iae.nl> writes:
    [..]
    In TAOCP Knuth uses GOTO all the time, if not exclusively.
    The code in TAOCP is in assembly language, and his informal algorithm descriptions are unstructured (no DO loops), so he can't do much else.

    May be "informal," but (from personal MIX experience) they
    work fine.

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to minf...@arcor.de on Mon Mar 13 14:33:15 2023
    On Friday, March 10, 2023 at 12:34:57 PM UTC-5, minf...@arcor.de wrote:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient. The same situation happens now and then with
    loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    Guessing that I am not alone in this, how do you manage? Any magic tricks
    up the sleeve to (ab)use standard Forth's control flow words? I don't
    expect that someone parses Forth definitions twice just to resolve
    backward jumps to preceding labels, or do we..?

    PS I don't want to revive that old structured programming yawner:
    "don't GOTO, it is evil"

    I didn't read all the replies, but... I won't say GOTO is evil. That's a strong word. I just never need it. It does make some things complicated, in terms of understanding what is going on in the code. I find the example Ruvim gave, to be a good
    example of this. I find the goto code to be much more complex or maybe the right word is "messy".

    Maybe you can give a concrete example where a GOTO is a better solution than the standard control flow structures?

    --

    Rick C.

    - Get 1,000 miles of free Supercharging
    - Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@arcor.de@21:1/5 to Lorem Ipsum on Mon Mar 13 15:14:38 2023
    Lorem Ipsum schrieb am Montag, 13. März 2023 um 22:33:17 UTC+1:
    On Friday, March 10, 2023 at 12:34:57 PM UTC-5, minf...@arcor.de wrote:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient. The same situation happens now and then with
    loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    Guessing that I am not alone in this, how do you manage? Any magic tricks up the sleeve to (ab)use standard Forth's control flow words? I don't expect that someone parses Forth definitions twice just to resolve backward jumps to preceding labels, or do we..?

    PS I don't want to revive that old structured programming yawner:
    "don't GOTO, it is evil"
    I didn't read all the replies, but... I won't say GOTO is evil. That's a strong word. I just never need it. It does make some things complicated, in terms of understanding what is going on in the code. I find the example Ruvim gave, to be a good
    example of this. I find the goto code to be much more complex or maybe the right word is "messy".

    Maybe you can give a concrete example where a GOTO is a better solution than the standard control flow structures?

    I use some non-standard idioms in my work that would be too distracting here.

    But good overview with examples here:
    https://en.wikipedia.org/wiki/Goto

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to minf...@arcor.de on Tue Mar 14 10:01:08 2023
    On 14/03/2023 2:02 am, minf...@arcor.de wrote:
    dxforth schrieb am Montag, 13. März 2023 um 14:03:11 UTC+1:
    On 13/03/2023 10:45 pm, minf...@arcor.de wrote:
    ...
    Good summary of the problems to expect when overloading the standard control structures
    like Wil Baden did. Particularly DO..LOOPs can become nasty then. BEGIN.. loops can be
    handled.

    I believe it would be more straightforward to work on the CS control flow stack directly,
    although I haven't tested the idea yet. CS-PICK and CS-ROLL would not be sufficient
    as primitives, >CS and CS> would have to be introduced to complement them. >>>
    But then it would not be portable. Different Forth systems might not even use a CS
    or might put address references (perhaps with flags) on the CS in a peculiar way.
    CS elements like orig are even implementation dependent data types of unknown size or
    unknown physical meaning, f.ex. like Ruvim's cons+lists concept.
    Wil Baden was responsible for the CS words in ANS. My understanding is he didn't
    do it because forth was lacking control structures; but rather for completeness.
    He wanted to be able to express control flow used in classical languages in forth.
    He wasn't promoting GOTO et al. If I can find where he explained his position,
    I'll post it. Closest to it I've found is this:

    https://groups.google.com/g/comp.lang.forth/c/ZXGrOtI1gtM/m/6ZC_JUPyHy8J

    Should one really rummage in Wil Baden's past "responsibleness" and past position papers?
    He may have changed his mind over time..

    Given the years he claims to have spent on the topic I'd say his conclusions are
    relevant. I accept folks may need to find out for themselves.

    Be it. Having a GOTO is very handy sometimes. In my observation it is about 3/4 jumping forward
    from one or more code positions to one single target, the rest is jumping backward to one
    single target. More would mean spaghetti code; to be avoided.

    This can be handled by only 4 simple words
    GOTO> >LABEL to jump forward, several gotos allowed
    LABEL< <GOTO to jump backward, several gotos allowed
    Restriction: only one of each label type allowed per word definition.

    Advantage: no namespace cluttering with label names, no interference with the CS because
    this simple scheme can be realized with 2 separate small arrays/stacks for holding GOTO
    jump locations.

    I use labels in assembler because I consider them a better fit. Structured conditionals
    are loadable but I never do. Mixing the two would strike me as an abomination. Same
    for high-level forth.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ruvim@21:1/5 to Marcel Hendrix on Mon Mar 13 22:48:32 2023
    On 2023-03-13 20:43, Marcel Hendrix wrote:
    On Monday, March 13, 2023 at 9:07:48 PM UTC+1, Ruvim wrote:
    [..]
    But if we jump inside DO-LOOP, it's impossible to correctly set the loop
    limit and loop index.

    Assume an optimizing compiler: the limit and index will be in registers.

    It does not matter. How they will be placed into the registers?


    An example:

    : foo ( u -- )

    2 mod if goto( x ) then

    10 0 do i . label( x ) i 2/ . loop

    ;

    There is no way to initialize "do-loop" other then via the initial "do".
    If we jump inside "do-loop" over this "do", then what the next "loop"
    will do is undetermined.

    --
    Ruvim

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Lorem Ipsum on Tue Mar 14 11:36:34 2023
    On 14/03/2023 8:33 am, Lorem Ipsum wrote:

    Maybe you can give a concrete example where a GOTO is a better solution than the standard control flow structures?

    The question I'll be asking myself is how many ways of manipulating control flow
    can I justify? I have the ANS CS words (with extensions CS-DROP CS-MARK CS-TEST
    CS-PUSH CS-POP). Either GOTO goes or the CS words go.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to minf...@arcor.de on Mon Mar 13 21:21:53 2023
    On Monday, March 13, 2023 at 6:14:40 PM UTC-4, minf...@arcor.de wrote:
    Lorem Ipsum schrieb am Montag, 13. März 2023 um 22:33:17 UTC+1:
    On Friday, March 10, 2023 at 12:34:57 PM UTC-5, minf...@arcor.de wrote:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient. The same situation happens now and then with
    loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    Guessing that I am not alone in this, how do you manage? Any magic tricks
    up the sleeve to (ab)use standard Forth's control flow words? I don't expect that someone parses Forth definitions twice just to resolve backward jumps to preceding labels, or do we..?

    PS I don't want to revive that old structured programming yawner:
    "don't GOTO, it is evil"
    I didn't read all the replies, but... I won't say GOTO is evil. That's a strong word. I just never need it. It does make some things complicated, in terms of understanding what is going on in the code. I find the example Ruvim gave, to be a good
    example of this. I find the goto code to be much more complex or maybe the right word is "messy".

    Maybe you can give a concrete example where a GOTO is a better solution than the standard control flow structures?
    I use some non-standard idioms in my work that would be too distracting here.

    But good overview with examples here:
    https://en.wikipedia.org/wiki/Goto

    Ok, so you don't have any useful examples. I get it. Thanks

    I asked, because I've never run across an example that was not a good match for structured programming. But this is Forth we are talking about, where people do all sorts of weird things.

    --

    Rick C.

    + Get 1,000 miles of free Supercharging
    + Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to minf...@arcor.de on Tue Mar 14 00:03:35 2023
    On Tuesday, March 14, 2023 at 2:56:27 AM UTC-4, minf...@arcor.de wrote:
    Lorem Ipsum schrieb am Dienstag, 14. März 2023 um 05:21:55 UTC+1:
    On Monday, March 13, 2023 at 6:14:40 PM UTC-4, minf...@arcor.de wrote:
    Lorem Ipsum schrieb am Montag, 13. März 2023 um 22:33:17 UTC+1:
    On Friday, March 10, 2023 at 12:34:57 PM UTC-5, minf...@arcor.de wrote:
    Now and then I happen to write code where a simple GOTO would be just too convenient. The same situation happens now and then with loops: BREAK to leave them, CONTINUE to jump back to loop start, would come in oh so handy.

    Guessing that I am not alone in this, how do you manage? Any magic tricks
    up the sleeve to (ab)use standard Forth's control flow words? I don't
    expect that someone parses Forth definitions twice just to resolve backward jumps to preceding labels, or do we..?

    PS I don't want to revive that old structured programming yawner: "don't GOTO, it is evil"
    I didn't read all the replies, but... I won't say GOTO is evil. That's a strong word. I just never need it. It does make some things complicated, in terms of understanding what is going on in the code. I find the example Ruvim gave, to be a good
    example of this. I find the goto code to be much more complex or maybe the right word is "messy".

    Maybe you can give a concrete example where a GOTO is a better solution than the standard control flow structures?
    I use some non-standard idioms in my work that would be too distracting here.

    But good overview with examples here:
    https://en.wikipedia.org/wiki/Goto
    Ok, so you don't have any useful examples. I get it. Thanks

    I asked, because I've never run across an example that was not a good match for structured programming. But this is Forth we are talking about, where people do all sorts of weird things.
    Indeed are they not useful to you. What could you do with FOR> .. i" goto m1;" .. NEXT ...
    while finding pivot or vector elements?

    Sorry, that is not very clear without more context.

    --

    Rick C.

    -- Get 1,000 miles of free Supercharging
    -- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@arcor.de@21:1/5 to Lorem Ipsum on Mon Mar 13 23:56:25 2023
    Lorem Ipsum schrieb am Dienstag, 14. März 2023 um 05:21:55 UTC+1:
    On Monday, March 13, 2023 at 6:14:40 PM UTC-4, minf...@arcor.de wrote:
    Lorem Ipsum schrieb am Montag, 13. März 2023 um 22:33:17 UTC+1:
    On Friday, March 10, 2023 at 12:34:57 PM UTC-5, minf...@arcor.de wrote:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient. The same situation happens now and then with loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    Guessing that I am not alone in this, how do you manage? Any magic tricks
    up the sleeve to (ab)use standard Forth's control flow words? I don't expect that someone parses Forth definitions twice just to resolve backward jumps to preceding labels, or do we..?

    PS I don't want to revive that old structured programming yawner: "don't GOTO, it is evil"
    I didn't read all the replies, but... I won't say GOTO is evil. That's a strong word. I just never need it. It does make some things complicated, in terms of understanding what is going on in the code. I find the example Ruvim gave, to be a good
    example of this. I find the goto code to be much more complex or maybe the right word is "messy".

    Maybe you can give a concrete example where a GOTO is a better solution than the standard control flow structures?
    I use some non-standard idioms in my work that would be too distracting here.

    But good overview with examples here:
    https://en.wikipedia.org/wiki/Goto
    Ok, so you don't have any useful examples. I get it. Thanks

    I asked, because I've never run across an example that was not a good match for structured programming. But this is Forth we are talking about, where people do all sorts of weird things.

    Indeed are they not useful to you. What could you do with FOR> .. i" goto m1;" .. NEXT ...
    while finding pivot or vector elements?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Lorem Ipsum on Tue Mar 14 00:31:34 2023
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> writes:
    I asked, because I've never run across an example that was not a good
    match for structured programming. But this is Forth we are talking
    about, where people do all sorts of weird things.

    Forth's control flow words are usually implemented with lower level
    primitives like 0BRANCH, which is a conditional goto.

    In C programming I've sometimes used goto to break out of multiple
    levels of loops. That's an occasional thing though, and some other
    languages make it easier to break from a named block instead of using
    goto.

    GCC also supports using labels as values, so you can goto an address.
    Gforth uses that feature in its inner interpreter to get faster code
    than you would get with a switch statement.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Paul Rubin on Tue Mar 14 19:14:13 2023
    On 14/03/2023 6:31 pm, Paul Rubin wrote:

    Forth's control flow words are usually implemented with lower level primitives like 0BRANCH, which is a conditional goto.

    Admittedly limited

    \ Jump between definitions
    CHECKING OFF

    : FORWARD 1 BEGIN ( adr) ... ;

    : BACKWARD -1 ( adr) AGAIN ;

    CHECKING ON

    but neither have I sought to use it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to Paul Rubin on Tue Mar 14 01:44:49 2023
    On Tuesday, March 14, 2023 at 3:31:37 AM UTC-4, Paul Rubin wrote:
    Lorem Ipsum <gnuarm.del...@gmail.com> writes:
    I asked, because I've never run across an example that was not a good match for structured programming. But this is Forth we are talking
    about, where people do all sorts of weird things.
    Forth's control flow words are usually implemented with lower level primitives like 0BRANCH, which is a conditional goto.

    Of course, but that means nothing. Assembly language doesn't typically have anything like control flow structures, it's all gotos. So branches, by necessity are created with them. But in Forth, it's all structured control flow, unless you insist on
    using a GOTO. It's not about what the machine does. It's about what the programmer does.


    In C programming I've sometimes used goto to break out of multiple
    levels of loops. That's an occasional thing though, and some other
    languages make it easier to break from a named block instead of using
    goto.

    I've never run into that situation myself, other than one where it would be handled by catch and throw.


    GCC also supports using labels as values, so you can goto an address.
    Gforth uses that feature in its inner interpreter to get faster code
    than you would get with a switch statement.

    You are saying the goto address is calculated? Are you doing that in Forth, or in assembly?

    I don't want to get into the whole structured programming debate. I'm just saying that I've never found a case where gotos were actually needed. I think we all know that one thing to be avoided, is optimization where it is not required. I think the OP
    has long ago decided he has no reason to prefer structured programming. But I believe the evidence is clear, that unless there is a direct need for something like a goto, structured programming provides more clear code. Hmmm.... I guess I lied when I
    wrote, "I don't want to get into the whole structured programming debate", because, here I am. Sorry. I'll stop now.

    --

    Rick C.

    -+ Get 1,000 miles of free Supercharging
    -+ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to All on Tue Mar 14 21:05:22 2023
    Add syntax sugar...

    \ DX-Forth

    create tbl 10 cells allot \ labels 0...9

    : @digit ( "num" -- adr ) bl word c@ $0F and cells tbl + ;

    : LABEL: ( "num" ) postpone BEGIN -1 bal +! @digit ! ; immediate

    : GOTO ( "num" ) @digit @ postpone AGAIN 1 bal +! ; immediate


    : bar label: 1 ." foobar" ;
    : foo goto 1 ;

    foo foobar ok

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to dxforth on Tue Mar 14 21:22:22 2023
    On 14/03/2023 9:05 pm, dxforth wrote:

    : @digit ( "num" -- adr )  bl word c@  $0F and  cells tbl + ;

    bugfix

    : @digit ( "num" -- adr ) bl word 1+ c@ $0F and cells tbl + ;

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Marcel Hendrix@21:1/5 to Marcel Hendrix on Tue Mar 14 05:22:31 2023
    On Tuesday, March 14, 2023 at 1:17:28 PM UTC+1, Marcel Hendrix wrote:
    On Tuesday, March 14, 2023 at 8:31:37 AM UTC+1, Paul Rubin wrote:
    [..]
    In C programming I've sometimes used goto to break out of multiple
    levels of loops. That's an occasional thing though, and some other languages make it easier to break from a named block instead of using
    goto.
    [..]

    I used it once.

    I lied.

    -marcel
    ---
    (*
    * LANGUAGE : ANS Forth with extensions
    * PROJECT : Forth Environments
    * DESCRIPTION : Use AMB construct
    * CATEGORY : Rosetta project
    * AUTHOR : Marcel Hendrix
    * LAST CHANGE : March 15, 2009, Marcel Hendrix
    *)



    NEEDS -miscutil
    NEEDS -goto

    REVISION -amb "--- AMB example Version 0.01 ---"

    PRIVATES

    DOC
    (*
    Define and give an example of the Amb operator.

    The Amb operator takes some number of expressions
    (or values if that's simpler in the language) and
    nondeterministically yields the one or fails if given
    no parameter, amb returns the value that doesn't lead to failure.

    The example is using amb to choose four words from the following strings:

    set 1: "the" "that" "a"

    set 2: "frog" "elephant" "thing"

    set 3: "walked" "treaded" "grows"

    set 4: "slowly" "quickly"

    It is a failure if the last character of word 1 is not equal to the
    first character of word 2, and similarly with word 2 and
  • From none) (albert@21:1/5 to minf...@arcor.de on Tue Mar 14 13:34:19 2023
    In article <ae7ed4c5-3b82-4384-9e00-a5152281325cn@googlegroups.com>, minf...@arcor.de <minforth@arcor.de> wrote:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient. The same situation happens now and then with
    loops: BREAK to leave them, CONTINUE to jump back to loop start,
    would come in oh so handy.

    Guessing that I am not alone in this, how do you manage? Any magic tricks
    up the sleeve to (ab)use standard Forth's control flow words? I don't
    expect that someone parses Forth definitions twice just to resolve
    backward jumps to preceding labels, or do we..?

    PS I don't want to revive that old structured programming yawner:
    "don't GOTO, it is evil"

    I cherish goto's. Non-local jumps into nested subroutines once won
    me a price at the Obfuscated C context. "most useful program"

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Marcel Hendrix@21:1/5 to Paul Rubin on Tue Mar 14 05:17:24 2023
    On Tuesday, March 14, 2023 at 8:31:37 AM UTC+1, Paul Rubin wrote:
    [..]
    In C programming I've sometimes used goto to break out of multiple
    levels of loops. That's an occasional thing though, and some other
    languages make it easier to break from a named block instead of using
    goto.
    [..]

    I used it once.

    -marcel

    ( excerpt )

    DOC
    (*
    By Dennis L. Feucht, in JFAR Vol 5, No 3, 1989, page 415-419
    'The Prolog Interpreter Algorithm'.

    Let's state problems as a set of rules:

    1) a :- x, y \ a is true if x and y are true
    2) x. \ x is true
    3) y :- u, v \ y is true if u and v are true
    4) u. \ u is true
    5) a :- b, c, d \ a is true if b, c and d are true
    6) b :- g, h \ b is true if g and h are true

    The goal is to prove that a is true, or in list notation:
    '( a ) set-to goal
    '( ( a x y ) ( x ) ( y u v ) ( u ) ( a b c d ) ( b g h ) ) set-to clauses
    *)
    ENDDOC

    nil SET-TO iclauses PRIVATE

    6 STATES
    1 || OVER nil? IF 2DROP TRUE EXIT ENDIF ;; \ succeed!
    2 || DUP nil? IF 2DROP FALSE EXIT ENDIF ;; \ fail!
    3 || OVER CAR OVER CAR CAR eq 5 4 ?GOTO ;
    4 || cdr 1 GOTO ;
    5 || DUP CAR CDR 2 PICK CDR copy-list1-append
    iclauses 1 CALL IF 2DROP TRUE EXIT ENDIF 4 GOTO ;

    \G Prolog inference engine. Search clauses to test if goals are true.
    \G Example: '( a ) set-to goals '( ( a x y ) ( x ) ( y ) ) set-to clauses
    \G goals clauses psearch . ---> -1
    : PSEARCH ( goals clauses -- f ) \ LISP "pee-search"
    DUP set-to iclauses 1 CALL ;


    :ABOUT CR ." Read LISP.DOC, TESTi.LSP, and ANIMAL.LSP" ;

    .ABOUT -lisp CR
    DEPRIVE

    (* End of Source *)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to dxforth on Tue Mar 14 05:25:18 2023
    dxforth schrieb am Dienstag, 14. März 2023 um 11:22:25 UTC+1:
    On 14/03/2023 9:05 pm, dxforth wrote:

    : @digit ( "num" -- adr ) bl word c@ $0F and cells tbl + ;
    bugfix

    : @digit ( "num" -- adr ) bl word 1+ c@ $0F and cells tbl + ;

    Thanks! Would this simple test case work with your method?
    Although artificially contrived, ISTM that it comprises the
    minimal requirements.

    \ Testing GOTO
    : GTEST1 ( -- )
    10 0 DO
    i 5 =
    IF i UNLOOP GOTO 1 THEN
    LOOP
    LABEL 2
    ." finished" EXIT
    LABEL 1
    ." unloop with " .
    GOTO 2 ;

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to dxforth on Tue Mar 14 10:27:15 2023
    On Tuesday, March 14, 2023 at 6:05:25 AM UTC-4, dxforth wrote:
    Add syntax sugar...

    \ DX-Forth

    create tbl 10 cells allot \ labels 0...9

    : @digit ( "num" -- adr ) bl word c@ $0F and cells tbl + ;

    : LABEL: ( "num" ) postpone BEGIN -1 bal +! @digit ! ; immediate

    : GOTO ( "num" ) @digit @ postpone AGAIN 1 bal +! ; immediate


    : bar label: 1 ." foobar" ;
    : foo goto 1 ;

    foo foobar ok

    So this works for jumping backwards, in a way that duplicates standard control flow features. How do you jump forward? You would need a forward LABEL: and :GOTO. I guess :LABEL and GOTO: would suffice. I can see situations where you want to jump
    forward and back to the same label, so you'd need,

    GOTO> here
    blah blah blah
    <LABEL: here
    LABEL>: here_too
    blah blah blah
    <GOTO here_too

    Yes, there are reasons why gotos are seldom used in Forth... if ever. I realize my example above is absurd. But then I'm not the one who says there is much use for GOTOs. Your example above, is literally replacing BEGIN and AGAIN with other names.
    How would you create GOTO> without using a second pass? A one pass compile would need a list of GOTO>s for every label. When you encounter the LABEL>: you would need to patch up every GOTO> in that list.

    Mostly, the problem is this code would likely be large for a single definition, with all the concomitant issues.

    --

    Rick C.

    +- Get 1,000 miles of free Supercharging
    +- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ruvim@21:1/5 to Lorem Ipsum on Tue Mar 14 17:53:57 2023
    On 2023-03-14 17:27, Lorem Ipsum wrote:
    [...]
    Your example above, is literally replacing BEGIN and AGAIN with other names.

    How would you create GOTO> without using a second pass?
    A one pass compile would need a list of GOTO>s for every label.
    When you encounter the LABEL>: you would need to patch up every GOTO> in that list.


    Imagine, you have "ahead2" and "then2" which use their own separate control-flow stack.

    Then, a code like:

    goto(x) ... goto(x) ... goto(x) ... label(x)

    is equivalent to:

    ahead2 ... ahead2 ... ahead2 ... then2 then2 then2

    Obviously, you don't need two passes for that.


    Also, you don't need both "GOTO>" and "<GOTO"

    If a given label name already defined above, "goto" behaves like
    "<goto", otherwise it behaves like "goto>".

    Similar for "label": if the given name already defined in some "goto"
    above, it resolves them (like "then2"), and removes the markers from the
    stack. After that it define new label for possible "goto" on this name
    bellow.


    --
    Ruvim

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to Ruvim on Tue Mar 14 11:26:24 2023
    On Tuesday, March 14, 2023 at 1:54:02 PM UTC-4, Ruvim wrote:
    On 2023-03-14 17:27, Lorem Ipsum wrote:
    [...]
    Your example above, is literally replacing BEGIN and AGAIN with other names.

    How would you create GOTO> without using a second pass?
    A one pass compile would need a list of GOTO>s for every label.
    When you encounter the LABEL>: you would need to patch up every GOTO> in that list.
    Imagine, you have "ahead2" and "then2" which use their own separate control-flow stack.

    Then, a code like:

    goto(x) ... goto(x) ... goto(x) ... label(x)

    is equivalent to:

    ahead2 ... ahead2 ... ahead2 ... then2 then2 then2

    Obviously, you don't need two passes for that.

    How do you make label(x) work like multiple then2?


    Also, you don't need both "GOTO>" and "<GOTO"

    If a given label name already defined above, "goto" behaves like
    "<goto", otherwise it behaves like "goto>".

    Similar for "label": if the given name already defined in some "goto"
    above, it resolves them (like "then2"), and removes the markers from the stack. After that it define new label for possible "goto" on this name bellow.

    So you would need to add two labels for the same location, if it is being jumped to from two different locations, one forward, and one back, no? In a college class I wrote an assembler for the IBM360. There were lots of tables for jumping and it was a
    PITA. Forth does it more simply, in part, by using defined control flow structures that work using a control flow stack. I can't think of a reason to toss that out.

    I don't know why I am discussing this. I think GOTOs are not a useful construct and will not use them.

    --

    Rick C.

    ++ Get 1,000 miles of free Supercharging
    ++ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andy Valencia@21:1/5 to Lorem Ipsum on Tue Mar 14 12:05:02 2023
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> writes:
    I asked, because I've never run across an example that was not a good
    match for structured programming. But this is Forth we are talking
    about, where people do all sorts of weird things.

    Almost always--in my experience--goto shows up for exceptional code paths. Errors, or extraordiinary scenarios.

    Very often in Forth that ends up as throw/catch. Which, while not goto, is still an unstructured control flow change.

    Andy Valencia
    Home page: https://www.vsta.org/andy/
    To contact me: https://www.vsta.org/contact/andy.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ruvim@21:1/5 to Lorem Ipsum on Tue Mar 14 19:27:49 2023
    On 2023-03-14 18:26, Lorem Ipsum wrote:
    On Tuesday, March 14, 2023 at 1:54:02 PM UTC-4, Ruvim wrote:
    On 2023-03-14 17:27, Lorem Ipsum wrote:
    [...]
    Your example above, is literally replacing BEGIN and AGAIN with other names.

    How would you create GOTO> without using a second pass?
    A one pass compile would need a list of GOTO>s for every label.
    When you encounter the LABEL>: you would need to patch up every GOTO> in that list.
    Imagine, you have "ahead2" and "then2" which use their own separate
    control-flow stack.

    Then, a code like:

    goto(x) ... goto(x) ... goto(x) ... label(x)

    is equivalent to:

    ahead2 ... ahead2 ... ahead2 ... then2 then2 then2

    Obviously, you don't need two passes for that.

    How do you make label(x) work like multiple then2?

    It can just pop all forward markers for name "x", and perform "then2"
    for each of them.

    After that it pushes a marker for name "x" for possible backward
    references (like "begin2" does).




    Also, you don't need both "GOTO>" and "<GOTO"

    If a given label name already defined above, "goto" behaves like
    "<goto", otherwise it behaves like "goto>".

    Similar for "label": if the given name already defined in some "goto"
    above, it resolves them (like "then2"), and removes the markers from the
    stack. After that it define new label for possible "goto" on this name
    bellow.

    So you would need to add two labels for the same location, if it is being jumped to
    from two different locations, one forward, and one back, no?

    No. Note that "then2" does not add any label, it only resolves a forward reference.


    Let's consider another example:

    goto(x) ... goto(x) ...
    label(x) ...
    goto(x) ... goto(x)
    ...

    It's equivalent to:

    ahead2 ... ahead2 ...
    then2 then2 begin2 ...
    [ cs2-dup ] again2 ... [ cs2-dup ] again2
    ...
    [ cs2-drop ] \ at the end


    As you can see, label(x) resolves all "ahead2", and adds only *one*
    label (marker) for possible backward references (like "begin2" does).

    Later we don't consume this marker from the stack, but make a copy and
    consumes this copy. We drop the original marker when we only sure that
    no more backward references are possible (i.e., at the end of the
    definition).

    Real labels behave like if you have a separate stack for each label
    name, and per each marker type (orig and dest).

    In my implementation [1], I have two stacks (actually lists) and copy or
    pop a marker from the stack by a label name. So the result is the same
    as you have a separate stack per each name. Don't sure what is simpler.

    My implementation works in *any* reach enough standard Forth system that implements the control-flow stack using the data stack. The full package
    in ZIP is also available [2].


    [1] https://github.com/ruv/puzzle-in-forth/blob/main/extension/goto.fth
    [2] https://github.com/ruv/puzzle-in-forth/archive/refs/heads/main.zip



    In a college class I wrote an assembler for the IBM360. There were lots
    of tables for jumping and it was a PITA. Forth does it more simply,
    in part, by using defined control flow structures that work using
    a control flow stack. I can't think of a reason to toss that out.

    Implementation of GOTO is more difficult than usual control-flow means
    in Forth. One simple stack is not enough for that. I employed an
    uncertain number of stacks of two types ;-))



    I don't know why I am discussing this. I think GOTOs are not a useful construct and will not use them.


    I also don't use GOTO. To me, it's just an interesting puzzle.


    --
    Ruvim

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to Andy Valencia on Tue Mar 14 14:39:07 2023
    On Tuesday, March 14, 2023 at 3:10:01 PM UTC-4, Andy Valencia wrote:
    Lorem Ipsum <gnuarm.del...@gmail.com> writes:
    I asked, because I've never run across an example that was not a good match for structured programming. But this is Forth we are talking
    about, where people do all sorts of weird things.
    Almost always--in my experience--goto shows up for exceptional code paths. Errors, or extraordiinary scenarios.

    Very often in Forth that ends up as throw/catch. Which, while not goto, is still an unstructured control flow change.

    Andy Valencia
    Home page: https://www.vsta.org/andy/
    To contact me: https://www.vsta.org/contact/andy.html

    Structured control flow is not a holy grail. It serves a purpose. That purpose is two fold, in the academic world and in some high reliability applications, it is desired to be able to "prove" the correctness of a program. Not done often, but with
    GOTOs, it can be impossible.

    The other purpose is to provide easy to use control structures that are clear, and result in code that is easy to understand. Throw and catch provide that result, even if it does not meet the standard usage of structured control flow. It meets the
    intent, if not the rule. So I don't consider throw/catch to be unstructured. In fact, it is designed to manage some of the issues with GOTOs, such as context changes. I think throw/catch manages a lot of that, no?

    --

    Rick C.

    --- Get 1,000 miles of free Supercharging
    --- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to Ruvim on Tue Mar 14 14:43:57 2023
    On Tuesday, March 14, 2023 at 3:27:53 PM UTC-4, Ruvim wrote:
    On 2023-03-14 18:26, Lorem Ipsum wrote:
    On Tuesday, March 14, 2023 at 1:54:02 PM UTC-4, Ruvim wrote:
    On 2023-03-14 17:27, Lorem Ipsum wrote:
    [...]
    Your example above, is literally replacing BEGIN and AGAIN with other names.

    How would you create GOTO> without using a second pass?
    A one pass compile would need a list of GOTO>s for every label.
    When you encounter the LABEL>: you would need to patch up every GOTO> in that list.
    Imagine, you have "ahead2" and "then2" which use their own separate
    control-flow stack.

    Then, a code like:

    goto(x) ... goto(x) ... goto(x) ... label(x)

    is equivalent to:

    ahead2 ... ahead2 ... ahead2 ... then2 then2 then2

    Obviously, you don't need two passes for that.

    How do you make label(x) work like multiple then2?
    It can just pop all forward markers for name "x", and perform "then2"
    for each of them.

    "Just" is a four letter word. This sounds very complex. I'm good with the standard control structures.


    After that it pushes a marker for name "x" for possible backward
    references (like "begin2" does).

    "Possible"??? What happens if there are none? Again, this gets very messy, lots of conditions to manage. I seem to recall someone talking about using GOTOs in their Forth to speed up something while compiling. Now it is getting slowed.


    Also, you don't need both "GOTO>" and "<GOTO"

    If a given label name already defined above, "goto" behaves like
    "<goto", otherwise it behaves like "goto>".

    Similar for "label": if the given name already defined in some "goto"
    above, it resolves them (like "then2"), and removes the markers from the >> stack. After that it define new label for possible "goto" on this name
    bellow.

    So you would need to add two labels for the same location, if it is being jumped to
    from two different locations, one forward, and one back, no?
    No. Note that "then2" does not add any label, it only resolves a forward reference.

    I've lost track. I'm not actually very interested in making this work. I have no use for it.


    Let's consider another example:

    goto(x) ... goto(x) ...
    label(x) ...
    goto(x) ... goto(x)
    ...

    It's equivalent to:

    ahead2 ... ahead2 ...
    then2 then2 begin2 ...
    [ cs2-dup ] again2 ... [ cs2-dup ] again2
    ...
    [ cs2-drop ] \ at the end


    As you can see, label(x) resolves all "ahead2", and adds only *one*
    label (marker) for possible backward references (like "begin2" does).

    Later we don't consume this marker from the stack, but make a copy and consumes this copy. We drop the original marker when we only sure that
    no more backward references are possible (i.e., at the end of the definition).

    Real labels behave like if you have a separate stack for each label
    name, and per each marker type (orig and dest).

    In my implementation [1], I have two stacks (actually lists) and copy or
    pop a marker from the stack by a label name. So the result is the same
    as you have a separate stack per each name. Don't sure what is simpler.

    My implementation works in *any* reach enough standard Forth system that implements the control-flow stack using the data stack. The full package
    in ZIP is also available [2].

    If you can make this work for you, great! I hope it doesn't appear in any Forth I use. Wasted space, in my opinion.


    [1] https://github.com/ruv/puzzle-in-forth/blob/main/extension/goto.fth
    [2] https://github.com/ruv/puzzle-in-forth/archive/refs/heads/main.zip
    In a college class I wrote an assembler for the IBM360. There were lots
    of tables for jumping and it was a PITA. Forth does it more simply,
    in part, by using defined control flow structures that work using
    a control flow stack. I can't think of a reason to toss that out.
    Implementation of GOTO is more difficult than usual control-flow means
    in Forth. One simple stack is not enough for that. I employed an
    uncertain number of stacks of two types ;-))

    I don't know why I am discussing this. I think GOTOs are not a useful construct and will not use them.

    I also don't use GOTO. To me, it's just an interesting puzzle.

    Fair enough. Enjoy!

    --

    Rick C.

    --+ Get 1,000 miles of free Supercharging
    --+ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to minf...@arcor.de on Wed Mar 15 02:32:05 2023
    minf...@arcor.de schrieb am Freitag, 10. März 2023 um 18:34:57 UTC+1:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient.

    Here's a very small but comprehensive solution for gforth 0.7.3
    including error checks and test suite (requires tester.fr).

    \ ###### GOTO for gforth 0.7.3 ######

    10 CONSTANT _#LBL \ max no. of labels/gotos, 0 <= id < #lbl

    CREATE _LABELS _#LBL CELLS ALLOT \ struct array {targetadr}
    CREATE _GOTOS _#LBL 2* CELLS ALLOT \ struct array {patchadr,id}

    : _LABEL() ( id -- adr ) cells _labels + ;
    : _GOTO() ( id -- adr ) 2* cells _gotos + ;
    : _LASTGOTO ( -- adr ) _#lbl 1- _goto() ;

    : _PARSE-ID ( "n" -- n id )
    0. parse-name >number abort" no number" 2drop here ;

    : _ADD-GOTO ( id adr -- )
    over _#lbl u< 0= abort" bad goto id"
    _lastgoto @ invert abort" gotos exhausted"
    0 _goto() dup 1 _goto() _#lbl 1- 2* cells move 2! ;

    \ system specific!
    : GOTO ( "n" -- ) \ 0 <= n < #lbl
    postpone branch _parse-id _add-goto here cell+ , ; IMMEDIATE

    : _ADD-LABEL ( id adr -- )
    over _#lbl u< 0= abort" bad label id"
    swap _label() dup @ abort" duplicated label" ! ;

    : L: ( "n" -- ) \ 0 <= n < #lbl
    _parse-id _add-label ; IMMEDIATE

    : _CLEAR-LABELS ( -- )
    _labels _#lbl cells erase _gotos _#lbl 2* cells -1 fill ; IMMEDIATE

    : _RESOLVE-GOTOS ( -- )
    _#lbl 0 DO i _label() @ IF
    _#lbl 0 DO i _goto() cell+ @ j = IF
    j _label() @ i _goto() @ ! \ system specific!
    THEN LOOP
    THEN LOOP ; IMMEDIATE

    \ system integration:

    warnings @ 0 warnings !
    : : postpone _clear-labels : ;
    : ; postpone _resolve-gotos postpone ; ; IMMEDIATE
    warnings !

    0 [IF] \ ---------- TESTS ----------

    REQUIRE tester.fr \ from standard test suite

    T{ : GT1 \ forward
    1 goto 5 2 L: 5 3 ; --> }T
    T{ GT1 --> 1 3 }T

    T{ : GT2 \ backward
    1 goto 5 2 L: 6 3 exit 4 L: 5 goto 6 7 ; --> }T
    T{ GT2 --> 1 3 }T

    T{ : GT3 \ multiple labels ignored
    L: 3 1 L: 4 2 L: 5 ; --> }T
    T{ GT3 --> 1 2 }T

    T{ : GT4 \ cross-over
    1 goto 0 3 L: 1 4 exit 6 L: 0 2 goto 1 5 ; --> }T
    T{ GT4 --> 1 2 4 }T

    T{ : GT5 \ with IF..THEN..ELSE
    IF goto 8 1 ELSE goto 9 2 THEN 3
    L: 8 8 exit 4 L: 9 9 ; --> }T
    T{ 1 GT5 --> 8 }T
    T{ 0 GT5 --> 9 }T

    T{ : GT6 \ with BEGIN..WHILE..REPEAT
    5 BEGIN dup WHILE dup 3 = IF goto 9 THEN 1- REPEAT exit
    L: 9 9 ; --> }T
    T{ GT6 --> 3 9 }T

    T{ : GT7 \ with DO..LOOP and CASE..ENDCASE
    5 0 DO i CASE
    1 OF 11 goto 0 ENDOF
    3 OF 13 ENDOF
    ENDCASE
    L: 1
    LOOP exit
    L: 0 12 goto 1 ; --> }T
    T{ GT7 --> 11 12 13 }T

    T{ : GT8 \ multiple gotos forward
    5 0 DO i CASE
    1 OF 11 goto 0 ENDOF
    3 OF 13 goto 0 ENDOF
    ENDCASE
    L: 1
    LOOP exit
    L: 0 12 goto 1 ; --> }T
    T{ GT8 --> 11 12 13 12 }T

    T{ : GT9 \ multiple gotos backward
    5 0 DO i CASE
    1 OF 11 goto 0 ENDOF
    3 OF 13 goto 1 ENDOF
    ENDCASE
    L: 2
    LOOP exit
    L: 0 12 goto 2
    L: 1 14 goto 2 ; --> }T
    T{ GT9 --> 11 12 13 14 }T

    sp0 @ sp! \ clean stack

    [THEN]

    \ ###### END ######

    Adaptation to other Forths should be straightforward with using some carnal knowledge about how the other Forth implements unconditional branches
    less control flow stack.

    Only words affected would be GOTO and _RESOLVE-GOTOS where indicated.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to gnuarm.deletethisbit@gmail.com on Wed Mar 15 10:45:17 2023
    In article <2c73807c-b1c9-4a37-bc0f-d8175f9de13cn@googlegroups.com>,
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> wrote:
    On Tuesday, March 14, 2023 at 6:05:25 AM UTC-4, dxforth wrote:
    Add syntax sugar...

    \ DX-Forth

    create tbl 10 cells allot \ labels 0...9

    : @digit ( "num" -- adr ) bl word c@ $0F and cells tbl + ;

    : LABEL: ( "num" ) postpone BEGIN -1 bal +! @digit ! ; immediate

    : GOTO ( "num" ) @digit @ postpone AGAIN 1 bal +! ; immediate


    : bar label: 1 ." foobar" ;
    : foo goto 1 ;

    foo foobar ok

    So this works for jumping backwards, in a way that duplicates standard control flow features. How do you jump
    forward? You would need a forward LABEL: and :GOTO. I guess :LABEL and GOTO: would suffice. I can see
    situations where you want to jump forward and back to the same label, so you'd need,

    GOTO> here
    blah blah blah
    <LABEL: here
    LABEL>: here_too
    blah blah blah
    <GOTO here_too

    Yes, there are reasons why gotos are seldom used in Forth... if ever. I realize my example above is absurd. But
    then I'm not the one who says there is much use for GOTOs. Your example above, is literally replacing BEGIN and
    AGAIN with other names. How would you create GOTO> without using a second pass? A one pass compile would need a
    list of GOTO>s for every label. When you encounter the LABEL>: you would need to patch up every GOTO> in that
    list.

    Mostly, the problem is this code would likely be large for a single definition, with all the concomitant issues.

    SEE IF
    : IF '0BRANCH , (FORWARD ; IMMEDIATE OK

    SEE THEN
    : THEN FORWARD) ; IMMEDIATE OK

    (FORWARD and (BACK serves with any control structure.

    But they work *equally well* in assembly source code,
    on the premise that the control structure of the code
    is not unstructured.
    Adding IF, UNTIL, .. is unnecessary, especially if
    for an occasional code word.

    Rick C.
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to minforth on Wed Mar 15 03:41:44 2023
    minforth schrieb am Mittwoch, 15. März 2023 um 10:32:08 UTC+1:
    minf...@arcor.de schrieb am Freitag, 10. März 2023 um 18:34:57 UTC+1:
    Now and then I happen to write code where a simple GOTO would be
    just too convenient.
    Here's a very small but comprehensive solution for gforth 0.7.3
    including error checks and test suite (requires tester.fr).

    \ ###### GOTO for gforth 0.7.3 ######

    10 CONSTANT _#LBL \ max no. of labels/gotos, 0 <= id < #lbl

    CREATE _LABELS _#LBL CELLS ALLOT \ struct array {targetadr}
    CREATE _GOTOS _#LBL 2* CELLS ALLOT \ struct array {patchadr,id}

    : _LABEL() ( id -- adr ) cells _labels + ;
    : _GOTO() ( id -- adr ) 2* cells _gotos + ;
    : _LASTGOTO ( -- adr ) _#lbl 1- _goto() ;

    : _PARSE-ID ( "n" -- n id )
    0. parse-name >number abort" no number" 2drop here ;

    : _ADD-GOTO ( id adr -- )
    over _#lbl u< 0= abort" bad goto id"
    _lastgoto @ invert abort" gotos exhausted"
    0 _goto() dup 1 _goto() _#lbl 1- 2* cells move 2! ;

    \ system specific!
    : GOTO ( "n" -- ) \ 0 <= n < #lbl
    postpone branch _parse-id _add-goto here cell+ , ; IMMEDIATE

    : _ADD-LABEL ( id adr -- )
    over _#lbl u< 0= abort" bad label id"
    swap _label() dup @ abort" duplicated label" ! ;

    : L: ( "n" -- ) \ 0 <= n < #lbl
    _parse-id _add-label ; IMMEDIATE

    : _CLEAR-LABELS ( -- )
    _labels _#lbl cells erase _gotos _#lbl 2* cells -1 fill ; IMMEDIATE

    : _RESOLVE-GOTOS ( -- )
    _#lbl 0 DO i _label() @ IF
    _#lbl 0 DO i _goto() cell+ @ j = IF
    j _label() @ i _goto() @ ! \ system specific!
    THEN LOOP
    THEN LOOP ; IMMEDIATE

    \ system integration:

    warnings @ 0 warnings !
    : : postpone _clear-labels : ;
    : ; postpone _resolve-gotos postpone ; ; IMMEDIATE
    warnings !

    0 [IF] \ ---------- TESTS ----------

    REQUIRE tester.fr \ from standard test suite

    T{ : GT1 \ forward
    1 goto 5 2 L: 5 3 ; --> }T
    T{ GT1 --> 1 3 }T

    T{ : GT2 \ backward
    1 goto 5 2 L: 6 3 exit 4 L: 5 goto 6 7 ; --> }T
    T{ GT2 --> 1 3 }T

    T{ : GT3 \ multiple labels ignored
    L: 3 1 L: 4 2 L: 5 ; --> }T
    T{ GT3 --> 1 2 }T

    T{ : GT4 \ cross-over
    1 goto 0 3 L: 1 4 exit 6 L: 0 2 goto 1 5 ; --> }T
    T{ GT4 --> 1 2 4 }T

    T{ : GT5 \ with IF..THEN..ELSE
    IF goto 8 1 ELSE goto 9 2 THEN 3
    L: 8 8 exit 4 L: 9 9 ; --> }T
    T{ 1 GT5 --> 8 }T
    T{ 0 GT5 --> 9 }T

    T{ : GT6 \ with BEGIN..WHILE..REPEAT
    5 BEGIN dup WHILE dup 3 = IF goto 9 THEN 1- REPEAT exit
    L: 9 9 ; --> }T
    T{ GT6 --> 3 9 }T

    T{ : GT7 \ with DO..LOOP and CASE..ENDCASE
    5 0 DO i CASE
    1 OF 11 goto 0 ENDOF
    3 OF 13 ENDOF
    ENDCASE
    L: 1
    LOOP exit
    L: 0 12 goto 1 ; --> }T
    T{ GT7 --> 11 12 13 }T

    T{ : GT8 \ multiple gotos forward
    5 0 DO i CASE
    1 OF 11 goto 0 ENDOF
    3 OF 13 goto 0 ENDOF
    ENDCASE
    L: 1
    LOOP exit
    L: 0 12 goto 1 ; --> }T
    T{ GT8 --> 11 12 13 12 }T

    T{ : GT9 \ multiple gotos backward
    5 0 DO i CASE
    1 OF 11 goto 0 ENDOF
    3 OF 13 goto 1 ENDOF
    ENDCASE
    L: 2
    LOOP exit
    L: 0 12 goto 2
    L: 1 14 goto 2 ; --> }T
    T{ GT9 --> 11 12 13 14 }T

    sp0 @ sp! \ clean stack

    [THEN]

    \ ###### END ######

    Adaptation to other Forths should be straightforward with using some carnal knowledge about how the other Forth implements unconditional branches
    less control flow stack.

    Only words affected would be GOTO and _RESOLVE-GOTOS where indicated.

    P.S. unresolved GOTOs are ignored silently, to add checking, exchange

    : _RESOLVE-GOTOS ( -- )
    _#lbl 0 DO i _label() @ IF
    _#lbl 0 DO i _goto() cell+ @ j = IF
    j _label() @ i _goto() @ ! \ system specific!
    -1 i _goto() !
    THEN LOOP
    THEN LOOP
    _#lbl 0 DO i _goto() @ invert abort" unresolved goto" LOOP ;

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to none albert on Wed Mar 15 16:29:37 2023
    On Wednesday, March 15, 2023 at 5:45:21 AM UTC-4, none albert wrote:
    In article <2c73807c-b1c9-4a37...@googlegroups.com>,
    Lorem Ipsum <gnuarm.del...@gmail.com> wrote:
    On Tuesday, March 14, 2023 at 6:05:25 AM UTC-4, dxforth wrote:
    Add syntax sugar...

    \ DX-Forth

    create tbl 10 cells allot \ labels 0...9

    : @digit ( "num" -- adr ) bl word c@ $0F and cells tbl + ;

    : LABEL: ( "num" ) postpone BEGIN -1 bal +! @digit ! ; immediate

    : GOTO ( "num" ) @digit @ postpone AGAIN 1 bal +! ; immediate


    : bar label: 1 ." foobar" ;
    : foo goto 1 ;

    foo foobar ok

    So this works for jumping backwards, in a way that duplicates standard control flow features. How do you jump
    forward? You would need a forward LABEL: and :GOTO. I guess :LABEL and GOTO: would suffice. I can see
    situations where you want to jump forward and back to the same label, so you'd need,

    GOTO> here
    blah blah blah
    <LABEL: here
    LABEL>: here_too
    blah blah blah
    <GOTO here_too

    Yes, there are reasons why gotos are seldom used in Forth... if ever. I realize my example above is absurd. But
    then I'm not the one who says there is much use for GOTOs. Your example above, is literally replacing BEGIN and
    AGAIN with other names. How would you create GOTO> without using a second pass? A one pass compile would need a
    list of GOTO>s for every label. When you encounter the LABEL>: you would need to patch up every GOTO> in that
    list.

    Mostly, the problem is this code would likely be large for a single definition, with all the concomitant issues.
    SEE IF
    : IF '0BRANCH , (FORWARD ; IMMEDIATE OK

    SEE THEN
    : THEN FORWARD) ; IMMEDIATE OK

    (FORWARD and (BACK serves with any control structure.

    But they work *equally well* in assembly source code,
    on the premise that the control structure of the code
    is not unstructured.
    Adding IF, UNTIL, .. is unnecessary, especially if
    for an occasional code word.

    Sorry, I have no idea what point you are trying to make. What does assembly language have to do with the issue?

    --

    Rick C.

    -+- Get 1,000 miles of free Supercharging
    -+- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Lorem Ipsum on Thu Mar 16 11:19:10 2023
    On 15/03/2023 4:27 am, Lorem Ipsum wrote:
    On Tuesday, March 14, 2023 at 6:05:25 AM UTC-4, dxforth wrote:
    Add syntax sugar...

    [...]

    So this works for jumping backwards, in a way that duplicates standard control flow features. How do you jump forward? You would need a forward LABEL: and :GOTO. I guess :LABEL and GOTO: would suffice. I can see situations where you want to jump
    forward and back to the same label, so you'd need,

    GOTO> here
    blah blah blah
    <LABEL: here
    LABEL>: here_too
    blah blah blah
    <GOTO here_too

    Yes, there are reasons why gotos are seldom used in Forth... if ever. I realize my example above is absurd. But then I'm not the one who says there is much use for GOTOs. Your example above, is literally replacing BEGIN and AGAIN with other names.
    How would you create GOTO> without using a second pass? A one pass compile would need a list of GOTO>s for every label. When you encounter the LABEL>: you would need to patch up every GOTO> in that list.

    Mostly, the problem is this code would likely be large for a single definition, with all the concomitant issues.


    Minforth has shown cost isn't overwhelming so it's worth comparing against other proposed schemes such as Anton's CASE extensions - which is better
    value for money. Folks are free to say they have no use for any of them,
    which would be the most cost effective of all. Since it's been mentioned, labels for assembler are likely to cost more than structured. OTOH one can
    do more with them which has saved me code. Whether one can make as good a
    case for labels in HLL *is* the question.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to minforth on Thu Mar 16 13:29:01 2023
    On 15/03/2023 8:32 pm, minforth wrote:

    Adaptation to other Forths should be straightforward with using some carnal knowledge about how the other Forth implements unconditional branches
    less control flow stack.

    \ ###### GOTO for DX-Forth ######
    \ 384 bytes
    \ based on Gforth version by Minforth

    forth definitions decimal system

    warning off

    10 constant ml \ max label/goto

    create lt ml cells allot \ targetadr
    create ft ml 2* cells allot \ patchadr,id

    : >l ( id -- adr ) cells lt + ;
    : >f ( id -- adr ) 2* cells ft + ;

    : ?l ( "n" -- n id )
    char 10 >digit 0= abort" bad label" here ;

    warning on

    : GOTO ( "n" -- ) \ 0-9
    ?l dup postpone again 1 bal +!
    [ ml 1- ] literal >f @ invert abort" too many refs"
    0 >f dup 1 >f [ ml 1- 2* cells ] literal move 2! ;
    immediate

    : L: ( "n" -- ) \ 0-9
    ?l swap >l dup @ abort" dup label" ! ; immediate

    : +LABELS ( -- )
    lt [ ml cells ] literal erase
    ft [ ml 2* cells ] literal -1 fill ; immediate

    : -LABELS ( -- )
    ml 0 do i >l @ if
    ml 0 do i >f cell+ @ j = if
    j >l @ i >f @ cell+ !
    then loop
    then loop ; immediate

    behead ml ?l

    application

    0 [if] \ Test forward/backward GOTO

    : DUP5 ( n -- n | 5 5 )
    +LABELS
    GOTO 1 L: 2 dup exit L: 1
    dup 5 = if GOTO 2 then
    -LABELS ;

    [then]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to minforth on Thu Mar 16 15:36:48 2023
    On 15/03/2023 8:32 pm, minforth wrote:

    \ system integration:

    warnings @ 0 warnings !
    : : postpone _clear-labels : ;
    : ; postpone _resolve-gotos postpone ; ; IMMEDIATE
    warnings !

    Ideally not as it will preclude far jumps.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxforth on Thu Mar 16 08:04:45 2023
    dxforth <dxforth@gmail.com> writes:
    Anton's CASE extensions

    Credit where credit is due: I have picked up ?OF and NEXT-CASE from
    Stephen Pelc. I only added CONTOF. Chuck Eaker designed the standard
    Forth CASE (aka Eaker's CASE). And of course, there is LISP's cond
    and Dijkstra's guarded commands that are precursors to the generalized
    Eaker's CASE. In particular, Dijkstra's repetition

    do G0 -> S0
    [] G1 -> S1
    ...
    [] Gn -> Sn
    od

    [where "[]" separates the guarded commands, like the box used by
    Dijkstra]

    corresponds to

    case
    G0 ?of S0 contof
    G1 ?of S1 contof
    ...
    Gn ?of Sn contof
    endcase

    Since it's been mentioned,
    labels for assembler are likely to cost more than structured. OTOH one can >do more with them which has saved me code.

    It seems to me that the condition code in architectures like AMD64 and
    ARM are the reason why we are not so happy with the standard Forth
    control flow words in assembly language: combining several conditions complicates the control structure. Wil Baden has suggested using
    ANDIF and ORIF, maybe they could make label-less control flow
    comfortable enough. RISC-V (like its ancestors MIPS and Alpha) has no
    condition codes and the standard Forth control structures may work
    better for RISC-V.

    - 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: https://forth-standard.org/
    EuroForth 2022: https://euro.theforth.net

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to gnuarm.deletethisbit@gmail.com on Thu Mar 16 13:21:53 2023
    In article <58c70431-d1d4-4d50-85c8-5f9fb69da280n@googlegroups.com>,
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> wrote:
    On Wednesday, March 15, 2023 at 5:45:21 AM UTC-4, none albert wrote:
    In article <2c73807c-b1c9-4a37...@googlegroups.com>,
    Lorem Ipsum <gnuarm.del...@gmail.com> wrote:
    On Tuesday, March 14, 2023 at 6:05:25 AM UTC-4, dxforth wrote:
    Add syntax sugar...

    \ DX-Forth

    create tbl 10 cells allot \ labels 0...9

    : @digit ( "num" -- adr ) bl word c@ $0F and cells tbl + ;

    : LABEL: ( "num" ) postpone BEGIN -1 bal +! @digit ! ; immediate

    : GOTO ( "num" ) @digit @ postpone AGAIN 1 bal +! ; immediate


    : bar label: 1 ." foobar" ;
    : foo goto 1 ;

    foo foobar ok

    So this works for jumping backwards, in a way that duplicates
    standard control flow features. How do you jump
    forward? You would need a forward LABEL: and :GOTO. I guess :LABEL
    and GOTO: would suffice. I can see
    situations where you want to jump forward and back to the same
    label, so you'd need,

    GOTO> here
    blah blah blah
    <LABEL: here
    LABEL>: here_too
    blah blah blah
    <GOTO here_too

    Yes, there are reasons why gotos are seldom used in Forth... if
    ever. I realize my example above is absurd. But
    then I'm not the one who says there is much use for GOTOs. Your
    example above, is literally replacing BEGIN and
    AGAIN with other names. How would you create GOTO> without using a
    second pass? A one pass compile would need a
    list of GOTO>s for every label. When you encounter the LABEL>: you
    would need to patch up every GOTO> in that
    list.

    Mostly, the problem is this code would likely be large for a single >definition, with all the concomitant issues.
    SEE IF
    : IF '0BRANCH , (FORWARD ; IMMEDIATE OK

    SEE THEN
    : THEN FORWARD) ; IMMEDIATE OK

    (FORWARD and (BACK serves with any control structure.

    But they work *equally well* in assembly source code,
    on the premise that the control structure of the code
    is not unstructured.
    Adding IF, UNTIL, .. is unnecessary, especially if
    for an occasional code word.

    Sorry, I have no idea what point you are trying to make. What does
    assembly language have to do with the issue?

    The issue of calculating offsets for relative branches is the
    same in Forth itself.
    If restricting yourself to emulating controled programming in
    Forth by branches and conditional branches, you have the same
    situation in assembly programming. In other words all
    information about a control flow stack can be mad to bear on it.

    Rick C.

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Anton Ertl on Fri Mar 17 00:43:00 2023
    On 16/03/2023 7:04 pm, Anton Ertl wrote:
    dxforth <dxforth@gmail.com> writes:
    ...
    Since it's been mentioned,
    labels for assembler are likely to cost more than structured. OTOH one can >> do more with them which has saved me code.

    It seems to me that the condition code in architectures like AMD64 and
    ARM are the reason why we are not so happy with the standard Forth
    control flow words in assembly language: combining several conditions complicates the control structure. Wil Baden has suggested using
    ANDIF and ORIF, maybe they could make label-less control flow
    comfortable enough. RISC-V (like its ancestors MIPS and Alpha) has no condition codes and the standard Forth control structures may work
    better for RISC-V.

    Curiously Forth Inc has not only stayed with structured conditionals,
    there's not even the option of using labels.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to none albert on Thu Mar 16 09:01:57 2023
    On Thursday, March 16, 2023 at 8:22:02 AM UTC-4, none albert wrote:
    In article <58c70431-d1d4-4d50...@googlegroups.com>,
    Lorem Ipsum <gnuarm.del...@gmail.com> wrote:
    On Wednesday, March 15, 2023 at 5:45:21 AM UTC-4, none albert wrote:
    In article <2c73807c-b1c9-4a37...@googlegroups.com>,
    Lorem Ipsum <gnuarm.del...@gmail.com> wrote:
    On Tuesday, March 14, 2023 at 6:05:25 AM UTC-4, dxforth wrote:
    Add syntax sugar...

    \ DX-Forth

    create tbl 10 cells allot \ labels 0...9

    : @digit ( "num" -- adr ) bl word c@ $0F and cells tbl + ;

    : LABEL: ( "num" ) postpone BEGIN -1 bal +! @digit ! ; immediate

    : GOTO ( "num" ) @digit @ postpone AGAIN 1 bal +! ; immediate


    : bar label: 1 ." foobar" ;
    : foo goto 1 ;

    foo foobar ok

    So this works for jumping backwards, in a way that duplicates
    standard control flow features. How do you jump
    forward? You would need a forward LABEL: and :GOTO. I guess :LABEL
    and GOTO: would suffice. I can see
    situations where you want to jump forward and back to the same
    label, so you'd need,

    GOTO> here
    blah blah blah
    <LABEL: here
    LABEL>: here_too
    blah blah blah
    <GOTO here_too

    Yes, there are reasons why gotos are seldom used in Forth... if
    ever. I realize my example above is absurd. But
    then I'm not the one who says there is much use for GOTOs. Your
    example above, is literally replacing BEGIN and
    AGAIN with other names. How would you create GOTO> without using a >second pass? A one pass compile would need a
    list of GOTO>s for every label. When you encounter the LABEL>: you >would need to patch up every GOTO> in that
    list.

    Mostly, the problem is this code would likely be large for a single >definition, with all the concomitant issues.
    SEE IF
    : IF '0BRANCH , (FORWARD ; IMMEDIATE OK

    SEE THEN
    : THEN FORWARD) ; IMMEDIATE OK

    (FORWARD and (BACK serves with any control structure.

    But they work *equally well* in assembly source code,
    on the premise that the control structure of the code
    is not unstructured.
    Adding IF, UNTIL, .. is unnecessary, especially if
    for an occasional code word.

    Sorry, I have no idea what point you are trying to make. What does >assembly language have to do with the issue?
    The issue of calculating offsets for relative branches is the
    same in Forth itself.
    If restricting yourself to emulating controled programming in
    Forth by branches and conditional branches, you have the same
    situation in assembly programming. In other words all
    information about a control flow stack can be mad to bear on it.

    Yeah, sorry, not really following your point.

    Control structures in Forth typically work by putting information on the control flow stack which is paired with another Forth word and resolved at that time. This works, because each word is defined to jump forward or backward. IF puts an item on the
    stack that THEN resolves. IF only jumps forward, ever, so the operation is straightforward. UNTIL only ever jumps backwards, so again, very straightforward.

    Branching using GOTOs with labels is much more complex, because the jump can be in either direction. Assemblers are typically implemented using tables of labels (why are they spelled differently?) so that any reference can be resolved in either
    direction, if you have multiple passes. To do this in one pass, requires tables of labels as well as tables of jumps which need to be patched up. Forth typically doesn't do either of these things.

    Do you have a simple way of handling the arbitrary nature of GOTOs and labels without multiple passes or multiple tables? Sounds complex to me.

    --

    Rick C.

    +-- Get 1,000 miles of free Supercharging
    +-- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to dxforth on Thu Mar 16 08:50:23 2023
    On Wednesday, March 15, 2023 at 8:19:13 PM UTC-4, dxforth wrote:
    On 15/03/2023 4:27 am, Lorem Ipsum wrote:
    On Tuesday, March 14, 2023 at 6:05:25 AM UTC-4, dxforth wrote:
    Add syntax sugar...

    [...]

    So this works for jumping backwards, in a way that duplicates standard control flow features. How do you jump forward? You would need a forward LABEL: and :GOTO. I guess :LABEL and GOTO: would suffice. I can see situations where you want to jump
    forward and back to the same label, so you'd need,

    GOTO> here
    blah blah blah
    <LABEL: here
    LABEL>: here_too
    blah blah blah
    <GOTO here_too

    Yes, there are reasons why gotos are seldom used in Forth... if ever. I realize my example above is absurd. But then I'm not the one who says there is much use for GOTOs. Your example above, is literally replacing BEGIN and AGAIN with other names.
    How would you create GOTO> without using a second pass? A one pass compile would need a list of GOTO>s for every label. When you encounter the LABEL>: you would need to patch up every GOTO> in that list.

    Mostly, the problem is this code would likely be large for a single definition, with all the concomitant issues.

    Minforth has shown cost isn't overwhelming so it's worth comparing against other proposed schemes such as Anton's CASE extensions - which is better value for money. Folks are free to say they have no use for any of them, which would be the most cost effective of all. Since it's been mentioned, labels for assembler are likely to cost more than structured. OTOH one can do more with them which has saved me code. Whether one can make as good a case for labels in HLL *is* the question.

    I'm not clear. Is Forth a HLL to you?

    --

    Rick C.

    -++ Get 1,000 miles of free Supercharging
    -++ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to gnuarm.deletethisbit@gmail.com on Thu Mar 16 21:00:41 2023
    In article <346f83f6-e15d-43ac-a26a-36986af36e4fn@googlegroups.com>,
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> wrote:
    <SNIP>

    Do you have a simple way of handling the arbitrary nature of GOTOs and
    labels without multiple passes or multiple tables? Sounds complex to
    me.

    It is quite simple. You mimic the control stack of Forth in assembler.
    You are likewise restricted to similar control structures as in Forth.
    I have no intention to handle arbitrary GOTOs.

    Rick C.

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Lorem Ipsum on Fri Mar 17 11:20:49 2023
    On 17/03/2023 2:50 am, Lorem Ipsum wrote:
    On Wednesday, March 15, 2023 at 8:19:13 PM UTC-4, dxforth wrote:
    ...
    Minforth has shown cost isn't overwhelming so it's worth comparing against >> other proposed schemes such as Anton's CASE extensions - which is better
    value for money. Folks are free to say they have no use for any of them,
    which would be the most cost effective of all. Since it's been mentioned,
    labels for assembler are likely to cost more than structured. OTOH one can >> do more with them which has saved me code. Whether one can make as good a
    case for labels in HLL *is* the question.

    I'm not clear. Is Forth a HLL to you?

    In Forth one programs at a higher-level than machine code. What else can it be?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to dxforth on Thu Mar 16 19:29:13 2023
    On Thursday, March 16, 2023 at 8:20:51 PM UTC-4, dxforth wrote:
    On 17/03/2023 2:50 am, Lorem Ipsum wrote:
    On Wednesday, March 15, 2023 at 8:19:13 PM UTC-4, dxforth wrote:
    ...
    Minforth has shown cost isn't overwhelming so it's worth comparing against
    other proposed schemes such as Anton's CASE extensions - which is better >> value for money. Folks are free to say they have no use for any of them, >> which would be the most cost effective of all. Since it's been mentioned, >> labels for assembler are likely to cost more than structured. OTOH one can
    do more with them which has saved me code. Whether one can make as good a >> case for labels in HLL *is* the question.

    I'm not clear. Is Forth a HLL to you?
    In Forth one programs at a higher-level than machine code. What else can it be?

    Sorry, you aren't making much sense to me. Assembly language that I've seen, has no structured flow control. You can make up macros or something, or just limit how you use jumps, but it's assembly language. It's not going to complain if you try to do
    stupid things, like jumping into the middle of an ELSE clause.

    Often, when programmers try to use goofy control flow, it's a sign of poor modularization. Using the fine scale modularization that is often used in Forth, gets around much of the issues that make people want to use GOTOs.

    --

    Rick C.

    ++- Get 1,000 miles of free Supercharging
    ++- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to none albert on Thu Mar 16 19:24:15 2023
    On Thursday, March 16, 2023 at 4:00:47 PM UTC-4, none albert wrote:
    In article <346f83f6-e15d-43ac...@googlegroups.com>,
    Lorem Ipsum <gnuarm.del...@gmail.com> wrote:
    <SNIP>

    Do you have a simple way of handling the arbitrary nature of GOTOs and >labels without multiple passes or multiple tables? Sounds complex to
    me.
    It is quite simple. You mimic the control stack of Forth in assembler.
    You are likewise restricted to similar control structures as in Forth.
    I have no intention to handle arbitrary GOTOs.

    The Forth control stack does not deal with arbitrary GOTOs, both forward and backward without some distinction, or a lot more complexity than just the control stack. There are no control flow words in Forth that can jump in either direction, that I'm
    aware of.

    Of course, you can hack a way. But it's a big, clumsy oaf of a coding solution.

    This discussion seems to have gone haywire. Sure, anything is possible. But GOTOs are just crap in Forth, just like any other language.

    --

    Rick C.

    +-+ Get 1,000 miles of free Supercharging
    +-+ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Lorem Ipsum on Fri Mar 17 14:23:26 2023
    On 17/03/2023 1:29 pm, Lorem Ipsum wrote:

    Often, when programmers try to use goofy control flow, it's a sign of poor modularization.

    Could be.

    Using the fine scale modularization that is often used in Forth, gets around much of the issues that make people want to use GOTOs.

    Baden quotes Moore as having used [ SWAP ] to do things standard conditionals couldn't. It cost Moore nothing - maybe why he was prepared to use it. Moore appears to have avoided labels e.g. assembler. As I've already eaten of that fruit, it's only my sensibilities I need to worry about.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Fox@21:1/5 to Lorem Ipsum on Thu Mar 16 22:18:56 2023
    On Thursday, March 16, 2023 at 10:29:14 PM UTC-4, Lorem Ipsum wrote:

    Sorry, you aren't making much sense to me. Assembly language that I've seen, has no structured flow control.

    Maybe you have never tried Forth Assembler?
    All Forth Assemblers that I have seen have structured branching and looping extensions
    and usually Labels as well for those sticky moments when it's faster to just jump.

    Here is -TRAILING for example in my systems Forth Assembler.

    HEX
    CODE -TRAILING ( addr len -- addr len')
    *SP TOS ADD,
    TOS DEC,
    R1 2000 LI,
    BEGIN,
    *TOS R1 CMPB,
    EQ WHILE,
    TOS DEC,
    REPEAT,
    *SP TOS SUB,
    TOS INC,
    NEXT,
    ENDCODE

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to Brian Fox on Thu Mar 16 22:49:14 2023
    On Friday, March 17, 2023 at 1:18:57 AM UTC-4, Brian Fox wrote:
    On Thursday, March 16, 2023 at 10:29:14 PM UTC-4, Lorem Ipsum wrote:

    Sorry, you aren't making much sense to me. Assembly language that I've seen, has no structured flow control.
    Maybe you have never tried Forth Assembler?
    All Forth Assemblers that I have seen have structured branching and looping extensions
    and usually Labels as well for those sticky moments when it's faster to just jump.

    Here is -TRAILING for example in my systems Forth Assembler.

    HEX
    CODE -TRAILING ( addr len -- addr len')
    *SP TOS ADD,
    TOS DEC,
    R1 2000 LI,
    BEGIN,
    *TOS R1 CMPB,
    EQ WHILE,
    TOS DEC,
    REPEAT,
    *SP TOS SUB,
    TOS INC,
    NEXT,
    ENDCODE

    Assembly code for what processor?

    --

    Rick C.

    +++ Get 1,000 miles of free Supercharging
    +++ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to Brian Fox on Thu Mar 16 23:24:46 2023
    Brian Fox schrieb am Freitag, 17. März 2023 um 06:18:57 UTC+1:
    On Thursday, March 16, 2023 at 10:29:14 PM UTC-4, Lorem Ipsum wrote:

    Sorry, you aren't making much sense to me. Assembly language that I've seen, has no structured flow control.
    Maybe you have never tried Forth Assembler?
    All Forth Assemblers that I have seen have structured branching and looping extensions
    and usually Labels as well for those sticky moments when it's faster to just jump.

    Here is -TRAILING for example in my systems Forth Assembler.

    HEX
    CODE -TRAILING ( addr len -- addr len')
    *SP TOS ADD,
    TOS DEC,
    R1 2000 LI,
    BEGIN,
    *TOS R1 CMPB,
    EQ WHILE,
    TOS DEC,
    REPEAT,
    *SP TOS SUB,
    TOS INC,
    NEXT,
    ENDCODE

    Most modern assemblers (not only in Forth) provide structured programming
    eg. as macros. It is no rocket science after all.

    I also have a working GOTO/LABEL mechanism in about 25 lines of Forth code.
    It is neither complicated nor clumsy. It works in my own Forths and with VFX/VFX64.
    A slightly different version ran with an antique gforth release on Debian.

    However portability is hampered by the fact that control flow data types in standard Forth are opaque ie. implementation dependent. See table 3.1 of
    the standard document. F.ex. newer gforths push not 1 but 3 cells on the stack while compiling BEGIN ( C: -- dest ). Other Forths that I checked use 1 or 2 cells,
    but even more 'elaborated' schemes would be allowed. That's where the clumsiness
    starts.

    Whether one has a personal use case for GOTO or not is a completely different story.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Brian Fox on Fri Mar 17 17:22:44 2023
    On 17/03/2023 4:18 pm, Brian Fox wrote:
    On Thursday, March 16, 2023 at 10:29:14 PM UTC-4, Lorem Ipsum wrote:

    Sorry, you aren't making much sense to me. Assembly language that I've seen, has no structured flow control.

    Maybe you have never tried Forth Assembler?
    All Forth Assemblers that I have seen have structured branching and looping extensions
    and usually Labels as well for those sticky moments when it's faster to just jump.

    Here is -TRAILING for example in my systems Forth Assembler.

    HEX
    CODE -TRAILING ( addr len -- addr len')
    *SP TOS ADD,
    TOS DEC,
    R1 2000 LI,
    BEGIN,
    *TOS R1 CMPB,
    EQ WHILE,
    TOS DEC,
    REPEAT,
    *SP TOS SUB,
    TOS INC,
    NEXT,
    ENDCODE

    Not faster - less effort. When I write asm I'm thinking in terms of instructions -
    not abstract control structures. It's an extra mental step to convert the instruction
    I want to use into one of these:

    NO OV U>= U< 0<> 0= U> U<= 0>= 0< PO PE >= < > <= CXNZ NEVER

    Often I use asm to save bytes. I can't do that when "the control structure says no".

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to minforth on Fri Mar 17 07:14:12 2023
    minforth <minforth@arcor.de> writes:
    F.ex. newer gforths push not 1 but 3 cells on the st=
    ack
    while compiling BEGIN ( C: -- dest ).

    Control-flow-stack items have taken 3 cells in Gforth between 1994
    (locals <http://www.complang.tuwien.ac.at/papers/ertl94l.ps.Z>) and
    2021. The first Gforth release was in 1995. In 2021
    control-flow-stack items grew to 4 cells (stack checking <http://www.euroforth.org/ef21/papers/ertl.pdf>).

    - 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: https://forth-standard.org/
    EuroForth 2022: https://euro.theforth.net

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to gnuarm.deletethisbit@gmail.com on Fri Mar 17 11:43:53 2023
    In article <3e537e06-c87e-453f-9efb-eaf943abb409n@googlegroups.com>,
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> wrote:
    On Thursday, March 16, 2023 at 4:00:47 PM UTC-4, none albert wrote:
    In article <346f83f6-e15d-43ac...@googlegroups.com>,
    Lorem Ipsum <gnuarm.del...@gmail.com> wrote:
    <SNIP>

    Do you have a simple way of handling the arbitrary nature of GOTOs and
    labels without multiple passes or multiple tables? Sounds complex to
    me.
    It is quite simple. You mimic the control stack of Forth in assembler.
    You are likewise restricted to similar control structures as in Forth.
    I have no intention to handle arbitrary GOTOs.

    The Forth control stack does not deal with arbitrary GOTOs, both
    forward and backward without some distinction, or a lot more complexity
    than just the control stack. There are no control flow words in Forth
    that can jump in either direction, that I'm aware of.

    Of course, you can hack a way. But it's a big, clumsy oaf of a coding >solution.

    This discussion seems to have gone haywire. Sure, anything is
    possible. But GOTOs are just crap in Forth, just like any other
    language.

    For your information. There is a habit in the Dutch Forth, e.g.
    Willem Ouwerkerk, Marcel Hendrix, and others to *not* implement
    jumps in assembler. Everything is done via structured assembler.

    This is some of the target assembler code for noforth:

    inside: code KEY?) ( -- f )
    tos sp -) mov #1 UARTctrl0 & bit
    #0 tos mov <>? if, #-1 tos mov then, NEXT end-code
    inside: code KEY) ( -- c )
    begin, #1 UARTctrl0 & .b bit <>? until,
    tos sp -) mov uart-in & tos .b mov NEXT end-code
    inside: code EMIT) ( c -- )
    begin, #2 UARTctrl0 & .b bit <>? until,
    tos uart-out & .b mov sp )+ tos mov NEXT end-code

    This is handled by code like this
    multi constant
    2000 =? 2400 <>? 2800 cs? 2C00 cc?
    and this
    : if, ( cond -- ifloc ifcond ) dup ?cond if,id or here swap 2 allot ;

    Why would structured programming work in Forth and not in assembler?

    Rick C.

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to minforth on Fri Mar 17 22:03:34 2023
    On 15/03/2023 9:41 pm, minforth wrote:

    P.S. unresolved GOTOs are ignored silently, to add checking, exchange

    : _RESOLVE-GOTOS ( -- )
    _#lbl 0 DO i _label() @ IF
    _#lbl 0 DO i _goto() cell+ @ j = IF
    j _label() @ i _goto() @ ! \ system specific!
    -1 i _goto() !
    THEN LOOP
    THEN LOOP
    _#lbl 0 DO i _goto() @ invert abort" unresolved goto" LOOP ;

    One loop should suffice. Scan GOTO array performing 2@. That gives label#
    and patch addr. If value is -1 exit loop; otherwise SWAP and use label# to index LABEL array then @. If value is zero then label was undefined; otherwise patch addr.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Fox@21:1/5 to Lorem Ipsum on Fri Mar 17 07:06:15 2023
    On Friday, March 17, 2023 at 1:49:15 AM UTC-4, Lorem Ipsum wrote:
    On Friday, March 17, 2023 at 1:18:57 AM UTC-4, Brian Fox wrote:
    On Thursday, March 16, 2023 at 10:29:14 PM UTC-4, Lorem Ipsum wrote:

    Sorry, you aren't making much sense to me. Assembly language that I've seen, has no structured flow control.
    Maybe you have never tried Forth Assembler?
    All Forth Assemblers that I have seen have structured branching and looping extensions
    and usually Labels as well for those sticky moments when it's faster to just jump.

    Here is -TRAILING for example in my systems Forth Assembler.

    HEX
    CODE -TRAILING ( addr len -- addr len')
    *SP TOS ADD,
    TOS DEC,
    R1 2000 LI,
    BEGIN,
    *TOS R1 CMPB,
    EQ WHILE,
    TOS DEC,
    REPEAT,
    *SP TOS SUB,
    TOS INC,
    NEXT,
    ENDCODE
    Assembly code for what processor?

    --

    Rick C.

    +++ Get 1,000 miles of free Supercharging
    +++ Tesla referral code - https://ts.la/richard11209
    Don't laugh to hard. TMS9900.

    But I have used structured Assemblers for Intel machines as well.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to dxforth on Fri Mar 17 06:36:56 2023
    dxforth schrieb am Freitag, 17. März 2023 um 12:03:35 UTC+1:
    On 15/03/2023 9:41 pm, minforth wrote:

    P.S. unresolved GOTOs are ignored silently, to add checking, exchange

    : _RESOLVE-GOTOS ( -- )
    _#lbl 0 DO i _label() @ IF
    _#lbl 0 DO i _goto() cell+ @ j = IF
    j _label() @ i _goto() @ ! \ system specific!
    -1 i _goto() !
    THEN LOOP
    THEN LOOP
    _#lbl 0 DO i _goto() @ invert abort" unresolved goto" LOOP ;

    One loop should suffice. Scan GOTO array performing 2@. That gives label# and patch addr. If value is -1 exit loop; otherwise SWAP and use label# to index LABEL array then @. If value is zero then label was undefined; otherwise
    patch addr.

    Thanks for optimizing some nanoseconds of compile time away,
    be it even by reducing code clarity. ;-)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Fox@21:1/5 to All on Fri Mar 17 07:10:45 2023
    On Friday, March 17, 2023 at 10:06:17 AM UTC-4, Brian Fox wrote:

    Just to double check since I am not in the mainstream,
    I copied these words out of the Assembler wordlist
    of a free download of SwiftForth.


    UNTIL REPEAT WHILE AGAIN BEGIN
    ELSE THEN IF
    -SHORT NOT (NOT) COND, CS? NEVER ECXNZ
    <= 0> > < >= PE PO 0< 0>= U<= U> 0= 0<> U< CC U>=

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to minforth on Sat Mar 18 01:26:10 2023
    On 18/03/2023 12:36 am, minforth wrote:
    dxforth schrieb am Freitag, 17. März 2023 um 12:03:35 UTC+1:
    On 15/03/2023 9:41 pm, minforth wrote:

    P.S. unresolved GOTOs are ignored silently, to add checking, exchange

    : _RESOLVE-GOTOS ( -- )
    _#lbl 0 DO i _label() @ IF
    _#lbl 0 DO i _goto() cell+ @ j = IF
    j _label() @ i _goto() @ ! \ system specific!
    -1 i _goto() !
    THEN LOOP
    THEN LOOP
    _#lbl 0 DO i _goto() @ invert abort" unresolved goto" LOOP ;

    One loop should suffice. Scan GOTO array performing 2@. That gives label#
    and patch addr. If value is -1 exit loop; otherwise SWAP and use label# to >> index LABEL array then @. If value is zero then label was undefined; otherwise
    patch addr.

    Thanks for optimizing some nanoseconds of compile time away,
    be it even by reducing code clarity. ;-)

    : -LABELS ( -- )
    #lbl 0 do
    i goto() 2@ -1 of drop leave then
    label() @ dup 0= abort" undef label" swap cell+ !
    loop ; immediate

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to All on Fri Mar 17 09:23:10 2023
    Just for useless puzzle playing ... :o)

    Below is a GOTO mechanism for VfxForth. IMO the test code is the more interesting thing because it covers quite a number of possible cases.
    Standard test code from file TESTER.FR is attached

    \ ###### GOTO for VfxForth using control flow items ######

    10 CONSTANT _#LBL \ max label/goto id range, 0 <= n < #lbl
    CREATE _LABELS _#LBL CELLS ALLOT \ array struct {dest}
    CREATE _GOTOS _#LBL 2* CELLS ALLOT \ queue struct {orig,id}
    : _LBL ( n -- adr ) cells _labels + ;
    : _GTO ( n -- adr ) 2* cells _gotos + ;
    : _GTID ( n -- adr ) _gto cell+ ;

    : _PARSE-ID ( "n" -- id )
    0 0 parse-name >number abort" no id number" 2drop
    dup _#lbl u< 0= abort" invalid id number" ;

    : GOTO ( "n" -- ) \ syntax GOTO <n> with 0 <= n < #lbl
    _#lbl 1- _gto @ invert abort" gotos exhausted"
    0 _gto 1 _gto _#lbl 1- 2* cells move
    _parse-id dup 0 0 _gto 2! _lbl @ ?dup
    IF postpone again -1 0 _gtid
    ELSE postpone ahead 0 _gto
    THEN ! ; IMMEDIATE

    : L: ( "n" -- ) \ label syntax L: <n> with 0 <= n < #lbl
    _parse-id dup _lbl @ abort" duplicated label"
    postpone begin over _lbl !
    _#lbl 0 DO
    i _gto @ -1 = IF leave THEN
    i _gtid @ over = IF i _gto @ postpone then -1 i _gtid ! THEN
    LOOP drop ; IMMEDIATE

    \ system integration:

    : _CLEAR-LABELS ( -- )
    _labels _#lbl cells erase _gotos _#lbl 2* cells -1 fill ; IMMEDIATE

    : _CHECK-GOTOS ( -- )
    _#lbl 0 DO i _gtid @ invert abort" unresolved goto" LOOP ; IMMEDIATE

    : : postpone _clear-labels : ;
    : ; postpone _check-gotos postpone ; ; IMMEDIATE

    1 [IF] \ ---------- TESTS ----------

    REQUIRE tester.fr \ from test suite

    T{ : GT1 \ forward
    1 goto 5 2 L: 5 3 ; -> }T
    T{ GT1 -> 1 3 }T

    T{ : GT2 \ backward
    1 goto 5 2 L: 6 3 exit 4 L: 5 goto 6 7 ; -> }T
    T{ GT2 -> 1 3 }T

    T{ : GT3 \ multiple labels ignored
    L: 3 1 L: 4 2 L: 5 ; -> }T
    T{ GT3 -> 1 2 }T

    T{ : GT4 \ cross-over
    1 goto 0 3 L: 1 4 exit 6 L: 0 2 goto 1 5 ; -> }T
    T{ GT4 -> 1 2 4 }T

    T{ : GT5 \ with IF..THEN..ELSE
    IF goto 8 1 ELSE goto 9 2 THEN 3
    L: 8 8 exit 4 L: 9 9 ; -> }T
    T{ 1 GT5 -> 8 }T
    T{ 0 GT5 -> 9 }T

    T{ : GT6 \ with BEGIN..WHILE..REPEAT
    5 BEGIN dup WHILE dup 3 = IF goto 9 THEN 1- REPEAT exit
    L: 9 9 ; -> }T
    T{ GT6 -> 3 9 }T

    T{ : GT7 \ with DO..LOOP and CASE..ENDCASE
    5 0 DO i CASE
    1 OF 11 goto 0 ENDOF
    3 OF 13 ENDOF
    ENDCASE
    L: 1
    LOOP exit
    L: 0 12 goto 1 ; -> }T
    T{ GT7 -> 11 12 13 }T

    T{ : GT8 \ multiple gotos forward
    5 0 DO i CASE
    1 OF 11 goto 0 ENDOF
    3 OF 13 goto 0 ENDOF
    ENDCASE
    L: 1
    LOOP exit
    L: 0 12 goto 1 ; -> }T
    T{ GT8 -> 11 12 13 12 }T

    T{ : GT9 \ multiple gotos backward
    5 0 DO i CASE
    1 OF 11 goto 0 ENDOF
    3 OF 13 goto 1 ENDOF
    ENDCASE
    L: 2
    LOOP exit
    L: 0 12 goto 2
    L: 1 14 goto 2 ; -> }T
    T{ GT9 -> 11 12 13 14 }T

    T{ : GT10 \ joint label forward & backward
    1
    goto 9 2
    L: 9
    IF 3 0 ELSE 4 exit 5 THEN
    goto 9 6 ; -> }T
    T{ GT10 -> 3 4 }T

    EMPTY-STACK DECIMAL

    [THEN]

    \ ########## END ##########

    att.:

    \ ========== TESTER.FR ==========

    \ (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY
    \ MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.
    \ VERSION 1.2

    HEX

    \ SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY
    \ ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG.
    VARIABLE VERBOSE
    FALSE VERBOSE !
    \ TRUE VERBOSE !

    : EMPTY-STACK \ ( ... -- ) EMPTY STACK: HANDLES UNDERFLOWED STACK TOO.
    DEPTH ?DUP IF DUP 0< IF NEGATE 0 DO 0 LOOP ELSE 0 DO DROP LOOP THEN THEN ;

    VARIABLE #ERRORS 0 #ERRORS !

    : ERROR \ ( C-ADDR U -- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY
    \ THE LINE THAT HAD THE ERROR.
    CR TYPE SOURCE TYPE \ DISPLAY LINE CORRESPONDING TO ERROR
    EMPTY-STACK \ THROW AWAY EVERY THING ELSE
    #ERRORS @ 1 + #ERRORS !
    \ QUIT \ *** Uncomment this line to QUIT on an error
    ;

    VARIABLE ACTUAL-DEPTH \ STACK RECORD
    CREATE ACTUAL-RESULTS 20 CELLS ALLOT

    : T{ \ ( -- ) SYNTACTIC SUGAR.
    ;

    : -> \ ( ... -- ) RECORD DEPTH AND CONTENT OF STACK.
    DEPTH DUP ACTUAL-DEPTH ! \ RECORD DEPTH
    ?DUP IF \ IF THERE IS SOMETHING ON STACK
    0 DO ACTUAL-RESULTS I CELLS + ! LOOP \ SAVE THEM
    THEN ;

    : }T \ ( ... -- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED
    \ (ACTUAL) CONTENTS.
    DEPTH ACTUAL-DEPTH @ = IF \ IF DEPTHS MATCH
    DEPTH ?DUP IF \ IF THERE IS SOMETHING ON THE STACK
    0 DO \ FOR EACH STACK ITEM
    ACTUAL-RESULTS I CELLS + @ \ COMPARE ACTUAL WITH EXPECTED
    = 0= IF S" INCORRECT RESULT: " ERROR LEAVE THEN
    LOOP
    THEN
    ELSE \ DEPTH MISMATCH
    S" WRONG NUMBER OF RESULTS: " ERROR
    THEN ;

    : TESTING \ ( -- ) TALKING COMMENT.
    SOURCE VERBOSE @
    IF DUP >R TYPE CR R> >IN !
    ELSE >IN ! DROP [CHAR] * EMIT
    THEN ;

    \ ========== END ==========

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to none albert on Fri Mar 17 14:09:50 2023
    On Friday, March 17, 2023 at 6:43:59 AM UTC-4, none albert wrote:
    In article <3e537e06-c87e-453f...@googlegroups.com>,
    Lorem Ipsum <gnuarm.del...@gmail.com> wrote:
    On Thursday, March 16, 2023 at 4:00:47 PM UTC-4, none albert wrote:
    In article <346f83f6-e15d-43ac...@googlegroups.com>,
    Lorem Ipsum <gnuarm.del...@gmail.com> wrote:
    <SNIP>

    Do you have a simple way of handling the arbitrary nature of GOTOs and >> >labels without multiple passes or multiple tables? Sounds complex to
    me.
    It is quite simple. You mimic the control stack of Forth in assembler.
    You are likewise restricted to similar control structures as in Forth.
    I have no intention to handle arbitrary GOTOs.

    The Forth control stack does not deal with arbitrary GOTOs, both
    forward and backward without some distinction, or a lot more complexity >than just the control stack. There are no control flow words in Forth
    that can jump in either direction, that I'm aware of.

    Of course, you can hack a way. But it's a big, clumsy oaf of a coding >solution.

    This discussion seems to have gone haywire. Sure, anything is
    possible. But GOTOs are just crap in Forth, just like any other
    language.
    For your information. There is a habit in the Dutch Forth, e.g.
    Willem Ouwerkerk, Marcel Hendrix, and others to *not* implement
    jumps in assembler. Everything is done via structured assembler.

    This is some of the target assembler code for noforth:

    inside: code KEY?) ( -- f )
    tos sp -) mov #1 UARTctrl0 & bit
    #0 tos mov <>? if, #-1 tos mov then, NEXT end-code
    inside: code KEY) ( -- c )
    begin, #1 UARTctrl0 & .b bit <>? until,
    tos sp -) mov uart-in & tos .b mov NEXT end-code
    inside: code EMIT) ( c -- )
    begin, #2 UARTctrl0 & .b bit <>? until,
    tos uart-out & .b mov sp )+ tos mov NEXT end-code

    This is handled by code like this
    multi constant
    2000 =? 2400 <>? 2800 cs? 2C00 cc?
    and this
    : if, ( cond -- ifloc ifcond ) dup ?cond if,id or here swap 2 allot ;

    Why would structured programming work in Forth and not in assembler?

    I'm not sure what you are replying to. What did I say that triggered all this?

    --

    Rick C.

    ---- Get 1,000 miles of free Supercharging
    ---- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to Brian Fox on Fri Mar 17 14:23:09 2023
    On Friday, March 17, 2023 at 10:06:17 AM UTC-4, Brian Fox wrote:
    On Friday, March 17, 2023 at 1:49:15 AM UTC-4, Lorem Ipsum wrote:
    On Friday, March 17, 2023 at 1:18:57 AM UTC-4, Brian Fox wrote:
    On Thursday, March 16, 2023 at 10:29:14 PM UTC-4, Lorem Ipsum wrote:

    Sorry, you aren't making much sense to me. Assembly language that I've seen, has no structured flow control.
    Maybe you have never tried Forth Assembler?
    All Forth Assemblers that I have seen have structured branching and looping extensions
    and usually Labels as well for those sticky moments when it's faster to just jump.

    Here is -TRAILING for example in my systems Forth Assembler.

    HEX
    CODE -TRAILING ( addr len -- addr len')
    *SP TOS ADD,
    TOS DEC,
    R1 2000 LI,
    BEGIN,
    *TOS R1 CMPB,
    EQ WHILE,
    TOS DEC,
    REPEAT,
    *SP TOS SUB,
    TOS INC,
    NEXT,
    ENDCODE
    Assembly code for what processor?

    --

    Rick C.

    +++ Get 1,000 miles of free Supercharging
    +++ Tesla referral code - https://ts.la/richard11209
    Don't laugh to hard. TMS9900.

    I used to have a couple of TMS99x processors. I bought a large PCB, 0.1" thick with the TMS9900 and I think 2708 EPROMs, a pair of course. I made a mod to work with 2716 EPROMs and planned for large parts.

    I also rolled a board with the TMS9995 and a single EPROM with some I/O to control a Selectric typewriter. But it turned out, these typewriters wear and become a bit erratic in operation. So that never panned out.

    When I started working with FPGAs, I realized the main "feature" of the TMS99x architecture, the registers in memory, was not destined for stardom. The inherent speed difference that had developed meant there was a huge performance penalty, when it was
    supposed to be a performance advantage from fast register context switches.

    Even when implemented in on-chip main storage RAM, the RAM interface presented a performance bottleneck. The speed of dedicated registers is not in the raw speed of access, but in being able to access registers in parallel with memory accesses.

    Much better is a stack oriented architecture which can have very fast access times, and have separate interfaces for as many operands as you'd like to pull off the stack at any one time. I typically split a block RAM for use as the return address stack
    and the data stack, with one hard register for the top of stack and the block RAM read ports being second on stack. This gives great performance, with address calculations done directly on the register stack.


    But I have used structured Assemblers for Intel machines as well.

    Ok

    --

    Rick C.

    ---+ Get 1,000 miles of free Supercharging
    ---+ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to minforth on Sat Mar 18 10:30:32 2023
    On 18/03/2023 3:23 am, minforth wrote:
    Just for useless puzzle playing ... :o)

    Below is a GOTO mechanism for VfxForth. IMO the test code is the more interesting thing because it covers quite a number of possible cases. Standard test code from file TESTER.FR is attached

    \ ###### GOTO for VfxForth using control flow items ######

    Resolving GOTOs on the fly results in less table usage at the expense
    of more code. I preferred the original strategy (though not the GOTO resolution which was pointlessly backwards). As there are usually more
    GOTO than labels I changed the proportions. Got mine down to 352 bytes
    (6 labels, 10 GOTO) ... about what it's worth. It will now go into a
    file with other miscellaneous routines along with the ANS CS words.
    Itch scratched.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Marcel Hendrix@21:1/5 to Brian Fox on Sat Mar 18 08:11:38 2023
    On Saturday, March 18, 2023 at 3:49:04 PM UTC+1, Brian Fox wrote:
    [..]
    I don't know CPU design, but I wonder if a Forth style processor, would benefit from a
    "workspace" register for fast context switching within the memory blocks used for the
    stacks. I suppose each workspace would need to hold the IP,SP,RP register values.
    If those registers were actually running in the fast stack RAM it should allow a fast,
    one register context switch.

    That is how INMOS's transputer worked. We wrote tForth for it, and it was, for a (very small) timewindow, quite hot. I lost interest when the T9000 did not materialize. I guess the transputer's ideas (1. CSP, 2. I/O should scale with computing horsepower) will resurface.

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Fox@21:1/5 to Lorem Ipsum on Sat Mar 18 07:49:02 2023
    On Friday, March 17, 2023 at 5:23:10 PM UTC-4, Lorem Ipsum wrote:

    Don't laugh to hard. TMS9900.
    I used to have a couple of TMS99x processors. I bought a large PCB, 0.1" thick with the TMS9900 and I think 2708 EPROMs, a pair of course. I made a mod to work with 2716 EPROMs and planned for large parts.

    I also rolled a board with the TMS9995 and a single EPROM with some I/O to control a Selectric typewriter. But it turned out, these typewriters wear and become a bit erratic in operation. So that never panned out.

    When I started working with FPGAs, I realized the main "feature" of the TMS99x architecture, the registers in memory, was not destined for stardom. The inherent speed difference that had developed meant there was a huge performance penalty, when it was
    supposed to be a performance advantage from fast register context switches.

    Even when implemented in on-chip main storage RAM, the RAM interface presented a performance bottleneck. The speed of dedicated registers is not in the raw speed of access, but in being able to access registers in parallel with memory accesses.

    Much better is a stack oriented architecture which can have very fast access times, and have separate interfaces for as many operands as you'd like to pull off the stack at any one time. I typically split a block RAM for use as the return address stack
    and the data stack, with one hard register for the top of stack and the block RAM read ports being second on stack. This gives great performance, with address calculations done directly on the register stack.

    That's a pretty clever design for I/O intensive applications. Neat.
    For clarity, the 2nd on stack doubles as the stack item or it can read I/O?
    Is there a bit switch somewhere to change its function to read to stack?

    Cool that you know the 9900. Yes the "workspace" concept was intriguing 50 years ago but
    in retrospect it was not the solution to the problem of sub-routine nesting. Stacks win that one.
    But it is amazing for context switching.

    I don't know CPU design, but I wonder if a Forth style processor, would benefit from a
    "workspace" register for fast context switching within the memory blocks used for the
    stacks. I suppose each workspace would need to hold the IP,SP,RP register values.
    If those registers were actually running in the fast stack RAM it should allow a fast,
    one register context switch.

    Would using stack RAM for the primary registers be to much performance hit?

    Of course it might be better to just make more small cores. :-)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Fox@21:1/5 to Brian Fox on Sat Mar 18 08:12:36 2023
    On Saturday, March 18, 2023 at 10:49:04 AM UTC-4, Brian Fox wrote:
    On Friday, March 17, 2023 at 5:23:10 PM UTC-4, Lorem Ipsum wrote:

    Don't laugh to hard. TMS9900.
    I used to have a couple of TMS99x processors. I bought a large PCB, 0.1" thick with the TMS9900 and I think 2708 EPROMs, a pair of course. I made a mod to work with 2716 EPROMs and planned for large parts.

    I also rolled a board with the TMS9995 and a single EPROM with some I/O to control a Selectric typewriter. But it turned out, these typewriters wear and become a bit erratic in operation. So that never panned out.

    When I started working with FPGAs, I realized the main "feature" of the TMS99x architecture, the registers in memory, was not destined for stardom. The inherent speed difference that had developed meant there was a huge performance penalty, when it
    was supposed to be a performance advantage from fast register context switches.

    Even when implemented in on-chip main storage RAM, the RAM interface presented a performance bottleneck. The speed of dedicated registers is not in the raw speed of access, but in being able to access registers in parallel with memory accesses.

    Much better is a stack oriented architecture which can have very fast access times, and have separate interfaces for as many operands as you'd like to pull off the stack at any one time. I typically split a block RAM for use as the return address
    stack and the data stack, with one hard register for the top of stack and the block RAM read ports being second on stack. This gives great performance, with address calculations done directly on the register stack.
    That's a pretty clever design for I/O intensive applications. Neat.
    For clarity, the 2nd on stack doubles as the stack item or it can read I/O? Is there a bit switch somewhere to change its function to read to stack?

    Cool that you know the 9900. Yes the "workspace" concept was intriguing 50 years ago but
    in retrospect it was not the solution to the problem of sub-routine nesting. Stacks win that one.
    But it is amazing for context switching.

    I don't know CPU design, but I wonder if a Forth style processor, would benefit from a
    "workspace" register for fast context switching within the memory blocks used for the
    stacks. I suppose each workspace would need to hold the IP,SP,RP register values.
    If those registers were actually running in the fast stack RAM it should allow a fast,
    one register context switch.

    Would using stack RAM for the primary registers be to much performance hit?

    Of course it might be better to just make more small cores. :-)

    "Even when implemented in on-chip main storage RAM, the RAM interface presented
    a performance bottleneck. The speed of dedicated registers is not in the raw speed
    of access, but in being able to access registers in parallel with memory accesses."

    I should have read your post slower. Here is my answer. :-)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Fox@21:1/5 to Marcel Hendrix on Sat Mar 18 08:14:15 2023
    On Saturday, March 18, 2023 at 11:11:40 AM UTC-4, Marcel Hendrix wrote:
    On Saturday, March 18, 2023 at 3:49:04 PM UTC+1, Brian Fox wrote:
    [..]
    I don't know CPU design, but I wonder if a Forth style processor, would benefit from a
    "workspace" register for fast context switching within the memory blocks used for the
    stacks. I suppose each workspace would need to hold the IP,SP,RP register values.
    If those registers were actually running in the fast stack RAM it should allow a fast,
    one register context switch.
    That is how INMOS's transputer worked. We wrote tForth for it, and it was, for
    a (very small) timewindow, quite hot. I lost interest when the T9000 did not materialize. I guess the transputer's ideas (1. CSP, 2. I/O should scale with
    computing horsepower) will resurface.

    -marcel
    Ok. Thanks for that insight. Nice to know that some of my thoughts have merit. :-)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jan Coombs@21:1/5 to Brian Fox on Sat Mar 18 15:28:53 2023
    On Sat, 18 Mar 2023 07:49:02 -0700 (PDT)
    Brian Fox <brian.fox@brianfox.ca> wrote:

    [...]
    I don't know CPU design, but I wonder if a Forth style processor, would benefit from a
    "workspace" register for fast context switching within the memory blocks used for the
    stacks. I suppose each workspace would need to hold the IP,SP,RP register values.
    If those registers were actually running in the fast stack RAM it should allow a fast,
    one register context switch.
    The smallest FPGA RAM blocks are ~256 x 16b, and using a RAM block for each stack is likely, so a 2-4b task register could support 4-16 tasks/contexts.

    Would using stack RAM for the primary registers be to much performance hit?
    The primary registers would then most likely need to be pushed sequentially
    to stacks, as in software implementations

    Of course it might be better to just make more small cores. :-)
    Probably not in FPGA, because of the size of the on-chip RAM blocks.

    Jan Coombs
    --

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to Marcel Hendrix on Sat Mar 18 09:50:18 2023
    On Saturday, March 18, 2023 at 11:11:40 AM UTC-4, Marcel Hendrix wrote:
    On Saturday, March 18, 2023 at 3:49:04 PM UTC+1, Brian Fox wrote:
    [..]
    I don't know CPU design, but I wonder if a Forth style processor, would benefit from a
    "workspace" register for fast context switching within the memory blocks used for the
    stacks. I suppose each workspace would need to hold the IP,SP,RP register values.
    If those registers were actually running in the fast stack RAM it should allow a fast,
    one register context switch.
    That is how INMOS's transputer worked. We wrote tForth for it, and it was, for
    a (very small) timewindow, quite hot. I lost interest when the T9000 did not materialize. I guess the transputer's ideas (1. CSP, 2. I/O should scale with
    computing horsepower) will resurface.

    Don't bet on it. If there were value to these ideas, they would have come back long ago.

    Many years ago (maybe 25?) I worked on a government project for a DSP application that used Transputers. At first they were going to use COTS computer boards with conventional software. Someone convinced them to use Transputers. It was a large system
    with dozens of processors. I believe it was delivered, but it was to a community where you never hear about it again. I don't think Transputers were used again. At least I didn't hear about them. Without continuing advancements in the devices, there
    is never a future in alternative architectures. I think they ran at 25 MHz. How long was that a cutting edge clock rate? I suppose you could emulate a few dozen of them in an FPGA for less than the chips cost back then.

    Hmmm... I still have one or two of those, somewhere. I remember they came with a fractal program which I didn't understand. Someone in a Google Group explained the colors represent the number of calculation cycles it takes to arrive at a stable value
    or running off to infinity giving black.

    I expect there's a game of Life out there somewhere. Isn't Life on every CPU ever made?

    --

    Rick C.

    --++ Get 1,000 miles of free Supercharging
    --++ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to Brian Fox on Sat Mar 18 09:34:02 2023
    On Saturday, March 18, 2023 at 10:49:04 AM UTC-4, Brian Fox wrote:
    On Friday, March 17, 2023 at 5:23:10 PM UTC-4, Lorem Ipsum wrote:

    Don't laugh to hard. TMS9900.
    I used to have a couple of TMS99x processors. I bought a large PCB, 0.1" thick with the TMS9900 and I think 2708 EPROMs, a pair of course. I made a mod to work with 2716 EPROMs and planned for large parts.

    I also rolled a board with the TMS9995 and a single EPROM with some I/O to control a Selectric typewriter. But it turned out, these typewriters wear and become a bit erratic in operation. So that never panned out.

    When I started working with FPGAs, I realized the main "feature" of the TMS99x architecture, the registers in memory, was not destined for stardom. The inherent speed difference that had developed meant there was a huge performance penalty, when it
    was supposed to be a performance advantage from fast register context switches.

    Even when implemented in on-chip main storage RAM, the RAM interface presented a performance bottleneck. The speed of dedicated registers is not in the raw speed of access, but in being able to access registers in parallel with memory accesses.

    Much better is a stack oriented architecture which can have very fast access times, and have separate interfaces for as many operands as you'd like to pull off the stack at any one time. I typically split a block RAM for use as the return address
    stack and the data stack, with one hard register for the top of stack and the block RAM read ports being second on stack. This gives great performance, with address calculations done directly on the register stack.
    That's a pretty clever design for I/O intensive applications. Neat.
    For clarity, the 2nd on stack doubles as the stack item or it can read I/O? Is there a bit switch somewhere to change its function to read to stack?

    Sorry, I don't understand the questions. I think you have a wrong image in mind. The block RAM has two ports, both Read/Write. I use the same block RAM for both return (I call it "address" since it is also used for address calculations in memory
    access such as @ and !) and data stacks. This is the second item on the stack. Then there are registers for the first item on each stack.

    I don't recall if the input to the stack is muxed with anything. I know the first on stack register has to be a source. The first on stack registers have lots of things muxed into it. This is one of the performance limiting parts of the design, the
    input mux to the stack. Lots of delay in this. I could reduce this by eliminating inputs by loading them into a temporary register or something, or just eliminating the instructions that use the path. Many processor designs have instructions that
    really are not used very often. Trade off between speeding up one function, and slowing the clock cycle that impacts every operation.


    Cool that you know the 9900. Yes the "workspace" concept was intriguing 50 years ago but
    in retrospect it was not the solution to the problem of sub-routine nesting. Stacks win that one.
    But it is amazing for context switching.

    The instruction set was from the 990 minicomputer, which was made with TTL chips. I think there was much less penalty in that case, or maybe it was a matter of cost. Minicomputers were very cost sensitive. Companies were starting to buy their own
    machines, rather than using computing services.


    I don't know CPU design, but I wonder if a Forth style processor, would benefit from a
    "workspace" register for fast context switching within the memory blocks used for the
    stacks. I suppose each workspace would need to hold the IP,SP,RP register values.
    If those registers were actually running in the fast stack RAM it should allow a fast,
    one register context switch.

    I've seen that used in two ways. One, like in my design, uses separate stacks for each level of interrupt and the main application. They are not deep, some 16 or 32 deep. This is done by setting the upper bits of the RAM from the small register that
    indicates the current interrupt being processed, or zero for the main task. As far as the software is concerned, it is N CPUs with no interaction other than by passing messages through RAM. BTW, the stack RAM is the same block RAM as the main memory.
    The main memory just uses more of them. It would be silly to try to couple slow external memory to a fast internal processor. In that case, just use an external processor.

    The other is in a pipelined design, that treats it as multiple processors. Have an eight stage pipeline and treat it as 8 processors. This lets you speed up the clock, significantly. Each processor may run slower, but the aggregate speed is higher.
    With pipeline numbers of two or four, the higher aggregate clock speed nearly makes up for the separate processors being slower. But it means the processor has a 1 to N clock interrupt response time. Without pipelining, the response time can be held to
    1 clock cycle always, even if a slower clock.


    Would using stack RAM for the primary registers be to much performance hit?

    I'm talking about a stack processor which has no registers other than the stacks, the program counter, the instruction register and the individual bits that make up the processor status word. There's no real performance hit from this in an FPGA. The
    first on stack *is* a register, and the block RAM is pretty fast for writing and not slow for reading if it is clocked on the output.


    Of course it might be better to just make more small cores. :-)

    Better than what, the pipelined design? The idea is that many designs need processing, but often have limited LUTs. The design I'm working on now will have around 13 kLUTs and will be the largest chip I've worked with in two decades. The FPGA that is
    being replaced only has 3,000 LUTs. Oddly enough, the 13 and 20 kLUT parts I'm considering are about the same price (if I could still buy the old part) and are the bargain basement devices of any I've found, other than Gowin devices, which I'm not
    allowed to use (Chinese supplier and this product is often sold to the US government).

    I think the idea of the time sliced processor is a poor man's way to get multiprocessing, without the hassle of writing multiprocessing software. It's really multiple processors using not many more LUTs than a single processor, and giving a higher
    instruction throughput to boot.

    --

    Rick C.

    --+- Get 1,000 miles of free Supercharging
    --+- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to Lorem Ipsum on Sat Mar 18 11:21:16 2023
    Lorem Ipsum schrieb am Samstag, 18. März 2023 um 17:50:20 UTC+1:
    On Saturday, March 18, 2023 at 11:11:40 AM UTC-4, Marcel Hendrix wrote:
    On Saturday, March 18, 2023 at 3:49:04 PM UTC+1, Brian Fox wrote:
    [..]
    I don't know CPU design, but I wonder if a Forth style processor, would benefit from a
    "workspace" register for fast context switching within the memory blocks used for the
    stacks. I suppose each workspace would need to hold the IP,SP,RP register values.
    If those registers were actually running in the fast stack RAM it should allow a fast,
    one register context switch.
    That is how INMOS's transputer worked. We wrote tForth for it, and it was, for
    a (very small) timewindow, quite hot. I lost interest when the T9000 did not
    materialize. I guess the transputer's ideas (1. CSP, 2. I/O should scale with
    computing horsepower) will resurface.
    Don't bet on it. If there were value to these ideas, they would have come back long ago.

    Many years ago (maybe 25?) I worked on a government project for a DSP application that used Transputers. At first they were going to use COTS computer boards with conventional software. Someone convinced them to use Transputers. It was a large system
    with dozens of processors. I believe it was delivered, but it was to a community where you never hear about it again. I don't think Transputers were used again. At least I didn't hear about them. Without continuing advancements in the devices, there is
    never a future in alternative architectures. I think they ran at 25 MHz. How long was that a cutting edge clock rate? I suppose you could emulate a few dozen of them in an FPGA for less than the chips cost back then.

    Hmmm... I still have one or two of those, somewhere. I remember they came with a fractal program which I didn't understand. Someone in a Google Group explained the colors represent the number of calculation cycles it takes to arrive at a stable value
    or running off to infinity giving black.

    I expect there's a game of Life out there somewhere. Isn't Life on every CPU ever made?

    Most probably Mandelbrot. Back then it had been the standard demo for parallel processing.

    Here's an old (serial) Forth gem:

    \ http://sametwice.com/8_line_mandelbrot
    \ 8 line mandelbrot
    fvariable ci fvariable c fvariable zi fvariable z
    : f> f< not ;
    : >2? z f@ fdup f* zi f@ fdup f* f+ 4.0e f> ;
    : nextr z f@ fdup f* zi f@ fdup f* f- c f@ f+ ;
    : nexti z f@ zi f@ f* 2.0e f* ci f@ f+ ;
    : pixel c f! ci f! 0e z f! 0e zi f! 150 50 do nextr nexti zi f! z f! >2? if i unloop exit then loop bl ;
    : left->right -1.5e 80 0 do fover fover pixel emit 0.026e f+ loop fdrop ;
    : top->bottom -1e 40 0 do left->right cr 0.05e f+ loop fdrop ;
    cr top->bottom \ bye

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Brian Fox@21:1/5 to Lorem Ipsum on Sat Mar 18 13:07:56 2023
    On Saturday, March 18, 2023 at 12:34:04 PM UTC-4, Lorem Ipsum wrote:
    Would using stack RAM for the primary registers be to much performance hit?
    snip>
    I'm talking about a stack processor which has no registers other than the stacks,
    the program counter, the instruction register and the individual bits that make up
    the processor status word. There's no real performance hit from this in an FPGA.
    The first on stack *is* a register, and the block RAM is pretty fast for writing and
    not slow for reading if it is clocked on the output.
    <snip>

    Thanks for the clarification on the rest.

    So we have top of the DATA stack in a register. Got that part.

    But how does the machine know what is the "next on stack" location in the block RAM?
    My little brain thinks it needs a register somewhere to hold an index value or a circular counter or something like that.
    Same question for the return stack.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to Brian Fox on Sat Mar 18 14:49:50 2023
    On Saturday, March 18, 2023 at 4:07:58 PM UTC-4, Brian Fox wrote:
    On Saturday, March 18, 2023 at 12:34:04 PM UTC-4, Lorem Ipsum wrote:
    Would using stack RAM for the primary registers be to much performance hit?
    snip>
    I'm talking about a stack processor which has no registers other than the stacks,
    the program counter, the instruction register and the individual bits that make up
    the processor status word. There's no real performance hit from this in an FPGA.
    The first on stack *is* a register, and the block RAM is pretty fast for writing and
    not slow for reading if it is clocked on the output.
    <snip>

    Thanks for the clarification on the rest.

    So we have top of the DATA stack in a register. Got that part.

    But how does the machine know what is the "next on stack" location in the block RAM?
    My little brain thinks it needs a register somewhere to hold an index value or
    a circular counter or something like that.
    Same question for the return stack.

    Yes, there are stack pointers, up/down counters. They can either be accessible to be read/written, or not, depending on the designer. The only reason for accessing the stack pointer from the code, is to tell when the stack is empty for error detection..
    . overflow/underflow. That can also be done with an non-maskable interrupt. When you get a stack over/underflow error, there's no point in continuing.

    Stacks don't really need to be very deep in Forth. A five or six bit pointer is plenty, 32 or 64 stack items. Overkill actually.

    --

    Rick C.

    -+-- Get 1,000 miles of free Supercharging
    -+-- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Hans Bezemer on Sun Mar 19 12:04:57 2023
    On 13/03/2023 9:30 pm, Hans Bezemer wrote:

    I find Antons CONTOF intriguing, though. Gotta contemplate that one a bit.

    It's syntax sugar for:

    BEGIN BEGIN BEGIN ( BEGIN)

    WHILE ... REPEAT

    WHILE ... REPEAT

    WHILE ... REPEAT

    ...

    ( AGAIN)

    Another itch scratched?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to dxforth on Sun Mar 19 05:53:33 2023
    dxforth schrieb am Samstag, 18. März 2023 um 00:30:32 UTC+1:
    On 18/03/2023 3:23 am, minforth wrote:
    Just for useless puzzle playing ... :o)

    Below is a GOTO mechanism for VfxForth. IMO the test code is the more interesting thing because it covers quite a number of possible cases. Standard test code from file TESTER.FR is attached

    \ ###### GOTO for VfxForth using control flow items ######
    Resolving GOTOs on the fly results in less table usage at the expense
    of more code. I preferred the original strategy (though not the GOTO resolution which was pointlessly backwards). As there are usually more
    GOTO than labels I changed the proportions. Got mine down to 352 bytes
    (6 labels, 10 GOTO) ... about what it's worth. It will now go into a
    file with other miscellaneous routines along with the ANS CS words.
    Itch scratched.

    Got an overdose of itching powder? :o)

    There's a bit more scratching in the background of the GOTO/LABEL mechanism.
    It lays the groundwork to simply add nested functions or closures to Forth without changing the internal compiler. Just imagine GOTO not compiling
    a branch but a colon plus upvalues, and LABEL a semis and some cleanup.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to gnuarm.deletethisbit@gmail.com on Sun Mar 19 13:56:31 2023
    In article <694431bd-9ae2-4ed9-b336-e513f09f5078n@googlegroups.com>,
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> wrote:
    On Saturday, March 18, 2023 at 11:11:40 AM UTC-4, Marcel Hendrix wrote:
    On Saturday, March 18, 2023 at 3:49:04 PM UTC+1, Brian Fox wrote:
    [..]
    I don't know CPU design, but I wonder if a Forth style processor,
    would benefit from a
    "workspace" register for fast context switching within the memory
    blocks used for the
    stacks. I suppose each workspace would need to hold the IP,SP,RP
    register values.
    If those registers were actually running in the fast stack RAM it
    should allow a fast,
    one register context switch.
    That is how INMOS's transputer worked. We wrote tForth for it, and it
    was, for
    a (very small) timewindow, quite hot. I lost interest when the T9000 did not >> materialize. I guess the transputer's ideas (1. CSP, 2. I/O should
    scale with
    computing horsepower) will resurface.

    Don't bet on it. If there were value to these ideas, they would have
    come back long ago.

    There are important counter examples for this. The USA should have
    50 year head start in Thorium reactors, now they are 10 years
    behind China. The wave around 3D printing started 20 years late,
    because the patent holders were holding back.
    Remember white leds? These were following blue leds. An obstinate
    Japanese inventor took the job on. Now white leds are everywhere.
    We are stuck with USA fighter jets in Europe. The fighter jets
    designed by Europeans were much better, but politics got in the way.

    I agree with Marcel Hendrix that a 1Ghz transputer is an opportunity
    that a venture capitalist should jump at. With a considerable
    chance of succes. Remember there are no real processors going substantially going beyond 1 Ghz. Supercomputers are parallel, AMD/INTEL or now ARM.
    So transputers with an inherent superior connectivity, and a
    corresponding software development could win the day. It boggles the
    mind what could have been 30 years of improvement to the t900.

    Many years ago (maybe 25?) I worked on a government project for a DSP >application that used Transputers. At first they were going to use
    COTS computer boards with conventional software. Someone convinced
    them to use Transputers. It was a large system with dozens of
    processors. I believe it was delivered, but it was to a community
    where you never hear about it again. I don't think Transputers were
    used again. At least I didn't hear about them. Without continuing >advancements in the devices, there is never a future in alternative >architectures. I think they ran at 25 MHz. How long was that a
    cutting edge clock rate? I suppose you could emulate a few dozen of
    them in an FPGA for less than the chips cost back then.

    In 1990 I was at Shell, geological modelling. The functionality
    presented by transputers was comparable with the CRAY.
    (they had one there in Rijswijk). The transputers were at a cost
    in order of magnitude lower.

    <SNIP>

    Rick C.

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to none albert on Sun Mar 19 07:35:38 2023
    On Sunday, March 19, 2023 at 8:56:35 AM UTC-4, none albert wrote:
    In article <694431bd-9ae2-4ed9...@googlegroups.com>,
    Lorem Ipsum <gnuarm.del...@gmail.com> wrote:
    On Saturday, March 18, 2023 at 11:11:40 AM UTC-4, Marcel Hendrix wrote: >> On Saturday, March 18, 2023 at 3:49:04 PM UTC+1, Brian Fox wrote:
    [..]
    I don't know CPU design, but I wonder if a Forth style processor, >would benefit from a
    "workspace" register for fast context switching within the memory >blocks used for the
    stacks. I suppose each workspace would need to hold the IP,SP,RP >register values.
    If those registers were actually running in the fast stack RAM it >should allow a fast,
    one register context switch.
    That is how INMOS's transputer worked. We wrote tForth for it, and it >was, for
    a (very small) timewindow, quite hot. I lost interest when the T9000 did not
    materialize. I guess the transputer's ideas (1. CSP, 2. I/O should
    scale with
    computing horsepower) will resurface.

    Don't bet on it. If there were value to these ideas, they would have
    come back long ago.
    There are important counter examples for this. The USA should have
    50 year head start in Thorium reactors, now they are 10 years
    behind China. The wave around 3D printing started 20 years late,
    because the patent holders were holding back.
    Remember white leds? These were following blue leds. An obstinate
    Japanese inventor took the job on. Now white leds are everywhere.
    We are stuck with USA fighter jets in Europe. The fighter jets
    designed by Europeans were much better, but politics got in the way.

    None of this is remotely relevant. Why ramble on like this?


    I agree with Marcel Hendrix that a 1Ghz transputer is an opportunity
    that a venture capitalist should jump at. With a considerable
    chance of succes.

    Based on what exactly? Is this like people who think Forth is a magical language that can solve all problems in computing?


    Remember there are no real processors going substantially
    going beyond 1 Ghz.

    What makes you think the Transputer would be any better at 1 GHz than any other processor?


    Supercomputers are parallel, AMD/INTEL or now ARM.

    ??? My car is electric. So?


    So transputers with an inherent superior connectivity, and a
    corresponding software development could win the day.

    You start off with an unproven assumption and you try to draw conclusions. There's no connection between Transputers and automatic success. The Transputer "connectivity" is at a very low level and would not have scaled with the processor speed. The
    real problem in connectivity in a massively parallel computer, is the shear number of connections, not the speed of any one connection.

    The GA144 has 144 small, very fast (700 MIPS) processors on a single die. Each processor has a direct connection to it's four neighbors. That's not a good model for connectivity. The chip is a total flop, and not the good FLOP.


    It boggles the
    mind what could have been 30 years of improvement to the t900.

    No, it's not remotely mind boggling, at least to me. Maybe I don't boggle so easily.


    Many years ago (maybe 25?) I worked on a government project for a DSP >application that used Transputers. At first they were going to use
    COTS computer boards with conventional software. Someone convinced
    them to use Transputers. It was a large system with dozens of
    processors. I believe it was delivered, but it was to a community
    where you never hear about it again. I don't think Transputers were
    used again. At least I didn't hear about them. Without continuing >advancements in the devices, there is never a future in alternative >architectures. I think they ran at 25 MHz. How long was that a
    cutting edge clock rate? I suppose you could emulate a few dozen of
    them in an FPGA for less than the chips cost back then.
    In 1990 I was at Shell, geological modelling. The functionality
    presented by transputers was comparable with the CRAY.
    (they had one there in Rijswijk). The transputers were at a cost
    in order of magnitude lower.

    In the late 80s the state of the art CPU was the Intel 486. I worked at a facility that made supercomputers, in Herndon, VA., 100 MFLOPS. We sold many machines to the geophysical modeling industry, mostly to support oil exploration. Transputers were
    not relevant to that industry. There was zero software to support using Transputers as supercomputers. It was some years later when I worked on the multiprocessor Transputer design that had to write all the software from the ground up.

    That has always been a limitation of using large numbers of small CPUs to run massive calculations, the inter-processor comms. It's a bitch. There's nothing magical about the Transputer in that regard.

    --

    Rick C.

    -+-+ Get 1,000 miles of free Supercharging
    -+-+ Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to minforth on Mon Mar 20 10:39:44 2023
    On 19/03/2023 11:53 pm, minforth wrote:
    dxforth schrieb am Samstag, 18. März 2023 um 00:30:32 UTC+1:
    On 18/03/2023 3:23 am, minforth wrote:
    Just for useless puzzle playing ... :o)

    Below is a GOTO mechanism for VfxForth. IMO the test code is the more
    interesting thing because it covers quite a number of possible cases.
    Standard test code from file TESTER.FR is attached

    \ ###### GOTO for VfxForth using control flow items ######
    Resolving GOTOs on the fly results in less table usage at the expense
    of more code. I preferred the original strategy (though not the GOTO
    resolution which was pointlessly backwards). As there are usually more
    GOTO than labels I changed the proportions. Got mine down to 352 bytes
    (6 labels, 10 GOTO) ... about what it's worth. It will now go into a
    file with other miscellaneous routines along with the ANS CS words.
    Itch scratched.

    Got an overdose of itching powder? :o)

    There's a bit more scratching in the background of the GOTO/LABEL mechanism. It lays the groundwork to simply add nested functions or closures to Forth without changing the internal compiler. Just imagine GOTO not compiling
    a branch but a colon plus upvalues, and LABEL a semis and some cleanup.

    I don't have those itches. I doubt I'll use what I wrote. I was able to reduce my assembler labels code somewhat based on your method of adding
    goto's so that was a useful outcome.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to gnuarm.deletethisbit@gmail.com on Mon Mar 20 12:37:46 2023
    In article <0ea8ed03-4da5-4a42-a561-b354070c44b6n@googlegroups.com>,
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> wrote:

    In the late 80s the state of the art CPU was the Intel 486. I worked at a facility that made supercomputers, in Herndon, VA., 100 MFLOPS. We sold many
    machines to the geophysical modeling industry, mostly to support oil exploration. Transputers were not relevant to that industry. There was zero software
    to support using Transputers as supercomputers. It was some years later when I worked on the multiprocessor Transputer design that had to write all the
    software from the ground up.

    I worked at Rijswijk the most important research centre of Shell worldwide,
    at geological modelling with transputers in 1990.
    I can testify that transputers were relevant. Of course it was bleeding edge and it was developed there and then. The models were certainly more
    advanced than what you're working at, but at I'm not at liberty to
    disclose details. The oil fields in the North Sea are stratified in a complicated way, more so that e.g. Nigeria.
    Color was essential, but not readily available on the VAX at this time.
    The project was important enough that Shell put extreme pressure on DEC
    for cooperation, cancelling orders.

    Rick C.

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lorem Ipsum@21:1/5 to none albert on Mon Mar 20 22:31:48 2023
    On Monday, March 20, 2023 at 7:37:50 AM UTC-4, none albert wrote:
    In article <0ea8ed03-4da5-4a42...@googlegroups.com>,
    Lorem Ipsum <gnuarm.del...@gmail.com> wrote:

    In the late 80s the state of the art CPU was the Intel 486. I worked at a facility that made supercomputers, in Herndon, VA., 100 MFLOPS. We sold many
    machines to the geophysical modeling industry, mostly to support oil exploration. Transputers were not relevant to that industry. There was zero software
    to support using Transputers as supercomputers. It was some years later when I worked on the multiprocessor Transputer design that had to write all the
    software from the ground up.
    I worked at Rijswijk the most important research centre of Shell worldwide, at geological modelling with transputers in 1990.
    I can testify that transputers were relevant. Of course it was bleeding edge and it was developed there and then. The models were certainly more
    advanced than what you're working at, but at I'm not at liberty to
    disclose details. The oil fields in the North Sea are stratified in a complicated way, more so that e.g. Nigeria.
    Color was essential, but not readily available on the VAX at this time.
    The project was important enough that Shell put extreme pressure on DEC
    for cooperation, cancelling orders.

    So Transputers were so relevant, that one lab, in a corner of Scandinavia (I'm guessing) worked with them for awhile. But they failed to advance in any significant way, and became quickly obsolete.

    I guess they provided some useful processing, but this barely made a blip on the radar screen of geophysical processing, I think. No?

    --

    Rick C.

    -++- Get 1,000 miles of free Supercharging
    -++- Tesla referral code - https://ts.la/richard11209

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to Marcel Hendrix on Sun Apr 2 17:24:12 2023
    Marcel Hendrix <mhx@iae.nl> writes:
    I guess the transputer's ideas (1. CSP, 2. I/O should scale w=
    ith
    computing horsepower) will resurface.

    1. The parallel and concurrent programming landscape seems to be quite fragmented (starting with the fragmentation between "parallel" and "concurrent"), but I don't see much stuff there that I would classify
    as CSP. Some of the parallel stuff can be likened to Occam's PAR
    statement, and the channels may be likened to pipelines and FIFOs, but
    the latter is more in the concurrent world. I am not an expert, but I
    don't have the impression that the particular combination of features
    in CSP or Occam is particularly relevant.

    A big downside of the transputer approach is that it has distributed
    memory (each CPU has its own memory and cannot access other CPU's
    memory). While the largest supercomputers use distributed memory,
    they have nodes with hundreds of CPU cores sharing a big memory; and
    anyway, supercomputers often live with restrictions that are
    unacceptable in the wider computing world. Large servers always have
    shared memory.

    2. It seems to me that I/O has been scaled as necessary (and
    economical), no need for anything to resurface.

    - 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: https://forth-standard.org/
    EuroForth 2022: https://euro.theforth.net

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxforth on Sun Apr 2 17:19:56 2023
    dxforth <dxforth@gmail.com> writes:
    On 13/03/2023 9:30 pm, Hans Bezemer wrote:

    I find Antons CONTOF intriguing, though. Gotta contemplate that one a bit.

    It's syntax sugar for:

    BEGIN BEGIN BEGIN ( BEGIN)

    WHILE ... REPEAT

    WHILE ... REPEAT

    WHILE ... REPEAT

    ...

    ( AGAIN)


    Only if you don't use ENDOF nor ENDCASE. But yes, you can transform
    Eaker's CASE into IF ELSE THEN, and Eaker's CASE extended with ?OF,
    CONTOF, and NEXT-CASE into standard Forth code. I find the extended
    Eaker's CASE easier to write and read, however.

    - 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: https://forth-standard.org/
    EuroForth 2022: https://euro.theforth.net

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to albert@cherry. on Sun Apr 2 17:42:17 2023
    albert@cherry.(none) (albert) writes:
    In article <694431bd-9ae2-4ed9-b336-e513f09f5078n@googlegroups.com>,
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> wrote:
    On Saturday, March 18, 2023 at 11:11:40 AM UTC-4, Marcel Hendrix wrote:
    That is how INMOS's transputer worked. We wrote tForth for it, and it >>was, for
    a (very small) timewindow, quite hot. I lost interest when the T9000 did not
    materialize. I guess the transputer's ideas (1. CSP, 2. I/O should
    scale with
    computing horsepower) will resurface.

    Don't bet on it. If there were value to these ideas, they would have
    come back long ago.

    There are important counter examples for this. The USA should have
    50 year head start in Thorium reactors, now they are 10 years
    behind China.

    Oh boy, justifying one wishful-thinking technology with another one.
    One can point to eventually successful technologies that had their ups
    and downs in earlier times (there is even the <https://en.wikipedia.org/wiki/Gartner_hype_cycle> that describes
    this), but there are also lots of failed technologies, some of which
    still have a loyal fan base.

    Thorium is a case in point. It's not fissile, but you have to breed
    it into fissile U233 to make any use of it. We live at a time when
    fissile U235 is so plentyful that the USA deems it even too costly to
    use fissile Pu239 in their nuclear power stations, and wants to fulfil
    their disarmament obligations by blending the Pu239 from their
    dismantled bombs with nuclear waste and depositing that. Thorium is
    not going to become important until U235 becomes rare, and probably
    not even then: There is lots of depleted Uranium already in pure form
    which can serve the same purpose, why would one mine Thorium?

    - 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: https://forth-standard.org/
    EuroForth 2022: https://euro.theforth.net

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to Anton Ertl on Sun Apr 2 20:55:29 2023
    In article <2023Apr2.194217@mips.complang.tuwien.ac.at>,
    Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
    albert@cherry.(none) (albert) writes:
    In article <694431bd-9ae2-4ed9-b336-e513f09f5078n@googlegroups.com>,
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> wrote:
    On Saturday, March 18, 2023 at 11:11:40 AM UTC-4, Marcel Hendrix wrote: >>>> That is how INMOS's transputer worked. We wrote tForth for it, and it >>>was, for
    a (very small) timewindow, quite hot. I lost interest when the T9000 did not
    materialize. I guess the transputer's ideas (1. CSP, 2. I/O should >>>scale with
    computing horsepower) will resurface.

    Don't bet on it. If there were value to these ideas, they would have >>>come back long ago.

    There are important counter examples for this. The USA should have
    50 year head start in Thorium reactors, now they are 10 years
    behind China.

    Oh boy, justifying one wishful-thinking technology with another one.
    One can point to eventually successful technologies that had their ups
    and downs in earlier times (there is even the ><https://en.wikipedia.org/wiki/Gartner_hype_cycle> that describes
    this), but there are also lots of failed technologies, some of which
    still have a loyal fan base.

    Thorium was not a failed technology per se. At the time nobody was
    really interested in nuclear energy, only nuclear bombs. So
    alternative deployments fall by the wayside.

    Thorium is a case in point. It's not fissile, but you have to breed
    it into fissile U233 to make any use of it. We live at a time when
    fissile U235 is so plentyful that the USA deems it even too costly to
    use fissile Pu239 in their nuclear power stations, and wants to fulfil
    their disarmament obligations by blending the Pu239 from their
    dismantled bombs with nuclear waste and depositing that. Thorium is
    not going to become important until U235 becomes rare, and probably
    not even then: There is lots of depleted Uranium already in pure form
    which can serve the same purpose, why would one mine Thorium?

    As far as I can tell, the Chinese are past the point of research and
    deploying them commercially.
    I wouldn't buy shares in uranium mining.

    --
    - anton

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Marcel Hendrix@21:1/5 to Anton Ertl on Sun Apr 2 15:19:07 2023
    On Sunday, April 2, 2023 at 7:42:09 PM UTC+2, Anton Ertl wrote:
    Marcel Hendrix <m...@iae.nl> writes:
    I guess the transputer's ideas (1. CSP, 2. I/O should scale with
    computing horsepower) will resurface.
    [..]
    A big downside of the transputer approach is that it has distributed
    memory (each CPU has its own memory and cannot access other CPU's
    memory).

    The T9000 has shared memory ('The T9000 transputer hardware
    reference manual', p26, Chapt.5.2.1). Shared areas can be set to
    non-cacheable.

    The above would work nicely with the way I intend to do parallel
    processing on my 44 core HP Z840 with Tesla K10. Maybe I'll
    pick up the transputer again when I have that working :--)

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Anton Ertl on Mon Apr 3 11:43:34 2023
    On 3/04/2023 3:19 am, Anton Ertl wrote:
    dxforth <dxforth@gmail.com> writes:
    On 13/03/2023 9:30 pm, Hans Bezemer wrote:

    I find Antons CONTOF intriguing, though. Gotta contemplate that one a bit. >>
    It's syntax sugar for:

    BEGIN BEGIN BEGIN ( BEGIN)

    WHILE ... REPEAT

    WHILE ... REPEAT

    WHILE ... REPEAT

    ...

    ( AGAIN)


    Only if you don't use ENDOF nor ENDCASE. But yes, you can transform
    Eaker's CASE into IF ELSE THEN, and Eaker's CASE extended with ?OF,
    CONTOF, and NEXT-CASE into standard Forth code. I find the extended
    Eaker's CASE easier to write and read, however.

    Like all extended control structures they get little to no use in
    practice. Your examples notwithstanding, what's being described
    is a loop with multiple exits - nothing that factoring can't solve.
    Wil Baden demonstrated everything ANS' CASE did could be done with
    two words: COND THENS. Accepting this, extending ANS CASE with
    more words is akin to throwing good money after bad.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Anton Ertl on Mon Apr 3 15:21:23 2023
    On 3/04/2023 3:42 am, Anton Ertl wrote:
    albert@cherry.(none) (albert) writes:
    In article <694431bd-9ae2-4ed9-b336-e513f09f5078n@googlegroups.com>,
    Lorem Ipsum <gnuarm.deletethisbit@gmail.com> wrote:
    On Saturday, March 18, 2023 at 11:11:40 AM UTC-4, Marcel Hendrix wrote: >>>> That is how INMOS's transputer worked. We wrote tForth for it, and it
    was, for
    a (very small) timewindow, quite hot. I lost interest when the T9000 did not
    materialize. I guess the transputer's ideas (1. CSP, 2. I/O should
    scale with
    computing horsepower) will resurface.

    Don't bet on it. If there were value to these ideas, they would have
    come back long ago.

    There are important counter examples for this. The USA should have
    50 year head start in Thorium reactors, now they are 10 years
    behind China.

    Oh boy, justifying one wishful-thinking technology with another one.
    One can point to eventually successful technologies that had their ups
    and downs in earlier times (there is even the <https://en.wikipedia.org/wiki/Gartner_hype_cycle> that describes
    this), but there are also lots of failed technologies, some of which
    still have a loyal fan base.

    Are programming languages technologies - or more akin to religions? Religions claim they're about peace and love but when the outcome is clearly the opposite they manage to escape critique. Is choosing a programming language like window-
    shopping - finding the best dressed manikin and imagining you can be that?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to albert@cherry. on Mon Apr 3 16:28:58 2023
    albert@cherry.(none) (albert) writes:
    In article <2023Apr2.194217@mips.complang.tuwien.ac.at>,
    Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
    One can point to eventually successful technologies that had their ups
    and downs in earlier times (there is even the >><https://en.wikipedia.org/wiki/Gartner_hype_cycle> that describes
    this), but there are also lots of failed technologies, some of which
    still have a loyal fan base.

    Thorium was not a failed technology per se. At the time nobody was
    really interested in nuclear energy, only nuclear bombs.

    A typical example of a lame excuse by a fan of a failed technology.
    Let's see what truth is there to it:

    <https://en.wikipedia.org/wiki/Thorium_fuel_cycle#List_of_thorium-fueled_reactors>
    lists reactors in Canada, USA, India, UK, West Germany and NL, half of
    which have nuclear bombs, a higher percentage than for Uranium-fueled
    reactors. And following the link to <https://en.wikipedia.org/wiki/Dhruva_reactor>, this reactor is
    described as "India's primary generator of weapons-grade plutonium".
    The CIRUS reactor is also mentioned among the "thorium-fueled
    reactors" and also produced plutonium for India's bombs.

    And the claim that all the reactors in the list are thorium-fueled is
    vastly overblown; many articles about the linked-to reactors don't
    mention Thorium at all (including those for the Dhruva and CIRUS
    reactors), and the only thing I found where the proportion of energy
    from Thorium is mentioned at all is <https://de.wikipedia.org/wiki/Kernkraftwerk_THTR-300>, which even has
    Thorium as the first part of its name, but where Thorium contributed
    about 30% of the energy (the rest was from Uranium, and it used
    weapons-grade Uranium); in particular, the THTR-300 had a breeding
    ratio of <0.5; a breeding ratio of >1 is needed for a proper Thorium
    fuel cycle.

    As far as I can tell, the Chinese are past the point of research and >deploying them commercially.

    References? <https://en.wikipedia.org/wiki/Nuclear_power_in_China>
    mentions "research and development into the thorium fuel cycle", but
    no details. Googling for it, it seems they have built a small
    molten-salt reactor, but the articles I found have little detail
    (hidden among a huge amount of overblown claims, probably directly
    from the mouth of a Thorium fan).

    - 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: https://forth-standard.org/
    EuroForth 2022: https://euro.theforth.net

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to Marcel Hendrix on Mon Apr 3 15:51:34 2023
    Marcel Hendrix <mhx@iae.nl> writes:
    On Sunday, April 2, 2023 at 7:42:09=E2=80=AFPM UTC+2, Anton Ertl wrote:
    Marcel Hendrix <m...@iae.nl> writes:
    I guess the transputer's ideas (1. CSP, 2. I/O should scale with
    computing horsepower) will resurface.
    [..]
    A big downside of the transputer approach is that it has distributed
    memory (each CPU has its own memory and cannot access other CPU's
    memory).

    Oh, and that's not because I think that shared memory is better than
    message passing for communicating between threads. It's because it
    allows to share common data between threads, and because it provides flexibility in memory allocation.

    The T9000 has shared memory ('The T9000 transputer hardware
    reference manual', p26, Chapt.5.2.1). Shared areas can be set to >non-cacheable.

    Interesting. And shared-memory computers went for NUMA. If Inmos had succeeded at delivering the T9000 and its successors in time, the
    transputers and shared-memory computers might have converged.

    Actually, when the Opteron with it's HyperTransport links was
    presented 20 years ago, which provided glueless interconnects for up
    to 8 CPUs, it reminded me of the Transputer links. And then the Horus
    system by Newisys was announced, which provided glue for scaling the
    system to more CPUs, it reminded me of the glue chips by Inmos were
    intended to support scaling to larger CPU numbers (but Horus had to
    support cache-coherent shared memory, which is a tough job; I don't
    know if it was ever delivered).

    - 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: https://forth-standard.org/
    EuroForth 2022: https://euro.theforth.net

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Travis Bemann@21:1/5 to All on Mon Apr 3 12:53:06 2023
    My issue with GOTO and LABEL in Forth is their compatiblity with local variables. E.g. my Forth, zeptoforth, has support for local variables such
    that they would be highly incompatible with GOTO and LABEL. In particular
    the issue is that it has block-scoped local variables, where local variables can be limited to a particular block scope. Consider what would happen with this:

    : foo ( -- )
    goto bar
    begin
    1 { my-local }
    label bar
    my-local .
    true until
    ;

    This is further complicated by the storing of local variables on the return stack, where they are pushed by { ... } and dropped when they leave the
    current scope. The above example would not simply output garbage but
    in many cases would simply crash afterwards due to dropping the return
    address from the return stack because my-local would have never been
    pushed onto the return stack in the first place.

    Another problem is when you try to combine them with do-loops. Consider
    the following:

    : baz ( -- )
    goto quux
    10 0 ?do
    label quux
    i .
    loop
    ;

    See the problem here?

    Travis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to Travis Bemann on Mon Apr 3 13:29:34 2023
    Travis Bemann schrieb am Montag, 3. April 2023 um 21:53:08 UTC+2:
    My issue with GOTO and LABEL in Forth is their compatiblity with local variables. E.g. my Forth, zeptoforth, has support for local variables such that they would be highly incompatible with GOTO and LABEL. In particular
    the issue is that it has block-scoped local variables, where local variables can be limited to a particular block scope. Consider what would happen with this:

    : foo ( -- )
    goto bar
    begin
    1 { my-local }
    label bar
    my-local .
    true until
    ;

    This is further complicated by the storing of local variables on the return stack, where they are pushed by { ... } and dropped when they leave the current scope. The above example would not simply output garbage but
    in many cases would simply crash afterwards due to dropping the return address from the return stack because my-local would have never been
    pushed onto the return stack in the first place.

    Another problem is when you try to combine them with do-loops. Consider
    the following:

    : baz ( -- )
    goto quux
    10 0 ?do
    label quux
    i .
    loop
    ;

    See the problem here?


    Sure. My advice: don't do it. It would be akin to exiting do-loops without UNLOOP.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Travis Bemann@21:1/5 to Travis Bemann on Mon Apr 3 13:23:50 2023
    On Monday, April 3, 2023 at 2:53:08 PM UTC-5, Travis Bemann wrote:
    My issue with GOTO and LABEL in Forth is their compatiblity with local variables. E.g. my Forth, zeptoforth, has support for local variables such that they would be highly incompatible with GOTO and LABEL. In particular the issue is that it has block-scoped local variables, where local variables can be limited to a particular block scope. Consider what would happen with this:

    : foo ( -- )
    goto bar
    begin
    1 { my-local }
    label bar
    my-local .
    true until
    ;

    This is further complicated by the storing of local variables on the return stack, where they are pushed by { ... } and dropped when they leave the current scope. The above example would not simply output garbage but
    in many cases would simply crash afterwards due to dropping the return address from the return stack because my-local would have never been
    pushed onto the return stack in the first place.

    Another problem is when you try to combine them with do-loops. Consider
    the following:

    : baz ( -- )
    goto quux
    10 0 ?do
    label quux
    i .
    loop
    ;

    See the problem here?

    Travis

    Okay, I was stupid - this does not require block-scoping to be an issue. Consider
    the following:

    : foobar ( -- )
    goto foobaz
    1 { my-local }
    label foobaz
    my-local .
    ;

    This will both output garbage and in many cases cause a crash due to dropping the top of the return stack (where it expected a local which was never pushed).

    Travis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to Travis Bemann on Mon Apr 3 14:09:51 2023
    Travis Bemann schrieb am Montag, 3. April 2023 um 22:46:05 UTC+2:
    On Monday, April 3, 2023 at 3:29:35 PM UTC-5, minforth wrote:
    Travis Bemann schrieb am Montag, 3. April 2023 um 21:53:08 UTC+2:
    My issue with GOTO and LABEL in Forth is their compatiblity with local variables. E.g. my Forth, zeptoforth, has support for local variables such
    that they would be highly incompatible with GOTO and LABEL. In particular
    the issue is that it has block-scoped local variables, where local variables
    can be limited to a particular block scope. Consider what would happen with
    this:

    : foo ( -- )
    goto bar
    begin
    1 { my-local }
    label bar
    my-local .
    true until
    ;

    This is further complicated by the storing of local variables on the return
    stack, where they are pushed by { ... } and dropped when they leave the current scope. The above example would not simply output garbage but
    in many cases would simply crash afterwards due to dropping the return address from the return stack because my-local would have never been pushed onto the return stack in the first place.

    Another problem is when you try to combine them with do-loops. Consider the following:

    : baz ( -- )
    goto quux
    10 0 ?do
    label quux
    i .
    loop
    ;

    See the problem here?

    Sure. My advice: don't do it. It would be akin to exiting do-loops without UNLOOP.
    I actually made it so that it is safe to exit DO-LOOPs without UNLOOP because
    I made EXIT an immediate word that is smart enough to check the compile-time local variable stack, on which the DO-LOOP control variables are recorded, and drop
    everything pushed onto it from the return stack prior to compiling a POP {PC}
    instruction. I kept UNLOOP for the sake of compatibility with existing code but it
    is now an no-op. (Note that all of this is not true when zeptoforth is first being
    built, where it uses more traditional DO-LOOP words, but it replaces those words
    at the same time as when it sets up the local variable stack.)

    Sounds good. I only would use new different names instead of changing the meanings
    of standard words. Might prevent surprises...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Travis Bemann@21:1/5 to minforth on Mon Apr 3 13:46:03 2023
    On Monday, April 3, 2023 at 3:29:35 PM UTC-5, minforth wrote:
    Travis Bemann schrieb am Montag, 3. April 2023 um 21:53:08 UTC+2:
    My issue with GOTO and LABEL in Forth is their compatiblity with local variables. E.g. my Forth, zeptoforth, has support for local variables such that they would be highly incompatible with GOTO and LABEL. In particular the issue is that it has block-scoped local variables, where local variables
    can be limited to a particular block scope. Consider what would happen with
    this:

    : foo ( -- )
    goto bar
    begin
    1 { my-local }
    label bar
    my-local .
    true until
    ;

    This is further complicated by the storing of local variables on the return
    stack, where they are pushed by { ... } and dropped when they leave the current scope. The above example would not simply output garbage but
    in many cases would simply crash afterwards due to dropping the return address from the return stack because my-local would have never been pushed onto the return stack in the first place.

    Another problem is when you try to combine them with do-loops. Consider the following:

    : baz ( -- )
    goto quux
    10 0 ?do
    label quux
    i .
    loop
    ;

    See the problem here?

    Sure. My advice: don't do it. It would be akin to exiting do-loops without UNLOOP.

    I actually made it so that it is safe to exit DO-LOOPs without UNLOOP because
    I made EXIT an immediate word that is smart enough to check the compile-time local variable stack, on which the DO-LOOP control variables are recorded, and drop
    everything pushed onto it from the return stack prior to compiling a POP {PC} instruction. I kept UNLOOP for the sake of compatibility with existing code but it
    is now an no-op. (Note that all of this is not true when zeptoforth is first being
    built, where it uses more traditional DO-LOOP words, but it replaces those words
    at the same time as when it sets up the local variable stack.)

    Travis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Travis Bemann on Tue Apr 4 10:32:46 2023
    On 4/04/2023 6:46 am, Travis Bemann wrote:

    I actually made it so that it is safe to exit DO-LOOPs without UNLOOP because I made EXIT an immediate word that is smart enough to check the compile-time local variable stack, on which the DO-LOOP control variables are recorded, and drop
    everything pushed onto it from the return stack prior to compiling a POP {PC} instruction. I kept UNLOOP for the sake of compatibility with existing code but it
    is now an no-op. (Note that all of this is not true when zeptoforth is first being
    built, where it uses more traditional DO-LOOP words, but it replaces those words
    at the same time as when it sets up the local variable stack.)

    You don't consider all this stuff under the hood is taking Forth in the opposite
    direction? The precedent appears to have been Forth-83 and the immediate LEAVE,
    whereby if one can hide complexity from the user then it is justified. When Forth
    users find out how much has been hidden from them, won't they question it, arguing
    other languages have already done that, and better?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Travis Bemann@21:1/5 to dxforth on Mon Apr 3 19:28:58 2023
    On Monday, April 3, 2023 at 7:35:35 PM UTC-5, dxforth wrote:
    On 4/04/2023 6:46 am, Travis Bemann wrote:

    I actually made it so that it is safe to exit DO-LOOPs without UNLOOP because
    I made EXIT an immediate word that is smart enough to check the compile-time
    local variable stack, on which the DO-LOOP control variables are recorded, and drop
    everything pushed onto it from the return stack prior to compiling a POP {PC}
    instruction. I kept UNLOOP for the sake of compatibility with existing code but it
    is now an no-op. (Note that all of this is not true when zeptoforth is first being
    built, where it uses more traditional DO-LOOP words, but it replaces those words
    at the same time as when it sets up the local variable stack.)
    You don't consider all this stuff under the hood is taking Forth in the opposite
    direction? The precedent appears to have been Forth-83 and the immediate LEAVE,
    whereby if one can hide complexity from the user then it is justified. When Forth
    users find out how much has been hidden from them, won't they question it, arguing
    other languages have already done that, and better?

    I for the longest time resisted adding local variables to zeptoforth because they were
    "un-traditional". I finally gave in and implemented them when I tried to implement
    a word for blitting from one rectangle on one bitmap to another rectangle on another
    bitmap. I was having to juggle about nine values on the data stack, the code was
    completely unreadable, the code almost certainly had bugs due to the likelihood of
    my making mistakes in the juggling, and it almost certainly would have gotten poor
    performance due to all the stack juggling. Also, I could not factor away much of the
    complexity; while I did factor away the physical blitting of strips of at most eight bits
    high to separate assembly-language routines, there was much that simply could not
    ahve been factored.

    Faced with this, I scrapped my existing code aside from the assembly-language routines and implemented local variables. After I re-implemented the blitting routine
    using local variables, they were far more readable, were bug-free, and were probably
    far faster than my original routine would have been had I stuck with it (because local
    variables can be accessed as simple offsets into the return stack, with fetches being
    three instructions, two to evict the TOS register to the data stack (due to the lack of an
    atomic decrement-and-store instruction for stacks other than SP in ARMv6-M), and
    just one to read the local variable from an offset from SP into the TOS, and stores
    being two instructions, one to store the TOS in an offset from SP, and another to
    read the top of the data stack into the TOS (thanks to the ARMv6-M LDM instruction)).

    This convinced me that local variables were a big win, and I have found since then that
    they make my code far more readable and manageable. Yes, they might be "un-traditional", but they have served me very well and my only regret is that I had not
    implemented them earlier, as I have plenty of barely-readable code that would almost
    certainly be far more readable to me now ─ and faster too ─ had I implemented them
    with local variables.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From none) (albert@21:1/5 to Anton Ertl on Tue Apr 4 11:33:55 2023
    In article <2023Apr3.182858@mips.complang.tuwien.ac.at>,
    Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
    albert@cherry.(none) (albert) writes:
    As far as I can tell, the Chinese are past the point of research and >>deploying them commercially.


    I got this from a more recent youtube video.
    At least the Chinese are serious about research, investing the equivalent
    of 500 million us$.

    A pilot plant is underway, 3 MWatt to serve "1000 dwellings".
    As it goes according to plan, the next step is a 373 MWatt plant.

    We shall see.


    - anton
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat spinning. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From dxforth@21:1/5 to Travis Bemann on Wed Apr 5 11:41:19 2023
    On 4/04/2023 12:28 pm, Travis Bemann wrote:
    On Monday, April 3, 2023 at 7:35:35 PM UTC-5, dxforth wrote:
    On 4/04/2023 6:46 am, Travis Bemann wrote:

    I actually made it so that it is safe to exit DO-LOOPs without UNLOOP because
    I made EXIT an immediate word that is smart enough to check the compile-time
    local variable stack, on which the DO-LOOP control variables are recorded, and drop
    everything pushed onto it from the return stack prior to compiling a POP {PC}
    instruction. I kept UNLOOP for the sake of compatibility with existing code but it
    is now an no-op. (Note that all of this is not true when zeptoforth is first being
    built, where it uses more traditional DO-LOOP words, but it replaces those words
    at the same time as when it sets up the local variable stack.)
    You don't consider all this stuff under the hood is taking Forth in the opposite
    direction? The precedent appears to have been Forth-83 and the immediate LEAVE,
    whereby if one can hide complexity from the user then it is justified. When Forth
    users find out how much has been hidden from them, won't they question it, arguing
    other languages have already done that, and better?

    I for the longest time resisted adding local variables to zeptoforth because they were
    "un-traditional". I finally gave in and implemented them when I tried to implement
    a word for blitting from one rectangle on one bitmap to another rectangle on another
    bitmap. I was having to juggle about nine values on the data stack, the code was
    completely unreadable, the code almost certainly had bugs due to the likelihood of
    my making mistakes in the juggling, and it almost certainly would have gotten poor
    performance due to all the stack juggling. Also, I could not factor away much of the
    complexity; while I did factor away the physical blitting of strips of at most eight bits
    high to separate assembly-language routines, there was much that simply could not
    ahve been factored.

    Faced with this, I scrapped my existing code aside from the assembly-language routines and implemented local variables. After I re-implemented the blitting routine
    using local variables, they were far more readable, were bug-free, and were probably
    far faster than my original routine would have been had I stuck with it (because local
    variables can be accessed as simple offsets into the return stack, with fetches being
    three instructions, two to evict the TOS register to the data stack (due to the lack of an
    atomic decrement-and-store instruction for stacks other than SP in ARMv6-M), and
    just one to read the local variable from an offset from SP into the TOS, and stores
    being two instructions, one to store the TOS in an offset from SP, and another to
    read the top of the data stack into the TOS (thanks to the ARMv6-M LDM instruction)).

    This convinced me that local variables were a big win, and I have found since then that
    they make my code far more readable and manageable. Yes, they might be "un-traditional", but they have served me very well and my only regret is that I had not
    implemented them earlier, as I have plenty of barely-readable code that would almost
    certainly be far more readable to me now ─ and faster too ─ had I implemented them
    with local variables.

    Certainly locals are easier and folks find ways of justifying them. My concern in using
    them would be what have I missed that's simpler? I imagine in C the question is never
    asked, hence the reliance on optimizing compilers to speed up the layers of code that
    inevitably accumulates.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From fabianorezende26@gmail.com@21:1/5 to All on Wed Apr 5 11:19:40 2023
    Em segunda-feira, 3 de abril de 2023 às 23:29:00 UTC-3, Travis Bemann escreveu:
    On Monday, April 3, 2023 at 7:35:35 PM UTC-5, dxforth wrote:
    On 4/04/2023 6:46 am, Travis Bemann wrote:

    I actually made it so that it is safe to exit DO-LOOPs without UNLOOP because
    I made EXIT an immediate word that is smart enough to check the compile-time
    local variable stack, on which the DO-LOOP control variables are recorded, and drop
    everything pushed onto it from the return stack prior to compiling a POP {PC}
    instruction. I kept UNLOOP for the sake of compatibility with existing code but it
    is now an no-op. (Note that all of this is not true when zeptoforth is first being
    built, where it uses more traditional DO-LOOP words, but it replaces those words
    at the same time as when it sets up the local variable stack.)
    You don't consider all this stuff under the hood is taking Forth in the opposite
    direction? The precedent appears to have been Forth-83 and the immediate LEAVE,
    whereby if one can hide complexity from the user then it is justified. When Forth
    users find out how much has been hidden from them, won't they question it, arguing
    other languages have already done that, and better?
    I for the longest time resisted adding local variables to zeptoforth because they were
    "un-traditional". I finally gave in and implemented them when I tried to implement
    a word for blitting from one rectangle on one bitmap to another rectangle on another
    bitmap. I was having to juggle about nine values on the data stack, the code was
    completely unreadable, the code almost certainly had bugs due to the likelihood of
    my making mistakes in the juggling, and it almost certainly would have gotten poor
    performance due to all the stack juggling. Also, I could not factor away much of the
    complexity; while I did factor away the physical blitting of strips of at most eight bits
    high to separate assembly-language routines, there was much that simply could not
    ahve been factored.

    Faced with this, I scrapped my existing code aside from the assembly-language
    routines and implemented local variables. After I re-implemented the blitting routine
    using local variables, they were far more readable, were bug-free, and were probably
    far faster than my original routine would have been had I stuck with it (because local
    variables can be accessed as simple offsets into the return stack, with fetches being
    three instructions, two to evict the TOS register to the data stack (due to the lack of an
    atomic decrement-and-store instruction for stacks other than SP in ARMv6-M), and
    just one to read the local variable from an offset from SP into the TOS, and stores
    being two instructions, one to store the TOS in an offset from SP, and another to
    read the top of the data stack into the TOS (thanks to the ARMv6-M LDM instruction)).

    This convinced me that local variables were a big win, and I have found since then that
    they make my code far more readable and manageable. Yes, they might be "un-traditional", but they have served me very well and my only regret is that I had not
    implemented them earlier, as I have plenty of barely-readable code that would almost
    certainly be far more readable to me now ─ and faster too ─ had I implemented them
    with local variables.
    Forth made me value variable locals. You can run a code "10x" faster and "10x" smaller but at the cost of taking "10x" and making "10x" more errors.
    A very simple design feature that saved me a lot of pain.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to albert@cherry. on Thu Apr 6 08:32:12 2023
    albert@cherry.(none) (albert) writes:
    In article <2023Apr3.182858@mips.complang.tuwien.ac.at>,
    Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
    albert@cherry.(none) (albert) writes:
    As far as I can tell, the Chinese are past the point of research and >>>deploying them commercially.


    I got this from a more recent youtube video.
    At least the Chinese are serious about research, investing the equivalent
    of 500 million us$.

    A pilot plant is underway, 3 MWatt to serve "1000 dwellings".
    As it goes according to plan, the next step is a 373 MWatt plant.

    Past the point of research and development?

    To make this a bit more technical, here are some reasons why Thorium
    never went beyond research and development, while Uranium light-water
    reactors have won:

    * No U235 shortage yet.

    * Some safety features of light-water reactors: solid fuel, enclosed
    in sealed tubes (fuel rods) prevent the escape of fission products.
    Light water as both moderator and coolant stops the reaction in case
    the coolant is lost. This all did not prevent decay-heat accidents
    such as Kyshtym, Three Mile Island, and Fukujima, but removing these
    safety features is not going to help safety.

    * To get the breeding ratio >1 needed for a Thorium fuel cycle, you
    cannot use solid fuel, because with solid fuel the fission products
    consume too many neutrons; that's why Thorium is often mentioned
    with molten-salt reactors where the fuel is liquid and some of the
    fission products (in particular gaseous ones like Xenon) can be
    removed quickly. But of course that means that there is a larger
    danger that these fission products escape into the environment. And
    if there's a crack in the system, the the fuel, and the fission
    products escape.

    * To get rid of other fission products quickly, the idea of
    reprocessing the fuel on-site has been proposed, but AFAIK never
    implemented. If it is implemented, it increases the cost,
    complexity and potential for accidents.

    * Pa233 (an intermediate product in the Thorium fuel cycle) has a
    half-life of 27 days, and while it lives, it can absorb neutrons,
    which means that both the neutron that converted the Th232 to
    Th233->Pa233, and this additional neutron goes to waste, reducing
    neutron economy; this effect can be reduced by lowering the neutron
    flux per fuel unit, but that means lower power output for the same
    amount of fuel or having a bigger fuel inventory for the same power
    output.

    I found no trace of anyone achieving a breeding ratio >1 in any of the
    thorium experiments.

    - 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: https://forth-standard.org/
    EuroForth 2022: https://euro.theforth.net

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)