-- Convert.mesa, definitions for safe number/string conversions
-- Russ Atkinson, August 26, 1982 5:23 pm

DIRECTORY
Real USING [DefaultSinglePrecision, MaxSinglePrecision],
Rope USING [ROPE],
Time USING [defaultTime, Packed];

Convert: CEDAR DEFINITIONS = BEGIN OPEN Real, Rope;

Base: TYPE = [2..36];
CARD: TYPE = LONG CARDINAL;
Precision: TYPE = [0..MaxSinglePrecision];

Index: TYPE = INT;
MaxIndex: INT = LAST[INT];

ErrorKind: TYPE = {badFormat, empty, overflow, badIndex};

Value: TYPE = RECORD [value: SELECT kind: * FROM
unsigned =>
[unsigned: CARD ← 0, base: Base ← 10],
signed =>
[signed: INT ← 0, base: Base ← 10],
real =>
[real: REAL ← 0.0, precision: Precision ← DefaultSinglePrecision, useE: BOOLFALSE],
time =>
[time: Time.Packed ← Time.defaultTime, useDate: BOOLTRUE,
useTime: BOOLTRUE, useZone: BOOLFALSE],
error =>
[kind: ErrorKind ← badFormat]
ENDCASE];
DefaultValue: Value = [signed[0]];
DefaultUnsigned: Value = [unsigned[0]];
DefaultSigned: Value = [signed[0]];
DefaultReal: Value = [real[0.0]];
DefaultTime: Value = [time[Time.defaultTime]];

Text: TYPE = RECORD [text: SELECT kind: * FROM
string => [string: REF READONLY TEXT],
rope => [rope: ROPE],
get => [get: Get],
ENDCASE];
DefaultText: Text = [rope[NIL]];

Get: TYPE = PROC [INT] RETURNS [CHAR];
Put: TYPE = PROC [CHAR];

ValueToRope: PROC [value: Value] RETURNS [ROPE];
ValueToRefText: PROC [value: Value] RETURNS [REF TEXT];
MapValue: PROC [put: Put, value: Value];

Parse: PROC [text: Text, template: Value ← DefaultValue,
pos: INT ← 0, size: INT ← MaxIndex]
RETURNS [value: Value, stop: Index];

IntFromRope: PROC [rope: ROPE] RETURNS [INT] = INLINE {
v: Value = Parse[[rope[rope]]].value;
RETURN [NARROW[v, Value[signed]].signed]};
-- illustration of how to use Parse
-- can raise RTTypesBasic.NarrowFault

END.