In article <
87im1r7...@nightsong.com>,
Paul Rubin <no.e...@nospam.invalid> wrote:
>Rick C <
gnuarm.del...@gmail.com> writes:
>> There is very little stack juggling in most applications. If there is
>> it shows the presence of a poor programmer, a poor compiler or both.
>
>I'd be interested in seeing some Forth applications with very little
>stack juggling. The ones I've looked at have considerable.
The tingle tangle video on youtube plays the following program
===================================================================
\ $Id: landmann.sco,v 1.4 2018/09/26 12:52:52 albert Exp $
\ Copyright (2018): Albert van der Horst {by GNU Public License}
' rest alias %
' chord alias {}
\ $Id: landmann.sco,v 1.4 2018/09/26 12:52:52 albert Exp $
\ Copyright (2018): Albert van der Horst {by GNU Public License}
' rest alias %
' chord alias {}
\ : ORGAN SPEAKER ;
SCORE Landmann
DEFAULT: 112 /4 MM 6 TRANSPOSE-UP
INFO: Schumann: Froehlicher Landmann transformed by AH & CH
PART one
PDEFAULT: SILVER \ 4 TRANSPOSE-UP
||: 4 /4 MEASURE /8 C2 |
L: m1 /4. F2 /8 A2 /4. C3 /8 F2 |
/8 BES2 D3 F3 D3 /4. C3 /8 A2 |
L: m3 /8 BES2 G2 C2 BES2 A2 F2 C2 A2 |
L: m4 /4 E2 D2 C2 /8 % C2 |
m1 .. m4 bis |
L: m9 /4. G2 /8 F2 /4. E2 /8 C2 |
L: m10 /8 G2 F2 E2 D2 /4. E2 /8 C2 |
m1 .. m3 bis
/4 { BES1 G2 } { C2 E2 } F2 /8 % C2 |
m9 .. m10 bis
m1 .. m3 bis
/4 { BES1 G2 } { C2 E2 } F2 % ||
PART two
\ PDEFAULT: GOLD
PDEFAULT: ORGAN L2
||: 4 /4 MEASURE /8 % |
L: m1 /8 % { C3 F3 A3 } {} % % { F3 A3 C4 } {} % |
/8 % { F3 BES3 D4 } {} % % { F3 A3 C4 } {} % |
L: m3 /8 % { E3 BES3 C4 } {} % % { C3 F3 A3 } {} % |
/8 % { C3 G3 } % { F3 G3 B3 } % { E3 G3 C4 } /4 {} |
m1 .. m3 bis
/8 % { C3 G3 } % { F3 G3 B3 } % { E3 G3 C4 } {} % |
L: m9 /8 % { C3 E3 } {} % % { BES2 C3 } {} % |
/8 % C3 C3 B2 % C3 C3 % |
/8 % { C3 E3 } {} % % { F3 A3 } {} % |
/8 % { F3 BES3 } % {} % { F3 A3 } {} % |
/8 % { E3 BES3 C4 } {} % % { C3 F3 A3 } {} {} |
L: m14 /8 % { D3 G3 } % { BES2 C3 } % { A2 C3 F3 } {} % |
m9 .. m14 bis ||
PART three
\ PDEFAULT: GOLD
PDEFAULT: ORGAN L8
||: 4 /4 MEASURE /8 % |
L: m1 whole rest |
whole rest |
L: m3 whole rest |
whole rest |
m1 .. m3 bis
L: m8 /4 % % % /8 % C3 |
/4. BES3 /8 A3 /4. G3 /8 C3 |
L6 /8 BES3 A3 G3 F3 L8 /4. G3 /8 C3 |
/4. F3 /8 A3 /4. C4 /8 F3 |
/8 BES3 D4 F4 D4 /4. C4 /8 % |
L: m13 whole rest |
m8 .. m13 bis
whole rest |
whole rest ||
\ : ORGAN SPEAKER ;
SCORE Landmann
DEFAULT: 112 /4 MM 6 TRANSPOSE-UP
INFO: Schumann: Froehlicher Landmann transformed by AH & CH
PART one
PDEFAULT: SILVER \ 4 TRANSPOSE-UP
||: 4 /4 MEASURE /8 C2 |
L: m1 /4. F2 /8 A2 /4. C3 /8 F2 |
/8 BES2 D3 F3 D3 /4. C3 /8 A2 |
L: m3 /8 BES2 G2 C2 BES2 A2 F2 C2 A2 |
L: m4 /4 E2 D2 C2 /8 % C2 |
m1 .. m4 bis |
L: m9 /4. G2 /8 F2 /4. E2 /8 C2 |
L: m10 /8 G2 F2 E2 D2 /4. E2 /8 C2 |
m1 .. m3 bis
/4 { BES1 G2 } { C2 E2 } F2 /8 % C2 |
m9 .. m10 bis
m1 .. m3 bis
/4 { BES1 G2 } { C2 E2 } F2 % ||
PART two
\ PDEFAULT: GOLD
PDEFAULT: ORGAN L2
||: 4 /4 MEASURE /8 % |
L: m1 /8 % { C3 F3 A3 } {} % % { F3 A3 C4 } {} % |
/8 % { F3 BES3 D4 } {} % % { F3 A3 C4 } {} % |
L: m3 /8 % { E3 BES3 C4 } {} % % { C3 F3 A3 } {} % |
/8 % { C3 G3 } % { F3 G3 B3 } % { E3 G3 C4 } /4 {} |
m1 .. m3 bis
/8 % { C3 G3 } % { F3 G3 B3 } % { E3 G3 C4 } {} % |
L: m9 /8 % { C3 E3 } {} % % { BES2 C3 } {} % |
/8 % C3 C3 B2 % C3 C3 % |
/8 % { C3 E3 } {} % % { F3 A3 } {} % |
/8 % { F3 BES3 } % {} % { F3 A3 } {} % |
/8 % { E3 BES3 C4 } {} % % { C3 F3 A3 } {} {} |
L: m14 /8 % { D3 G3 } % { BES2 C3 } % { A2 C3 F3 } {} % |
m9 .. m14 bis ||
PART three
\ PDEFAULT: GOLD
PDEFAULT: ORGAN L8
||: 4 /4 MEASURE /8 % |
L: m1 whole rest |
whole rest |
L: m3 whole rest |
whole rest |
m1 .. m3 bis
L: m8 /4 % % % /8 % C3 |
/4. BES3 /8 A3 /4. G3 /8 C3 |
L6 /8 BES3 A3 G3 F3 L8 /4. G3 /8 C3 |
/4. F3 /8 A3 /4. C4 /8 F3 |
/8 BES3 D4 F4 D4 /4. C4 /8 % |
L: m13 whole rest |
m8 .. m13 bis
whole rest |
whole rest ||
===================================================================
The program creates a word of type SCORE, called Landmann
After loading you type
Landmann PLAY
IMHO this is a fine example of "extending the language".
You can use DUP ROT SWAP in this code, but it was nowhere necessary.
An other examply is the assembler in the ciforth blocks.
The first block has some benign stack handling:
------------------------------------------------------------
( ASSEMBLER-GENERIC SPLIT 1PI FIR 1FAMILY, ) \ B9jan27 AvdH
\ Post one byte of INSTRUCTION . Leave REMAINDER.
: POST DUP C, 8 RSHIFT ;
\ Fixup with ms byte of FIX below ADDR, leave next FIX ADDR
: FIX| 1- >R R@ OVER 0FF AND TOGGLE 8 RSHIFT R> ;
: 1PI CREATE , DOES> @ POST DROP ; \ post-it 1 byte opcode
: 2PI CREATE , DOES> @ POST POST DROP ; \ 2 byte
: 3PI CREATE , DOES> @ POST POST POST DROP ; \ 3 byte
\ Fixup from behind starting with ls byte.
: FIR CREATE , DOES> @ HERE BEGIN FIX| OVER 0= UNTIL 2DROP ;
: NO-- PP @ NAME PRESENT ?DUP IF HIDDEN THEN PP ! ;
\ Create a family adding INC to OPCODE with COUNT members
: 1FAMILY, 0 DO DUP NO-- 1PI OVER + LOOP DROP DROP ;
: 2FAMILY, 0 DO DUP NO-- 2PI OVER + LOOP DROP DROP ;
: 3FAMILY, 0 DO DUP NO-- 3PI OVER + LOOP DROP DROP ;
: FAMILY|R 0 DO DUP NO-- FIR OVER + LOOP DROP DROP ;
------------------------------------------------------------
Note that it is restricted to:
1. DUP : I need the top stack item twice
2. OVER : I need the next stack item twice
3. DROP : I need the top stack item no more.
Important is of course that there is no puzzle about
what the stack item presents.
Also notable, this runs on CORE wordset. The Forth language is
not even extended.
Then the remaining 10 screens of the assembler do not contain
a single (!) stack operation.
Another good example is the basic in Forth.
Yes there is a word DEFER that consists mainly of stack operations.
After that it is smooth sailing with few stack operations.
After that you can write BASIC. Of course BASIC doesnot contain stack
operations at all.
Let those examples supersede the silly washing machine example of Brody
that does not actually work.