HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

A simple clock in FORTH

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simpleforthclock

Problem

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 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> ;

: 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

Solution

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 <> while
        case
            ....
        endcase
    repeat

Code Snippets

: get-elapsed-time  ( ud -- ud )
: get-elapsed-time
    utime
    2over
    d- drop ;
begin key dup [char] q <> while
        case
            ....
        endcase
    repeat

Context

StackExchange Code Review Q#155969, answer score: 3

Revisions (0)

No revisions yet.