RoseStateIOImpl.Mesa
Last Edited by: Spreitzer, September 14, 1983 12:54 pm
DIRECTORY
Cucumber, FileIO, IO, Rope, OrderedSymbolTableRef, Rosemary, RoseStateIO, SafeStorage;
RoseStateIOImpl: PROGRAM
IMPORTS Cucumber, FileIO, IO, OrderedSymbolTableRef, Rope, Rosemary, SS: SafeStorage
EXPORTS RoseStateIO =
BEGIN
ROPE: TYPE = Rope.ROPE;
Cell: TYPE = Rosemary.Cell;
Dir: TYPE = Cucumber.Direction;
Save: PUBLIC PROC [cell: Cell, fileName: ROPE] RETURNS [errMsg: ROPE] =
BEGIN
file: IO.STREAM ← FileIO.Open[fileName: fileName, accessOptions: overwrite];
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 ← FileIO.Open[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];
SELECT part.first FROM
$class => NULL;
$nextInstance => NULL;
$parent => NULL;
$leftChild => NULL;
$rightSibling => NULL;
$firstInternalNode => NULL;
$internalNodes => NULL;
$components => TransferComponents[cell, where, direction];
$interfaceNodes => NULL;
$other => NULL;
$type => NULL;
$realCellStuff => IF cell.type = Real THEN TransferRealCellStuff[cell, where, direction];
ENDCASE => ERROR;
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.rope[component.name]];
Cucumber.Transfer[component, where, out];
stop ← FALSE;
END;
SELECT direction FROM
in => DO
name: ROPE ← where.GetToken[IO.IDProc];
component: Cell;
IF name.Equal["!"] 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["! "];
END;
ENDCASE => ERROR;
END;
TransferRealCellStuff: PROC [cell: Cell, where: IO.STREAM, direction: Dir] =
BEGIN
ReadIO: Rosemary.ModifyProc = TRUSTED
BEGIN
FOR i: CARDINAL IN [0 .. cell.class.ioWordCount) DO
card: CARDINAL ← where.GetCard[!SS.NarrowRefFault => ERROR Cucumber.Error["Not a CARDINAL"]];
(cell.realCellStuff.newIOAsWP + i)^ ← card;
ENDLOOP;
END;
SELECT direction FROM
in => BEGIN
hasState: BOOLEAN;
scheduled: BOOLEAN ← where.GetBool[!SS.NarrowRefFault => ERROR Cucumber.Error["Not a BOOLEAN"]];
IF cell.parent # NIL THEN cell.AllowToModify[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 # Rosemary.notInSchedule]];
FOR i: CARDINAL IN [0 .. cell.class.ioWordCount) DO
where.PutF["%g ", IO.card[(cell.realCellStuff.newIOAsWP + i)^]];
ENDLOOP;
where.PutF["%g ", IO.bool[hasState]];
IF hasState THEN Cucumber.Transfer[cell.realCellStuff.state, where, out];
END;
ENDCASE => ERROR;
END;
TransferStructure: Cucumber.PartTransferProc = {
str: Rosemary.Structure ← NARROW[whole];
SELECT part.first FROM
$container, $schedFirst, $schedLast, $insideNodes => NULL;
$mirror => 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[Rosemary.CellRep]];
strHandler.Register[CODE[Rosemary.StructureRep]];
END;
Setup[];
END.