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 ANY ← NIL];
InitData: TYPE = REF InitDataRep;
InitDataRep:
TYPE =
RECORD [
name: ROPE,
ioTemplate: REF ANY];
ExpandQuery: TYPE = REF ExpandQueryRep;
ExpandQueryRep:
TYPE =
RECORD [
instanceName, className: ROPE ← NIL,
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
ANY ←
NIL, 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: ROPE ← NIL;
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.STREAM ← NIL;
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: LORA ← NARROW[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: BOOLEAN ← TRUE;
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.