RoseHelpImpl.Mesa
Last Edited by: Spreitzer, June 28, 1983 6:48 pm
Last Edited by: Barth, June 9, 1983 11:23 am
DIRECTORY
AMBridge, AMTypes, Atom, Buttons, Cucumber, Pausers, ViewerClasses, ViewRec, FileIO, IO, MessageWindow, OrderedSymbolTableRef, Rope, Rosemary, RosemaryExtras, RoseHelp;
RoseHelpImpl: CEDAR PROGRAM
IMPORTS AMBridge, AMTypes, Atom, --Buttons,-- Cucumber, MessageWindow, OrderedSymbolTableRef, Pausers, Rope, FIO: FileIO, IO, ViewRec, Rosemary, RosemaryExtras
EXPORTS RoseHelp =
BEGIN OPEN Rosemary, RosemaryExtras;
NoHelpForAnything: PUBLIC ERROR = CODE;
LORA: TYPE = LIST OF REF ANY;
Viewer: TYPE = ViewerClasses.Viewer;
Type: TYPE = AMTypes.Type;
TypedVariable: TYPE = AMTypes.TypedVariable;
Name: TYPE = LIST OF ROPE;
StartData: TYPE = REF StartDataRep;
StartDataRep: TYPE = RECORD [
instanceName: ROPE,
class: CellClass,
initData: REF ANYNIL];
InitData: TYPE = REF InitDataRep;
InitDataRep: TYPE = RECORD [
name: ROPE,
ioTemplate: REF ANY];
ProviderData: TYPE = REF ProviderDataRep;
ProviderDataRep: TYPE = RECORD [
cell: Cell,
pauser: Pausers.Pauser ← NIL,
armed: BOOLEANFALSE];
ExpandQuery: TYPE = REF ExpandQueryRep;
ExpandQueryRep: TYPE = RECORD [
instanceName, className: ROPENIL,
whatToDo: Rosemary.ExpandDecision ← Nested];
providerHandler: Cucumber.Handler ← NEW [Cucumber.HandlerRep ← [
PartTransfer: TransferProvider]];
qp: Pausers.Pauser ← NIL;
eq: ExpandQuery ← NEW [ExpandQueryRep ← []];
ask: PUBLIC Rosemary.ExpandDeciderClosure ← NEW [Rosemary.ExpandDeciderClosureRep ← [
Decide: Ask, otherData: NIL]];
decisionProp: ATOM ← Atom.Gensym[];
TransferProvider: Cucumber.PartTransferProc = {};
GiveItAnything: PUBLIC PROC [topInstanceName, instanceName, className: ROPE, initData: REF ANYNIL, decider: ExpandDeciderClosure] RETURNS [topCell: Cell] =
BEGIN
sd: StartData ← NEW [StartDataRep ← [
instanceName: instanceName, class: NIL, initData: initData]];
sd.class ← NARROW[cellClasses.Lookup[className]];
IF sd.class = NIL THEN ERROR Error[IO.PutFR["No such class (%g)", IO.rope[className]]];
topCell ← CreateTopCell[instanceName: topInstanceName, className: "GiveItAnything", initData: sd, decider: decider];
END;
ExpandAnything: ExpandProc =
BEGIN
sd: StartData ← NARROW[initData];
usersCell: Cell;
providerClassName: ROPE;
ioTemplate: REF ANYNIL;
usersInterface: ROPENIL;
FOR index: CARDINAL IN [0 .. sd.class.ports.length) DO
name: ROPE ← sd.class.ports[index].name;
step: ROPE ← name.Cat[": ", name];
[] ← CreateNode[within: thisCell, name: name, type: sd.class.ports[index].type];
usersInterface ← IF usersInterface = NIL THEN step ELSE usersInterface.Cat[", ", step];
ENDLOOP;
providerClassName ← GetProvider[sd.class];
usersCell ← CreateCell[within: thisCell, instanceName: sd.instanceName, className: sd.class.name, interfaceNodes: usersInterface, initData: sd.initData];
ioTemplate ← SELECT usersCell.type FROM
Real => usersCell.realCellStuff.newIO,
Shadow => sd.class.ioTemplate,
ENDCASE => ERROR;
IF ioTemplate = Unspecified THEN ERROR NoHelpForAnything;
[] ← CreateCell[within: thisCell, instanceName: sd.instanceName.Concat["-provider"], className: providerClassName, interfaceNodes: usersInterface, initData: NEW [InitDataRep ← [name: sd.instanceName.Concat["-provider"], ioTemplate: ioTemplate]] ];
END;
GetProvider: PROC [for: CellClass] RETURNS [providerName: ROPE] =
BEGIN
provider: CellClass;
providerName ← for.name.Concat["-provider"];
IF (provider ← NARROW[cellClasses.Lookup[providerName]]) = NIL THEN
BEGIN
RegisterCellClass[className: providerName, expandProc: NIL, ioCreator: CreateProviderIO, initializer: InitializeProvider, evalProc: EvalProvider, ports: MirrorPorts[for.ports]];
END;
END;
--no longer needed (and thus commented out):--
RunButtonProc: Buttons.ButtonProc =
BEGIN
pd: ProviderData ← NARROW[clientData];
pd.armed ← TRUE;
Rosemary.ScheduleCell[pd.cell];
Rosemary.Run[CellToStr[pd.cell.parent]];
pd.armed ← FALSE;
END;
InitializeProvider: Initializer =
BEGIN
--no longer needed (and thus commented out):--
MakePauser: ViewRec.OtherStuffProc =
TRUSTED BEGIN
v, b: Viewer;
[pd.pauser, v] ← Pausers.CreatePauser[enabledName: "Proceed", disabledName: "", viewerInit: [parent: in, border: FALSE], paint: FALSE];
b ← Buttons.Create[
proc: RunButtonProc,
info: [parent: in, name: "Schedule & Run"],
clientData: pd,
paint: FALSE];
RETURN [LIST[v, b]];
END;
pd: ProviderData ← NEW [ProviderDataRep ← [cell: cell]];
--no longer needed (and thus commented out):--
id: InitData ← NARROW[initData];
TRUSTED BEGIN
[] ← ViewRec.ViewRef[rec: cell.realCellStuff.newIO, otherStuff: MakePauser, viewerInit: [iconic: FALSE, name: id.name.Concat[".newIO"]]];
END;
cell.realCellStuff.state ← pd;
END;
CreateProviderIO: IOCreator =
BEGIN
id: InitData ← NARROW[initData];
IF id.ioTemplate # NIL THEN
--beg in-- TRUSTED --end in--
BEGIN
usersIOAsTV: TypedVariable ← AMBridge.TVForReferent[id.ioTemplate];
ioType: Type ← AMTypes.TVType[usersIOAsTV];
newIOAsTV: TypedVariable ← AMTypes.New[ioType];
oldIOAsTV: TypedVariable ← AMTypes.New[ioType];
cell.realCellStuff.newIO ← AMBridge.RefFromTV[newIOAsTV];
cell.realCellStuff.oldIO ← AMBridge.RefFromTV[oldIOAsTV];
END
ELSE {cell.realCellStuff.newIO ← cell.realCellStuff.oldIO ← NIL};
END;
EvalProvider: EvalProc =
BEGIN
pd: ProviderData ← NARROW[cell.realCellStuff.state];
FOR i: CARDINAL IN [0 .. cell.class.ioWordCount) DO
TRUSTED BEGIN
(cell.realCellStuff.oldIOAsWP + i)^ ← (cell.realCellStuff.newIOAsWP + i)^;
END;
ENDLOOP;
IF pd.armed THEN pd.pauser.Pause[];
END;
LookupClass: PROC [name: ROPE] RETURNS [CellClass] =
{RETURN [NARROW[cellClasses.Lookup[name]]]};
DecideFromFile: PUBLIC PROC [fileName: ROPE] RETURNS [dff: Rosemary.ExpandDeciderClosure] =
BEGIN
file: IO.STREAMNIL;
top: LORA;
file ← FIO.Open[fileName: fileName];
top ← LIST[NIL, NIL, IO.GetRefAny[file]];
file.Close[];
dff ← NEW [Rosemary.ExpandDeciderClosureRep ← [Decide: DecideByName, otherData: top]];
END;
DecideByName: Rosemary.ExpandDecider =
BEGIN
Yelp: PROC [problem: ROPE] RETURNS [Rosemary.ExpandDecision] = TRUSTED
BEGIN
qerv.DisplayMessage[problem];
RETURN [Ask[cell, NIL]];
END;
decisionsByName: LORANARROW[otherData];
name: Name ← GetName[cell];
descr: LORA ← GetDescr[name, decisionsByName];
decAt: ATOM;
asAny: REF ANY;
IF descr = NIL THEN RETURN [Yelp["no decision given"]];
IF descr.rest = NIL THEN
BEGIN
IF RosemaryExtras.Possible[cell, Leaf] THEN RETURN [Leaf];
RETURN [Yelp["cant make it a Leaf"]];
END;
IF NOT ISTYPE[descr.rest.first, ATOM] THEN RETURN [Yelp["decision not an Atom"]];
IF (asAny ← Atom.GetProp[atom: (decAt ← NARROW[descr.rest.first]), prop: decisionProp]) = NIL THEN RETURN [Yelp["atom not a decision"]];
IF (IF asAny = NIL THEN TRUE ELSE NOT ISTYPE[asAny, ExpandDecisionRef]) THEN RETURN [Yelp["atom not a decision"]];
RETURN [NARROW[asAny, ExpandDecisionRef]^];
END;
ExpandDecisionRef: TYPE = REF Rosemary.ExpandDecision;
GetName: PROC [cell: Cell] RETURNS [name: Name] =
BEGIN
name ← NIL;
WHILE cell # NIL DO
name ← CONS[cell.name, name];
cell ← cell.parent;
ENDLOOP;
END;
GetDescr: PROC [name: Name, dbn: LORA] RETURNS [LORA] =
BEGIN
Matches: PROC [name: ROPE, asAny: REF ANY] RETURNS [BOOLEAN] =
BEGIN
dbn: LORA;
s2: ROPE;
IF NOT ISTYPE[asAny, LORA] THEN TRUSTED
BEGIN
MessageWindow.Append[message: "Ill formed decisions!", clearFirst: TRUE];
RETURN [FALSE];
END;
dbn ← NARROW[asAny];
IF (IF dbn = NIL THEN TRUE ELSE (IF dbn.first = NIL THEN TRUE ELSE (NOT ISTYPE[dbn.first, ROPE] AND NOT ISTYPE[dbn.first, ATOM]))) THEN TRUSTED
BEGIN
MessageWindow.Append[message: "Ill formed decisions!", clearFirst: TRUE];
RETURN [FALSE];
END;
s2 ← WITH dbn.first SELECT FROM
r: ROPE => r,
a: ATOM => Atom.GetPName[a],
ENDCASE => ERROR;
RETURN [Rope.Equal[s1: name, s2: s2, case: FALSE]];
END;
WHILE name # NIL DO
tail: LORA;
IF (IF dbn = NIL THEN TRUE ELSE dbn.rest = NIL) THEN TRUSTED
BEGIN
MessageWindow.Append[message: "Ill formed decisions!", clearFirst: TRUE];
RETURN [NIL];
END;
FOR tail ← dbn.rest.rest, tail.rest WHILE tail # NIL DO
IF Matches[name.first, tail.first] THEN EXIT;
ENDLOOP;
IF tail = NIL THEN TRUSTED
BEGIN
MessageWindow.Append[message: "No decsion", clearFirst: TRUE];
RETURN [NIL];
END;
name ← name.rest;
dbn ← NARROW[tail.first];
ENDLOOP;
RETURN [dbn];
END;
MakeQueryPauser: ViewRec.OtherStuffProc =
BEGIN
v: Viewer;
[qp, v] ← Pausers.CreatePauser[enabledName: "Answer Query", disabledName: "", viewerInit: [parent: in, border: FALSE], paint: FALSE];
RETURN [LIST[v]];
END;
Ask: Rosemary.ExpandDecider =
BEGIN
first: BOOLEANTRUE;
eq.instanceName ← cell.name;
eq.className ← cell.class.name;
WHILE first OR NOT RosemaryExtras.Possible[cell, eq.whatToDo] DO qp.Pause[]; first ← FALSE ENDLOOP;
RETURN [eq.whatToDo];
END;
qerv: ViewRec.RecordViewer;
Setup: PROC =
BEGIN
RegisterCellClass[className: "GiveItAnything",
expandProc: ExpandAnything,
ioCreator: NIL,
evalProc: NIL,
ports: NEW [PortsRep[0]]];
TRUSTED BEGIN
qerv ← ViewRec.ViewRef[
agg: eq,
otherStuff: MakeQueryPauser,
viewerInit: [iconic: FALSE, column: right, name: "ExpandQuery"]];
END;
Atom.PutProp[atom: $N, prop: decisionProp, val: NEW [Rosemary.ExpandDecision ← Nested]];
Atom.PutProp[atom: $I, prop: decisionProp, val: NEW [Rosemary.ExpandDecision ← Inline]];
Atom.PutProp[atom: $L, prop: decisionProp, val: NEW [Rosemary.ExpandDecision ← Leaf]];
providerHandler.Register[CODE[ProviderDataRep]];
END;
Setup[];
END.