IntCodeTwig.mesa
Copyright Ó 1986, 1987, 1988, 1991 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) July 18, 1989 4:27:30 pm PDT
JKF July 27, 1988 8:17:53 am PDT
Willie-s, September 23, 1991 6:00 pm PDT
DIRECTORY
Basics USING [LongNumber],
Basics16 USING [BITOR, BITXOR],
IntCodeDefs USING [Label, LogicalId, Node, NodeList, NodeRep, nullVariableFlags, Var, VariableFlag, VariableFlags, VarList],
IntCodeUtils USING [Fetch, IdTab, Store];
Model declarations
(to convert to non-Cedar, replace NARROW with LOOPHOLE)
The important trick here is to not allow the "user" to access any parts of the base without going through these routines.
BaseModel: TYPE = REF BaseModelRep;
BaseModelRep:
TYPE =
RECORD [
module: Node ¬ NIL, -- module that produced this model
labels: IdTab ¬ NIL, -- table of label definitions
decls: IdTab ¬ NIL, -- table of variable definitions
models: IdTab ¬ NIL, -- table of stack models
first: LambdaModel ¬ NIL, -- first lambda model
tail: LambdaModel ¬ NIL -- last lambda model
];
LambdaModel: TYPE = REF LambdaModelRep;
LambdaModelRep:
TYPE =
RECORD [
next: LambdaModel ¬ NIL, -- next model in visitation order
label: Label ¬ NIL, -- lambda label that starts this model
lambda: Lambda ¬ NIL, -- lambda that starts this model
parentModel: LambdaModel ¬ NIL, -- model for the enclosing procedure
parentLabel: Label ¬ NIL, -- label (if any) of the parent
argumentBits: INT ¬ 0, -- bits for the argument record
argVar: Var ¬ NIL, -- argument record ptr (if large)
returnBits: INT ¬ 0, -- bits for the return record
returnVar: Var ¬ NIL, -- return record ptr (if large)
memTemps: VarList ¬ NIL, -- current temps for memory
frameExtension: Var ¬ NIL, -- variable (if any) for the frame extension
memoryLink: Var ¬ NIL, -- variable (if any) pointing to the frame extension
globalLink: Var ¬ NIL, -- variable (if any) holding the global link
staticLink: Var ¬ NIL, -- variable (if any) holding the static link
entryPoint: NodeList ¬ NIL, -- first node after the frame extension has been setup
nesting: INT ¬ 0, -- nesting level for the proc
lockVar: Var ¬ NIL, -- lock variable for an ENTRY procedure
memDepth: INT ¬ 0, -- current # of memory locals in use
memMax: INT ¬ 0, -- max # of memory locals in the procedure
forceLong: BOOL ¬ FALSE, -- TRUE => force long args & rets
isCatch: BOOL ¬ FALSE]; -- TRUE iff the label is for a catch phrase lambda
Lambda:
TYPE =
REF lambda NodeRep;
LabelsSize:
PROC [base: BaseModel]
RETURNS [
INT] =
INLINE {
RETURN [base.labels.entries];
};
DeclsSize:
PROC [base: BaseModel]
RETURNS [
INT] =
INLINE {
RETURN [base.decls.entries];
};
ModelsSize:
PROC [base: BaseModel]
RETURNS [
INT] =
INLINE {
RETURN [base.models.entries];
};
LabelsFetch:
PROC [base: BaseModel, id: LogicalId]
RETURNS [Label] =
INLINE {
RETURN [NARROW[IntCodeUtils.Fetch[base.labels, id]]];
};
DeclsFetch:
PROC [base: BaseModel, id: LogicalId]
RETURNS [Var] =
INLINE {
RETURN [NARROW[IntCodeUtils.Fetch[base.decls, id]]];
};
ModelsFetch:
PROC [base: BaseModel, id: LogicalId]
RETURNS [LambdaModel] =
INLINE {
RETURN [NARROW[IntCodeUtils.Fetch[base.models, id]]];
};
LabelsStore:
PROC [base: BaseModel, id: LogicalId, label: Label] =
INLINE {
IF IntCodeUtils.Store[base.labels, id, label] # NIL THEN SIGNAL Duplicate;
};
DeclsStore:
PROC [base: BaseModel, id: LogicalId, var: Var] =
INLINE {
IF IntCodeUtils.Store[base.decls, id, var] # NIL THEN SIGNAL Duplicate;
};
ModelsStore:
PROC [base: BaseModel, id: LogicalId, model: LambdaModel] =
INLINE {
IF IntCodeUtils.Store[base.models, id, model] # NIL THEN SIGNAL Duplicate;
};