MnemonicsTranslation.Mesa
Last Edited by: Spreitzer, March 18, 1983 1:40 pm
DIRECTORY
Atom, ConvertUnsafe, Directory, FileIO, Inline, IO, Rope, RoseTranslateTypes, System;
MnemonicsTranslation: CEDAR PROGRAM
IMPORTS Atom, ConvertUnsafe, Directory, FileIO, Inline, IO, Rope, RoseTranslateTypes, System =
BEGIN
ROPE: TYPE = Rope.ROPE;
Mnemonic: TYPE = REF MnemonicRep;
MnemonicRep: TYPE = RECORD [
name: ROPE,
mesaTypeDecl, roseType: ROPENIL,
analyzeSinceEpoch: LONG CARDINAL,
bits: CARDINAL ← 0];
ConstructMnemonic: RoseTranslateTypes.SignalTypeConstructor = TRUSTED
BEGIN
asAny: REF ANY ← RoseTranslateTypes.GetParm[1, "file", parms];
mnemName, fileName: ROPE;
atom: ATOM;
need: BOOLEANTRUE;
fileString: LONG STRING ← [256];
tempString: LONG STRING ← [256];
fileTime: System.GreenwichMeanTime;
fileSinceEpoch: LONG CARDINAL;
fileExists: BOOLEANTRUE;
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: BOOLEANFALSE;
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;
mnemProcs: RoseTranslateTypes.SignalTypeProcs ← NEW [RoseTranslateTypes.SignalTypeProcsRep ← [
Info: Info,
Describe: Describe,
Cannonize: Cannonize,
MesaTypeDecl: MesaTypeDecl]];
Info: PROC [data: REF ANY] RETURNS [bitWidth: INT, roseType, mesaType: ROPE] =
BEGIN
mnem: Mnemonic ← NARROW[data];
bitWidth ← mnem.bits;
roseType ← mnem.roseType;
mesaType ← mnem.name;
END;
Describe: PROC [data: REF ANY] RETURNS [description: ROPE] =
BEGIN
mnem: Mnemonic ← NARROW[data];
description ← IO.PutFR["Mnemonic[\"%g\"]", IO.rope[mnem.name]];
END;
Cannonize: PROC [data: REF ANY] RETURNS [cannonized: REF ANY] =
{cannonized ← data};
MesaTypeDecl: PROC [data: REF ANY] RETURNS [mesaTypeDecl: ROPE] =
BEGIN
mnem: Mnemonic ← NARROW[data];
mesaTypeDecl ← mnem.mesaTypeDecl;
END;
RoseTranslateTypes.RegisterSignalTypeConstructor["Mnemonic", ConstructMnemonic];
END.