4. Convert
Parsing
Each procedure in this section takes r: ROPE as a parameter, but is perfectly happy to have the client use RefText.TrustTextAsRope to loophole a REF TEXT into ROPE to pass in. This is ok because these procedures do not retain the ROPE or test its type at runtime.
Each procedure in this section raises the following errors:
! Error[$empty, 0] (the input string is empty or contains only whitespace characters; the client might wish to supply a default value in this case)
! 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)
In general, the parsing procedures do not consume the entire input rope, but are willing to stop by reaching the end of the input rope or by seeing whitespace after a valid token.
IntFromRope: PROC [r: ROPE, defaultBase: Base ← 10] RETURNS [INT];
Base:
TYPE = [2..36];
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 [BasicTime.
GMT];
Accepts time in a wide variety of formats (same formats as IO.GetTime).
UnpackedTimeFromRope:
PROC [r:
ROPE]
RETURNS [BasicTime.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 (length of result rope would exceed NAT.LAST characters)
Each "Append..." proc raises the following errors:
! PointerFault (to = NIL)
! BoundsFault (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 [Rope.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:
BOOL ←
TRUE]
RETURNS [Rope.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: BOOL ← FALSE]
RETURNS [Rope.Text];
If useE, prints in "scientific notation". <I cannot explain how "precision" is interpreted, yet, because I do not know. Something to do with number of digits printed ...>
RopeFromTime:
PROC [from: BasicTime.
GMT,
start: TimePrecision ← years, end: TimePrecision ← minutes,
includeDayOfWeek: BOOL ← FALSE, useAMPM: BOOL ← TRUE, includeZone: BOOL ← TRUE]
RETURNS [Rope.Text];
TimePrecision: TYPE = { years, months, days, hours, minutes, seconds, unspecified };
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". <As of October 5, 1983, time zone printing is not implemented.>
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: BasicTime.Unpacked,
start: TimePrecision ← years, end: TimePrecision ← minutes,
includeDayOfWeek: BOOL ← FALSE, useAMPM: BOOL ← TRUE, includeZone: BOOL ← TRUE]
RETURNS [Rope.Text];
Returns a rope representing a time, in the same format as RopeFromTime, but from an unpacked time.
RopeFromBool:
PROC [from:
BOOL]
RETURNS [Rope.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>" is generated for 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 [Rope.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 [Rope.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 literal = TRUE and base is not = 8, 10, or 16.
AppendCard:
PROC [to:
REF
TEXT, from:
LONG
CARDINAL, base: Base ← 10, showRadix:
BOOL ←
TRUE]
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: BOOL ← FALSE]
RETURNS [REF TEXT];
AppendTime:
PROC [to:
REF
TEXT, from: BasicTime.
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: BasicTime.Unpacked,
start: TimePrecision ← years, end: TimePrecision ← minutes,
includeDayOfWeek: BOOL ← FALSE, useAMPM: BOOL ← TRUE, includeZone: BOOL ← TRUE]
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];