System.Date (v8.0)

General discussions about using the Astrobe IDE to program the FPGA RISC5 cpu used in Project Oberon 2013
Post Reply
gray
Posts: 109
Joined: Tue Feb 12, 2019 2:59 am
Location: Mauritius

System.Date (v8.0)

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: 109
Joined: Tue Feb 12, 2019 2:59 am
Location: Mauritius

Re: System.Date (v8.0)

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;

Post Reply