Keeping Track of Time, revisited

Date:

2017-11-03

Intro

The original code in timeup_v0.0.fs was cleaned by moving two blocks of code to their own files:

  • the handling of several software clocks using structures. Moved to clocks_v0.3.fs.

  • calculating the last day of a given month in the gregorian calendar, thereby correctly accounting for leap years. Moved to gregorian_last_day_of_month.fs.

Details

This is what remains in timeup_v1.0.fs:

timeup is the function, which is called after a second has passed to increment the __sec field and any higher counters as needed. The file holds this function and all the additional infrastructure needed:

tu.flags to hold the bit flags indicating various conditions

tu.limits to hold the limits for each counter

timeup.init to create a valid state

tu.upd.limits to update the limit of day (length of month)

In timeup itself, I decided to unfold the loop in this function into a somewhat lengthy nested cond? if ... then block. The loop was shorter in code but not simpler to read. I hope that this is simpler to read when I come back to this code in the future.

 1\ 2017-11-08 timeup_v1.0.fs
 2\
 3\ Written in 2017 by Erich Wälde <erich.waelde@forth-ev.de>
 4\
 5\ To the extent possible under law, the author(s) have dedicated
 6\ all copyright and related and neighboring rights to this software
 7\ to the public domain worldwide. This software is distributed
 8\ without any warranty.
 9\
10\ You should have received a copy of the CC0 Public Domain
11\ Dedication along with this software. If not, see
12\ <http://creativecommons.org/publicdomain/zero/1.0/>.
13\
14\
15\ words:
16\     timeup.init
17\     timeup                    \ called in run-masterclock
18\     tu.upd.limits ( Y m -- )  \ called in job.month
19\ in main.fs
20\ s" UT" clock: MasterClock
21
22#include gregorian_lastday_of_month.fs
23
24variable tu.flags
25
26variable tu.limits  #6 allot
27: tu.max.sec   tu.limits  1+  ;
28: tu.max.min   tu.limits #2 + ;
29: tu.max.hour  tu.limits #3 + ;
30: tu.max.day   tu.limits #4 + ;
31: tu.max.month tu.limits #5 + ;
32
33: timeup.init
34  0      tu.flags !
35  #60  tu.max.sec   c!
36  #60  tu.max.min   c!
37  #24  tu.max.hour  c!
38  #31  tu.max.day   c! \ must be corrected later!
39  #12  tu.max.month c!
40;
41
42\ update lastday_of_month in tu.limits
43\ once current date is known
44: tu.upd.limits ( Y m -- )
45  ( Y m ) gregorian_lastday_of_month  tu.max.day  c!
46;
47
48\ requires _clock to be set correctly!
49\ is called at "second over"
50\ original loop replaced by if-else chain,
51\ which is short-cutting as well
52: timeup ( -- )
53  1 sec +!                         \ sec++
54  $02 tu.flags fset                \ secflag++
55
56  sec @ 1+  tu.max.sec c@ > if
57    \ min.over
58    tu.max.sec c@ negate  sec +!   \ sec -= max.sec
59    1 min +!                       \ min++
60    $04 tu.flags fset              \ minflag++
61
62    min @ 1+  tu.max.min c@ > if
63      \ hour.over
64      0 min !
65      1 hour +!
66      $08 tu.flags fset
67
68      hour @ 1+  tu.max.hour c@ > if
69        \ day.over
70        0 hour !
71        1 day +!
72        $10 tu.flags fset
73        \ fixme: day of year++
74        \ fixme: day of week++ % 7
75
76        day @ 1+  tu.max.day c@ > if
77          \ month.over
78          0 day !
79          1 month +!
80          $20 tu.flags fset
81
82          month @ 1+  tu.max.month c@ > if
83            \ year.over
84            0 month !
85            1 year +!
86            $40 tu.flags fset
87            \ fixme: reset day of year
88          then
89        then
90      then
91    then
92  then
93;