-- AMTypes.Mesa
-- last modified on December 17, 1982 8:52 am by Paul Rovner

DIRECTORY
Rope USING[ROPE],
RTBasic USING[Type, TypedVariable, TV, Index, nullType],
WorldVM USING[World, LocalWorld];

AMTypes: CEDAR DEFINITIONS IMPORTS WorldVM

= BEGIN OPEN Rope;

-- T Y P E S
Type: TYPE = RTBasic.Type;
TypedVariable: TYPE = RTBasic.TypedVariable;
TV: TYPE = RTBasic.TV;

Status: TYPE = {mutable, readOnly, const};
Index: TYPE = RTBasic.Index; --index range for records, enumerations, etc is [1..n]

Class: TYPE =
{ definition, -- e.g. TypeClass[CODE[T]] where T: TYPE = ...--
cardinal, longCardinal, integer, longInteger, real, character, --basic--
atom, rope, list, ref, pointer, longPointer, descriptor, longDescriptor, basePointer,
relativePointer, --address--
procedure, signal, error, program, port, --transfer--
enumerated, subrange,
union, sequence,
record, structure,
array,
countedZone, uncountedZone,
nil, -- e.g. TypeClass[TVType[NIL]]
unspecified,
process,
type,
opaque,
any, -- e.g. TypeClass[Range[CODE[REF ANY]]]
globalFrame, localFrame --frame--
};

-- E R R O R S

Error: ERROR[ reason: ErrorReason,
msg: ROPENIL,
type: Type ← RTBasic.nullType, -- used with TypeFault, IncompatibleTypes
otherType: Type ← RTBasic.nullType -- used with IncompatibleTypes
];
ErrorReason: TYPE = {noSymbols, -- msg has moduleName
notImplemented, -- mostly DefaultInitialValue cases
incompatibleTypes, -- raised by Assign
rangeFault, -- e.g. empty subrange, Apply bounds check
notMutable, -- raised by (e.g.) Assign
internalTV, -- raised by (e.g.) RefFromTV
badName, -- raised by NameToIndex
badIndex, -- raised by (e.g.) IndexToType
typeFault -- general applicability violation
};

-- P R O C E D U R E S

-- (1.) Access to general Type characteristics.
Size: PROC[type: Type, length: CARDINAL--sequence only: number of elements--𡤀]
RETURNS[words: CARDINAL--max for unions--];

DefaultInitialValue: PROC[type: Type] RETURNS[TypedVariable];

IndexToDefaultInitialValue: PROC[type: Type--record, structure--, index: Index]
RETURNS[TypedVariable];

TypeClass: PROC[type: Type] RETURNS[Class];

UnderClass: PROC[type: Type] RETURNS[Class] =
INLINE {RETURN[TypeClass[UnderType[type]]]};

IsPainted: PROC[type: Type] RETURNS[BOOLEAN];
-- Enumerated types and records declared in interfaces are painted.

-- (2.) Access to general TV characteristics.
TVType: PROC[tv: TypedVariable] RETURNS[Type];
TVStatus: PROC[tv: TypedVariable] RETURNS[Status];
TVSize: PROC[tv: TypedVariable] RETURNS[words: INT];

-- These procedures are applicable to all but the frame types, opaque and any.

New
: PROC[type: Type,
status: Status ← mutable,
world: WorldVM.World ← WorldVM.LocalWorld[],
tag: TVNIL]
RETURNS[TypedVariable];
-- New creates and returns a cleared object.
-- tag has meaning only for union or sequence-containing record types.
-- See DefaultInitialValue.

Copy: PROC[tv: TypedVariable] RETURNS[TypedVariable];

Assign: PROC[lhs, rhs: TypedVariable];

-- Two TypedVariables are Eq if assignment to one is equivalent to assignment
-- to the other; i.e, they address the same bits.
-- Two TypedVariables are Equal if the values have the same size and same bits.
-- NOTE no type checking is done.
TVEq: PROC[tv1, tv2: TypedVariable] RETURNS [BOOLEAN];

TVEqual: PROC[tv1, tv2: TypedVariable] RETURNS [BOOLEAN];


-- (3.) These procedures have applicability restrictions, noted as comments
NComponents: PROC[type: Type--record, structure--] RETURNS[Index];

VariableType: PROC[type: Type--record, structure--]
RETURNS[v: Type, c: Class--union, sequence, or nil--];

IndexToTV: PROC[tv: TypedVariable--record, structure--, index: Index]
RETURNS[TypedVariable];
-- index range is [1..NComponents[TVType[tv]]]

IndexToType: PROC[type: Type--record, structure, union--, index: Index]
RETURNS[Type];
-- Returns the specified component of the type. SPECIAL CASE for
-- union types: index = 0 gets you the tag type
-- (redundant: Tag does this too).

NameToIndex: PROC[type: Type--record, structure, union, enumerated--,
name: ROPE]
RETURNS[CARDINAL];

IndexToName: PROC[type: Type--record, structure, union, enumerated--,
index: CARDINAL]
RETURNS[ROPE];
-- SPECIAL CASE for union types: index = 0 gets you the tag name

TVToType: PROC[tv: TypedVariable--type--] RETURNS[Type];

--applicable to enumerated, transfer, program, globalFrame, atom, rope--
TVToName: PROC[tv: TypedVariable] RETURNS[ans: ROPE];

Tag: PROC[tv: TypedVariable--union--] RETURNS[TypedVariable--enumerated--];

Variant: PROC[tv: TypedVariable--union--] RETURNS[TypedVariable--record--];

IsOverlaid: PROC[type: Type--union--] RETURNS[BOOLEAN];

IsMachineDependent: PROC[type: Type] RETURNS[BOOLEAN];
--record, structure, union, enumerated, sequence--

Domain: PROC[type: Type--array, sequence, transfer, union--] RETURNS[Type];

-- applicable to array, sequence, procedure, signal, process, address
-- (not atom, rope)
Range: PROC[type: Type] RETURNS[Type];

IsPacked: PROC[type: Type--array, sequence--] RETURNS[BOOLEAN];

IsComputed: PROC[type: Type--union, sequence--] RETURNS[BOOLEAN];

Apply: PROC[mapper: TypedVariable--array, sequence--, arg: TypedVariable]
RETURNS[TypedVariable];

-- For a rope, Length returns an INT for the number of characters in the given rope.
-- For a sequence, Length returns an INT specifying the (max) number of elements
-- in the sequence. Use Tag[tv] to obtain the actual sequence tag field. Their
-- values may differ if the tag type has a non-zero lower bound.
Length: PROC[tv: TypedVariable--sequence, rope--] RETURNS[INT];

Fetch: PROC[tv: TypedVariable--rope--, index: INT] RETURNS[CHAR];

Referent: PROC[tv: TypedVariable--ref, list, pointer, longPointer, relativePointer--,
base: TypedVariable ← NIL--non-nil only if ref is a relativePointer. UNSAFE
]
RETURNS[TypedVariable];

ConcreteRef: PROC[tv: TypedVariable--ref any--] RETURNS[TypedVariable];
-- ConcreteRef returns a TV for the REF <concrete referent type>. NIL -> NIL.
-- ConcreteRef is implemented only for REFANY's that are really ATOM, LIST or ROPE guys
-- (Error[reason: notImplemented] is raised otherwise)

ReferentStatus: PROC[type: Type--address (not basePointer, atom)--]
RETURNS[Status];

IsRefAny: PROC[type: Type--ref--] RETURNS[BOOL];

IsAtom: PROC[tv: TypedVariable--ref any--] RETURNS[BOOL];

IsRope: PROC[tv: TypedVariable--ref any--] RETURNS[BOOL];

IsNil: PROC[tv: TypedVariable--address--] RETURNS[BOOL];

IsOrdered: PROC[type: Type--basePointer, relativePointer--]
RETURNS[BOOLEAN];

PropertyList: PROC[tv: TypedVariable--atom--]
RETURNS[TypedVariable--list, nil--];

Coerce: PROC[tv: TypedVariable, targetType: Type]
RETURNS[TypedVariable];
-- use to Narrow or Widen

TypeToName: PROC[type: Type--definition--,
moduleName: REF ROPENIL,
fileName: REF ROPENIL]
RETURNS[ROPE];
-- IF name exists and REFs to moduleName and/or fileName
-- ROPEs are provided, TypeToName provides that info too.

Ground: PROC[type: Type--definition, subrange--]
RETURNS[Type]; -- peels off one layer

GroundStar: PUBLIC PROC[type: Type--definition, subrange--]
RETURNS[Type]; -- peels 'em all off

UnderType: PUBLIC PROC[type: Type--definition--] RETURNS[Type];
-- returns first non-definition type

InRange: PROC[type: Type--subrange--, groundTV: TypedVariable]
RETURNS[BOOLEAN];

First: PROC[type: Type--enumerated, subrange, basic--]
RETURNS[TypedVariable];

Last: PROC[type: Type--enumerated, subrange, basic--]
RETURNS[TypedVariable];

Next: PROC[tv: TypedVariable--enumerated, subrange, basic--]
RETURNS[TypedVariable]; -- returns NIL if no next

NValues: PROC[type: Type--enumerated--] RETURNS[INT];

Value: PROC[type: Type--enumerated--, index: CARDINAL]
RETURNS[TypedVariable];
-- index range is [1..NValues[type]]

StaticParent: PROC[tv: TypedVariable--procedure--]
RETURNS[TypedVariable--procedure--]; -- may return NIL

GlobalParent: PROC[tv: TypedVariable--transfer or local frame--]
RETURNS[TypedVariable--globalFrame--];

Globals: PROC[tv: TypedVariable--globalFrame--]
RETURNS[TypedVariable--record--];

Procedure: PROC[tv: TypedVariable--localFrame--]
RETURNS[TypedVariable--procedure--];

Signal: PROC[tv: TypedVariable--localFrame--]
RETURNS[TypedVariable--signal descriptor--];

Argument: PROC[tv: TypedVariable--local or catch frame--, index: Index]
RETURNS[TypedVariable];

Result: PROC[tv: TypedVariable--local or catch frame--, index: Index]
RETURNS[TypedVariable];

EnclosingBody: PROC[tv: TypedVariable--localFrame--]
RETURNS[TypedVariable--localFrame--]; -- may return NIL

Locals: PROC[tv: TypedVariable--localFrame--]
RETURNS[TypedVariable--record--]; -- may return NIL

DynamicParent: PROC[tv: TypedVariable--localFrame--]
RETURNS[TypedVariable--localFrame--];

END.