Convert.mesa
Copyright Ó 1985, 1986, 1987, 1988, 1991 by Xerox Corporation. All rights reserved.
MBrown on September 17, 1983 11:39 am
Russ Atkinson (RRA) February 19, 1985 7:10:04 pm PST
Beach, February 27, 1985 10:30:40 am PST
Doug Wyatt, January 19, 1987 2:40:33 pm PST
Carl Hauser, January 20, 1988 5:14:25 pm PST
Michael Plass, August 9, 1991 10:37 am PDT
=
BEGIN
GMT: TYPE ~ BasicTime.GMT;
Unpacked: TYPE ~ BasicTime.Unpacked;
ROPE: TYPE ~ Rope.ROPE;
Text: TYPE ~ Rope.Text;
Base: TYPE = [2..36] ¬ 10;
RealPrecision: TYPE = [0 .. Real.MaxSinglePrecision] ¬ Real.DefaultSinglePrecision;
TimePrecision: TYPE = { years, months, days, hours, minutes, seconds, unspecified };
AtomFromTimePrecision: PROC [TimePrecision] RETURNS [ATOM];
TimePrecisionFromAtom: PROC [ATOM] RETURNS [TimePrecision];
Error: ERROR [reason: ErrorType, index: INT];
ErrorType:
TYPE =
MACHINE
DEPENDENT {
syntax, overflow, empty, -- parse errors, index gives error location
invalidBase, unprintableAtom, invalidNetFormat, -- unparse errors, index = 0
(BYTE.LAST)
};
AtomFromErrorType: PROC [ErrorType] RETURNS [ATOM];
ErrorTypeFromAtom: PROC [ATOM] RETURNS [ErrorType];
Parsing
In all cases it is ok to loophole REF TEXT into ROPE to pass to these procedures, using RefText.TrustTextAsRope.
See Section 3.1.1 of the Cedar Language Reference Manual for a description of the notation used for grammars below.
Each "<Type>From..." proc raises the following errors:
! Error[$empty, 0] (if the input string is empty or contains only whitespace characters)
! Error[$syntax, index] (syntax error detected in the input string at the given location)
Each "CardFrom..." or "IntFrom" or "TimeFrom" or "CharFrom" proc raises the following error:
! Error[$overflow, index] (input string cannot be expressed as a CARD or INT or GMT or CHAR)
IntFromRope:
PROC [r:
ROPE, defaultBase: Base ¬ 10]
RETURNS [
INT];
If r (or a prefix of r) consists of whitespaceChar...?(+|-)num?whitespaceChar where num is digit!... and digit is a numeric or alphabetic character that is meaningful in the default base, then convert r according to this base. If r contains a character that is not meaningful in the default base (e.g. 'H in a "decimal" literal), then accept whitespaceChar...?(+|-)wholeNum where wholeNum is a string acceptable to CardFromWholeNumberLiteral below.
CardFromRope:
PROC [r:
ROPE, defaultBase: Base ¬ 10]
RETURNS [
CARD];
Like IntFromRope, but leading minus is not allowed.
RealFromRope:
PROC [r:
ROPE]
RETURNS [
REAL];
Accepts whitespaceChar...?(+|-)realNum where realNum is a string acceptable to RealFromLiteral below.
DIntFromRope:
PROC [r:
ROPE]
RETURNS [
DINT];
Double-precision analog to IntFromRope, default base 10.
DRealFromRope:
PROC [r:
ROPE]
RETURNS [
DREAL];
Double-precision analog to RealFromRope
TimeFromRope:
PROC [r:
ROPE]
RETURNS [
GMT];
Accepts time in a wide variety of formats (same formats as IO.GetTime).
UnpackedTimeFromRope:
PROC [r:
ROPE]
RETURNS [Unpacked];
Accepts time in a wide variety of formats (same formats as IO.GetTime).
BoolFromRope:
PROC [r:
ROPE]
RETURNS [
BOOL];
Accepts if r (or a prefix of r delimited by white space) matches (ignoring case) a prefix of "true", yes" (returning TRUE), "false", or "no" (returning FALSE).
AtomFromRope:
PROC [r:
ROPE]
RETURNS [
ATOM];
Derives a print name by eliminating the leading '$ of r (if any), then making an atom with that print name.
The following procedures accept the same literal formats accepted by the compiler. This means, for instance, that the octal and hex routines demand that a radix character ('B or 'b for octal, 'H or 'h for hex) be present. Numeric literals are always non-negative, and these procedures do not recognize a leading plus or minus sign. The numeric procedures are willing to skip over leading white space, and will terminate the literal on end of string or on trailing white space.
CardFromDecimalLiteral:
PROC [r:
ROPE, start:
INT ¬ 0]
RETURNS [
CARD];
Accepts whitespaceChar...num?((D|d)?num)?whitespaceChar
CardFromOctalLiteral:
PROC [r:
ROPE, start:
INT ¬ 0]
RETURNS [
CARD];
Accepts whitespaceChar...num(B|b)?num?whitespaceChar
CardFromHexLiteral:
PROC [r:
ROPE, start:
INT ¬ 0]
RETURNS [
CARD];
Accepts whitespaceChar...num(H|h)?num?whitespaceChar
CardFromWholeNumberLiteral:
PROC [r:
ROPE, start:
INT ¬ 0]
RETURNS [
CARD];
Accepts any of the above formats, but is less efficient than any of the above procedures.
DCardFromWholeNumberLiteral:
PROC [r:
ROPE, start:
INT ¬ 0]
RETURNS [
DCARD];
Same formats as above, 64-bit precision.
RealFromLiteral:
PROC [r:
ROPE, start:
INT ¬ 0]
RETURNS [
REAL];
Accepts both whitespaceChar...num exponent?whitespaceChar and whitespaceChar...?num.num?exponent?whitespaceChar, where exponent is (E|e)?(+|-)num
RopeFromLiteral:
PROC [r:
ROPE, start:
INT ¬ 0]
RETURNS [
ROPE];
Accepts "extendedChar..."?(L|l)
CharFromLiteral:
PROC [r:
ROPE, start:
INT ¬ 0]
RETURNS [
CHAR];
Accepts both 'extendedChar and digit!...(C|c)
Printing
There are two parallel sets of procs for printing. A proc in the first set returns a rope, while the proc in the second set appends its result to an existing REF TEXT (usually avoiding additional storage allocation) and returns a REF TEXT (usually but not always the same REF as the original).
Each "RopeFrom..." proc raises the following error:
! BoundsFault (if length of result rope would exceed NAT.LAST characters)
Each "Append..." proc raises the following errors:
! PointerFault (if to = NIL)
! BoundsFault (if length of result text would exceed NAT.LAST characters)
Other errors are identical for the two variants of each procedure.
RopeFromInt:
PROC [from:
INT,
base: Base ¬ 10, showRadix:
BOOL ¬
TRUE
]
RETURNS [Text];
! Error[$invalidBase, 0]: base is statically invalid (not IN [2 .. 36]), or showRadix = TRUE and base is not = 8, 10, or 16.
If showRadix = TRUE, returns a rope including a radix character ('B or 'H, not 'D) to make the result a valid Cedar literal (perhaps with a unary minus operator in front).
RopeFromCard:
PROC [from:
CARD,
base: Base ¬ 10, showRadix:
BOOL ¬
TRUE
]
RETURNS [Text];
! Error[$invalidBase, 0]: base is statically invalid (not IN [2 .. 36]), or showRadix = TRUE and base is not = 8, 10, or 16.
If showRadix = TRUE, returns a rope including a radix character ('B or 'H, not 'D) to make the result a valid Cedar literal.
RopeFromDInt: PROC [from: DINT, base: Base ¬ 10, showRadix: BOOL ¬ TRUE] RETURNS [Text];
RopeFromDCard:
PROC [from:
DCARD, base: Base ¬ 10, showRadix:
BOOL ¬
TRUE]
RETURNS [Text];
RopeFromReal:
PROC [from:
REAL,
precision: RealPrecision ¬ Real.DefaultSinglePrecision, useE:
BOOL ¬
FALSE
]
RETURNS [Text];
If useE, then uses E format, otherwise uses G format
RopeFromDReal:
PROC [from:
DREAL,
precision: [0..17] ¬ 15, useE:
BOOL ¬
FALSE
]
RETURNS [Text];
If useE, then uses E format, otherwise uses G format
RopeFromTime:
PROC [from:
GMT,
start: TimePrecision ¬ years, end: TimePrecision ¬ minutes,
includeDayOfWeek:
BOOL ¬
FALSE,
useAMPM:
BOOL ¬
TRUE, includeZone:
BOOL ¬
TRUE
]
RETURNS [Text];
Returns a rope representing a time, for instance "September 16, 1983 7:50 pm PDT". If includeDayOfWeek then prefixes this with "Friday, ". If NOT useAMPM then renders the time of day as "19:50" instead of "7:50 pm". If NOT includeZone then omits the " PDT". If end = $seconds then includes more precision, as in "7:50:05 pm".
To obtain the weekday only, pass includeDayOfWeek = TRUE and pass an empty [start .. end] interval (e.g. start = $months, end = $years). To obtain the month only, pass includeDayOfWeek = FALSE and start = end = $months.
RopeFromUnpackedTime:
PROC [from: Unpacked,
start: TimePrecision ¬ years, end: TimePrecision ¬ minutes,
includeDayOfWeek:
BOOL ¬
FALSE,
useAMPM:
BOOL ¬
TRUE, includeZone:
BOOL ¬
TRUE
]
RETURNS [Text];
Returns a rope representing a time, in the same format as RopeFromTime, but from an unpacked time.
RopeFromTimeRFC822:
PROC [from:
GMT, includeSeconds:
BOOL ¬
TRUE,
includeDayOfWeek:
BOOL ¬
FALSE, useUT:
BOOL ¬
FALSE
]
RETURNS [Text];
Returns a rope representing a time according to the RFC 822 Standard for ARPA Internet Text Messages, for instance "19 Jan 87 14:27:05 PST". If NOT includeSeconds, omits the seconds, as in "19 Jan 87 14:27 PST". If includeDayOfWeek, prefixes the day of the week, as in "Mon, 19 Jan 87 14:27:05 PST". If useUT, uses Universal Time, as in "19 Jan 87 22:27:05 UT".
RopeFromBool:
PROC [from:
BOOL]
RETURNS [Text];
Returns "TRUE" or "FALSE".
RopeFromAtom:
PROC [from:
ATOM, quote:
BOOL ¬
TRUE]
RETURNS [
ROPE];
! Error[$unprintableAtom, 0]: quote = TRUE, and either from = NIL or from's print name is not a valid Cedar identifier.
Return's atom's print name ("<NIL>" if from = NIL). If quote then inserts a leading quote ($) and checks that the print name is a valid Cedar identifier.
RopeFromRope:
PROC [from:
ROPE, quote:
BOOL ¬
TRUE]
RETURNS [Text];
Returns a rope that represents "from" as a literal acceptable to the compiler, i.e. inserts backslash escapes as necessary. If quote then adds an outer pair of quotes ("").
RopeFromChar:
PROC [from:
CHAR, quote:
BOOL ¬
TRUE]
RETURNS [Text];
Returns a rope that represents "from" as a literal acceptable to the compiler, i.e. adds backslash escape as necessary. If quote then inserts a leading quote (').
AppendInt:
PROC [to:
REF
TEXT, from:
INT,
base: Base ¬ 10, showRadix:
BOOL ¬
TRUE
]
RETURNS [
REF
TEXT];
! Error[$invalidBase, 0]: base is statically invalid (not IN [2 .. 36]), or showRadix = TRUE and base is not = 8, 10, or 16.
AppendCard:
PROC [to:
REF
TEXT, from:
CARD,
base: Base ¬ 10, showRadix:
BOOL ¬
TRUE
]
RETURNS [
REF
TEXT];
! Error[$invalidBase, 0]: base is statically invalid (not IN [2 .. 36]), or showRadix = TRUE and base is not 8, 10, or 16.
AppendReal:
PROC [to:
REF
TEXT, from:
REAL,
precision: RealPrecision ¬ Real.DefaultSinglePrecision, useE:
BOOL ¬
FALSE
]
RETURNS [
REF
TEXT];
If useE, then uses E format, otherwise uses G format
AppendDCard:
PROC [to:
REF
TEXT, from:
DCARD,
base: Base ¬ 10, showRadix:
BOOL ¬
TRUE
]
RETURNS [
REF
TEXT];
! Error[$invalidBase, 0]: base is statically invalid (not IN [2 .. 36]), or showRadix = TRUE and base is not 8, 10, or 16.
AppendDReal:
PROC [to:
REF
TEXT, from:
DREAL,
precision: [0..17] ¬ 15, useE:
BOOL ¬
FALSE
]
RETURNS [
REF
TEXT];
If useE, then uses E format, otherwise uses G format
AppendTime:
PROC [to:
REF
TEXT, from:
GMT,
start: TimePrecision ¬ years, end: TimePrecision ¬ minutes,
includeDayOfWeek:
BOOL ¬
FALSE,
useAMPM:
BOOL ¬
TRUE, includeZone:
BOOL ¬
TRUE
]
RETURNS [
REF
TEXT];
AppendUnpackedTime:
PROC [to:
REF
TEXT, from: Unpacked,
start: TimePrecision ¬ years, end: TimePrecision ¬ minutes,
includeDayOfWeek:
BOOL ¬
FALSE,
useAMPM:
BOOL ¬
TRUE, includeZone:
BOOL ¬
TRUE
]
RETURNS [
REF
TEXT];
AppendTimeRFC822:
PROC [to:
REF
TEXT, from:
GMT, includeSeconds:
BOOL ¬
TRUE,
includeDayOfWeek:
BOOL ¬
FALSE, useUT:
BOOL ¬
FALSE
]
RETURNS [
REF
TEXT];
AppendBool:
PROC [to:
REF
TEXT, from:
BOOL]
RETURNS [
REF
TEXT];
AppendAtom:
PROC [to:
REF
TEXT, from:
ATOM, quote:
BOOL ¬
TRUE]
RETURNS [
REF
TEXT];
! Error[$unprintableAtom, 0]: quote = TRUE, and either from = NIL or from's print name is not a valid Cedar identifier.
AppendRope:
PROC [to:
REF
TEXT, from:
ROPE, quote:
BOOL ¬
TRUE]
RETURNS [
REF
TEXT];
AppendChar:
PROC [to:
REF
TEXT, from:
CHAR, quote:
BOOL ¬
TRUE]
RETURNS [
REF
TEXT];
Real Formatting
FtoRope:
PROC [r:
REAL, afterDot: RealPrecision ¬ Real.DefaultSinglePrecision]
RETURNS [
ROPE];
AppendF:
PROC [buffer:
REF
TEXT, r:
REAL,
afterDot: RealPrecision ¬ Real.DefaultSinglePrecision]
RETURNS [
REF
TEXT];
Appends a fixed-point string representation to the buffer, using afterDot places after the decimal point. Examples: FtoRope[-1.23, 3] = "-1.230", FtoRope[-0.023, 2] = "-0.02".
EtoRope:
PROC [r:
REAL, afterDot: RealPrecision ¬ Real.DefaultSinglePrecision]
RETURNS [rope:
ROPE];
AppendE:
PROC [buffer:
REF
TEXT, r:
REAL,
precision: RealPrecision ¬ Real.DefaultSinglePrecision]
RETURNS [
REF
TEXT];
Appends a scientific notation string representation to the buffer, with the given amount of precision. Examples: EtoRope[-1.23, 3] = "-1.23e+0", FtoRope[-0.023, 2] = "-2.3e-2".
GtoRope:
PROC [r:
REAL, precision: RealPrecision ¬ Real.DefaultSinglePrecision]
RETURNS [rope:
ROPE];
AppendG:
PROC [buffer:
REF
TEXT, r:
REAL,
precision: RealPrecision ¬ Real.DefaultSinglePrecision]
RETURNS [
REF
TEXT];
Appends a fixed-point or scientific notation string representation to the buffer, with the given amount of precision. Will use fixed-point notation where it fits in the given precision range.
Network Address Formatting
NetFormat: TYPE = MACHINE DEPENDENT {octal, hex, productSoftware, (BYTE.LAST)};
AtomFromNetFormat: PROC [NetFormat] RETURNS [ATOM];
NetFormatFromAtom: PROC [ATOM] RETURNS [NetFormat];
XNSAddressFromRope: PROC [r: ROPE] RETURNS [XNS.Address];
XNSNetFromRope: PROC [r: ROPE] RETURNS [XNS.Net];
XNSHostFromRope: PROC [r: ROPE] RETURNS [XNS.Host];
XNSSocketFromRope:
PROC [r:
ROPE]
RETURNS [
XNS.Socket];
Parses ROPEs and makes the XNS stuff from it. Raises Error[syntax] if not parsable.
RopeFromXNSAddress: PROC [address: XNS.Address,
format: NetFormat ¬ productSoftware] RETURNS [ROPE];
RopeFromXNSNet: PROC [net: XNS.Net,
format: NetFormat ¬ productSoftware] RETURNS [ROPE];
RopeFromXNSHost: PROC [host: XNS.Host,
format: NetFormat ¬ productSoftware] RETURNS [ROPE];
RopeFromXNSSocket:
PROC [socket:
XNS.Socket,
format: NetFormat ¬ productSoftware]
RETURNS [
ROPE];
Converts the XNS stuff to ROPEs
ArpaAddressFromRope:
PROC [r:
ROPE]
RETURNS [Arpa.Address];
RopeFromArpaAddress:
PROC [address: Arpa.Address]
RETURNS [
ROPE];
AppendArpaAddress: PROC [to: REF TEXT, address: Arpa.Address] RETURNS [REF TEXT];
AppendXNSAddress: PROC [to: REF TEXT, address: XNS.Address,
format: NetFormat ¬ productSoftware] RETURNS [REF TEXT];
AppendXNSNet: PROC [to: REF TEXT, net: XNS.Net,
format: NetFormat ¬ productSoftware] RETURNS [REF TEXT];
AppendXNSHost: PROC [to: REF TEXT, host: XNS.Host,
format: NetFormat ¬ productSoftware] RETURNS [REF TEXT];
AppendXNSSocket:
PROC [to:
REF
TEXT, socket:
XNS.Socket,
format: NetFormat ¬ productSoftware]
RETURNS [
REF
TEXT];
Append the XNS stuff to REF TEXT.