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