GenCImpl:
PUBLIC
PROC [] ~ {
failure: BOOLEAN;
programKey: ROPE;
programKeyWD: ROPE;
cImplStream: IO.STREAM;
allTheTables: TABLES;
uniqueNo: NAT;
h: Handle;
CollectProcsAndErrors: HashTable.EachPairAction ~ {
entry: REF DirectoryEntry ← NARROW [value];
successful: BOOLEAN;
type: CType;
value1: Value;
[successful, value1] ← HashTable.Fetch[allTheTables.condensedTypeTable, entry.type];
type ← NARROW [value1];
IF (type.class = procedure)
THEN [] ← HashTable.Insert[allTheTables.procedures, key, value]
ELSE {
IF (type.class = error)
THEN [] ← HashTable.Insert[allTheTables.errors, key, value];
};
RETURN[FALSE];
};
GenerateRemoteProc: HashTable.EachPairAction ~ {
entry: REF DirectoryEntry ← NARROW [value];
name: ROPE ← NARROW [key];
code: ROPE;
id: ROPE;
list: CComponent;
successful: BOOLEAN;
type: CType;
value1: Value;
[successful, value1] ← HashTable.Fetch[allTheTables.condensedTypeTable, entry.type];
type ← NARROW[value1];
IO.PutF[cImplStream, Nest["", 1]];
IO.PutF[cImplStream, "%g: PUBLIC PROC [h: CrRPC.Handle",
IO.rope[name]
];
list ← type.children;
IF (list #
NIL)
THEN {
FOR loopindex:
CARD
IN [0..type.bound)
DO
IO.PutF[cImplStream,", %g: %g",
IO.rope[list.name],
IO.rope[SiroccoPrivate.UnDo[list.type, programKey]]
];
list ← list.sibling;
ENDLOOP;
IO.PutF[cImplStream, "] RETURNS ["];
IF (list #
NIL)
THEN {
IO.PutF[cImplStream,"%g: %g",
IO.rope[list.name],
IO.rope[SiroccoPrivate.UnDo[list.type, programKey]]
];
list ← list.sibling;
};
WHILE (list #
NIL)
DO
IO.PutF[cImplStream,", %g: %g",
IO.rope[list.name],
IO.rope[SiroccoPrivate.UnDo[list.type, programKey]]
];
list ← list.sibling;
ENDLOOP;
};
IO.PutF[cImplStream, Nest["] ~ {", 2]];
IO.PutF[cImplStream, Nest["PutArgs: CrRPC.PutArgsProc ~ {", 3]];
list ← type.children;
uniqueNo ← 0;
IF (list =
NIL)
THEN IO.PutF[cImplStream, Nest["NULL", 3]]
ELSE {
FOR loopindex:
CARD
IN [0..type.bound)
DO
code ← " ";
[successful, value1] ← HashTable.Fetch[allTheTables.condensedTypeTable, list.type];
type ← NARROW[value1];
[code, id] ← SiroccoPrivate.Marshal[h, type, list.type, list.name, code, uniqueNo, 3];
IO.PutF[cImplStream, Nest["%g", 3],
IO.rope[code]
];
list ← list.sibling;
ENDLOOP;
};
IO.PutF[cImplStream, Nest["};", 2]];
IO.PutF[cImplStream, Nest["GetResults: CrRPC.GetResultsProc ~ {", 3]];
uniqueNo ← 0;
IF (list =
NIL)
THEN IO.PutF[cImplStream, Nest["NULL", 3]];
WHILE (list #
NIL)
DO
code ← "";
[successful, value1] ← HashTable.Fetch[allTheTables.condensedTypeTable, list.type];
type ← NARROW [value1];
[code, id] ← SiroccoPrivate.UnMarshal[h, type, list.type, list.name, code, uniqueNo, 3];
IO.PutF[cImplStream, Nest["%g", 3],
IO.rope[code]
];
list ← list.sibling;
ENDLOOP;
IO.PutF[cImplStream, Nest["};", 3]];
IO.PutF[cImplStream, Nest["", 2]];
IO.PutF[cImplStream, Nest["CrRPC.Call[h~h, remotePgm~%g, remotePgmVersion~%g, remoteProc~%g, putArgs~PutArgs, getResults~GetResults, getError~GetError];", 2],
IO.int[h.programNo],
IO.int[h.versionNo],
IO.rope[entry.constant]
];
IO.PutF[cImplStream, Nest["};", 1]];
};
GenerateErrorDefinition: HashTable.EachPairAction ~ {
name: ROPE ← NARROW [key];
entry: REF DirectoryEntry ← NARROW [value];
list: CComponent;
successful: BOOLEAN;
type: CType;
value1: Value;
[successful, value1] ← HashTable.Fetch[allTheTables.condensedTypeTable, entry.type];
type ← NARROW[value1];
IO.PutF[cImplStream, "%g: ",
IO.rope[name]
];
IO.PutF[cImplStream, "PUBLIC ERROR"];
list ← type.children;
IF (list #
NIL)
THEN {
IO.PutF[cImplStream, " ["];
IO.PutF[cImplStream,"%g: %g",
IO.rope[list.name],
IO.rope[SiroccoPrivate.UnDo[list.type, programKey]]
];
list ← list.sibling;
WHILE (list #
NIL)
DO
IO.PutF[cImplStream,", %g: %g",
IO.rope[list.name],
IO.rope[SiroccoPrivate.UnDo[list.type, programKey]]
];
list ← list.sibling;
ENDLOOP;
IO.PutF[cImplStream, "]"];
};
IO.PutF[cImplStream, Nest[" ~ CODE;", 1]]
};
GenerateErrorCase: HashTable.EachPairAction ~ {
entry: REF DirectoryEntry ← NARROW [value];
name: ROPE ← NARROW [key];
code: ROPE;
id: ROPE;
list: CComponent;
successful: BOOLEAN;
type: CType;
value1: Value;
IF Rope.Equal[entry.constant , ""] THEN RETURN;
IO.PutF[cImplStream, "%g => ",
IO.rope[entry.constant]
];
[successful, value1] ← HashTable.Fetch[allTheTables.condensedTypeTable, entry.type];
type ← NARROW[value1];
list ← type.children;
IF (list =
NIL)
THEN {
IO.PutF[cImplStream, Nest["ERROR %g[];", 3],
IO.rope[name]
];
}
ELSE {
IO.PutF[cImplStream, Nest["{", 4]];
WHILE (list #
NIL)
DO
IO.PutF[cImplStream, Nest["%g: %g;", 4],
IO.rope[list.name],
IO.rope[SiroccoPrivate.UnDo[list.type, programKey]]
];
list ← list.sibling;
ENDLOOP;
list ← type.children;
WHILE (list #
NIL)
DO
code ← "";
[successful, value1] ← HashTable.Fetch[allTheTables.condensedTypeTable, list.type];
[code, id] ← SiroccoPrivate.UnMarshal[h, NARROW [value1], list.type, list.name, code, uniqueNo, 3];
IO.PutF[cImplStream, Nest["%g", 4],
IO.rope[code]
];
list ← list.sibling;
ENDLOOP;
list ← type.children;
IO.PutF[cImplStream, "ERROR %g[%g",
IO.rope[name],
IO.rope[list.name]
];
list ← list.sibling;
WHILE (list #
NIL)
DO
IO.PutF[cImplStream, ", %g",
IO.rope[list.name]
];
list ← list.sibling;
ENDLOOP;
IO.PutF[cImplStream, Nest["]", 4]];
IO.PutF[cImplStream, Nest["};", 3]];
};
};
Heading:
PROC [out:
IO.
STREAM] ~ {
PutDirectory: HashTable.EachPairAction ~ {
interface: ROPE ~ NARROW [value];
IO.PutF[out, Nest["%g,", 1],
IO.rope[interface]
];
};
SiroccoPrivate.FileHeader[out, Rope.Concat[programKeyWD,"ClientImpl.Mesa"]];
IO.PutF[out, Nest["DIRECTORY", 1]];
IO.PutF[out, Nest["CrRPC,", 1]];
failure ← HashTable.Pairs[allTheTables.directory, PutDirectory];
IO.PutF[out, Nest["%g;", 0], IO.rope[programKeyWD]];
IO.PutF[out, Nest["", 0]];
IO.PutF[out, Nest["%gClientImpl: CEDAR PROGRAM", 1], IO.rope[programKeyWD]];
IO.PutF[out, Nest["IMPORTS CrRPC", 1]];
IO.PutF[out, Nest["EXPORTS %g ~ {", 1], IO.rope[programKeyWD]];
IO.PutF[out, Nest["OPEN %g;", 0], IO.rope[programKeyWD]];
IO.PutF[out, Nest["", 0]];
};
GenCImpl MAIN
h ← SIGNAL SiroccoPrivate.AquireState[];
allTheTables ← h.allTheTables;
programKey ← h.programKey;
programKeyWD ←
IO.PutFR["%gP%gV%g",
IO.rope[h.programName],
IO.int[h.programNo],
IO.int[h.versionNo]
];
cImplStream ← FS.StreamOpen[Rope.Concat[programKeyWD,"ClientImpl.Mesa"], $create];
Heading[cImplStream];
HashTable.Erase[allTheTables.procedures];
HashTable.Erase[allTheTables.errors];
failure ← HashTable.Pairs[allTheTables.localTable, CollectProcsAndErrors];
IF (HashTable.GetSize[allTheTables.errors] = 0)
THEN
{
IO.PutF[cImplStream, Nest["GetError: CrRPC.GetErrorProc ~ {", 2]];
IO.PutF[cImplStream, Nest["ERROR CrRPC.Error[h, remoteError, \"%g\"];", 2],
IO.rope["Unexpected Remote Error"]
];
IO.PutF[cImplStream, Nest["};", 1]];
}
ELSE {
IO.PutF[cImplStream, Nest["-- Errors", 1]];
IO.PutF[cImplStream, Nest["", 1]];
failure ← HashTable.Pairs[allTheTables.errors, GenerateErrorDefinition];
IO.PutF[cImplStream, Nest["", 0]];
IO.PutF[cImplStream, Nest["-- GetErrorProc", 1]];
IO.PutF[cImplStream, Nest["", 1]];
IO.PutF[cImplStream, Nest["GetError: CrRPC.GetErrorProc ~ {", 2]];
IO.PutF[cImplStream, Nest["SELECT errNum FROM", 3]];
failure ← HashTable.Pairs[allTheTables.errors, GenerateErrorCase];
IO.PutF[cImplStream, Nest["ENDCASE => {", 4]];
IO.PutF[cImplStream, Nest["ERROR CrRPC.Error[h, remoteError, \"%g\"];", 4],
IO.rope["Unexpected Remote Error"]
];
IO.PutF[cImplStream, Nest["};", 2]];
IO.PutF[cImplStream, Nest["};", 1]];
};
IO.PutF[cImplStream, Nest["", 0]];
IO.PutF[cImplStream, Nest["-- Remote Procedures", 1]];
failure ← HashTable.Pairs[allTheTables.procedures, GenerateRemoteProc];
IO.PutF[cImplStream, Nest["", 0]];
IO.PutF[cImplStream, Nest["}...", 0]];
IO.Close[cImplStream];
};