RoseHelpImpl.Mesa
Last Edited by: Spreitzer, July 8, 1983 3:33 pm
Last Edited by: Barth, June 9, 1983 11:23 am
DIRECTORY
Atom, Buttons, Pausers, ViewerClasses, ViewRec, FileIO, IO, MessageWindow, OrderedSymbolTableRef, Rope, Rosemary, RoseHelp;
RoseHelpImpl: CEDAR PROGRAM
IMPORTS Atom, MessageWindow, OrderedSymbolTableRef, Pausers, Rope, FIO: FileIO, IO, ViewRec, Rosemary
EXPORTS RoseHelp =
BEGIN OPEN Rosemary;
NoHelpForAnything: PUBLIC ERROR = CODE;
LORA: TYPE = LIST OF REF ANY;
Viewer: TYPE = ViewerClasses.Viewer;
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];
ExpandQuery: TYPE = REF ExpandQueryRep;
ExpandQueryRep: TYPE = RECORD [
instanceName, className: ROPENIL,
whatToDo: Rosemary.ExpandDecision ← Nested];
qp: Pausers.Pauser ← NIL;
eq: ExpandQuery ← NEW [ExpandQueryRep ← []];
ask: PUBLIC Rosemary.ExpandDeciderClosure ← NEW [Rosemary.ExpandDeciderClosureRep ← [
Decide: Ask, otherData: NIL]];
decisionProp: ATOM ← Atom.Gensym[];
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;
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;
usersCell ← CreateCell[within: thisCell, instanceName: sd.instanceName, className: sd.class.name, interfaceNodes: usersInterface, initData: sd.initData];
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 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 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]];
END;
Setup[];
END.