DIRECTORY Atom, FS, Basics, BasicTime, IO, Mnemonics, Rope, RoseTranslateTypes, RoseTypes, SignalTypeRegistration, VFonts; MnemonicsImpl: CEDAR PROGRAM IMPORTS Atom, FS, Basics, BasicTime, IO, Rope, RoseTranslateTypes, SignalTypeRegistration, VFonts EXPORTS Mnemonics = BEGIN ROPE: TYPE = Rope.ROPE; WordPtr: TYPE = RoseTypes.WordPtr; NodeType: TYPE = RoseTypes.NodeType; NodeTypeRep: TYPE = RoseTypes.NodeTypeRep; Format: TYPE = RoseTypes.Format; Node: TYPE = RoseTypes.Node; NodeTestProc: TYPE = RoseTypes.NodeTestProc; NodeTestData: TYPE = RoseTypes.NodeTestData; MnemData: TYPE = REF MnemDataRep; MnemDataRep: TYPE = RECORD [ fileSinceEpoch: LONG CARDINAL, bits: CARDINAL, name, mesaType, mesaTypeDecl: ROPE, members: SEQUENCE length: CARDINAL OF ROPE ]; mnemonicProcs: RoseTypes.NodeProcs _ NEW [RoseTypes.NodeProcsRep _ [ Bits: MnemonicBits, MesaUse: MnemonicMesaUse, MesaDefinition: MnemonicMesaDefinition, UserDescription: MnemonicUserDescription, MesaDescription: MnemonicMesaDescription, ListFormats: MnemonicListFormats, GetFormat: MnemonicGetFormat]]; ConstructMnemonic: RoseTranslateTypes.NodeTypeConstructor--PROC [parms: REF ANY - -UNION [BindingList, Args]- -] RETURNS [type: NodeType]-- = BEGIN name: RoseTranslateTypes.Quoted _ NARROW[RoseTranslateTypes.GetParm[n: 1, name: "name", parms: parms]]; type _ Mnemonic[name.rope]; END; Mnemonic: PUBLIC PROC [mnemName: ROPE] RETURNS [nt: NodeType] = BEGIN fileName: ROPE; atom: ATOM; memList: LIST OF ROPE _ NIL; count, newCount, bits: CARDINAL _ 0; file: IO.STREAM; md: MnemData; saturated: BOOLEAN _ FALSE; fileTime: BasicTime.GMT; fileSinceEpoch: LONG CARDINAL; fileExists: BOOLEAN _ TRUE; atom _ Atom.MakeAtom[fileName _ mnemName.Concat[".mnemonics"]]; nt _ NARROW[Atom.GetProp[atom: atom, prop: $mnemonicRoseImpl]]; fileTime _ FS.FileInfo[fileName !FS.Error => {fileExists _ FALSE; CONTINUE}].created; IF NOT fileExists THEN ERROR; fileSinceEpoch _ BasicTime.Period[from: BasicTime.earliestGMT, to: fileTime]; IF nt # NIL THEN BEGIN mnem: MnemData _ NARROW[nt.typeData]; IF fileSinceEpoch = mnem.fileSinceEpoch THEN RETURN; END; file _ FS.StreamOpen[fileName]; [] _ file.SkipWhitespace[flushComments: FALSE]; WHILE NOT file.EndOf[] DO mem: ROPE _ file.GetTokenRope[IO.IDProc].token; newCount: CARDINAL _ count + 1; overlap: CARDINAL _ Basics.BITAND[count, newCount]; IF saturated THEN bits _ bits + 1; saturated _ overlap = 0; count _ newCount; memList _ CONS[mem, memList]; [] _ file.SkipWhitespace[flushComments: FALSE]; ENDLOOP; file.Close[]; md _ NEW [MnemDataRep[count]]; md.fileSinceEpoch _ fileSinceEpoch; md.name _ mnemName; md.bits _ bits; md.mesaType _ mnemName; md.mesaTypeDecl _ "}"; FOR i: CARDINAL DECREASING IN [0 .. md.length) DO md[i] _ memList.first; IF i+1 = md.length THEN md.mesaTypeDecl _ memList.first.Cat[md.mesaTypeDecl] ELSE md.mesaTypeDecl _ memList.first.Cat[", ", md.mesaTypeDecl]; memList _ memList.rest; ENDLOOP; md.mesaTypeDecl _ mnemName.Cat[": TYPE = {", md.mesaTypeDecl]; nt _ NEW [NodeTypeRep _ [ procs: mnemonicProcs, typeData: md, structure: atom[] ]]; Atom.PutProp[atom: atom, prop: $mnemonicRoseImpl, val: nt]; END; MnemonicBits: PROC [nt: NodeType] RETURNS [bits: INTEGER] = {md: MnemData _ NARROW[nt.typeData]; bits _ md.bits}; MnemonicMesaUse: PROC [nt: NodeType] RETURNS [m: RoseTypes.Mesa] = {md: MnemData _ NARROW[nt.typeData]; m _ [md.mesaType]}; MnemonicMesaDefinition: PROC [nt: NodeType] RETURNS [m: RoseTypes.Mesa] = {md: MnemData _ NARROW[nt.typeData]; m _ [md.mesaTypeDecl]}; MnemonicUserDescription: PROC [nt: NodeType] RETURNS [ud: ROPE] = {md: MnemData _ NARROW[nt.typeData]; ud _ Rope.Cat["Mnemonic[\"", md.name, "\"]"]}; MnemonicMesaDescription: PROC [nt: NodeType] RETURNS [m: RoseTypes.Mesa] = {md: MnemData _ NARROW[nt.typeData]; m _ [ mesa: Rope.Cat["Mnemonics.Mnemonic[\"", md.name, "\"]"], imports: LIST["Mnemonics"]]}; MnemonicListFormats: PROC [NodeType] RETURNS [rl: RoseTypes.RopeList] = {rl _ LIST["mnem"]}; MnemonicGetFormat: PROC [NodeType, ROPE] RETURNS [Format] = {RETURN [mnemonicFormat]}; mnemonicFormat: RoseTypes.Format _ NEW [RoseTypes.FormatRep _ [ FormatValue: MnemonicFormatValue, ParseValue: MnemonicParseValue, FormatTest: MnemonicFormatTest, ParseTest: MnemonicParseTest, MaxWidth: MnemonicMaxWidth, formatData: NIL, key: "mnem"]]; MnemonicFormatValue: PROC [node: Node, format: Format, where: WordPtr] RETURNS [rope: ROPE] = BEGIN md: MnemData _ NARROW[node.type.typeData]; index: CARDINAL; TRUSTED {index _ Basics.BITAND[where^, masks[md.bits]]}; RETURN [IF index >= md.length THEN "??" ELSE md[index]]; END; masks: ARRAY [0..16] OF CARDINAL = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535]; MnemonicParseValue: PROC [node: Node, format: Format, where: WordPtr, from: IO.STREAM] RETURNS [success: BOOLEAN] = BEGIN md: MnemData _ NARROW[node.type.typeData]; i: CARDINAL; rope: ROPE _ from.GetTokenRope[].token; [i, success] _ Lookup[md, rope]; IF success THEN TRUSTED {where^ _ i}; END; Lookup: PROC [md: MnemData, rope: ROPE] RETURNS [index: CARDINAL, success: BOOLEAN] = BEGIN FOR i: CARDINAL IN [0 .. md.length) DO IF rope.Equal[md[i]] THEN RETURN [i, TRUE]; ENDLOOP; success _ FALSE; index _ 0; END; MnemonicMaxWidth: PROC [nodeType: NodeType, format: Format, font: VFonts.Font] RETURNS [INT] = BEGIN md: MnemData _ NARROW[nodeType.typeData]; mw: INT _ 0; FOR i: CARDINAL IN [0 .. md.length) DO mw _ MAX[mw, VFonts.StringWidth[md[i], font]]; ENDLOOP; RETURN [mw]; END; MnemonicParseTest: PROC [nodeType: NodeType, format: Format, from: IO.STREAM] RETURNS [success: BOOLEAN, testProc: NodeTestProc, testData: NodeTestData] = BEGIN md: MnemData _ NARROW[nodeType.typeData]; i: CARDINAL; rope: ROPE _ from.GetTokenRope[].token; [i, success] _ Lookup[md, rope]; IF success THEN testData _ NEW [CARDINAL _ i] ELSE testData _ NIL; testProc _ TestMnemonic; END; MnemonicFormatTest: PROC [nodeType: NodeType, format: Format, testProc: NodeTestProc, testData: NodeTestData] RETURNS [rope: ROPE] = BEGIN md: MnemData _ NARROW[nodeType.typeData]; rc: REF CARDINAL _ NARROW[testData]; rope _ IF rc = NIL THEN "??" ELSE md[rc^]; END; TestMnemonic: RoseTypes.NodeTestProc--PROC [where: WordPtr, testData: NodeTestData, nodeType: NodeType] RETURNS [passes: BOOLEAN]-- = BEGIN rc: REF CARDINAL _ NARROW[testData]; md: MnemData _ NARROW[nodeType.typeData]; TRUSTED {passes _ rc^ = Basics.BITAND[where^, masks[md.bits]]}; END; SignalTypeRegistration.RegisterNodeTypeConstructor["Mnemonic", ConstructMnemonic]; END. RMnemonicsImpl.Mesa Last Edited by: Spreitzer, March 10, 1984 1:27:35 pm PST Κ˜J™J™8Icode˜KšΟk œœœQ˜zK˜šΠbx œœ˜Kšœœœ:˜aKšœ ˜—K˜Kš˜K˜Kšœœœ˜K˜Kšœ œ˜"Kšœ œ˜$Kšœ œ˜*Kšœœ˜ Kšœœ˜Kšœœ˜,Kšœœ˜,K˜Kšœ œœ ˜!šœ œœ˜Kšœœœ˜Kšœœ˜Kšœœ˜#Kšœ œ œœ˜*K˜—K˜šœ%œ˜DKšœ˜Kšœ˜Kšœ'˜'Kšœ)˜)Kšœ)˜)Kšœ!˜!Kšœ˜—K˜šΟnœ(ΟcRœ˜Kš˜Kšœ"œ?˜gK˜Kšœ˜—K˜š Ÿœœœ œœ˜?Kš˜Kšœ œ˜Kšœœ˜ Kš œ œœœœ˜Kšœœ˜$Kšœœœ˜K˜ Kšœ œœ˜Kšœœ˜Kšœœœ˜Kšœ œœ˜K˜K˜?Kšœœ4˜?K˜Kšœ;œœ ˜UK˜Kšœœ œœ˜KšœM˜Mšœœ˜Kš˜Kšœœ˜%Kšœ&œœ˜4Kšœ˜—K˜K˜Kšœ(œ˜/šœœ˜Kšœœœ˜/Kšœ œ ˜Kšœ œ œ˜3Kšœ œ˜"K˜K˜Kšœ œ˜Kšœ(œ˜/Kšœ˜—K˜ Kšœœ˜Kšœ#˜#K˜K˜K˜Kšœ˜š œœ œœ˜1K˜šœ˜Kšœ5˜9Kšœ<˜@—K˜Kšœ˜—Kšœ>˜>šœœ˜K˜K˜ K˜—Kšœ;˜;Kšœ˜—K˜šŸ œœœœ˜;Kšœœ˜5—K˜šŸœœœ˜BKšœœ"˜8—K˜šŸœœœ˜IKšœœ&˜<—K˜šŸœœœœ˜AKšœœ˜$Kšœ.˜.—K˜šŸœœœ˜JKšœœ˜$šœ˜Kšœ8˜8Kšœ œ˜——K˜šŸœœ œ˜GKšœœ ˜—K˜šŸœœ œœ ˜;Kšœœ˜—K˜šœ#œ˜?Kšœ!˜!Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ œ˜Kšœ˜—K˜šŸœœ.œœ˜]Kš˜Kšœœ˜*Kšœ ˜Kšœœ˜8Kšœœœœ ˜8Kšœ˜—K˜Kšœœ œœX˜xK˜š Ÿœœ4œœœ œ˜sKš˜Kšœœ˜*Kšœœ˜ Kšœœ˜'K˜ Kšœ œœ˜%Kšœ˜—K˜š Ÿœœœœ œ œ˜UKš˜šœœœ˜&Kšœœœœ˜+Kšœ˜—Kšœ œ ˜Kšœ˜—K˜šŸœœ9œœ˜^Kš˜Kšœœ˜)Kšœœ˜ šœœœ˜&Kšœœ&˜.Kšœ˜—Kšœ˜ Kšœ˜—K˜š Ÿœœ,œœœ œ3˜šKš˜Kšœœ˜)Kšœœ˜ Kšœœ˜'K˜ Kš œ œ œœœ œ˜BK˜Kšœ˜—K˜šŸœœVœœ˜„Kš˜Kšœœ˜)Kšœœœœ ˜$Kš œœœœœ ˜*Kšœ˜—K˜šŸ œ _œ˜…Kš˜Kšœœœœ ˜$Kšœœ˜)Kšœœ˜?Kšœ˜—K˜KšœR˜RK˜Kšœ˜—…—|!λ