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]; IntCodeTwig: CEDAR DEFINITIONS IMPORTS Basics16, IntCodeUtils = BEGIN OPEN IntCodeDefs, IntCodeUtils; DoModule: PROC [module: Node, switches: Switches] RETURNS [BaseModel]; Switches: TYPE = PACKED ARRAY CHAR['a..'z] OF BOOL; Duplicate: SIGNAL; LogicalRegister: TYPE = RECORD [ kind: LogicalRegisterKind, offset: INT ]; LogicalRegisterKind: TYPE = MACHINE DEPENDENT { local (0), -- a local register used for local variables global (1), -- a global register constant (2), -- a constant register last (255)}; -- just in case we need this many IdToRegister: PROC [id: LogicalId] RETURNS [LogicalRegister] = INLINE { ln: Basics.LongNumber ¬ [int[id]]; reg: LogicalRegister; reg.kind ¬ VAL[ln.hh]; ln.hi ¬ Basics16.BITXOR[ln.hl, 100B] - 100B; reg.offset ¬ ln.int; RETURN [reg]; }; RegisterToId: PROC [reg: LogicalRegister] RETURNS [LogicalId] = INLINE { ln: Basics.LongNumber ¬ [int[reg.offset]]; IF (Basics16.BITXOR[ln.hl, 100B] - 100B) # ln.hi THEN ERROR; ln.hh ¬ ORD[reg.kind]; RETURN [ln.int]; }; OrVarFlags: PROC [var: Var, flags: VariableFlags] = INLINE { var.flags ¬ LOOPHOLE[Basics16.BITOR[LOOPHOLE[var.flags], LOOPHOLE[flags]]]; }; OrFlags: PROC [flags1, flags2: VariableFlags] RETURNS [VariableFlags] = INLINE { RETURN [LOOPHOLE[Basics16.BITOR[LOOPHOLE[flags1], LOOPHOLE[flags2]]]]; }; OrFlag: PROC [flag: VariableFlag, old: VariableFlags ¬ nullVariableFlags] RETURNS [VariableFlags] = INLINE { old[flag] ¬ TRUE; RETURN [old]; }; 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; }; END. X 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 processes the node for the module, returning a model for the module Signalled when a duplicate variable or lable is found Logical register declarations Variable flag goodies 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. Κξ•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ ΟeœC™NK™0K™ K™(—K˜šΟk ˜ Kšœžœ˜Kšœ žœžœžœ˜Kšœ žœk˜|Kšœ žœ˜)—headšœ žœž ˜Kšžœ˜Kšœžœžœ˜'K˜—šΟnœžœ$žœ ˜FKš œ žœžœžœžœ žœžœ˜3KšœC™CK˜—šœ žœ˜Kšœ5™5—head2šœ™šœžœžœ˜ Kšœ˜Kšœž˜ K˜–2.0 in tabStopsšœžœžœž œ˜/K–2.0 in tabStopsšœ Οc,˜7K–2.0 in tabStopsšœ  ˜ K–2.0 in tabStopsšœ ˜$K–2.0 in tabStopsšœ  !˜.—K˜—šŸ œžœžœžœ˜GK˜"Kšœ˜Kšœ žœ˜Kšœžœ˜,Kšœ˜Kšžœ˜ K˜K˜—šŸ œžœžœžœ˜HKšœ*˜*Kšžœ žœžœžœ˜žœžœ˜lKšœ žœ˜Kšžœ˜ K˜——šœ™Kšœ"žœžœ™7K™K™yK™Kšœ žœžœ˜#–2.9 in tabStopsšœžœžœ˜K–2.9 in tabStopsšœžœ "˜6K–2.9 in tabStopsšœžœ ˜2K–2.9 in tabStopsšœžœ  ˜4K–2.9 in tabStopsšœžœ ˜-K–2.9 in tabStopsšœžœ ˜/K–2.9 in tabStopsšœžœ ˜,K–2.9 in tabStops˜K–2.9 in tabStops˜—Kšœ žœžœ˜'–2.9 in tabStopsšœžœžœ˜K–2.9 in tabStopsšœžœ !˜:K–2.9 in tabStopsšœžœ &˜:K–2.9 in tabStopsšœžœ  ˜6K–2.9 in tabStopsšœžœ $˜DK–2.9 in tabStopsšœžœ ˜9K–2.9 in tabStopsšœžœ ˜6K–2.9 in tabStopsšœžœ !˜4K–2.9 in tabStopsšœ žœ ˜2K–2.9 in tabStopsšœžœ ˜5K–2.9 in tabStopsšœžœ ˜4K–2.9 in tabStopsšœžœ ,˜GK–2.9 in tabStopsšœžœ 4˜KK–2.9 in tabStopsšœžœ ,˜CK–2.9 in tabStopsšœžœ ,˜CK–2.9 in tabStopsšœžœ 6˜RK–2.9 in tabStopsšœ žœ ˜/K–2.9 in tabStopsšœžœ '˜;K–2.9 in tabStopsšœ žœ $˜7K–2.9 in tabStopsšœžœ *˜;K–2.9 in tabStopsšœ žœžœ !˜:K–2.9 in tabStopsšœ žœžœ Πck +˜JK–2.9 in tabStops˜—–2.8 in tabStopsšœžœžœ˜"K–2.8 in tabStops˜—š Ÿ œžœžœžœžœ˜;Kšžœ˜K˜K˜—š Ÿ œžœžœžœžœ˜:Kšžœ˜K˜K˜—š Ÿ œžœžœžœžœ˜;Kšžœ˜K˜K˜—šŸ œžœ"žœ žœ˜MKšžœžœ'˜5K˜K˜—šŸ œžœ"žœ žœ˜JKšžœžœ&˜4K˜K˜—šŸ œžœ"žœžœ˜SKšžœžœ'˜5K˜K˜—šŸ œžœ2žœ˜KKšžœ.žœžœžœ ˜JK˜K˜—šŸ œžœ.žœ˜FKšžœ+žœžœžœ ˜GK˜K˜—šŸ œžœ8žœ˜QKšžœ.žœžœžœ ˜JK˜K˜—K˜—K˜Kšžœ˜K˜—…—F