[Indigo]<Rosemary>®>Rosemary.df=>RoseStateIOImpl.Mesa
Last Edited by: Spreitzer, October 25, 1985 6:34:06 pm PDT
DIRECTORY Asserting, Cucumber, FS, IO, Rope, RedBlackTree, RoseDisplayInsides, RoseTypes, RoseRun, RoseStateIO, SafeStorage;
RoseStateIOImpl:
PROGRAM
IMPORTS Asserting, Cucumber, FS, IO, RedBlackTree, RoseDisplayInsides, RoseRun, RoseTypes, SS: SafeStorage
EXPORTS RoseStateIO =
BEGIN
ROPE: TYPE = Rope.ROPE;
Cell: TYPE = RoseTypes.Cell;
Dir: TYPE = Cucumber.Direction;
Save:
PUBLIC
PROC [cell: Cell, fileName:
ROPE]
RETURNS [errMsg:
ROPE] =
BEGIN
file: IO.STREAM ← FS.StreamOpen[fileName: fileName, accessOptions: create];
errMsg ← NIL;
Cucumber.Transfer[what: cell, where: file, direction: out !
Cucumber.Error => {errMsg ← msg; CONTINUE};
UNWIND => {file.Close[]}
];
file.Close[];
END;
Restore:
PUBLIC
PROC [cell: Cell, fileName:
ROPE]
RETURNS [errMsg:
ROPE] =
BEGIN
file: IO.STREAM ← FS.StreamOpen[fileName: fileName, accessOptions: read];
errMsg ← NIL;
Cucumber.Transfer[what: cell, where: file, direction: in !
Cucumber.Error => {errMsg ← msg; CONTINUE};
UNWIND => file.Close[]
];
IF errMsg # NIL THEN errMsg ← IO.PutFR["at %g: %g", IO.int[file.GetIndex[]], IO.rope[errMsg]];
file.Close[];
END;
cellHandler: Cucumber.Handler ←
NEW [Cucumber.HandlerRep ← [
PartTransfer: TransferCell]];
strHandler: Cucumber.Handler ←
NEW [Cucumber.HandlerRep ← [
PartTransfer: TransferStructure]];
TransferCell: Cucumber.PartTransferProc =
BEGIN
cell: Cell ← NARROW[whole];
SELECT part.first
FROM
$type => NULL;
$nextInstance => NULL;
$sim => NULL;
$parent => NULL;
$leftChild => NULL;
$rightSibling => NULL;
$firstInternalNode => NULL;
$internalNodes => NULL;
$components => TransferComponents[cell, where, direction];
$interfaceNodes => NULL;
$other => IF direction = out THEN CheckCellProps[cell];
$realCellStuff => IF cell.substantiality = Real THEN TransferRealCellStuff[cell, where, direction];
ENDCASE => ERROR;
END;
CheckCellProps:
PROC [cell: Cell] =
BEGIN
FOR al: RoseTypes.Assertions ← cell.other, al.rest
WHILE al #
NIL
DO
key: Asserting.Term ← Asserting.RelnOf[al.first];
rest: Asserting.Terms ← Asserting.TermsOf[al.first];
IF key #
NIL
THEN
WITH key
SELECT
FROM
x: RoseDisplayInsides.Display => LOOP;
ENDCASE;
SELECT key
FROM
$ExpandDeciderClosure, RoseDisplayInsides.cellStateDisplayProp, RoseDisplayInsides.typeDataDisplayProp => LOOP;
ENDCASE;
IF rest # NIL AND rest.first # NIL THEN ERROR Cucumber.Error[IO.PutFR["%g has a %g relation, and I don't know what to do with it", IO.rope[cell.name], IO.refAny[key]]];
ENDLOOP;
END;
TransferComponents:
PROC [cell: Cell, where:
IO.
STREAM, direction: Dir] =
BEGIN
WriteCell:
SAFE
PROC [asAny:
REF
ANY]
RETURNS [stop:
BOOLEAN] =
TRUSTED
BEGIN
component: Cell ← NARROW[asAny];
where.PutF["%g ", IO.refAny[component.name]];
Cucumber.Transfer[component, where, out];
stop ← FALSE;
END;
SELECT direction
FROM
in =>
DO
name: ROPE ← NARROW[where.GetRefAny[]];
component: Cell;
IF name = NIL THEN EXIT;
component ← NARROW[cell.components.Lookup[name]];
IF component = NIL THEN ERROR Cucumber.Error[IO.PutFR["component %g not found", IO.rope[name]]];
Cucumber.Transfer[component, where, direction];
ENDLOOP;
out =>
BEGIN
IF cell.components # NIL THEN cell.components.EnumerateIncreasing[WriteCell];
where.PutRope["NIL "];
END;
ENDCASE => ERROR;
END;
TransferWords:
PUBLIC
PROC [wp: RoseTypes.WordPtr, wordCount:
CARDINAL, stream:
IO.
STREAM, direction: Cucumber.Direction] =
BEGIN
SELECT direction
FROM
in => {
FOR i:
CARDINAL
IN [0 .. wordCount)
DO
card: CARDINAL ← stream.GetCard[!SS.NarrowRefFault => ERROR Cucumber.Error["Not a CARDINAL"]];
TRUSTED {(wp + i)^ ← card};
ENDLOOP;
};
out => {
FOR i:
CARDINAL
IN [0 .. wordCount)
DO
TRUSTED {stream.PutF["%g ", IO.card[(wp + i)^]]};
ENDLOOP;
};
ENDCASE => ERROR;
END;
TransferRealCellStuff:
PROC [cell: Cell, where:
IO.
STREAM, direction: Dir] =
BEGIN
SELECT direction
FROM
in =>
BEGIN
ReadIO:
SAFE
PROC [cell: Cell]
--RoseTypes.CellProc-- =
TRUSTED
{TransferWords[cell.realCellStuff.newIOAsWP, cell.type.simpleWordCount, where, in]};
hasState: BOOLEAN;
scheduled: BOOLEAN ← where.GetBool[!SS.NarrowRefFault => ERROR Cucumber.Error["Not a BOOLEAN"]];
IF cell.parent # NIL THEN RoseRun.AllowToModify[cell, ReadIO] ELSE [] ← ReadIO[cell];
hasState ← where.GetBool[!SS.NarrowRefFault => ERROR Cucumber.Error["Not a BOOLEAN"]];
IF hasState # (cell.realCellStuff.state # NIL) THEN ERROR Cucumber.Error[IO.PutFR["disagreement on emptiness of state of %g", IO.rope[cell.name]]];
IF hasState THEN Cucumber.Transfer[cell.realCellStuff.state, where, in];
END;
out =>
BEGIN
hasState: BOOLEAN ← cell.realCellStuff.state # NIL;
where.PutF["%g ", IO.bool[cell.realCellStuff.schedNext # RoseTypes.notInCellList]];
TransferWords[cell.realCellStuff.newIOAsWP, cell.type.simpleWordCount, where, out];
where.PutF["%g ", IO.bool[hasState]];
IF hasState THEN Cucumber.Transfer[cell.realCellStuff.state, where, out];
END;
ENDCASE => ERROR;
END;
TransferStructure:
PROC [whole:
REF
ANY, part: Cucumber.Path, where:
IO.
STREAM, direction: Cucumber.Direction, data:
REF
ANY]
--Cucumber.PartTransferProc-- = {
str: RoseTypes.Structure ← NARROW[whole];
SELECT part.first
FROM
$sim, $schedFirst, $schedLast, $firstNeeded, $firstPerturbed, $firstAffected => NULL;
ENDCASE => ERROR Cucumber.Error[IO.PutFR["Unexpected part %g of Structure", IO.refAny[part]]]
};
Setup:
PROC =
BEGIN
cellHandler.Register[CODE[RoseTypes.CellRep]];
strHandler.Register[CODE[RoseTypes.StructureRep]];
END;
Setup[];
END.