DIRECTORY
Basics USING [DoubleAnd, DoubleShiftRight, LongNumber],
BasicTime USING [GetClockPulses, PulsesToMicroseconds],
Commander USING [CommandProc, Register],
IO USING [time, PutFR, STREAM],
PascalBasic,
Process USING [priorityNormal, SetPriority],
Rope USING [Fetch, Length],
SafeStorage USING [GetSystemZone],
UnsafeStorage USING [GetSystemUZone];
PascalBasicImpl:
CEDAR
MONITOR
IMPORTS
Basics, BasicTime, Commander, IO, Process, Rope, SafeStorage, UnsafeStorage
EXPORTS PascalBasic =
BEGIN OPEN PascalBasic;
V A R I A B L E S
Note: These variables are the reason why the Pascal
runtime environment isn't re-entrant at the moment.
PascalZone: PUBLIC UNCOUNTED ZONE;
PascalStaticZone: PUBLIC UNCOUNTED ZONE;
z: PUBLIC ZONE; -- for the runtime's own use
subsystemName: PUBLIC ROPE;
commandLineTail: PUBLIC ROPE;
clientData: PUBLIC REF ANY;
ttyInputStream: PUBLIC IO.STREAM;
ttyOutputStream: PUBLIC IO.STREAM;
startTime: LONG CARDINAL;
S I G N A L S
NumericInputError: PUBLIC SIGNAL = CODE;
PascalHalt: PUBLIC SIGNAL = CODE;
AttemptToDisposeInvalidPointer: PUBLIC SIGNAL = CODE;
P R O C E D U R E S
SubsystemProcRec: PUBLIC ProcRec;
ExclusiveProc:
PUBLIC ENTRY CommandProc =
TRUSTED BEGIN
ENABLE
UNWIND =>
Process.SetPriority[Process.priorityNormal];
commandLineTail𡤌md.commandLine;
clientData𡤌md.procData.clientData;
ttyInputStream𡤌md.in;
ttyOutputStream𡤌md.out;
SubsystemProcRec.p[];
END;
PascalShiftR:
PROC [t:
--nonneg--
INT, lg:
NAT]
RETURNS [
INT] =
INLINE {
RETURN [Basics.DoubleShiftRight[[li[t]],lg].li]
};
PascalDIVPower2:
PUBLIC
PROC [i:
INT, lg:
NAT]
RETURNS [
INT] = {
RETURN [IF i >= 0 THEN PascalShiftR[i, lg] ELSE -PascalShiftR[-i, lg]];
};
PascalMask:
PROC [a, b:
INT]
RETURNS [
INT] =
INLINE {
RETURN [Basics.DoubleAnd[[li[a]], [li[b]]].li]
};
PascalMODPower2Mask:
PUBLIC
PROC [i:
INT, mask:
--nonneg--
INT]
RETURNS [
INT] = {
RETURN [IF i >= 0 THEN PascalMask[i, mask] ELSE -PascalMask[-i, mask]];
};
PascalRegister:
PUBLIC
PROCEDURE[name:
ROPE, proc: UnsafeCommandProc] =
BEGIN
SubsystemProcRec.p ← proc;
subsystemName ← name;
Commander.Register[key: name, proc: ExclusiveProc, doc: "A Pascal program"];
END;
PascalDATE:
PUBLIC
PROCEDURE [a:
LONG
POINTER
TO Alfa] =
TRUSTED BEGIN OPEN IO, Rope;
s: ROPE ← PutFR[v1: IO.time[]];
s contains something like "March 26, 1982 2:47 pm"
i: CARDINAL;
day, yr: INT;
FOR day ← 1, day+1 WHILE Fetch[s, day-1]#' DO ENDLOOP;
FOR yr ← day+1, yr+1 WHILE Fetch[s, yr-1]#' DO ENDLOOP;
IF Fetch[s, day+1] NOT IN ['0..'9] THEN day ← day-1;
FOR i IN [0..1] DO a[1+i] ← Fetch[s, day+i] ENDLOOP;
a[3] ← '-;
FOR i IN [0..2] DO a[4+i] ← Fetch[s, i] ENDLOOP;
a[7] ← '-;
FOR i IN [0..1] DO a[8+i] ← Fetch[s, yr+2+i] ENDLOOP;
FOR i IN [10..LAST[AlfaIndex]] DO a[i] ← ' ENDLOOP;
END; -- of PascalDATE
PascalTIME:
PUBLIC
PROCEDURE [a:
LONG
POINTER
TO Alfa] =
TRUSTED BEGIN OPEN IO, Rope;
s: ROPE ← PutFR[v1: IO.time[]];
s contains something like "March 26, 1982 2:47 pm"
i: CARDINAL;
time, j: INT ← 0;
FOR group: [1..3]
IN [1..3]
DO
FOR time ← time+1, time+1 WHILE Fetch[s, time-1]#' DO ENDLOOP;
ENDLOOP;
i ← 1;
FOR j IN [time..Length[s]) DO a[i] ← Fetch[s, j]; i ← i+1 ENDLOOP;
FOR i IN [i..LAST[AlfaIndex]] DO a[i] ← ' ENDLOOP;
END; -- of PascalTIME
PascalReadClock:
PUBLIC
PROCEDURE
RETURNS [PascalInteger] =
BEGIN
RETURN[(BasicTime.PulsesToMicroseconds[BasicTime.GetClockPulses[]]-startTime+500)/1000];
END; -- ms since program start
Initialization
TRUSTED {PascalZone ← UnsafeStorage.GetSystemUZone[];
PascalStaticZone ← UnsafeStorage.GetSystemUZone[]};
z ← SafeStorage.GetSystemZone[];
startTime ← BasicTime.PulsesToMicroseconds[BasicTime.GetClockPulses[]];
END. -- PascalBasicImpl