file: PascalBasicImpl.mesa
last modified by Ramshaw, February 3, 1984 8:45 pm
written by McCreight, December 19, 1980 10:44 AM
Changed by Pavel on May 9, 1985 5:17:19 pm PDT
Michael Plass, September 27, 1985 10:06:40 am PDT
the basics of Pascal runtime support in Cedar:
storage, arithmetic, date, time, stringcompare, and CommandProc stuff
May 9, 1985: Pavel changed this into a MONITOR with ExclusiveProc as its only ENTRY as part of moving it to Cedar6.0. This replaced a scheme involving Resource.Acquire on the atom which was the name of the program.
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