• Re: Juggling system-compilation items

    From Krishna Myneni@21:1/5 to Ruvim on Sat Aug 10 22:29:14 2024
    On 8/9/24 09:05, Ruvim wrote:
    Do you know a Forth system in which the following definition for "const"
    is compiled but does not work as expected?


    : const ( x "<spaces>name" -- )
      depth >r          ( x )                   ( R: n.depth )
      :                 ( x colon-sys )         ( R: n.depth )
      depth r> -        ( x colon-sys n.size )  ( R: )
      n>r               ( x )                   ( R: i*x n.size )
      postpone literal  (   )                   ( R: i*x n.size )
      nr>               ( colon-sys n.size )    ( R: )
      drop              ( colon-sys )
      postpone ;        (   )
    ;


    t{ 123 const foo -> }t
    t{ foo -> 3 }t


    Note 3.1.5.1 System-compilation types <https://forth-standard.org/standard/usage#subsubsection.3.1.5.1>


    --
    Ruvim


    In kForth, for the code above, foo returns 123 which is what I expect.

    --
    Krishna


    === begin code ===

    : N>R \ xn .. x1 N -- ; R: -- x1 .. xn n
    \ Transfer N items and count to the return stack.
    dup \ xn .. x1 N N --
    begin
    dup
    while
    rot r> swap >r >r \ xn .. N N -- ; R: .. x1 --
    1- \ xn .. N 'N -- ; R: .. x1 --
    repeat
    drop \ N -- ; R: x1 .. xn --
    r> swap >r >r
    ;

    : NR> \ -- xn .. x1 N ; R: x1 .. xn N --
    \ Pull N items and count off the return stack.
    r> r> swap >r dup
    begin
    dup
    while
    r> r> swap >r -rot
    1-
    repeat
    drop
    ;


    : const ( x "<spaces>name" -- )
    depth >r ( x ) ( R: n.depth )
    : ( x colon-sys ) ( R: n.depth )
    depth r> - ( x colon-sys n.size ) ( R: )
    n>r ( x ) ( R: i*x n.size )
    postpone literal ( ) ( R: i*x n.size )
    nr> ( colon-sys n.size ) ( R: )
    drop ( colon-sys )
    postpone ; ( )
    ;
    === end code ===

    === begin test ===
    123 const foo
    ok
    foo .
    123 ok
    === end test ===

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to ruvim.pinka@gmail.com on Sun Aug 11 10:38:28 2024
    In article <v98sed$kldc$2@dont-email.me>, Ruvim <ruvim.pinka@gmail.com> wrote: >On 2024-08-10 12:57, PMF wrote:
    I think !csp and ?csp are common also in other systems. I certainly did
    not invent them.

    Yes, it's a simple method to check the control-flow structures balance
    from the FIG-Forth model.

    I would suggest avoiding this method in Forth implementations.

    It saved me a lot of mistakes. ciforth reports an error.
    If you care to look the error up in the documentation, you can see
    that you can turn this off, if you want to.

    --
    Ruvim

    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 purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerry Jackson@21:1/5 to Ruvim on Sun Aug 11 23:26:00 2024
    On 09/08/2024 15:05, Ruvim wrote:
    Do you know a Forth system in which the following definition for "const"
    is compiled but does not work as expected?


    : const ( x "<spaces>name" -- )
      depth >r          ( x )                   ( R: n.depth )
      :                 ( x colon-sys )         ( R: n.depth )
      depth r> -        ( x colon-sys n.size )  ( R: )
      n>r               ( x )                   ( R: i*x n.size )
      postpone literal  (   )                   ( R: i*x n.size )
      nr>               ( colon-sys n.size )    ( R: )
      drop              ( colon-sys )
      postpone ;        (   )
    ;


    t{ 123 const foo -> }t
    t{ foo -> 3 }t


    Note 3.1.5.1 System-compilation types <https://forth-standard.org/standard/usage#subsubsection.3.1.5.1>



    ISTM that using the data stack to hold the control stack is an
    anachronism that was used in early Forth systems because of the limited
    amount of memory available. I also think that the system should not get
    in the way of user programs as putting control stack data on the data
    stack certainly does.

    Therefore I developed my system (for desktop systems only) with a
    separate control flow stack. It doesn't stop checking for unbalanced
    stack errors. As it is only used when compiling speed isn't important it
    can be a linked list implementation discarded at runtime. It allows data
    to be passed into or out of colon definitions or other control
    structures without considering the control stack unless you are trying
    to write portable software.

    So in your definition above the use of DEPTH, N>R etc is unnecessary as
    DEPTH >R : DEPTH R> -
    returns 0 for my system. CONST works.

    --
    Gerry

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to do-not-use@swldwa.uk on Mon Aug 12 11:45:39 2024
    In article <v9bdpm$2sbsi$1@dont-email.me>,
    Gerry Jackson <do-not-use@swldwa.uk> wrote:
    ISTM that using the data stack to hold the control stack is an
    anachronism that was used in early Forth systems because of the limited >amount of memory available. I also think that the system should not get
    in the way of user programs as putting control stack data on the data
    stack certainly does.

    It alleviates restriction. Marcel Hendrix hated the restrictions of
    R and added the socalled "system stack" S> >S that can be used
    over definitions. The disadvantage is of course that there are more
    regions of memory that you have to keep track of.
    I think that added complexity is a more important consideration as
    memory usage. The more stacks you have and the more stack items
    you keep in registers, the more difficult e.g. task switching becomes.

    Therefore I developed my system (for desktop systems only) with a
    separate control flow stack. It doesn't stop checking for unbalanced
    stack errors. As it is only used when compiling speed isn't important it
    can be a linked list implementation discarded at runtime. It allows data
    to be passed into or out of colon definitions or other control
    structures without considering the control stack unless you are trying
    to write portable software.

    So in your definition above the use of DEPTH, N>R etc is unnecessary as
    DEPTH >R : DEPTH R> -
    returns 0 for my system. CONST works.

    --
    Gerry

    --
    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 purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Krishna Myneni@21:1/5 to Gerry Jackson on Mon Aug 12 07:09:36 2024
    On 8/11/24 17:26, Gerry Jackson wrote:
    On 09/08/2024 15:05, Ruvim wrote:
    Do you know a Forth system in which the following definition for
    "const" is compiled but does not work as expected?


    : const ( x "<spaces>name" -- )
       depth >r          ( x )                   ( R: n.depth )
       :                 ( x colon-sys )         ( R: n.depth )
       depth r> -        ( x colon-sys n.size )  ( R: )
       n>r               ( x )                   ( R: i*x n.size )
       postpone literal  (   )                   ( R: i*x n.size )
       nr>               ( colon-sys n.size )    ( R: )
       drop              ( colon-sys )
       postpone ;        (   )
    ;


    t{ 123 const foo -> }t
    t{ foo -> 3 }t


    Note 3.1.5.1 System-compilation types
    <https://forth-standard.org/standard/usage#subsubsection.3.1.5.1>



    ISTM that using the data stack to hold the control stack is an
    anachronism that was used in early Forth systems because of the limited amount of memory available. I also think that the system should not get
    in the way of user programs as putting control stack data on the data
    stack certainly does.


    Agreed. Placing control stack items on the data stack shouldn't be
    necessary now. I favor standardization of a separate control stack.
    Indeed, in kForth it is possible to define const simply as

    : const : postpone literal postpone ; ;

    No return stack juggling needed because ":" does not introduce anything
    onto the data stack. Balancing of control structures are verified.

    This is quite useful when passing args to colon defs as well as to
    quotations.

    My test of Ruvim's code simply validated the portable version for the
    current standard.

    --
    Krishna

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From mhx@21:1/5 to Krishna Myneni on Mon Aug 12 17:06:39 2024
    On Mon, 12 Aug 2024 12:09:36 +0000, Krishna Myneni wrote:
    [..]

    : const : postpone literal postpone ; ;

    No return stack juggling needed because ":" does not introduce anything
    onto the data stack. Balancing of control structures are verified.

    This is quite useful when passing args to colon defs as well as to quotations.

    Seconded. In iForth the scheme is less rigorous [1], but it is enough
    to allow argument passing to code in progress. This has proved
    incredibly useful for my iSPICE code generators (the circuit netlist
    is completely converted to early binding machine code).

    -marcel

    [1] If all control info is passed on the S-stack, the stack juggling
    becomes too hairy for my taste.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerry Jackson@21:1/5 to albert@spenarnc.xs4all.nl on Tue Aug 13 20:31:00 2024
    On 12/08/2024 10:45, albert@spenarnc.xs4all.nl wrote:
    In article<v9bdpm$2sbsi$1@dont-email.me>,
    Gerry Jackson<do-not-use@swldwa.uk> wrote:
    ISTM that using the data stack to hold the control stack is an
    anachronism that was used in early Forth systems because of the limited
    amount of memory available. I also think that the system should not get
    in the way of user programs as putting control stack data on the data
    stack certainly does.
    It alleviates restriction. Marcel Hendrix hated the restrictions of
    R and added the socalled "system stack" S> >S that can be used
    over definitions. The disadvantage is of course that there are more
    regions of memory that you have to keep track of.
    I think that added complexity is a more important consideration as
    memory usage. The more stacks you have and the more stack items
    you keep in registers, the more difficult e.g. task switching becomes.

    As use of a control stack is during compilation, speed is not too
    important so why would register(s) be used for it?

    --
    Gerry

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerry Jackson@21:1/5 to Ruvim on Tue Aug 13 20:26:25 2024
    On 12/08/2024 10:00, Ruvim wrote:
    On 2024-08-12 02:26, Gerry Jackson wrote:
    On 09/08/2024 15:05, Ruvim wrote:
    Do you know a Forth system in which the following definition for
    "const" is compiled but does not work as expected?


    : const ( x "<spaces>name" -- )
       depth >r          ( x )                   ( R: n.depth )
       :                 ( x colon-sys )         ( R: n.depth )
       depth r> -        ( x colon-sys n.size )  ( R: )
       n>r               ( x )                   ( R: i*x n.size )
       postpone literal  (   )                   ( R: i*x n.size )
       nr>               ( colon-sys n.size )    ( R: )
       drop              ( colon-sys )
       postpone ;        (   )
    ;


    t{ 123 const foo -> }t
    t{ foo -> 3 }t


    Note 3.1.5.1 System-compilation types <https://forth-standard.org/
    standard/usage#subsubsection.3.1.5.1>



    ISTM that using the data stack to hold the control stack is an
    anachronism that was used in early Forth systems because of the
    limited amount of memory available. I also think that the system
    should not get in the way of user programs as putting control stack
    data on the data stack certainly does.


    This is a more restrictive requirement to the systems, than a
    requirement to be independent of the data stack depth.


    This requirement can be reasonable. But a problem is that user-defined control-flow and alike structures will leave their intermediate data on
    the data stack anyway (unless they are implemented as parsing words, or
    using a user-defined control-flow stack).

    Therefore, if the standard will require the control-flow stack be
    separate, it should probably provide programs access to this stack (to
    save intermediate data in compile time).

    Yes that would be the case, a separate control stack with existing
    associated words CS-PICK CS-ROLL and CS-DROP (because it has been
    needed). There is still a need for user defined control structures.




    Therefore I developed my system (for desktop systems only) with a
    separate control flow stack. It doesn't stop checking for unbalanced
    stack errors. As it is only used when compiling speed isn't important
    it can be a linked list implementation discarded at runtime. It allows
    data to be passed into or out of colon definitions or other control
    structures without considering the control stack unless you are trying
    to write portable software.

    So in your definition above the use of DEPTH, N>R etc is unnecessary as
       DEPTH >R : DEPTH R> -
    returns 0 for my system. CONST works.



    It's possible to implement a library that defines a separate
    control-flow stack and redefines all the standard words to use this stack.

    It can make sense only if control-flow checking is data stack depth independent in the Forth system.


    I doubt that a change like a mandated separate control stack would be
    accepted as too much existing code would be broken. A possible step in
    that direction could be:
    - have the default position to be as it is a present i.e. the control
    stack to use the data stack or not. Label this as obsolescent
    - provision of a word to define the memory region to be used for the
    control stack, such a word would have the stack effect ( ad u -- ) where
    u is a maximum number of sys type items e.g. orig etc. That would enable
    a user to ALLOT or ALLOCATE the memory.

    In another discussion I advanced the opinion that transient memory areas
    such as PAD and other buffers were also an anachronism due to early
    systems being memory limited. ISTM that a similar solution to making
    those permanent could be applied to those e.g.
    - have the default position as it is at present i.e. transient or not,
    marked as obsolescent
    - provide words to define the memory region to be used for the currently
    transient regions. That could enable <# buffers to be nested, multiple
    PADs.

    --
    Gerry

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to do-not-use@swldwa.uk on Wed Aug 14 12:58:16 2024
    In article <v9gc9i$1nqu$1@dont-email.me>,
    Gerry Jackson <do-not-use@swldwa.uk> wrote:
    On 12/08/2024 10:45, albert@spenarnc.xs4all.nl wrote:
    In article<v9bdpm$2sbsi$1@dont-email.me>,
    Gerry Jackson<do-not-use@swldwa.uk> wrote:
    ISTM that using the data stack to hold the control stack is an
    anachronism that was used in early Forth systems because of the limited
    amount of memory available. I also think that the system should not get
    in the way of user programs as putting control stack data on the data
    stack certainly does.
    It alleviates restriction. Marcel Hendrix hated the restrictions of
    R and added the socalled "system stack" S> >S that can be used
    over definitions. The disadvantage is of course that there are more
    regions of memory that you have to keep track of.
    I think that added complexity is a more important consideration as
    memory usage. The more stacks you have and the more stack items
    you keep in registers, the more difficult e.g. task switching becomes.

    As use of a control stack is during compilation, speed is not too
    important so why would register(s) be used for it?

    The control stack pointer can be a user variable, so the switching
    is automatic. 1) So you are right that it doesn't impose extra
    restrictions for task switching.
    Probably I was rationalizing that I hate making things more complicated.
    Having a separate control flow stack is a complication in itself,
    but it makes other things simpler.
    I have the example of restricting STATE to [ ] and INTERPRET.
    Marcel Hendrix has the example of passing data to a definition.
    There are probably more.

    1) By swapping the user pointer, all user variables are switched.


    --
    Gerry

    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 purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From mhx@21:1/5 to All on Sat Aug 10 09:51:51 2024
    iForth64 does not have N>R and NR> ( never needed them ).
    After pulling them from https://forth-standard.org/standard/tools/ ...

    FORTH> 42 const aap ok
    FORTH> words
    aap const
    ok
    FORTH> see aap
    Flags: TOKENIZE, ANSI
    : aap 42 ; ok
    FORTH> ' aap idis
    $013414C0 : aap
    $013414CA push #42 b#
    $013414CC ;

    No problem.

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)