General discussions about using the Astrobe IDE to program the FPGA RISC5 cpu used in Project Oberon 2013
-
gray
- Posts: 82
- Joined: Tue Feb 12, 2019 2:59 am
- Location: Mauritius
Post
by gray » Mon Oct 25, 2021 9:19 am
The new System.Date procedure in v8.0:
Code: Select all
PROCEDURE Date*;
(* ... *)
BEGIN
(* ... *)
IF S.class = Texts.Int THEN (*set clock*)
(* ... *)
IF (day >= 1) & (day <= 31) & (mo >= 1) & (mo <= 12) & (yr >= 0) & (yr <= 63) THEN
dt := ((((yr*16 + mo)*32 + day)*32 + hr)*64 + min)*64 + sec;
Kernel.SetClock(dt)
END
ELSE (*read clock*)
dt := Oberon.Clock()
END;
Texts.WriteClock(W, dt); EndLine
END Date;
can leave 'dt' undefined if one of the integer arguments has an out-of-range value. 'Texts.WriteClock(W, dt)' will then print a value that is most likely not correct.
I have fixed this thusly OMM:
Code: Select all
PROCEDURE Date*;
(* ... *)
BEGIN
(* ... *)
IF S.class = Texts.Int THEN (*set clock*)
(* ... *)
IF (day >= 1) & (day <= 31) & (mo >= 1) & (mo <= 12) & (yr >= 0) & (yr <= 63) THEN
dt := ((((yr*16 + mo)*32 + day)*32 + hr)*64 + min)*64 + sec;
Kernel.SetClock(dt)
END
END;
dt := Oberon.Clock();
Texts.WriteClock(W, dt); EndLine
END Date;
This has the additional advantage that we can verify that setting the clock via 'Kernel.SetClock' has worked.
-
gray
- Posts: 82
- Joined: Tue Feb 12, 2019 2:59 am
- Location: Mauritius
Post
by gray » Thu Oct 28, 2021 5:21 am
Checking for the correctness of the date and time actually set is also useful as we actually can set the clock even with incorrect parameters.
Here are two example cases with incorrect parameters where the clock gets set nonetheless. Typos happen.
Code: Select all
System.Date 28 10 n21 10 20 30
System.Date 28 10 21 10 20
Here's the variant I use that does a more thorough argument checking, also for the ranges of hours, mins, and secs.
Code: Select all
PROCEDURE Date*;
VAR
S: Texts.Scanner;
arg: ARRAY 6 OF LONGINT; (* day, month, year, hour, mins, secs *)
dt, i: LONGINT;
BEGIN
Texts.WriteString(W, "System.Date"); EndLine;
Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos);
Texts.Scan(S); i := 0;
WHILE (S.class = Texts.Int) & (i < 6) DO
arg[i] := S.i; Texts.Scan(S); INC(i)
END;
IF i = 6 THEN
IF (arg[0] >= 1) & (arg[0] <= 31) & (arg[1] >= 1) & (arg[1] <= 12) & (arg[2] >= 0) & (arg[2] <= 63)
& (arg[3] >= 0) & (arg[3] <= 23) & (arg[4] >= 0) & (arg[4] <= 59) & (arg[5] >= 0) & (arg[5] <= 59) THEN
dt := ((((arg[2]*16 + arg[1])*32 + arg[0])*32 + arg[3])*64 + arg[4])*64 + arg[5];
Oberon.SetClock(dt)
END
END;
dt := Oberon.Clock();
Texts.WriteClock(W, dt); EndLine
END Date;