[Indigo]<Rosemary>Release>Rosemary2.df=>RoseStateIOImpl.Mesa
Last Edited by: Spreitzer, May 10, 1984 3:48:15 pm PDT PDT PDT PDT PDT PDT PDT PDT PDT PDT PDT PDT PDT
DIRECTORY Cucumber, FS, IO, Rope, OrderedSymbolTableRef, RoseDisplayInsides, RoseTypes, RoseRun, RoseStateIO, SafeStorage;
RoseStateIOImpl:
PROGRAM
IMPORTS Cucumber, FS, IO, OrderedSymbolTableRef, 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}];
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}];
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];
str: RoseTypes.Structure ← IF cell.parent # NIL THEN RoseTypes.ContainingStr[cell] ELSE NIL;
IF (str # NIL) AND (cell = str.mirror) THEN ERROR;
SELECT part.first
FROM
$class => NULL;
$nextInstance => NULL;
$sim => NULL;
$parent => NULL;
$leftChild => NULL;
$rightSibling => NULL;
$firstInternalNode => NULL;
$internalNodes => NULL;
$components => TransferComponents[cell, where, direction];
$interfaceNodes => NULL;
$props => IF direction = out THEN CheckCellProps[cell];
$realCellStuff => IF cell.type = Real THEN TransferRealCellStuff[cell, where, direction];
ENDCASE => ERROR;
END;
CheckCellProps:
PROC [cell: Cell] =
BEGIN
FOR al: RoseTypes.AList ← cell.props, al.rest
WHILE al #
NIL
DO
IF al.first.key #
NIL
THEN
WITH al.first.key
SELECT
FROM
x: RoseDisplayInsides.Display => LOOP;
ENDCASE;
SELECT al.first.key
FROM
$ExpandDeciderClosure, RoseDisplayInsides.cellStateDisplayProp => LOOP;
ENDCASE;
IF al.first.val # NIL THEN ERROR Cucumber.Error[IO.PutFR["%g has a %g property, and I don't know what to do with it", IO.rope[cell.name], IO.refAny[al.first.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
ReadIO: RoseRun.ModifyProc = TRUSTED {TransferWords[cell.realCellStuff.newIOAsWP, cell.class.ioWordCount, where, in]};
SELECT direction
FROM
in =>
BEGIN
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.class.ioWordCount, 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
$container, $schedFirst, $schedLast, $firstNeeded, $insideNodes, $nextPerturbed, $nextWasPerturbed, $firstPerturbed, $firstAffected => NULL;
$mirror =>
NULL;
Cucumber.Transfer[what: str.mirror, where: where, direction: direction];
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.