SaffronInstance.Mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
James Rauen, June 20, 1988 4:34:50 pm PDT
Last edited by: James Rauen July 14, 1988 7:55:00 pm PDT
This file defines the Instance abstraction, which Saffron uses to represent a Cedar value. Instances are immutable. There are three kinds of instances: static values (values whose concrete representation are known at compile time), runtime values (values whose concrete representation is not known at compile time), and TRASH.
The three kinds of instances can be distinguished with the Static, RuntimeValue, and Trash predicates.
There are several generic procedures which may be applied to any instance. The Type procedure returns the type graph node for the type of the instance. The Code procedure returns a program graph which contains code to place the instance on top of the local (runtime) execution stack. (If the Code procedure is applied to a TRASH instance, it will signal a warning and return a program graph which contains code to place trash (of the correct type) on top of the local execution stack).
DIRECTORY
Rope USING [ROPE],
SaffronBaseDef USING [FListNode, InstanceNode, LocalContextNode, ProgramGraphNode, TypeGraphNodeNode, TypeGraphNodeListNode],
SaffronContextPrivateTypes USING [TypeGraphNodeNode, TypeGraphNodeList],
SaffronTargetArchitecture USING [TargetArchitecture];
SaffronInstance: CEDAR DEFINITIONS ~ BEGIN
OPEN BD: SaffronBaseDef;
Nicknames
ROPE: TYPE ~ Rope.ROPE;
LocalContextNode: TYPE ~ SaffronBaseDef.LocalContextNode;
ProgramGraphNode: TYPE ~ SaffronBaseDef.ProgramGraphNode;
TypeGraphNodeNode: TYPE ~ SaffronBaseDef.TypeGraphNodeNode;
TypeGraphNodeListNode: TYPE ~ SaffronBaseDef.TypeGraphNodeListNode;
TargetArchitecture: TYPE ~ SaffronTargetArchitecture.TargetArchitecture;
Representation
InstanceNode: TYPE ~ SaffronBaseDef.InstanceNode;
Generic Operations
Static: PROC [i: InstanceNode] RETURNS [BOOLEAN];
Return TRUE if i is a constant known at compile time, FALSE otherwise.
RuntimeValue: PROC [i: InstanceNode] RETURNS [BOOLEAN];
Return TRUE if i is a runtime value, FALSE otherwise.
Trash: PROC [i: InstanceNode] RETURNS [BOOLEAN];
Return TRUE if i is TRASH, FALSE otherwise.
Type: PROC [i: InstanceNode] RETURNS [TypeGraphNodeNode];
Return the type graph node for the type of i.
ChangeType: PROC [i: InstanceNode, newType: TypeGraphNodeNode] RETURNS [InstanceNode];
Return a new instance identical to i except for its type, which is replaced by newType. This should only be done if FreelyConform[Type[i], newType] as defined in SaffronTypeConformanceImpl.
Code: PROC [i: InstanceNode] RETURNS [ProgramGraphNode];
Return code to place i on top of the local (runtime) execution stack. If applied to a TRASH instance, signal a warning and code to place trash of the correct type on top of the local execution stack.
GetConcreteRepresentation: PROC [i: InstanceNode] RETURNS [REF ANY];
If i is static, return the concrete representation of i. Otherwise signal a compiler error.
RopeFromInstance: PROC [i: InstanceNode] RETURNS [ROPE];
Return a rope representation of i suitable for debugging and error messages.
Dummies Until Everything's Implemented
MakeDummy: PROC [msg: Rope.ROPE] RETURNS [InstanceNode];
Trash
MakeTrash: PROC [type: TypeGraphNodeNode] RETURNS [InstanceNode];
Runtime Values
MakeRuntime: PROC [type: TypeGraphNodeNode, code: ProgramGraphNode] RETURNS [InstanceNode];
Numeric Types
Discussion
The procedures in this section deal with statically known numerical values.
IntegerValues represent arbitrary integer values (in the mathematical sense) independent of any particular Cedar type. Likewise, RealValues represent arbitrary real values (actually, rational approximations which have terminating binary representations) with arbitrary precision, independent of any particular Cedar type.
The Cedar types which have integer values are the following: the various flavors of INTEGER, the various flavors of CARDINAL, the various flavors of NATURAL, and subranges whose base type is one of these types. In the comments below, these types are referred to as "valid integer types". The valid elements of the INTEGER/CARDINAL/NATURAL types are defined within the procedure InstallBaseTypes in the SaffronContextCreateCTImpl file. The valid elements of subrange types are apparent from the subrange type declarations.
The Cedar types which have real values are the following: all the valid integer types, plus REAL. The valid elements of the REAL type are defined within the procedure InstallBaseTypes in the SaffronContextCreateCTImpl file.
Generic Definitions
NumericType: TYPE = REF ANY;
Must be UnsignedIntegerType, SignedIntegerType, or RealType.
NumericValue: TYPE = REF ANY;
Must be UnsignedIntegerValue, SignedIntegerValue, or RealValue.
Sign: TYPE = {plus, minus};
Integers
IntegerValue: TYPE = REF IntegerValueBody;
IntegerValueBody: TYPE;
InvalidIntegerType: ERROR;
CannotCastInteger: ERROR;
MakeIntegerValue: PROC [j: INT] RETURNS [IntegerValue];
Create and return an integer value with the value j.
ParseIntegerLiteral: PROC [text: ROPE, base: [2..36] ← 10] RETURNS [IntegerValue];
Requirement: text must have the form ( (+ | - | ) (digit)+ ), where each digit is meaningful for base; if not, signal an internal error. Parse text, assuming the specified base, and return the corresponding integer value.
UnparseIntegerValue: PROC [value: IntegerValue, base: [2..36] ← 10] RETURNS [ROPE];
Return a rope representation of value, using the specified base.
CastIntegerValue: PROC [value: IntegerValue, types: TypeGraphNodeListNode] RETURNS [InstanceNode];
If type is a valid integer type, and value is an element of type, return an instance of the given type with the given value. If type is a valid integer type, but value is not an okay element, then signal an error and return an instance of the given type whose value is an arbitrary valid element of the type. If type is not valid, then signal a fatal error.
CanCastIntegerValue: PROC [value: IntegerValue, type: TypeGraphNodeNode] RETURNS [BOOLEAN];
If type is a valid integer type, and value is an element of type, return TRUE. Otherwise return FALSE.
RetrieveIntegerValue: PROC [i: InstanceNode] RETURNS [IntegerValue];
Requirement: i must be static; if it isn't, signal an internal error. If i has a valid integer type, return its integer value. Otherwise, signal an error and return an arbitrary integer value. (i.e., do type checking on i).
DemandIntegerType: PROC ?? for nonstatic instances...this belongs in type stuff.
IsInteger: PROC [i: InstanceNode] RETURNS [BOOLEAN];
Return TRUE if i is an integer instance, FALSE otherwise.
AddIntegers: PROC [i1, i2: IntegerValue] RETURNS [IntegerValue];
Return i1 + i2.
SubtractIntegers: PROC [i1, i2: IntegerValue] RETURNS [IntegerValue];
Return i1 - i2.
MultiplyIntegers: PROC [i1, i2: IntegerValue] RETURNS [IntegerValue];
Return i1 * i2.
DivideIntegers: PROC [i1, i2: IntegerValue] RETURNS [IntegerValue];
If i2 = 0, signal an error and return an arbitrary integer value. Otherwise, return the integer part of i1 / i2.
ModIntegers: PROC [i1, i2: IntegerValue] RETURNS [IntegerValue];
If i2 = 0, signal an error and return an arbitrary integer value. Otherwise, return i1 MOD i2.
NegateInteger: PROC [i: IntegerValue] RETURNS [IntegerValue];
Return -i.
Reals
RealValue: TYPE = REF RealValueBody;
RealValueBody: TYPE;
ParseLiteralReal: PROC [text: ROPE, precision: CARDINAL] RETURNS [RealValue];
AddReals: PROC [r1, r2: RealValue] RETURNS [RealValue];
SubtractReals: PROC [r1, r2: RealValue] RETURNS [RealValue];
MultiplyReals: PROC [r1, r2: RealValue] RETURNS [RealValue];
DivideReals: PROC [r1, r2: RealValue] RETURNS [RealValue];
Generic Operations
IsNumeric: PROC [i: InstanceNode] RETURNS [BOOLEAN];
Return TRUE if i is an integer or real instance, FALSE otherwise.
CoerceIntegerToReal: PROC [i: InstanceNode] RETURNS [InstanceNode];
Foo.
Other Basic Types
Atom
MakeStaticAtom: PROC [value: ATOM, type: TypeGraphNodeNode] RETURNS [InstanceNode];
MakeUnknownAtom: PROC [code: ProgramGraphNode, type: TypeGraphNodeNode] RETURNS [InstanceNode];
AtomValue: PROC [i: InstanceNode] RETURNS [ATOM];
i must be a static atom instance. Return its value.
Boolean
MakeStaticBoolean: PROC [value: BOOLEAN, type: TypeGraphNodeNode] RETURNS [InstanceNode];
MakeUnknownBoolean: PROC [code: ProgramGraphNode, type: TypeGraphNodeNode] RETURNS [InstanceNode];
BooleanValue: PROC [i: InstanceNode] RETURNS [BOOLEAN];
i must be a static boolean instance. Return its value.
Character
MakeStaticChar: PROC [value: CHARACTER, type: TypeGraphNodeNode] RETURNS [InstanceNode];
MakeUnknownChar: PROC [code: ProgramGraphNode, type: TypeGraphNodeNode] RETURNS [InstanceNode];
CharacterValue: PROC [i: InstanceNode] RETURNS [CHARACTER];
i must be a static character instance. Return its value.
Rope
MakeStaticRope: PROC [value: ROPE, type: TypeGraphNodeNode] RETURNS [InstanceNode];
MakeUnknownRope: PROC [code: ProgramGraphNode, type: TypeGraphNodeNode] RETURNS [InstanceNode];
RopeValue: PROC [i: InstanceNode] RETURNS [ROPE];
i must be a static rope instance. Return its value.
Constructed Types
MakeList: PROC [elements: LIST OF InstanceNode, listType: TypeGraphNodeNode] RETURNS [i: InstanceNode];
Procedure/Program Frames
MakeFrame: PROC [procType: BD.TypeGraphNodeNode, definingContext: BD.LocalContextNode, fields: BD.FListNode, code: BD.ProgramGraphNode] RETURNS [i: InstanceNode];
END.