A simple clock in FORTH I try to program a stopwatch/countdown clock in FORTH with Gforth (and using Gforth-specific words).

I'm  a complete beginner and the following code is the basic stuff (going to add an alarm function / countdown option and more).

For now the stopwatch counts from 00:00:00 (hh:mm:ss) up to 24:00:00 and


pressing space pauses the clock, pressing it again resumes the clock
pressing j/k sets the clock back/ahead one minute
pressing J/K sets the clock back/ahead one hour
pressing q quits the program


Does my code follow best practices? Is it bad style for words like move-clock-seconds-back to return flags because they will be used in a begin ... until statement?

1000000 constant million

: sextal  ( -- )
   6 base ! ;

: hhmmss.  ( ud --  )
   drop million /  0 &lt;# decimal # sextal # [char] : hold decimal # sextal # [char] : hold decimal # sextal # decimal #&gt; TYPE ;

: pause-clock  ( ud -- ud f )
   utime
   begin
      50 ms
      key? if
         key bl = ( pause is released )
      else
        false ( clock keeps pausing )
      then
   until
   utime d- d- 
   false ;

: move-clock-seconds-ahead  ( u ud -- ud f )
    million * 0 d-
    false ;

: move-clock-seconds-back  ( u ud -- ud f )
    million * 0 d+
    utime dmin
    false ;

: get-elapsed-time  ( ud -- ud )
    2dup
    utime 
    2swap d- ;

: 24-hours-elapsed?  ( ud -- f )
    get-elapsed-time ( elapsed time fits in single integer )
    drop 24 60 * 60 * million * u&gt; ;

: run-clock  ( -- )
    page ( clears the terminal )
    utime ( returns a ud timestamp in microseconds )
    begin
       50 ms ( sleep for 50 ms )
       get-elapsed-time
       5 0 at-xy ( coordinates where to print output )
       hhmmss.
       key? if
       key case
       bl of pause-clock endof
          [char] j of 60 move-clock-seconds-back endof
          [char] k of 60 move-clock-seconds-ahead endof
          [char] J of 60 60 * move-clock-seconds-back endof
          [char] K of 60 60 * move-clock-seconds-ahead endof
          [char] q of true endof
          false swap ( the char is now on top of the stack, will be dropped by endcase )
       endcase
       else 24-hours-elapsed? if
          CR
          ." 24 hours elapsed."
          true
       else
          false
       then then
    until ;

run-clock

bye
A comment in

: get-elapsed-time  ( ud -- ud )


seems wrong. The code leaves the elapsed time on top of the otherwise unchanged stack, so the action is really (-- ud).

The way get-elapsed-time leaves a double results in very unnerving drop in hhmmss. and 24-hours-elapsed?. I strongly recommend to make it leave a single integer instead.

I also recommend to reduce stack manipulations with

: get-elapsed-time
    utime
    2over
    d- drop ;





  Is it bad style for words like move-clock-seconds-back to return flags


Yes. It makes it very hard to reuse them in other contexts. Consider (untested)

    begin key dup [char] q &lt;&gt; while
        case
            ....
        endcase
    repeat