DIRECTORY
Atom, ConvertUnsafe, Directory, FileIO, Inline, IO, Rope, RoseTranslateTypes, System;
MnemonicsTranslation:
CEDAR
PROGRAM
IMPORTS Atom, ConvertUnsafe, Directory, FileIO, Inline, IO, Rope, RoseTranslateTypes, System =
ConstructMnemonic: RoseTranslateTypes.SignalTypeConstructor =
TRUSTED
BEGIN
asAny: REF ANY ← RoseTranslateTypes.GetParm[1, "file", parms];
mnemName, fileName: ROPE;
atom: ATOM;
need: BOOLEAN ← TRUE;
fileString: LONG STRING ← [256];
tempString: LONG STRING ← [256];
fileTime: System.GreenwichMeanTime;
fileSinceEpoch: LONG CARDINAL;
fileExists: BOOLEAN ← TRUE;
WITH asAny
SELECT
FROM
q: RoseTranslateTypes.Quoted => mnemName ← q.rope;
ENDCASE => ERROR RoseTranslateTypes.TypeConstructionError["Mnemonic constructor not given a quoted string"];
IF mnemName.Length[] < 1 THEN ERROR RoseTranslateTypes.TypeConstructionError["Mnemonic constructor given an empty string"];
atom ← Atom.MakeAtom[fileName ← mnemName.Concat[".mnemonics"]];
type ← NARROW[Atom.GetProp[atom: atom, prop: $mnemonicRoseType]];
ConvertUnsafe.AppendRope[fileString, fileName];
fileTime ← Directory.GetProps[Directory.Lookup[fileString !Directory.Error => {fileExists ← FALSE; CONTINUE}], tempString].createDate;
IF
NOT fileExists
THEN
BEGIN
IF type = NIL THEN ERROR RoseTranslateTypes.TypeConstructionError[IO.PutFR["File %g not found", IO.rope[fileName]]];
RETURN;
END;
fileSinceEpoch ← System.SecondsSinceEpoch[fileTime];
IF type #
NIL
THEN
BEGIN
mnem: Mnemonic ← NARROW[type.data];
need ← fileSinceEpoch > mnem.analyzeSinceEpoch;
END;
IF need
THEN
BEGIN
mnem: Mnemonic ←
NEW [MnemonicRep ← [
name: mnemName,
roseType: IO.PutFR["Mnemonic[\"%g\"]", IO.rope[mnemName]],
mesaTypeDecl: IO.PutFR["%g: TYPE = {", IO.rope[mnemName]],
analyzeSinceEpoch: fileSinceEpoch]];
file: IO.STREAM ← FileIO.Open[fileName];
count: CARDINAL ← 0;
goingToNextBit: BOOLEAN ← FALSE;
file.SkipOver[IO.WhiteSpace];
WHILE
NOT file.EndOf[]
DO
member: ROPE ← file.GetToken[IO.IDProc];
newCount: CARDINAL ← count + 1;
overlap: CARDINAL ← Inline.BITAND[count, newCount];
IF count > 0 THEN mnem.mesaTypeDecl ← mnem.mesaTypeDecl.Concat[", "];
mnem.mesaTypeDecl ← mnem.mesaTypeDecl.Concat[member];
IF goingToNextBit THEN mnem.bits ← mnem.bits + 1;
goingToNextBit ← overlap = 0;
count ← newCount;
file.SkipOver[IO.WhiteSpace];
ENDLOOP;
file.Close[];
IF count = 0 THEN ERROR RoseTranslateTypes.TypeConstructionError[IO.PutFR["No names in mnemonic file %g", IO.rope[fileName]]];
mnem.mesaTypeDecl ← mnem.mesaTypeDecl.Concat["}"];
IF type # NIL THEN type.data ← mnem ELSE type ← NEW [RoseTranslateTypes.SignalTypeRep ← [mnemProcs, mnem]];
Atom.PutProp[atom: atom, prop: $mnemonicRoseType, val: type];
END;
END;
RoseTranslateTypes.RegisterSignalTypeConstructor["Mnemonic", ConstructMnemonic];