patternMinor
A simple clock in FORTH
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
Does my code follow best practices? Is it bad style for words like
```
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
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
seems wrong. The code leaves the elapsed time on top of the otherwise unchanged stack, so the action is really
The way
I also recommend to reduce stack manipulations with
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)
: 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
repeatCode Snippets
: get-elapsed-time ( ud -- ud ): get-elapsed-time
utime
2over
d- drop ;begin key dup [char] q <> while
case
....
endcase
repeatContext
StackExchange Code Review Q#155969, answer score: 3
Revisions (0)
No revisions yet.