CCTypes.mesa
Sturgis: March 24, 1990 3:17:07 pm PST
theimer May 17, 1989 3:56:12 pm PDT
Last changed by Theimer on June 28, 1989 12:26:55 pm PDT
Spreitze, January 9, 1992 9:03 am PST
DIRECTORY
CedarCode USING[Operator],
CirioSyntacticOperations USING[NameArgPair, ParseTree],
CirioTypes USING[CompilerContext, Mem, Node, Type, TypeClass, TypedCode
, BinaryTargetTypes, CCTypeProcs, ConformanceCheck, IdFieldCase, LR],
IO USING[STREAM],
Rope USING[ROPE];
CCTypes: CEDAR DEFINITIONS SHARES CirioTypes =
BEGIN OPEN CirioTypes;
ROPE: TYPE ~ Rope.ROPE;
Note: Because not all of these procedures are implemented in CCTypesImpl, we indicate for each where it is implemented.
Operator: TYPE = CedarCode.Operator;
LR: TYPE = {left, right, unary, nary};
LR: TYPE = CirioTypes.LR;
BinaryTargetTypes: TYPE = RECORD[tLeft, tRight: Type];
BinaryTargetTypes: TYPE = CirioTypes.BinaryTargetTypes;
We must create a Cedar Compiler Context
CC: TYPE = CompilerContext;
CreateCedarCompilerContext: PROC RETURNS[CompilerContext];
A CompilerContext has a name scope, it can be set any number of times. We set it as follows:
This name scope may be an ampersand context, a frame, or, more usually, the following compound name scope:
CreateCompoundNameScope: PROC[ampersandContext1, ampersandContext2, targetWorldContext: Node, cc: CC] RETURNS[Node];
At the moment, we do not check that the parameters are as claimed. If they are not, havoc will ensue.
&identifiers behave as follows: for loads, we try ampersandContext1, then ampersandContext2. For stores, we only use ampersandContext1.
GlobalScopeIndex: CARD = 1;
Scope index at which to find the global frame name scope.
Local name scopes are indexed above this.
Ampersand name scopes are indexed from 0 to GlobalScopeIndex-1.
Some standard types are available from the CompilerContext
These types are installed in the CompilerContext as follows. For each of these types, the CreateCedarCompilerContext routine calls an appropriate type creation routine. That routine will call the appropriate get routine listed below. Since the type has not yet been installed in the CompilerContext, the get routine will return NIL. Seeing NIL, the type creation routine will create a type and return it to the CreateCedarCompilerContext routine. (If the create routine saw non NIL, it would return what it saw.) CreateCedarCompilerContext then installs the returned type in the CompilerContext. This installed type will be returned by subsequent calls to the get routine, and hence will also be returned by subsequent calls to the type creation routine.
Change on May 14, 1991 by MJS: When target world and local world are different, that won't work because CreateCedarCompilerContext doesn't have its hands on a world. Instead, for types actually reified in the debuggee, NewRMTW.CreateRemoteMimosaTargetWorld calls the appropriate Set*Type routine after analyzing CirioRopeHelper. Although CreateRemoteMimosaTargetWorld is called twice for a cc for a remote world (first for the remote world, second for the local one), a Boolean argument controls whether the Set*Type routines are called.
The "insist" argument controls whether an error is raised or NIL is returned for as-yet-undefined types.
GetWrongType: PROC[cc: CC] RETURNS[Type];
GetNodeType: PROC[cc: CC] RETURNS[Type];
GetBooleanType: PROC[cc: CC] RETURNS[Type];
SetBooleanType: PROC[cc: CC, t: Type];
GetCharType: PROC[cc: CC] RETURNS[Type];
SetCharType: PROC[cc: CC, t: Type];
GetCedarNumericType: PROC[desc: NumericDescriptor, cc: CC, insist: BOOL] RETURNS[Type];
SetCedarNumericType: PROC[cc: CC, desc: NumericDescriptor, t: Type];
GetRopeType: PROC[cc: CC] RETURNS[Type];
SetRopeType: PROC[cc: CC, t: Type];
GetAnyTargetType: PROC[cc: CC] RETURNS[Type];
SetRefAnyType: PROC[cc: CC, t: Type];
GetRefAnyType: PROC[cc: CC] RETURNS[Type];
GetNilRefType: PROC[cc: CC] RETURNS[Type];
GetNilPointerType: PROC[cc: CC] RETURNS[Type];
SetNilPointerType: PROC[cc: CC, t: Type];
GetAmpersandContextType: PROC[cc: CC] RETURNS[Type];
GetAmpersandVarType: PROC[cc: CC] RETURNS[Type];
NumericDescriptor: TYPE = RECORD[
nBits: INT,
basicCases: SELECT primary: * FROM
real => [],
signed => [
cases: SELECT secondary: * FROM
full => [],
subRange => [bottom, top: INT32],
ENDCASE],
unsigned => [
cases: SELECT secondary: * FROM
full => [],
subRange => [bottom, top: CARD32],
ENDCASE],
ENDCASE];
The following type is used to support the Conforms test. A hash table, concerning pairs of types, is maintained in the compiler context cc. This algorithm is described and implemented in CCTypesImpl.
ConformanceCheck: TYPE = {yes, dontKnow, no};
ConformanceCheck: TYPE = CirioTypes.ConformanceCheck;
The following routine supports the Coerce object routines. It is called before the object routine is called. If the value already conforms to the target type, the target class is $amnode, or the target class is $wrong, then the object routine is never called.
TryStandardCoercion: PROC[targetType: CirioTypes.Type, tc: TypedCode, continueCoerce: PROC RETURNS[TypedCode], cc: CC] RETURNS[TypedCode];
The following routine supports the BinaryOperandTypes object routines. It is called before the object routine is called. If either type class is $amnode, then it returns [thatType, thatType]. If the op is assign, it checks that the right type conforms to the target type of the left; if so it returns [left, right], if not it generates an error. If neither of these cases holds, it calls BinaryOperandTypesInner.
StandardBinaryOperandTypes: PROC[op: Operator, left, right: Type, BinaryOperandTypesInner: PROC[op: Operator, left, right: Type, cc: CC, oc: Type] RETURNS[BinaryTargetTypes], cc: CC, oc: Type] RETURNS[BinaryTargetTypes];
The following procedures provide access to the local Cedar target world. This access is needed, for example, to support various ampersand routines used in the debugger tools. The registration routine must be called early and exactly once. (The debugger tool and many ampersand routines run in the local Cedar target world.)
LocalCedarTargetWorld: TYPE = REF LocalCedarTargetWorldBody;
LocalCedarTargetWorldBody: TYPE = RECORD[
createNodeFromRefAny: PROC[refAny: REF ANY, lctw: LocalCedarTargetWorld, cc: CC] RETURNS[Node], -- this may be de-implemented
createFrameNodeForSelf: PROC[lctw: LocalCedarTargetWorld, cc: CC] RETURNS[Node],
data: REF ANY];
createNodeFromRefAny returns a Node for the target value of the refAny, that is, if refAny is NEW[CARD�], then node ← createNodeFromRefAny[refAny, lctw] will return a Node containing a CARD equal to 27. CedarCode.GetTypeOfNode[node] returns a Cirio local target world Type for CARD.
createFrameNodeForSelf returns a Frames IndirectFrameNode for the caller to createFrameNodeForSelf.
RegisterLocalCedarTargetWorld: PROC[lctw: LocalCedarTargetWorld, cc: CC];
must be called exactly once early in the game, certainly before any calls on CreateNodeFromRefAny and GetCirioAddressType.
CreateNodeFromRefAny: PROC[refAny: REF ANY, cc: CC] RETURNS[Node];
behaves as described for LocalCedarTargetWorldBody.createNodeFromRefAny, using the localCedarTargetWorld previously registered with cc.
CreateFrameNodeForSelf: PROC[cc: CC] RETURNS[Node];
behaves as described for LocalCedarTargetWorldBody.createFrameNodeForSelf, using the createFrameNodeForSelf previously registered with cc, followed by some appropriate manipulations.
GetCirioAddressType: PROC[cc: CC] RETURNS[Type];
returns a cirio Type for CirioTypes.CirioAddress. (RegisterLocalCedarTargetWorld must have been previously called.)
Various errors can occur during parsing, compiling, or interpretation.
CCError: ERROR[case: CCErrorCase, msg: ROPE];
implemented in CCTypesImpl
CCErrorCase: TYPE = {none, syntax, operation, typeConformity, unimplemented, cirioError};
The first case (none) is to use for initializing variables to indicate that no error has occurred.
The next three are client errors, the last two are cirio deficiencies.
syntax: there is a syntactical error in the client supplied text
operation: an attempt to perform an operation on a value that does not supply that operation. e.g., extract a sub field from an integer.
typeConformity: an attempt to use a value of incorrect type.
unimplemented: the client has attempted to use a missing feature
cirioError: the client has tripped over a bug in Cirio.
These procedures provide the Cedar compilers with their access to compile time type information. (They are also used by the run time routines which must discriminate between node types.) These procedures are implemented object style. Roughly, there is a different collection of implementing procedures for each type class. One of the parameters is specified as the standard control parameter. This is usually either a Type or TypedCode. However, there is an optional explicit control parameter, named oc. The object procedure is chosen as follows. First, we choose a type from which to select an object procedure. If oc is non-nil, oc is the type. Otherwise, we use the standard control parameter. (If this is TypedCode, we use the type field of that parameter.) Having chosen the control type, we check to see if it has an appropriate object procedure. If so, we call that procedure. If not, we check to see if it has a default type. If so, we iterate this mechanism using as the next control type the default type of the current control type. Finally, if we reach the NIL default type, we try one of two standard defaults as the contorl type. For a direct type, we use a standard default direct type. For an indirect type we use a standard default indirect type. If this last ditch attempt does not produce a procedure, then we generate CCError[operation].
At the moment, the first stage implementations of these procedures are located in CirioTypesImpl.mesa.
Conformance checking is based on the following notion (tersely explained in TypeNotes.tioga). A Cedar type is a family of ordinary types. An indirect to a Cedar type is a family consisting of a single ordinary type: the union of indirects to each ordinary type in the given family. Conformance checking for indirects depends on whether the nominal target type is a singleton family, or contains more than one type.
Conforms: PROC[valType, varType: Type, cc: CC, oc: Type ← NIL] RETURNS[BOOLEAN];
Returns true if it is ok for a variable of type varType to hold a value of type varType. (This is less restrictive than Assignable would be. Assignable would be Storable(valType, GetLTargetType(GetIndirectType(varType))).)
This is not a complete test for legality, for example, it ignores issues of target world compatibility.
TypeNotes.tioga contains a (very) terse discussion of the ideas behind Conforms, Storable, CheckFamilyInclusion, and IsaSingleton.
Note: the first level object routine calls a routine in CCTypesImpl to mantain a hash table of currently active pairs as well as known pairs. Further, these routines recurse through calls on CheckConformance.
valType is the standard control parameter.
Storable: PROC[valType, indirectType: Type, cc: CC, oc: Type ← NIL] RETURNS[BOOLEAN];
Returns true if it is ok to store a value of type valType through an indirect of type indirectType. The standard default implementation is Conforms[valType, GetLTargetType[indirectType], cc].
valType is the standard control parameter.
CheckConformance: PROC[valType, varType: Type, cc: CC, oc: Type ← NIL] RETURNS[ConformanceCheck];
This is the recursive procedure called by Conforms. During the computation it will recursively call CheckConformance. NotKnown is a possible answer at assorted deep levels of recursion.
Note: the first level object routine (in CirioTypesImpl) calls a routine in CCTypesImpl to mantain a hash table of currently active pairs as well as known pairs.
valType is the standard control parameter.
CheckFamilyInclusion: PROC[valType, varType: Type, cc: CC, oc: Type ← NIL] RETURNS[BOOLEAN];
valType and varType are treated as families of types. This procedure returns TRUE if valType I varType. This routine is called by the CheckConformance object routine of an indirect, when the target type of either indirect (valType, varType) is not a singleton.
valType is the standard control parameter.
IsASingleton: PROC[type: Type, cc: CC, oc: Type ← NIL] RETURNS[BOOLEAN];
This routine is called by the standard indirect CheckConformance object procedure, applied to the RTarget types of the two given indirect types. If it returns TRUE for both RTargetTypes involved in the CheckConformance, then CheckConformance is implemented as CheckConformance(RTargetType(valType), RTargetType(varType) and CheckConformance(RTargetType(varType), RTargetType(valType). If either return false, then the indirect CheckCOnformance is implemented as CheckFamilyInclusion(RTargetType(valType), RTargetType(varType)).
This routine is also called by the standard indirect LTargetType routine. It is applied to the IsASingleton(RTargetType), then LTargetType returns RTargetType. If NOT IsASingleton(RTargetType), then LTargetType returns the empty type.
type is the standard control parameter.
BinaryOperandTypes: PROC[op: Operator, left, right: Type, cc: CC, oc: Type ← NIL] RETURNS[BinaryTargetTypes];
op one of: plus, minus, div, mult, mod, le, lt, eq, gt, ge, and, or
Produces an appropriate pair of argument types for op, given that one has to start with values who's types are left and right.
left is the standard control parameter.
IsAnIndirect: PROC[type: Type, cc: CC, oc: Type ← NIL] RETURNS[BOOLEAN];
Returns true if type is an indirect
type is the control parameter
GetLTargetType: PROC[type: Type, cc: CC, oc: Type ← NIL] RETURNS[Type];
Intended that indirects will return their target type and $amnode will return $amnode.
Default implementation for indirect types is: if IsSingleton[GetTargetTypeOfIndirect[type]], then return GetTargetTypeOfIndirect[type], else return the empty type;
type is the control parameter.
GetRTargetType: PROC[type: Type, cc: CC, oc: Type ← NIL] RETURNS[Type];
Intended that indirects will return their target type and $amnode will return $amnode.
Default implementation for indirect types is GetTargetTypeOfIndirect[type]];
type is the control parameter.
GetFieldsType: PROC[rcdType: Type, cc: CC, oc: Type ← NIL] RETURNS[Type];
rcdType is a record type. Returns the type of the fields of the record
rcdType is the control parameter.
GetRefType: PROC[rhs: Type, cc: CC, oc: Type ← NIL] RETURNS[Type];
Returns a ref type whose nominal target is rhs. If rhs is some sort of variant (ANY, Sequence, or VariantRecord), then the type produced by this procedure will, in fact, be some sort of union type.
rhs is the standard control parameter.
IdFieldCase: TYPE = {yes, possible, no};
IdFieldCase: TYPE = CirioTypes.IdFieldCase;
HasIdField: PROC[id: ROPE, fieldContext: Type, cc: CC, oc: Type ← NIL] RETURNS[IdFieldCase];
Assumes that fieldContext is a record-like type. Returns yes if id is the name of one of the fields of the record-like type, possible if id appears as a field in one of the variants, or no if id can not appear as a field name.
fieldContext is the control parameter.
ContainsVariance: PROC[type: Type, cc: CC, oc: Type ← NIL] RETURNS[BOOLEAN];
Returns true if type is a not-fully-discriminated variant record, or if it is record-like and some (possiby very nested) field has the type of a not-fully-discriminated variant record.
type is the standard control parameter
GetNVariants: PROC[type: Type, cc: CC, oc: Type ← NIL] RETURNS[INT];
Returns 1 unless type is a (undiscriminated or partially discriminated) variant record. Returns the number of variants possible at the current level of discrimination.
type is the standard control parameter
AsIndexSet: PROC[type: Type, cc: CC, oc: Type ← NIL] RETURNS[Type];
Applies only to discrete numeric types and enumerated types. Returns given type argument except when the type is full-signed, in which case it returns a subrange starting at 0 and ending at LAST[type]. This is a "feature" of Cedar.
type is the standard control paramter.
Operand: PROC[op: Operator, lr: LR, tc: TypedCode, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
op one of: plus, minus, div, mult, mod, le, lt, eq, gt, ge, and, or, not, max, min
Extends the code tc so that the resulting type is appropriate as an argument to the operation op. The parameter, lr, specifies whether this is to be a left, right, unary, or nary argument to the operation.
tc.type is the standard control parameter.
ApplyOperand: PROC[operatorType: Type, operand: CirioSyntacticOperations.ParseTree, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
Compiles the operand as appropriate for the operator. (The operator can be an array or a procedure.)
operatorType is the standard control parameter.
IndexOperand: PROC[operatorType: Type, operand: CirioSyntacticOperations.ParseTree, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
the operand as appropriate for the operator. (The operator can be a ref to an array etc.)
operatorType is the standard control parameter.
CoerceToType: PROC[targetType: Type, tc: TypedCode, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
Extends the code tc so that the resulting type is assignable to targetType. The first level object routine (in CirioTypesImpl) first calls CCTypesImpl.TryStandardCoercion. If the tc.type already conforms to targetType, then tc is returned as the result. If the class of targetType is either $amnode or $wrong, then tc is extended in the appropirate manner and the extended code is returned. If these three conditions fail, then an object routine is called in the standard manner.
tc.type is the standard control parameter.
BinaryOp: PROC[op: Operator, left, right: TypedCode, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
op one of: plus, minus, div, mult, mod, le, lt, eq, gt, ge, and, or
left and right have already been coerced to be an appropriate pair of types for op. Combines left and right with additional code so as to perform op on the results of left and right.
left.type is the standard control parameter.
UnaryOp: PROC[op: Operator, arg: TypedCode, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
op one of: plus, minus, not
arg has already been coerced to be an appropriate type for op. Combines arg with additional code so as to perform op on the result of arg.
arg.type is the standard control parameter.
NAryOperandType: PROC[op: Operator, typeSoFar, nextType: Type, cc: CC, oc: Type ← NIL] RETURNS[Type];
op is one of: max and min.
Used for determining a common operand type for max and min. On the first call typeSoFar and nextType are the given type of the first argument. On subsequent calls typeSoFar is the type returned on the previous call and nextType is the given type of the next argument.
typeSoFar is the standard control parameter.
NAryOp: PROC[op: Operator, args: LIST OF TypedCode, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
op is one of: max and min.
The arguments have already been coerced to an appropriate uniform type. Combines supplied code with additional code so as to compute the specied operation.
assumes that args is non nil
args.first.type is the standard control parameter
TypeOp: PROC[op: Operator, type: Type, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
op one of: size, bits, bytes, units, words, first, last
Produces the appropriate code to compute op[type].
type is the standard control parameter
TypeOp2OperandType: PROC[op: Operator, type: Type, cc: CC, oc: Type ← NIL] RETURNS[Type];
op one of: size, bits, bytes, units, words, first, last
TypeOp2 computes a value from a <type, number> pair. For example, this might be the size of a sequence type with n components. TypeOp2OperandType defines the target type for the number expression.
type is the standard control parameter
TypeOp2: PROC[op: Operator, type: Type, arg: TypedCode, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
op one of: size, bits, bytes, units, words, first, last
arg has been coerced to be of the appropriate numerical type as defined by TypeOp2OperandType. TypeOp2 combines arg with additional code so as to compute op[type, e], where arg computes e.
type is the standard control parameter
Constructor: PROC[list: LIST OF CirioSyntacticOperations.ParseTree, targetType: Type, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
We are compiling [arg1, ..., argk] to be a targetType.
targetType is the standard control parameter
PairConstructor: PROC[list: LIST OF CirioSyntacticOperations.NameArgPair, targetType: Type, cc: CompilerContext, oc: Type ← NIL] RETURNS[TypedCode];
We are compiling [id1: arg1, ..., idk: argk] to be a targetType.
targetType is the standard control parameter
Store: PROC[value: TypedCode, indirect: TypedCode, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
value has been coerced to conform to indirect.targetType. Resulting code: computes at, computes value, stores value at the location specified by at, returns value as a result.
indirect.type is the standard control parameter
Load: PROC[indirect: TypedCode, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
Loads through the indirect. Works ok for read only indirects (which can result from looking up constant indentifiers).
indirect.type is the standard control parameter
ExtractIdField: PROC[id: ROPE, fieldContext: Type, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
Assumes that fieldContext is a record like value already on the stack. Supplies the code to extract the named field. (Some how we should be able to replace uses of LoadIdVal with this one?
fieldContext is the control parameter.
LoadIdVal: PROC[id: ROPE, targetType: Type, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
Generates code to load the defined value. For example, if the targetType is an enumerated type, and id is one of the elements of that type, then the resulting code will load that element onto the stack.
targetType is the standard control parameter
SelectIdField: PROC[id: ROPE, fieldIndirectContext: Type, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
Assumes that fieldContext is an indirect (already on the stack) to a record like value. Supplies the code to obtain an indirect to the named field. (Some how we should be able to replace uses of IndirectToIdentifier with this one? Confusion is over whether a type or typed code is passed.
fieldIndirectContext is the control parameter.
LoadIdField: PROC[id: ROPE, fieldIndirectContext: Type, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
Assumes that fieldContext is an indirect (already on the stack) to a record like value. Supplies the code to load the named field. (at the time of this writing, this is only used to load fields in name contexts
fieldIndirectContext is the control parameter.
Apply: PROC[operator: TypedCode, operand: TypedCode, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
Applies the operator to the operand. The operator is a procedure, an array, a sequence, ... .
operator.type is the control parameter.
Index: PROC[operator: TypedCode, operand: TypedCode, cc: CC, oc: Type ← NIL] RETURNS[TypedCode];
Applies the operator to the operand. The operator is an indirect to an array, a sequence, ... .
operator.type is the control parameter. (For arrays, sequences, etc the relationship between Apply and Index is that same as that between ExtractIdField and SelectIdField.) (Note that Apply also occurs for procedure calls, signals, etc. There is no related use of Index.)
GetTypeRepresentation: PROC[type: Type, cc: CC, oc: Type ← NIL] RETURNS[REF ANY];
This is type class dependent. Not all types supply this operation.
type is the control parameter.
GetNElements: PROC[type: Type, cc: CC, oc: Type ← NIL] RETURNS[CARD];
This is type class dependent. Supplied by the discrete numeric types and by enumerated types.
type is the control parameter.
GetScopeIndex: PROC [type: Type, cc: CC, oc: Type ← NIL] RETURNS [CARD];
Returns the name scope index of a frame or ampersand type.
GetGroundType: PROC[type: Type, cc: CC, oc: Type ← NIL] RETURNS[Type];
Returns the ground type of a type.
type is the control parameter.
PrintType: PROC[to: IO.STREAM, type: Type, printDepth, printWidth: INT, cc: CC, oc: Type ← NIL];
Prints a type.
type is the control parameter.
sia: READONLY INT; --Standard Indentation Amount
DoObject: PROC [to: IO.STREAM, printit: PROC];
Calls printit inside a SS.Begin .. SS.End pair.
BreakObject: PROC [to: IO.STREAM, printit: PROC, sep: ROPENIL];
= {SS.Bp[to, lookLeft, sia, sep]; DoObject[printit]}
PrintTypeBracketed: PROC[to: IO.STREAM, type: Type, printDepth: INT, printWidth: INT, cc: CC, oc: Type ← NIL];
= DoObject[to, {PrintType[...]}]
BreakPrintType: PROC[to: IO.STREAM, type: Type, printDepth, printWidth: INT, cc: CC, sep: ROPENIL, oc: Type ← NIL];
= BreakObject[to, {PrintType[...]}, sep]
GetIndirectCreateNode: PROC[targetType: Type, mem: Mem, cc: CC] RETURNS[Node];
CreateIndirectNode: PROC[indirectType: Type, mem: Mem, cc: CC, oc: Type ← NIL] RETURNS[Node];
GetBitSize: PROC[indirectType: Type, cc: CC, oc: Type ← NIL] RETURNS[CARD];
The following are used by implementors of a Type. We again warn an implementor, that due to defaulting, the object procedure may have been supplied from a different type than that of the standard control parameter. The procData parameter is the procData field from the type that actually supplied the object procedure.
CreateCedarType: PROC[class: TypeClass, typeOps, indirectTypeOps: REF CCTypeProcs, cc: CC, procData: REF ANYNIL, defaultType: Type ← NIL] RETURNS[Type];
The Type returned by this procedure it is the direct type. (Call it "type".) That is, it's object procedures are typeOps. One can obtain the corresponding indirect type by GetIndirect[type]. Note that: type = GetTargetType[GetIndirect[type]]. The procData argument can be obtained by GetProcDataFromType[type]. The default type of type is defaultType. The default type of GetIndirect[type] is GetIndirect[defaultType]. Supplying NIL as one of the CCTypeProcs parameters is equivalent to supply no procedures for that parameter.
IsIndirectType: PROC [type: Type] RETURNS [BOOLEAN];
GetIndirectType: PROC[rhs: Type] RETURNS[Type];
GetTargetTypeOfIndirect: PROC[indirect: Type] RETURNS[Type];
GetTypeClass: PROC [type: Type] RETURNS [CirioTypes.TypeClass];
GetProcDataFromType: PROC[type: Type] RETURNS[REF ANY];
GetDefaultTypeFromType: PROC[type: Type] RETURNS[Type];
GetGroundTypeClass: PROC [type: Type, cc: CC] RETURNS [CirioTypes.TypeClass];
GetProcDataFromGroundType: PROC[type: Type, cc: CC] RETURNS[REF ANY];
CCTypeProcs: TYPE ~ CirioTypes.CCTypeProcs;
and last but not least, CirioTypesImpl exports a procedure for stuffing REF CCTypeProcs into a type. This is called ONLY by CCTypesImpl.
(Note: February 27, 1989 11:44:56 am PST: I don't believe that this routine is used anymore. I shall comment it out to check that claim.)
FillCCTypeProcs: PROC[type: Type, procs: REF CCTypeProcs];
(implemented in CirioTypesImpl.)
END..