Ptr: TYPE = LONG POINTER;
UZone: TYPE = LONG POINTER TO UZoneObject;
UZoneObject:
TYPE =
RECORD[
new: PROC[self: UZone, size: CARDINAL] RETURNS[LONG POINTER],
free: PROC[self: UZone, object: LONG POINTER]
];
CHARPtr: TYPE ~ RECORD [ptr: POINTER TO RawChars ← NIL];
RawChars: TYPE = RECORD [PACKED SEQUENCE COMPUTED CARD OF CHAR];
PutD:
PUBLIC
PROCEDURE [i:
INT] = {
PrintD: PROCEDURE [value: UNSPEC32] = MACHINE CODE {
"+#define printd(value) XR←Msg(-3, \" %d \", (value) ).printd" };
PrintD[i];
};
PutChar:
PUBLIC
PROCEDURE [ch:
CHAR] = {
CharInner:
PROC [buf: CHARPtr, nBytes:
INT] =
TRUSTED
MACHINE
CODE {
s: STRING ← [4];
buf: CHARPtr;
s[0] ← ch;
s[1] ← 0C;
s[2] ← 0C;
s[3] ← 0C;
buf ← LOOPHOLE[LOOPHOLE[s, CARD]+UNITS[TEXT[0]]];
CharInner[buf: buf, nBytes: 1];
};
Order of the declarations and their initialization is important.
GetSystemUZone:
PUBLIC
PROC
RETURNS [
UNCOUNTED
ZONE] = {
RETURN [zhs];
};
NewHeapObject:
PROC [self: UZone, size:
CARDINAL]
RETURNS [p: Ptr] = {
p ← Malloc[size*SIZE[WORD]];
};
FreeHeapObject:
PROC [self: UZone, object: Ptr] = {
Free[object];
};
Malloc:
PROC [size:
CARDINAL]
RETURNS [ptr: Ptr] =
TRUSTED
MACHINE
CODE {
"XR←malloc"
};
Free:
PROC [ptr: Ptr] =
TRUSTED
MACHINE
CODE {
"XR𡤏ree"
};
rZnHeapSystem: UZoneObject ← [new: NewHeapObject, free: FreeHeapObject];
zhs: UNCOUNTED ZONE ← LOOPHOLE[@rZnHeapSystem];
PutReal:
PUBLIC
PROCEDURE [r:
REAL] = {
PutRealInner:
PROCEDURE [x:
LONG
POINTER
TO
REAL] =
TRUSTED MACHINE CODE {
"*#define PutReal(x) XR←Msg(-3, \"%4.1f\", *(float *)x).PutReal";};
PutRealInner[@r];
};
AlmostEqual:
PUBLIC
PROCEDURE [y, x:
REAL, distance:
INTEGER [-126..0]]
RETURNS [BOOLEAN] = {
RETURN[RealFns.AlmostEqual[y, x, distance]];
RETURN[x = y];
};
milSecondsPerSecond: CARDINAL = 1000;
CurrentTime:
PUBLIC
PROCEDURE
RETURNS [currentTime:
LONG
CARDINAL] = {
CurrentTimeInner:
PROCEDURE [x:
LONG
POINTER
--TO 10 byte structure--]
RETURNS [LONG CARDINAL] = TRUSTED MACHINE CODE {
"%<sys/types.h>\n<sys/timeb.h>\n*#define GetMSec(x) (ftime((struct timeb *)x), (((struct timeb *)x)->time * 1000) + ((struct timeb *)x)->millitm).GetMSec";
};
a: ARRAY [0..4] OF CARD; -- just has to be 10 bytes for the unix time function
RETURN[CurrentTimeInner[@a]];
};