Convert.mesa
Copyright © 1985 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
This interface contains procs for parsing character strings to produce Cedar values (INT, REAL, GMT, and so on), and procs for printing Cedar values to produce character strings.
The IO interface contains analogous procs for use when the character strings are being produced or consumed by a STREAM.
DIRECTORY
BasicTime USING [GMT, Unpacked],
Real USING [MaxSinglePrecision, DefaultSinglePrecision],
Rope USING [ROPE, Text];
Convert: CEDAR DEFINITIONS
= 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 };
Error: ERROR [reason: ErrorType, index: INT];
ErrorType: TYPE = {
syntax, overflow, empty, -- parse errors, index gives error location
invalidBase, unprintableAtom -- unparse errors, index = 0
};
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 [LONG CARDINAL];
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.
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 [LONG CARDINAL];
Accepts whitespaceChar...num?((D|d)?num)?whitespaceChar
CardFromOctalLiteral: PROC [r: ROPE, start: INT ← 0] RETURNS [LONG CARDINAL];
Accepts whitespaceChar...num(B|b)?num?whitespaceChar
CardFromHexLiteral: PROC [r: ROPE, start: INT ← 0] RETURNS [LONG CARDINAL];
Accepts whitespaceChar...num(H|h)?num?whitespaceChar
CardFromWholeNumberLiteral: PROC [r: ROPE, start: INT ← 0] RETURNS [LONG CARDINAL];
Accepts any of the above formats, but is less efficient than any of the above procedures.
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: BOOLTRUE] RETURNS [Text];
! Error[$invalidBase, 0]: base is statically invalid (not IN [2 .. 36]), or literal = 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: LONG CARDINAL, base: Base ← 10, showRadix: BOOLTRUE]
RETURNS
[Text];
! Error[$invalidBase, 0]: base is statically invalid (not IN [2 .. 36]), or literal = 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.
RopeFromReal: PROC [from: REAL, precision: RealPrecision ← Real.DefaultSinglePrecision,
useE: BOOLFALSE]
RETURNS
[Text];
If useE, then uses E format, otherwise uses G format
RopeFromTime: PROC [from: GMT, start: TimePrecision ← years, end: TimePrecision ← minutes,
includeDayOfWeek: BOOLFALSE, useAMPM: BOOLTRUE,
includeZone: BOOLTRUE]
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: BOOLFALSE,
useAMPM: BOOLTRUE, includeZone: BOOLTRUE]
RETURNS
[Text];
Returns a rope representing a time, in the same format as RopeFromTime, but from an unpacked time.
RopeFromBool: PROC [from: BOOL] RETURNS [Text];
Returns "TRUE" or "FALSE".
RopeFromAtom: PROC [from: ATOM, quote: BOOLTRUE] 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: BOOLTRUE] 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: BOOLTRUE] 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: BOOLTRUE]
RETURNS
[REF TEXT];
! Error[$invalidBase, 0]: base is statically invalid (not IN [2 .. 36]), or literal = TRUE and base is not = 8, 10, or 16.
AppendCard: PROC [to: REF TEXT, from: LONG CARDINAL, base: Base ← 10,
showRadix: BOOLTRUE]
RETURNS
[REF TEXT];
! Error[$invalidBase, 0]: base is statically invalid (not IN [2 .. 36]), or literal = TRUE and base is not 8, 10, or 16.
AppendReal: PROC [to: REF TEXT, from: REAL,
precision: RealPrecision ← Real.DefaultSinglePrecision, useE: BOOLFALSE]
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: BOOLFALSE,
useAMPM: BOOLTRUE, includeZone: BOOLTRUE]
RETURNS
[REF TEXT];
AppendUnpackedTime: PROC [to: REF TEXT, from: Unpacked, start: TimePrecision ← years,
end: TimePrecision ← minutes, includeDayOfWeek: BOOLFALSE,
useAMPM: BOOLTRUE, includeZone: BOOLTRUE]
RETURNS
[REF TEXT];
AppendBool: PROC [to: REF TEXT, from: BOOL] RETURNS [REF TEXT];
AppendAtom: PROC [to: REF TEXT, from: ATOM, quote: BOOLTRUE] 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: BOOLTRUE] RETURNS [REF TEXT];
AppendChar: PROC [to: REF TEXT, from: CHAR, quote: BOOLTRUE] RETURNS [REF TEXT];
Real Formatting
FtoRope: PROC [r: REAL, afterDot: [0..Real.MaxSinglePrecision] ← Real.DefaultSinglePrecision]
RETURNS [rope: ROPE];
AppendF: PROC [buffer: REF TEXT, r: REAL,
afterDot: [0..Real.MaxSinglePrecision] ← 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: [0..Real.MaxSinglePrecision] ← Real.DefaultSinglePrecision]
RETURNS [rope: ROPE];
AppendE: PROC [buffer: REF TEXT, r: REAL,
precision: [0..Real.MaxSinglePrecision] ← 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: [0..Real.MaxSinglePrecision] ← Real.DefaultSinglePrecision]
RETURNS [rope: ROPE];
AppendG: PROC [buffer: REF TEXT, r: REAL,
precision: [0..Real.MaxSinglePrecision] ← 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.
END.