DIRECTORY AMBridge, AMModel, AMTypes, Basics USING [bytesPerWord], BcdDefs USING [VersionStamp], CD, CDApplications, CDCallSpecific, CDConditions, CDDirectory, CDExtras, CDInline, CDIO, CDOps, CDProperties, CDValue, FS, Interpreter USING [Evaluate], IO, Loader USING [Instantiate, IRItem], PrincOps USING [ControlModule], Rope, --RuntimeError, TerminalIO, TokenIO, WorldVM USING [LocalWorld]; CDConditionsImpl: CEDAR PROGRAM IMPORTS AMBridge, AMModel, AMTypes, CD, CDApplications, CDDirectory, CDExtras, CDInline, CDIO, CDOps, CDProperties, CDValue, FS, Interpreter, IO, Loader, Rope, --RuntimeError,-- TerminalIO, TokenIO, WorldVM EXPORTS CDConditions SHARES CDDirectory = BEGIN ConditionProc: TYPE = CDConditions.ConditionProc; CondPtr: TYPE = CDConditions.CondPtr; CondRec: TYPE = CDConditions.CondRec; pForConditions: REF CD.ObjectProcs ~ CD.RegisterObjectType[$Cond]; ConditionList: TYPE = LIST OF CD.ObPtr; DrawMe: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN cptr: CondPtr = NARROW[aptr.ob.specificRef]; IF cptr.condition=NIL OR cptr.condition[aptr, pr] THEN { cptr.app.ob.p.drawMe[cptr.app, pos, orient, pr]; } END; DescribeCond: PROC[me: CD.ObPtr] RETURNS [Rope.ROPE] = { cptr: CondPtr = NARROW[me.specificRef]; RETURN [Rope.Concat["conditional ", CDOps.Info[cptr.app.ob]]] }; GetProp: PUBLIC PROC [environment: CD.DrawRef, prop: REF, skipInnerMost: NAT_0] RETURNS [REF] = BEGIN x: REF_NIL; FOR al: CD.ApplicationList _ environment.nesting, al.rest WHILE al#NIL DO x _ CDProperties.GetPropFromApplication[al.first, prop]; IF x#NIL THEN IF skipInnerMost=0 THEN RETURN [x] ELSE skipInnerMost _ skipInnerMost-1 ENDLOOP; RETURN [NIL] END; GetIntProp: PUBLIC PROC[environment: CD.DrawRef, prop: REF, skipInnerMost: NAT_0, ifNotFound: INT_0] RETURNS [INT] = BEGIN x: INT _ ifNotFound; WITH GetProp[environment: environment, prop: prop, skipInnerMost: skipInnerMost] SELECT FROM intP: REF INT => x _ intP^; ENDCASE => NULL; RETURN [x] END; Index: PUBLIC PROC[environment: CD.DrawRef, skipInnerMost: NAT_0, ifNotFound: INT_0] RETURNS [INT] = BEGIN RETURN [GetIntProp[environment, $CDxIndex, skipInnerMost, ifNotFound]] END; RepositionElementsC: CDDirectory.RepositionElementsProc -- PROC [me: CD.ObPtr, objToReposition: CD.ObPtr, oldSize: CD.DesignPosition, newBound: CD.DesignRect, design: CD.Design] -- = BEGIN cp: CondPtr ~ NARROW[me.specificRef]; IF cp.app.ob=objToReposition THEN { cp.app.location _ CDInline.AddPoints[cp.app.location, CDInline.BaseOfRect[newBound]]; CDDirectory.RepositionAnObject[design, me]; } END; ComputeBoundsC: CDDirectory.ComputeBoundsProc -- PROC [ob: CD.ObPtr] RETURNS [CD.DesignRect] -- = BEGIN cp: CondPtr = NARROW[ob.specificRef]; RETURN CDInline.RectAt[cp.app.location, cp.app.ob.size]; END; AdjustItselfC: CDDirectory.AdjustItselfProc -- PROC [objToReposition: CD.ObPtr, newBound: CD.DesignRect] -- = BEGIN cp: CondPtr = NARROW[objToReposition.specificRef]; IF cp.app.location#CDInline.BaseOfRect[newBound] THEN ERROR; cp.app.location _ [0, 0] END; GetConditionList: PROC[design: CD.Design] RETURNS [REF ConditionList] = BEGIN x: REF _ CDValue.Fetch[design, $ConditionList]; IF x=NIL OR ~ISTYPE[x, REF ConditionList] THEN { x _ NEW[ConditionList_NIL]; CDValue.Store[design, $ConditionList, x]; }; RETURN [NARROW[x, REF ConditionList]]; END; InternalCreateCondOb: PROC [design: CD.Design, ob: CD.ObPtr, condition: ConditionProc, data: REF] RETURNS [CD.ObPtr] = BEGIN refcl: REF ConditionList = GetConditionList[design]; cOb: CD.ObPtr = NEW[CD.ObjectDefinition]; cp: CondPtr = NEW[CondRec]; cOb.p _ pForConditions; cOb.size _ ob.size; cOb.level _ ob.level; cOb.specificRef _ cp; cp.app _ CDApplications.NewApplication[ob: ob]; cp.condition _ condition; cp.data _ data; refcl^ _ CONS[cOb, refcl^]; RETURN [cOb]; END; CreateCondition: PUBLIC PROC [design: CD.Design, ob: CD.ObPtr, condition: ConditionProc_NIL, data: REF_NIL] RETURNS [CD.ObPtr] = BEGIN cOb: CD.ObPtr = InternalCreateCondOb[design, ob, condition, data]; [] _ CDDirectory.Include[design, cOb]; RETURN [cOb]; END; ChangeCondition: PUBLIC PROC [design: CD.Design, ob: CD.ObPtr, fileName, procName: Rope.ROPE_NIL, data: REF_NIL, condition: ConditionProc_NIL] RETURNS [done: BOOL_FALSE] = BEGIN WriteNames: PROC [r: Rope.ROPE_NIL] = { TerminalIO.WriteRope[" Condition proc "]; TerminalIO.WriteRope[procName]; TerminalIO.WriteRope[" on file "]; TerminalIO.WriteRope[fileName]; TerminalIO.WriteRope["; "]; IF ~Rope.IsEmpty[r] THEN TerminalIO.WriteRope[r]; }; cptr: CondPtr = NARROW[ob.specificRef]; cptr.data _ data; cptr.fileName _ fileName; cptr.procName _ procName; IF condition#NIL THEN { cptr.condition _ condition; done _ TRUE; } ELSE IF Rope.IsEmpty[procName] THEN { cptr.condition _ NIL; done _ TRUE; } ELSE { procAlone, modName: Rope.ROPE_NIL; cptr.condition _ NIL; cptr.data _ data; cptr.fileName _ fileName; cptr.procName _ procName; BEGIN -- determine procAlone, modName procDot: INT = TrailingDot[procName]; IF procDot < Rope.Length[procName] THEN { procAlone _ Rope.Flatten[procName, procDot+1]; modName _ Rope.Flatten[procName, 0, procDot] } ELSE procAlone _ procName; IF Rope.IsEmpty[modName] THEN modName _ SuggestedModule[fileName]; IF Rope.IsEmpty[procAlone] THEN procAlone _ "Condition"; END; TRUSTED BEGIN -- compare the file with the wanted module; load the file root: AMModel.Context = AMModel.RootContext[WorldVM.LocalWorld[]]; ctxVersion, fileVersion: BcdDefs.VersionStamp; modCtx: AMModel.Context; fileStream: IO.STREAM; fileStream _ FS.StreamOpen[CDExtras.AppendExt[fileName, "bcd"] ! FS.Error => IF error.group # bug THEN { WriteNames[]; TerminalIO.WriteRope["Could not open "]; TerminalIO.WriteRope[fileName]; TerminalIO.WriteRope[" "]; TerminalIO.WriteRope[error.explanation]; TerminalIO.WriteLn[]; GOTO NotDone }]; IO.SetIndex[fileStream, SIZE[CARDINAL]*Basics.bytesPerWord]; [] _ IO.UnsafeGetBlock[fileStream, [ base: LOOPHOLE[LONG[@fileVersion]], startIndex: 0, count: SIZE[BcdDefs.VersionStamp]*Basics.bytesPerWord]]; modCtx _ AMModel.MostRecentNamedContext[modName, root]; IF modCtx # NIL THEN ctxVersion _ AMModel.SectionVersion[AMModel.ContextSection[modCtx]]; IF modCtx = NIL OR ctxVersion # fileVersion THEN { msg: Rope.ROPE _ NIL; unboundImports: LIST OF Loader.IRItem _ NIL; cm: PrincOps.ControlModule; file: FS.OpenFile = FS.OpenFileFromStream[fileStream]; fullName: Rope.ROPE = FS.GetName[file].fullFName; TerminalIO.WriteRope["Loading "]; TerminalIO.WriteRope[fullName]; TerminalIO.WriteLn[]; [cm, unboundImports] _ Loader.Instantiate[file]; IF unboundImports # NIL THEN { TerminalIO.WriteRope["Warning! Unbound imports:"]; FOR eachIR: LIST OF Loader.IRItem _ unboundImports, eachIR.rest WHILE eachIR # NIL DO TerminalIO.WriteRope[eachIR.first.interfaceName]; TerminalIO.WriteRope["#"]; TerminalIO.WriteInt[eachIR.first.index]; ENDLOOP; TerminalIO.WriteLn[]; }; }; IO.Close[fileStream]; END; TRUSTED BEGIN -- get the procedure we want errorRope: Rope.ROPE; noResult: BOOL; tv: AMTypes.TV _ NIL; type: AMTypes.Type; [tv, errorRope, noResult] _ Interpreter.Evaluate[Rope.Cat[modName, ".", procAlone]]; IF noResult OR tv=NIL OR ~Rope.IsEmpty[errorRope] THEN { WriteNames[]; TerminalIO.WriteRope[" no condition procedure: "]; TerminalIO.WriteRope[errorRope]; TerminalIO.WriteLn[]; RETURN }; type _ AMTypes.TVType[tv]; WHILE AMTypes.TypeClass[type]=definition DO tv _ AMTypes.Coerce[tv, AMTypes.UnderType[type]]; type _ AMTypes.TVType[tv]; ENDLOOP; IF AMTypes.TypeClass[type]=ref THEN { WITH AMBridge.SomeRefFromTV[tv] SELECT FROM cond: REF ConditionProc => { cptr.condition _ cond^; done _ TRUE }; ENDCASE => NULL; } ELSE IF AMTypes.TypeClass[type]=procedure THEN { p: PROC ANY RETURNS ANY _ LOOPHOLE[AMBridge.TVToProc[tv]]; WITH p SELECT FROM cond: ConditionProc => { cptr.condition _ cond; done _ TRUE }; ENDCASE => NULL; }; IF ~done THEN WriteNames[" has wrong type; not done\n"]; END; }; IF done THEN CDOps.DelayedRedraw[design] EXITS NotDone => NULL; END; SuggestedModule: PROC [base: Rope.ROPE] RETURNS [Rope.ROPE] = { len, dot: INT; base _ ShortName[base]; len _ Rope.Length[base]; dot _ TrailingDot[base]; IF len>dot AND Rope.Equal[Rope.Substr[base, dot+1], "bcd", FALSE] THEN base _ Rope.Flatten[base, 0, dot]; RETURN [base] }; TrailingDot: PROC [base: Rope.ROPE] RETURNS [INT] = { len: INT _ Rope.Length[base]; pos: INT _ len; WHILE pos > 0 DO SELECT Rope.Fetch[base, pos _ pos - 1] FROM '. => RETURN [pos]; '!, '], '>, '/ => EXIT; ENDCASE; ENDLOOP; RETURN [len]; }; ShortName: PROC [base: Rope.ROPE] RETURNS [Rope.ROPE] = { len: INT _ Rope.Length[base]; pos: INT _ len; bang: INT _ len; WHILE pos > 0 DO SELECT Rope.Fetch[base, pos _ pos - 1] FROM '! => bang _ pos; '], '>, '/ => RETURN [Rope.Flatten[base, pos+1, bang-pos-1]]; ENDCASE; ENDLOOP; RETURN [Rope.Flatten[base, 0, bang]]; }; EnumerateCondOb: PROC [me: CD.ObPtr, p: CDDirectory.EnumerateObjectsProc, x: REF] = BEGIN cptr: CondPtr = NARROW[me.specificRef]; p[cptr.app.ob, x]; END; ReadCondOb: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN ob: CD.ObPtr = CDIO.ReadObject[]; procName: Rope.ROPE = TokenIO.ReadRope[]; fileName: Rope.ROPE = TokenIO.ReadRope[]; cOb: CD.ObPtr = InternalCreateCondOb[CDIO.DesignInReadOperation[], ob, NIL, NIL]; [] _ ChangeCondition[design: CDIO.DesignInReadOperation[], ob: cOb, procName: procName, fileName: fileName]; RETURN [cOb] END; WriteCondOb: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN specific: CondPtr = NARROW[me.specificRef]; CDIO.WriteObject[specific.app.ob]; TokenIO.WriteRope[specific.procName]; TokenIO.WriteRope[specific.fileName]; END; UpdateConditions: PUBLIC PROC [design: CD.Design, doAll: BOOL_TRUE] RETURNS [done: BOOL_FALSE] = BEGIN doneSoFar: BOOL_TRUE; cl: ConditionList _ GetConditionList[design]^; FOR l: ConditionList _ cl, l.rest WHILE l#NIL DO WITH l.first.specificRef SELECT FROM cptr: CondPtr => IF doAll OR cptr.condition=NIL THEN { doneSoFar _ doneSoFar AND ChangeCondition[design, l.first, cptr.fileName, cptr.procName, cptr.data] }; ENDCASE => doneSoFar_FALSE; ENDLOOP; RETURN [doneSoFar] END; InitConditions: PROC [] = BEGIN cp: REF CDDirectory.DirectoryProcs ~ CDDirectory.InstallDirectoryProcs[pForConditions]; cp.enumerateChildObjects _ EnumerateCondOb; cp.adjustItself _ AdjustItselfC; cp.repositionElements _ RepositionElementsC; cp.computeBounds _ ComputeBoundsC; pForConditions.drawMe _ DrawMe; pForConditions.internalRead _ ReadCondOb; pForConditions.internalWrite _ WriteCondOb; pForConditions.describe _ DescribeCond; CDValue.EnregisterKey[$ConditionList]; END; InitConditions[]; END. ÎCDConditionsImpl.mesa (part of Chipndale) by Christian Jacobi May 4, 1984 10:12:34 am PDT last edited by Christian Jacobi May 9, 1984 6:13:34 pm PDT some code stolen from Russ Atkinson's HandCodingDriver --there are restrictions on the type of data; (because of IO!) --if condition is nil, tries to evaluate fileName, procName --redraws the complete design --there are restrictions on the type of data --Read the version stamp of the file --Get the version stamp of the loaded bcd. --We must try to load this file dynamically --At this point we have found the named module, and we want to find the named procedure in the module, if there is one. If one was not specified, default to "Condition". --given a filename, suggests a modulename --position of last dot --checks if any conditions have been recompiled and reloads them --doAll TRUE: checks all, including already loded conditions --doAll FALSE: checks the conditions which are not already loded ʘJšœ0™0J˜Jšœ2™2Jšœ<™™>Jš˜Jšœœ;˜BJšœ&˜&Jšœ˜ Jšœ˜—J˜šÐbnœœœ œ œ!œœœœœœœœ˜«Jšœ;™;Jšœ™J™,Jš˜šŸ œœ œœ˜'Jšœ*˜*Jšœ ˜ Jšœ$˜$Jšœ ˜ Jšœ˜Jšœœ˜2J˜—Jšœœ˜'Jšœ˜Jšœ˜Jšœ˜šœ œœ˜Jšœ˜Jšœ˜ J˜—šœœœ˜%Jšœœ˜Jšœœ˜ J˜—šœ˜Jšœœ˜"Jšœœ˜Jšœ˜Jšœ˜Jšœ˜šœ ˜%Jšœ œ˜%šœ!œ˜)Jšœ.˜.Jšœ,˜,J˜—Jšœ˜Jšœœ%˜BJšœœ˜8Jšœ˜—š œ 9˜GJšœB˜BJšœ.˜.Jšœ˜Jšœ œœ˜Jšœ$™$šœ œ/˜>šœœ œœ˜)Jšœ ˜ Jšœ(˜(Jšœ˜Jšœ˜Jšœ(˜(Jšœ˜Jšœ˜ Jšœ˜——Jšœœœ˜<šœœ˜$Jšœœœ˜#Jšœ˜Jšœœ-˜8—Jšœ*™*Jšœ7˜7šœ œ˜JšœD˜D—šœ œœœ˜2Jšœ,™,Jšœ œœ˜Jšœœœœ˜,Jšœ˜Jšœœ œ ˜6Jšœœœ˜1Jšœ!˜!Jšœ˜Jšœ˜Jšœ0˜0šœœœ˜Jšœ3˜3š œ œœ-œ œ˜UJšœ2˜2Jšœ˜Jšœ(˜(Jšœ˜—Jšœ˜J˜—Jšœ˜—Jšœ˜Jšœª™ªJšœ˜—šœœ ˜,Jšœœ˜Jšœ œ˜Jšœ œœ˜Jšœ˜JšœT˜Tš œ œœœœ˜8Jšœ ˜ Jšœ4˜4Jšœ!˜!J˜Jš˜Jšœ˜—Jšœ˜šœ$˜+Jšœ1˜1Jšœ˜Jšœ˜—šœœ˜&šœœ˜+šœœ˜Jšœ˜Jšœ˜ Jšœ˜—Jšœœ˜—J˜—šœœ#œ˜0Jš œœœœœœ˜:šœœ˜šœ˜Jšœ˜Jšœ˜ J˜—Jšœœ˜—J˜—Jšœœ-˜:Jšœ˜—Jšœ˜—Jšœœ˜(š˜Jšœ œ˜—Jšœ˜—J˜š Ÿœœ œœœ˜?Jšœ)™)Jšœ œ˜Jšœ˜Jšœ˜Jšœ˜šœ œ-œœ˜GJšœ"˜"—Jšœ˜ J˜—J˜š Ÿ œœ œœœ˜5Jšœ™Jšœœ˜Jšœœ˜šœ ˜šœ!˜+Jšœœ˜Jšœœ˜Jšœ˜—Jšœ˜—Jšœ˜ J˜J˜—š Ÿ œœ œœœ˜9Jšœœ˜Jšœœ˜Jšœœ˜šœ ˜šœ!˜+Jšœ˜Jšœœ)˜=Jšœ˜—Jšœ˜—Jšœ˜%J˜J˜—šŸœœœ0œ˜TJš˜Jšœœ˜'Jšœ˜Jšœ˜—J˜šž œœ œ˜=Jš˜Jšœœ œ˜!Jšœœ˜)Jšœœ˜)Jš œœœœœ˜QJšœœK˜lJšœ˜ Jšœ˜—J˜šž œœ œ˜:Jš˜Jšœœ˜+Jšœ˜"Jšœ%˜%Jšœ%˜%Jšœ˜—J˜šŸœœœ œœœœœœ˜`Jšœ@™@Jšœ=™=JšœA™AJš˜Jšœ œœ˜Jšœ.˜.šœœœ˜0šœœ˜$š œœœœœ˜6JšœœK˜dJ˜—Jšœœ˜—Jšœ˜—Jšœ ˜Jšœ˜—J˜J˜šŸœœ˜Jš˜JšœœP˜WJšœ+˜+Jšœ ˜ Jšœ,˜,Jšœ"˜"Jšœ˜Jšœ)˜)Jšœ+˜+Jšœ'˜'Jšœ&˜&Jšœ˜—J˜Jšœ˜Jšœ˜J˜—…—)n<>